diff options
Diffstat (limited to 'drivers')
1593 files changed, 51415 insertions, 95446 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig index af02a8a8ec4a..694d5a70d6ce 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -184,4 +184,6 @@ source "drivers/ras/Kconfig" source "drivers/thunderbolt/Kconfig" +source "drivers/android/Kconfig" + endmenu diff --git a/drivers/Makefile b/drivers/Makefile index 628b512b625b..527a6da8d539 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -50,7 +50,10 @@ obj-$(CONFIG_RESET_CONTROLLER) += reset/ obj-y += tty/ obj-y += char/ -# gpu/ comes after char for AGP vs DRM startup +# iommu/ comes before gpu as gpu are using iommu controllers +obj-$(CONFIG_IOMMU_SUPPORT) += iommu/ + +# gpu/ comes after char for AGP vs DRM startup and after iommu obj-y += gpu/ obj-$(CONFIG_CONNECTOR) += connector/ @@ -141,7 +144,6 @@ obj-y += clk/ obj-$(CONFIG_MAILBOX) += mailbox/ obj-$(CONFIG_HWSPINLOCK) += hwspinlock/ -obj-$(CONFIG_IOMMU_SUPPORT) += iommu/ obj-$(CONFIG_REMOTEPROC) += remoteproc/ obj-$(CONFIG_RPMSG) += rpmsg/ @@ -162,3 +164,4 @@ obj-$(CONFIG_MCB) += mcb/ obj-$(CONFIG_RAS) += ras/ obj-$(CONFIG_THUNDERBOLT) += thunderbolt/ obj-$(CONFIG_CORESIGHT) += coresight/ +obj-$(CONFIG_ANDROID) += android/ diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index 1fdf5e07a1c7..1020b1b53a17 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c @@ -170,7 +170,7 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr) acpi_status status; int ret; - if (pr->apic_id == -1) + if (pr->phys_id == -1) return -ENODEV; status = acpi_evaluate_integer(pr->handle, "_STA", NULL, &sta); @@ -180,13 +180,13 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr) cpu_maps_update_begin(); cpu_hotplug_begin(); - ret = acpi_map_lsapic(pr->handle, pr->apic_id, &pr->id); + ret = acpi_map_cpu(pr->handle, pr->phys_id, &pr->id); if (ret) goto out; ret = arch_register_cpu(pr->id); if (ret) { - acpi_unmap_lsapic(pr->id); + acpi_unmap_cpu(pr->id); goto out; } @@ -215,7 +215,7 @@ static int acpi_processor_get_info(struct acpi_device *device) union acpi_object object = { 0 }; struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; struct acpi_processor *pr = acpi_driver_data(device); - int apic_id, cpu_index, device_declaration = 0; + int phys_id, cpu_index, device_declaration = 0; acpi_status status = AE_OK; static int cpu0_initialized; unsigned long long value; @@ -262,15 +262,18 @@ static int acpi_processor_get_info(struct acpi_device *device) pr->acpi_id = value; } - apic_id = acpi_get_apicid(pr->handle, device_declaration, pr->acpi_id); - if (apic_id < 0) - acpi_handle_debug(pr->handle, "failed to get CPU APIC ID.\n"); - pr->apic_id = apic_id; + phys_id = acpi_get_phys_id(pr->handle, device_declaration, pr->acpi_id); + if (phys_id < 0) + acpi_handle_debug(pr->handle, "failed to get CPU physical ID.\n"); + pr->phys_id = phys_id; - cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id); + cpu_index = acpi_map_cpuid(pr->phys_id, pr->acpi_id); if (!cpu0_initialized && !acpi_has_cpu_in_madt()) { cpu0_initialized = 1; - /* Handle UP system running SMP kernel, with no LAPIC in MADT */ + /* + * Handle UP system running SMP kernel, with no CPU + * entry in MADT + */ if ((cpu_index == -1) && (num_online_cpus() == 1)) cpu_index = 0; } @@ -458,7 +461,7 @@ static void acpi_processor_remove(struct acpi_device *device) /* Remove the CPU. */ arch_unregister_cpu(pr->id); - acpi_unmap_lsapic(pr->id); + acpi_unmap_cpu(pr->id); cpu_hotplug_done(); cpu_maps_update_done(); diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 7556e7c4a055..9b693d54c743 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -305,60 +305,6 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { */ /* - * Lenovo has a mix of systems OSI(Linux) situations - * and thus we can not wildcard the vendor. - * - * _OSI(Linux) helps sound - * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad R61"), - * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T61"), - * T400, T500 - * _OSI(Linux) has Linux specific hooks - * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"), - * _OSI(Linux) is a NOP: - * DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"), - * DMI_MATCH(DMI_PRODUCT_VERSION, "LENOVO3000 V100"), - */ - { - .callback = dmi_enable_osi_linux, - .ident = "Lenovo ThinkPad R61", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad R61"), - }, - }, - { - .callback = dmi_enable_osi_linux, - .ident = "Lenovo ThinkPad T61", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T61"), - }, - }, - { - .callback = dmi_enable_osi_linux, - .ident = "Lenovo ThinkPad X61", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"), - }, - }, - { - .callback = dmi_enable_osi_linux, - .ident = "Lenovo ThinkPad T400", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T400"), - }, - }, - { - .callback = dmi_enable_osi_linux, - .ident = "Lenovo ThinkPad T500", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T500"), - }, - }, - /* * Without this this EEEpc exports a non working WMI interface, with * this it exports a working "good old" eeepc_laptop interface, fixing * both brightness control, and rfkill not working. diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 897640188acd..c0d44d394ca3 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -257,7 +257,7 @@ int acpi_bus_init_power(struct acpi_device *device) device->power.state = ACPI_STATE_UNKNOWN; if (!acpi_device_is_present(device)) - return 0; + return -ENXIO; result = acpi_device_get_power(device, &state); if (result) @@ -680,13 +680,21 @@ static int acpi_device_wakeup(struct acpi_device *adev, u32 target_state, if (error) return error; + if (adev->wakeup.flags.enabled) + return 0; + res = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number); - if (ACPI_FAILURE(res)) { + if (ACPI_SUCCESS(res)) { + adev->wakeup.flags.enabled = 1; + } else { acpi_disable_wakeup_device_power(adev); return -EIO; } } else { - acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number); + if (adev->wakeup.flags.enabled) { + acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number); + adev->wakeup.flags.enabled = 0; + } acpi_disable_wakeup_device_power(adev); } return 0; diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 5f9b74b9b71f..1b5853f384e2 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -844,6 +844,8 @@ static int ec_install_handlers(struct acpi_ec *ec) static void ec_remove_handlers(struct acpi_ec *ec) { + if (!test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) + return; acpi_disable_gpe(NULL, ec->gpe); if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index caf9b76b7ef8..7a36f02598a6 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -325,6 +325,7 @@ static int acpi_fan_probe(struct platform_device *pdev) struct thermal_cooling_device *cdev; struct acpi_fan *fan; struct acpi_device *device = ACPI_COMPANION(&pdev->dev); + char *name; fan = devm_kzalloc(&pdev->dev, sizeof(*fan), GFP_KERNEL); if (!fan) { @@ -346,7 +347,12 @@ static int acpi_fan_probe(struct platform_device *pdev) } } - cdev = thermal_cooling_device_register("Fan", device, + if (!strncmp(pdev->name, "PNP0C0B", strlen("PNP0C0B"))) + name = "Fan"; + else + name = acpi_device_bid(device); + + cdev = thermal_cooling_device_register(name, device, &fan_cooling_ops); if (IS_ERR(cdev)) { result = PTR_ERR(cdev); diff --git a/drivers/acpi/int340x_thermal.c b/drivers/acpi/int340x_thermal.c index a27d31d1ba24..9dcf83682e36 100644 --- a/drivers/acpi/int340x_thermal.c +++ b/drivers/acpi/int340x_thermal.c @@ -14,10 +14,10 @@ #include "internal.h" -#define DO_ENUMERATION 0x01 +#define INT3401_DEVICE 0X01 static const struct acpi_device_id int340x_thermal_device_ids[] = { - {"INT3400", DO_ENUMERATION }, - {"INT3401"}, + {"INT3400"}, + {"INT3401", INT3401_DEVICE}, {"INT3402"}, {"INT3403"}, {"INT3404"}, @@ -34,7 +34,10 @@ static int int340x_thermal_handler_attach(struct acpi_device *adev, const struct acpi_device_id *id) { #if defined(CONFIG_INT340X_THERMAL) || defined(CONFIG_INT340X_THERMAL_MODULE) - if (id->driver_data == DO_ENUMERATION) + acpi_create_platform_device(adev); +#elif defined(INTEL_SOC_DTS_THERMAL) || defined(INTEL_SOC_DTS_THERMAL_MODULE) + /* Intel SoC DTS thermal driver needs INT3401 to set IRQ descriptor */ + if (id->driver_data == INT3401_DEVICE) acpi_create_platform_device(adev); #endif return 1; diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 7cc4e33179f9..5277a0ee5704 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -413,6 +413,9 @@ int acpi_pci_irq_enable(struct pci_dev *dev) return 0; } + if (dev->irq_managed && dev->irq > 0) + return 0; + entry = acpi_pci_irq_lookup(dev, pin); if (!entry) { /* @@ -456,6 +459,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) return rc; } dev->irq = rc; + dev->irq_managed = 1; if (link) snprintf(link_desc, sizeof(link_desc), " -> Link[%s]", link); @@ -478,7 +482,7 @@ void acpi_pci_irq_disable(struct pci_dev *dev) u8 pin; pin = dev->pin; - if (!pin) + if (!pin || !dev->irq_managed || dev->irq <= 0) return; /* Keep IOAPIC pin configuration when suspending */ @@ -506,6 +510,9 @@ void acpi_pci_irq_disable(struct pci_dev *dev) */ dev_dbg(&dev->dev, "PCI INT %c disabled\n", pin_name(pin)); - if (gsi >= 0 && dev->irq > 0) + if (gsi >= 0) { acpi_unregister_gsi(gsi); + dev->irq = 0; + dev->irq_managed = 0; + } } diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index ef58f46c8442..02e48394276c 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -69,7 +69,7 @@ static int map_madt_entry(int type, u32 acpi_id) unsigned long madt_end, entry; static struct acpi_table_madt *madt; static int read_madt; - int apic_id = -1; + int phys_id = -1; /* CPU hardware ID */ if (!read_madt) { if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0, @@ -79,7 +79,7 @@ static int map_madt_entry(int type, u32 acpi_id) } if (!madt) - return apic_id; + return phys_id; entry = (unsigned long)madt; madt_end = entry + madt->header.length; @@ -91,18 +91,18 @@ static int map_madt_entry(int type, u32 acpi_id) struct acpi_subtable_header *header = (struct acpi_subtable_header *)entry; if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { - if (!map_lapic_id(header, acpi_id, &apic_id)) + if (!map_lapic_id(header, acpi_id, &phys_id)) break; } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) { - if (!map_x2apic_id(header, type, acpi_id, &apic_id)) + if (!map_x2apic_id(header, type, acpi_id, &phys_id)) break; } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { - if (!map_lsapic_id(header, type, acpi_id, &apic_id)) + if (!map_lsapic_id(header, type, acpi_id, &phys_id)) break; } entry += header->length; } - return apic_id; + return phys_id; } static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) @@ -110,7 +110,7 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *obj; struct acpi_subtable_header *header; - int apic_id = -1; + int phys_id = -1; if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) goto exit; @@ -125,53 +125,52 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) } header = (struct acpi_subtable_header *)obj->buffer.pointer; - if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { - map_lapic_id(header, acpi_id, &apic_id); - } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { - map_lsapic_id(header, type, acpi_id, &apic_id); - } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) { - map_x2apic_id(header, type, acpi_id, &apic_id); - } + if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) + map_lapic_id(header, acpi_id, &phys_id); + else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) + map_lsapic_id(header, type, acpi_id, &phys_id); + else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) + map_x2apic_id(header, type, acpi_id, &phys_id); exit: kfree(buffer.pointer); - return apic_id; + return phys_id; } -int acpi_get_apicid(acpi_handle handle, int type, u32 acpi_id) +int acpi_get_phys_id(acpi_handle handle, int type, u32 acpi_id) { - int apic_id; + int phys_id; - apic_id = map_mat_entry(handle, type, acpi_id); - if (apic_id == -1) - apic_id = map_madt_entry(type, acpi_id); + phys_id = map_mat_entry(handle, type, acpi_id); + if (phys_id == -1) + phys_id = map_madt_entry(type, acpi_id); - return apic_id; + return phys_id; } -int acpi_map_cpuid(int apic_id, u32 acpi_id) +int acpi_map_cpuid(int phys_id, u32 acpi_id) { #ifdef CONFIG_SMP int i; #endif - if (apic_id == -1) { + if (phys_id == -1) { /* * On UP processor, there is no _MAT or MADT table. - * So above apic_id is always set to -1. + * So above phys_id is always set to -1. * * BIOS may define multiple CPU handles even for UP processor. * For example, * * Scope (_PR) - * { + * { * Processor (CPU0, 0x00, 0x00000410, 0x06) {} * Processor (CPU1, 0x01, 0x00000410, 0x06) {} * Processor (CPU2, 0x02, 0x00000410, 0x06) {} * Processor (CPU3, 0x03, 0x00000410, 0x06) {} * } * - * Ignores apic_id and always returns 0 for the processor + * Ignores phys_id and always returns 0 for the processor * handle with acpi id 0 if nr_cpu_ids is 1. * This should be the case if SMP tables are not found. * Return -1 for other CPU's handle. @@ -179,28 +178,28 @@ int acpi_map_cpuid(int apic_id, u32 acpi_id) if (nr_cpu_ids <= 1 && acpi_id == 0) return acpi_id; else - return apic_id; + return phys_id; } #ifdef CONFIG_SMP for_each_possible_cpu(i) { - if (cpu_physical_id(i) == apic_id) + if (cpu_physical_id(i) == phys_id) return i; } #else /* In UP kernel, only processor 0 is valid */ - if (apic_id == 0) - return apic_id; + if (phys_id == 0) + return phys_id; #endif return -1; } int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) { - int apic_id; + int phys_id; - apic_id = acpi_get_apicid(handle, type, acpi_id); + phys_id = acpi_get_phys_id(handle, type, acpi_id); - return acpi_map_cpuid(apic_id, acpi_id); + return acpi_map_cpuid(phys_id, acpi_id); } EXPORT_SYMBOL_GPL(acpi_get_cpuid); diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 499536504698..87b704e41877 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -985,8 +985,6 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr) state->flags = 0; switch (cx->type) { case ACPI_STATE_C1: - if (cx->entry_method != ACPI_CSTATE_FFH) - state->flags |= CPUIDLE_FLAG_TIME_INVALID; state->enter = acpi_idle_enter_c1; state->enter_dead = acpi_idle_play_dead; diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 2ba8f02ced36..782a0d15c25f 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -200,7 +200,7 @@ bool acpi_dev_resource_address_space(struct acpi_resource *ares, status = acpi_resource_to_address64(ares, &addr); if (ACPI_FAILURE(status)) - return true; + return false; res->start = addr.minimum; res->end = addr.maximum; diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 1b1cf558d3d3..dc4d8960684a 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1001,7 +1001,7 @@ static void acpi_free_power_resources_lists(struct acpi_device *device) if (device->wakeup.flags.valid) acpi_power_resources_list_free(&device->wakeup.resources); - if (!device->flags.power_manageable) + if (!device->power.flags.power_resources) return; for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) { @@ -1744,10 +1744,8 @@ static void acpi_bus_get_power_flags(struct acpi_device *device) device->power.flags.power_resources) device->power.states[ACPI_STATE_D3_COLD].flags.os_accessible = 1; - if (acpi_bus_init_power(device)) { - acpi_free_power_resources_lists(device); + if (acpi_bus_init_power(device)) device->flags.power_manageable = 0; - } } static void acpi_bus_get_flags(struct acpi_device *device) @@ -2214,7 +2212,7 @@ static void acpi_device_dep_initialize(struct acpi_device *adev) status = acpi_evaluate_reference(adev->handle, "_DEP", NULL, &dep_devices); if (ACPI_FAILURE(status)) { - dev_err(&adev->dev, "Failed to evaluate _DEP.\n"); + dev_dbg(&adev->dev, "Failed to evaluate _DEP.\n"); return; } @@ -2224,7 +2222,7 @@ static void acpi_device_dep_initialize(struct acpi_device *adev) status = acpi_get_object_info(dep_devices.handles[i], &info); if (ACPI_FAILURE(status)) { - dev_err(&adev->dev, "Error reading device info\n"); + dev_dbg(&adev->dev, "Error reading _DEP device info\n"); continue; } @@ -2371,13 +2369,18 @@ static void acpi_bus_attach(struct acpi_device *device) /* Skip devices that are not present. */ if (!acpi_device_is_present(device)) { device->flags.visited = false; + device->flags.power_manageable = 0; return; } if (device->handler) goto ok; if (!device->flags.initialized) { - acpi_bus_update_power(device, NULL); + device->flags.power_manageable = + device->power.states[ACPI_STATE_D0].flags.valid; + if (acpi_bus_init_power(device)) + device->flags.power_manageable = 0; + device->flags.initialized = true; } device->flags.visited = false; diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index dd8ff63ee2b4..cd49a3982b6a 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -346,22 +346,16 @@ acpi_evaluate_reference(acpi_handle handle, package = buffer.pointer; if ((buffer.length == 0) || !package) { - printk(KERN_ERR PREFIX "No return object (len %X ptr %p)\n", - (unsigned)buffer.length, package); status = AE_BAD_DATA; acpi_util_eval_error(handle, pathname, status); goto end; } if (package->type != ACPI_TYPE_PACKAGE) { - printk(KERN_ERR PREFIX "Expecting a [Package], found type %X\n", - package->type); status = AE_BAD_DATA; acpi_util_eval_error(handle, pathname, status); goto end; } if (!package->package.count) { - printk(KERN_ERR PREFIX "[Package] has zero elements (%p)\n", - package); status = AE_BAD_DATA; acpi_util_eval_error(handle, pathname, status); goto end; @@ -380,17 +374,13 @@ acpi_evaluate_reference(acpi_handle handle, if (element->type != ACPI_TYPE_LOCAL_REFERENCE) { status = AE_BAD_DATA; - printk(KERN_ERR PREFIX - "Expecting a [Reference] package element, found type %X\n", - element->type); acpi_util_eval_error(handle, pathname, status); break; } if (!element->reference.handle) { - printk(KERN_WARNING PREFIX "Invalid reference in" - " package %s\n", pathname); status = AE_NULL_ENTRY; + acpi_util_eval_error(handle, pathname, status); break; } /* Get the acpi_handle. */ diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 185a57d13723..032db459370f 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -155,6 +155,7 @@ struct acpi_video_bus { u8 dos_setting; struct acpi_video_enumerated_device *attached_array; u8 attached_count; + u8 child_count; struct acpi_video_bus_cap cap; struct acpi_video_bus_flags flags; struct list_head video_device_list; @@ -504,6 +505,33 @@ static struct dmi_system_id video_dmi_table[] __initdata = { DMI_MATCH(DMI_PRODUCT_NAME, "HP ENVY 15 Notebook PC"), }, }, + + { + .callback = video_disable_native_backlight, + .ident = "SAMSUNG 870Z5E/880Z5E/680Z5E", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "870Z5E/880Z5E/680Z5E"), + }, + }, + { + .callback = video_disable_native_backlight, + .ident = "SAMSUNG 370R4E/370R4V/370R5E/3570RE/370R5V", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "370R4E/370R4V/370R5E/3570RE/370R5V"), + }, + }, + + { + /* https://bugzilla.redhat.com/show_bug.cgi?id=1163574 */ + .callback = video_disable_native_backlight, + .ident = "Dell XPS15 L521X", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "XPS L521X"), + }, + }, {} }; @@ -1159,8 +1187,12 @@ static bool acpi_video_device_in_dod(struct acpi_video_device *device) struct acpi_video_bus *video = device->video; int i; - /* If we have a broken _DOD, no need to test */ - if (!video->attached_count) + /* + * If we have a broken _DOD or we have more than 8 output devices + * under the graphics controller node that we can't proper deal with + * in the operation region code currently, no need to test. + */ + if (!video->attached_count || video->child_count > 8) return true; for (i = 0; i < video->attached_count; i++) { @@ -1413,6 +1445,7 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video, dev_err(&dev->dev, "Can't attach device\n"); break; } + video->child_count++; } return status; } diff --git a/drivers/android/Kconfig b/drivers/android/Kconfig new file mode 100644 index 000000000000..bdfc6c6f4f5a --- /dev/null +++ b/drivers/android/Kconfig @@ -0,0 +1,37 @@ +menu "Android" + +config ANDROID + bool "Android Drivers" + ---help--- + Enable support for various drivers needed on the Android platform + +if ANDROID + +config ANDROID_BINDER_IPC + bool "Android Binder IPC Driver" + depends on MMU + default n + ---help--- + Binder is used in Android for both communication between processes, + and remote method invocation. + + This means one Android process can call a method/routine in another + Android process, using Binder to identify, invoke and pass arguments + between said processes. + +config ANDROID_BINDER_IPC_32BIT + bool + depends on !64BIT && ANDROID_BINDER_IPC + default y + ---help--- + The Binder API has been changed to support both 32 and 64bit + applications in a mixed environment. + + Enable this to support an old 32-bit Android user-space (v4.4 and + earlier). + + Note that enabling this will break newer Android user-space. + +endif # if ANDROID + +endmenu diff --git a/drivers/android/Makefile b/drivers/android/Makefile new file mode 100644 index 000000000000..3b7e4b072c58 --- /dev/null +++ b/drivers/android/Makefile @@ -0,0 +1,3 @@ +ccflags-y += -I$(src) # needed for trace events + +obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o diff --git a/drivers/staging/android/binder.c b/drivers/android/binder.c index c69c40d69d5c..8c43521d3f11 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/android/binder.c @@ -38,7 +38,11 @@ #include <linux/slab.h> #include <linux/pid_namespace.h> -#include "binder.h" +#ifdef CONFIG_ANDROID_BINDER_IPC_32BIT +#define BINDER_IPC_32BIT 1 +#endif + +#include <uapi/linux/android/binder.h> #include "binder_trace.h" static DEFINE_MUTEX(binder_main_lock); diff --git a/drivers/staging/android/binder_trace.h b/drivers/android/binder_trace.h index 7f20f3dc8369..7f20f3dc8369 100644 --- a/drivers/staging/android/binder_trace.h +++ b/drivers/android/binder_trace.h diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index cd4cccbfd2ab..5f601553b9b0 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -61,7 +61,7 @@ config ATA_ACPI config SATA_ZPODD bool "SATA Zero Power Optical Disc Drive (ZPODD) support" - depends on ATA_ACPI && PM_RUNTIME + depends on ATA_ACPI && PM default n help This option adds support for SATA Zero Power Optical Disc @@ -835,6 +835,7 @@ config PATA_AT32 config PATA_AT91 tristate "PATA support for AT91SAM9260" depends on ARM && SOC_AT91SAM9 + depends on !ARCH_MULTIPLATFORM help This option enables support for IDE devices on the Atmel AT91SAM9260 SoC. diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 49f1e6890587..33bb06e006c9 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -325,7 +325,6 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x9d05), board_ahci }, /* Sunrise Point-LP RAID */ { PCI_VDEVICE(INTEL, 0x9d07), board_ahci }, /* Sunrise Point-LP RAID */ { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */ - { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H RAID */ { PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */ { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */ { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */ diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c index feeb8f1e2fe8..cbcd20810355 100644 --- a/drivers/ata/ahci_xgene.c +++ b/drivers/ata/ahci_xgene.c @@ -125,10 +125,11 @@ static int xgene_ahci_restart_engine(struct ata_port *ap) * xgene_ahci_qc_issue - Issue commands to the device * @qc: Command to issue * - * Due to Hardware errata for IDENTIFY DEVICE command, the controller cannot - * clear the BSY bit after receiving the PIO setup FIS. This results in the dma - * state machine goes into the CMFatalErrorUpdate state and locks up. By - * restarting the dma engine, it removes the controller out of lock up state. + * Due to Hardware errata for IDENTIFY DEVICE command and PACKET + * command of ATAPI protocol set, the controller cannot clear the BSY bit + * after receiving the PIO setup FIS. This results in the DMA state machine + * going into the CMFatalErrorUpdate state and locks up. By restarting the + * DMA engine, it removes the controller out of lock up state. */ static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc) { @@ -137,7 +138,8 @@ static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc) struct xgene_ahci_context *ctx = hpriv->plat_data; int rc = 0; - if (unlikely(ctx->last_cmd[ap->port_no] == ATA_CMD_ID_ATA)) + if (unlikely((ctx->last_cmd[ap->port_no] == ATA_CMD_ID_ATA) || + (ctx->last_cmd[ap->port_no] == ATA_CMD_PACKET))) xgene_ahci_restart_engine(ap); rc = ahci_qc_issue(qc); @@ -188,7 +190,7 @@ static unsigned int xgene_ahci_read_id(struct ata_device *dev, * * Clear reserved bit 8 (DEVSLP bit) as we don't support DEVSLP */ - id[ATA_ID_FEATURE_SUPP] &= ~(1 << 8); + id[ATA_ID_FEATURE_SUPP] &= cpu_to_le16(~(1 << 8)); return 0; } diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 97683e45ab04..61a9c07e0dff 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -2003,7 +2003,7 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep) devslp = readl(port_mmio + PORT_DEVSLP); if (!(devslp & PORT_DEVSLP_DSP)) { - dev_err(ap->host->dev, "port does not support device sleep\n"); + dev_info(ap->host->dev, "port does not support device sleep\n"); return; } diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 5c84fb5c3372..d1a05f9bb91f 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4233,10 +4233,33 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, /* devices that don't properly handle queued TRIM commands */ - { "Micron_M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, - { "Crucial_CT???M500SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, - { "Micron_M550*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, - { "Crucial_CT*M550SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, + { "Micron_M[56]*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | + ATA_HORKAGE_ZERO_AFTER_TRIM, }, + { "Crucial_CT*SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, + + /* + * As defined, the DRAT (Deterministic Read After Trim) and RZAT + * (Return Zero After Trim) flags in the ATA Command Set are + * unreliable in the sense that they only define what happens if + * the device successfully executed the DSM TRIM command. TRIM + * is only advisory, however, and the device is free to silently + * ignore all or parts of the request. + * + * Whitelist drives that are known to reliably return zeroes + * after TRIM. + */ + + /* + * The intel 510 drive has buggy DRAT/RZAT. Explicitly exclude + * that model before whitelisting all other intel SSDs. + */ + { "INTEL*SSDSC2MH*", NULL, 0, }, + + { "INTEL*SSD*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, }, + { "SSD*INTEL*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, }, + { "Samsung*SSD*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, }, + { "SAMSUNG*SSD*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, }, + { "ST[1248][0248]0[FH]*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, }, /* * Some WD SATA-I drives spin up and down erratically when the link @@ -4748,7 +4771,10 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) return NULL; for (i = 0, tag = ap->last_tag + 1; i < max_queue; i++, tag++) { - tag = tag < max_queue ? tag : 0; + if (ap->flags & ATA_FLAG_LOWTAG) + tag = i; + else + tag = tag < max_queue ? tag : 0; /* the last tag is reserved for internal command. */ if (tag == ATA_TAG_INTERNAL) diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 3dbec8954c86..8d00c2638bed 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2389,6 +2389,7 @@ const char *ata_get_cmd_descript(u8 command) return NULL; } +EXPORT_SYMBOL_GPL(ata_get_cmd_descript); /** * ata_eh_link_report - report error handling to user diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index e364e86e84d7..6abd17a85b13 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2532,13 +2532,15 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf) rbuf[15] = lowest_aligned; if (ata_id_has_trim(args->id)) { - rbuf[14] |= 0x80; /* TPE */ + rbuf[14] |= 0x80; /* LBPME */ - if (ata_id_has_zero_after_trim(args->id)) - rbuf[14] |= 0x40; /* TPRZ */ + if (ata_id_has_zero_after_trim(args->id) && + dev->horkage & ATA_HORKAGE_ZERO_AFTER_TRIM) { + ata_dev_info(dev, "Enabling discard_zeroes_data\n"); + rbuf[14] |= 0x40; /* LBPRZ */ + } } } - return 0; } diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index db90aa35cb71..2e86e3b85266 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -1333,7 +1333,19 @@ void ata_sff_flush_pio_task(struct ata_port *ap) DPRINTK("ENTER\n"); cancel_delayed_work_sync(&ap->sff_pio_task); + + /* + * We wanna reset the HSM state to IDLE. If we do so without + * grabbing the port lock, critical sections protected by it which + * expect the HSM state to stay stable may get surprised. For + * example, we may set IDLE in between the time + * __ata_sff_port_intr() checks for HSM_ST_IDLE and before it calls + * ata_sff_hsm_move() causing ata_sff_hsm_move() to BUG(). + */ + spin_lock_irq(ap->lock); ap->hsm_task_state = HSM_ST_IDLE; + spin_unlock_irq(ap->lock); + ap->sff_pio_task_link = NULL; if (ata_msg_ctl(ap)) diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index c7ddef89e7b0..8e8248179d20 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c @@ -797,7 +797,7 @@ static int dma_dwc_init(struct sata_dwc_device *hsdev, int irq) if (err) { dev_err(host_pvt.dwc_dev, "%s: dma_request_interrupts returns" " %d\n", __func__, err); - goto error_out; + return err; } /* Enabe DMA */ @@ -808,11 +808,6 @@ static int dma_dwc_init(struct sata_dwc_device *hsdev, int irq) sata_dma_regs); return 0; - -error_out: - dma_dwc_exit(hsdev); - - return err; } static int sata_dwc_scr_read(struct ata_link *link, unsigned int scr, u32 *val) @@ -1662,7 +1657,7 @@ static int sata_dwc_probe(struct platform_device *ofdev) char *ver = (char *)&versionr; u8 *base = NULL; int err = 0; - int irq, rc; + int irq; struct ata_host *host; struct ata_port_info pi = sata_dwc_port_info[0]; const struct ata_port_info *ppi[] = { &pi, NULL }; @@ -1725,7 +1720,7 @@ static int sata_dwc_probe(struct platform_device *ofdev) if (irq == NO_IRQ) { dev_err(&ofdev->dev, "no SATA DMA irq\n"); err = -ENODEV; - goto error_out; + goto error_iomap; } /* Get physical SATA DMA register base address */ @@ -1734,14 +1729,16 @@ static int sata_dwc_probe(struct platform_device *ofdev) dev_err(&ofdev->dev, "ioremap failed for AHBDMA register" " address\n"); err = -ENODEV; - goto error_out; + goto error_iomap; } /* Save dev for later use in dev_xxx() routines */ host_pvt.dwc_dev = &ofdev->dev; /* Initialize AHB DMAC */ - dma_dwc_init(hsdev, irq); + err = dma_dwc_init(hsdev, irq); + if (err) + goto error_dma_iomap; /* Enable SATA Interrupts */ sata_dwc_enable_interrupts(hsdev); @@ -1759,9 +1756,8 @@ static int sata_dwc_probe(struct platform_device *ofdev) * device discovery process, invoking our port_start() handler & * error_handler() to execute a dummy Softreset EH session */ - rc = ata_host_activate(host, irq, sata_dwc_isr, 0, &sata_dwc_sht); - - if (rc != 0) + err = ata_host_activate(host, irq, sata_dwc_isr, 0, &sata_dwc_sht); + if (err) dev_err(&ofdev->dev, "failed to activate host"); dev_set_drvdata(&ofdev->dev, host); @@ -1770,7 +1766,8 @@ static int sata_dwc_probe(struct platform_device *ofdev) error_out: /* Free SATA DMA resources */ dma_dwc_exit(hsdev); - +error_dma_iomap: + iounmap((void __iomem *)host_pvt.sata_dma_regs); error_iomap: iounmap(base); error_kmalloc: @@ -1791,6 +1788,7 @@ static int sata_dwc_remove(struct platform_device *ofdev) /* Free SATA DMA resources */ dma_dwc_exit(hsdev); + iounmap((void __iomem *)host_pvt.sata_dma_regs); iounmap(hsdev->reg_base); kfree(hsdev); kfree(host); diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index d81b20ddb527..ea655949023f 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -246,7 +246,7 @@ enum { /* host flags */ SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA | ATA_FLAG_NCQ | ATA_FLAG_ACPI_SATA | - ATA_FLAG_AN | ATA_FLAG_PMP, + ATA_FLAG_AN | ATA_FLAG_PMP | ATA_FLAG_LOWTAG, SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */ IRQ_STAT_4PORTS = 0xf, diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 6a103a35ea9b..0d8780c04a5e 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -2088,7 +2088,7 @@ EXPORT_SYMBOL_GPL(of_genpd_del_provider); * Returns a valid pointer to struct generic_pm_domain on success or ERR_PTR() * on failure. */ -static struct generic_pm_domain *of_genpd_get_from_provider( +struct generic_pm_domain *of_genpd_get_from_provider( struct of_phandle_args *genpdspec) { struct generic_pm_domain *genpd = ERR_PTR(-ENOENT); @@ -2108,6 +2108,7 @@ static struct generic_pm_domain *of_genpd_get_from_provider( return genpd; } +EXPORT_SYMBOL_GPL(of_genpd_get_from_provider); /** * genpd_dev_pm_detach - Detach a device from its PM domain. diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index 2d195f3a1998..106c69359306 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c @@ -84,7 +84,11 @@ struct dev_pm_opp { * * This is an internal data structure maintaining the link to opps attached to * a device. This structure is not meant to be shared to users as it is - * meant for book keeping and private to OPP library + * meant for book keeping and private to OPP library. + * + * Because the opp structures can be used from both rcu and srcu readers, we + * need to wait for the grace period of both of them before freeing any + * resources. And so we have used kfree_rcu() from within call_srcu() handlers. */ struct device_opp { struct list_head node; @@ -104,6 +108,14 @@ static LIST_HEAD(dev_opp_list); /* Lock to allow exclusive modification to the device and opp lists */ static DEFINE_MUTEX(dev_opp_list_lock); +#define opp_rcu_lockdep_assert() \ +do { \ + rcu_lockdep_assert(rcu_read_lock_held() || \ + lockdep_is_held(&dev_opp_list_lock), \ + "Missing rcu_read_lock() or " \ + "dev_opp_list_lock protection"); \ +} while (0) + /** * find_device_opp() - find device_opp struct using device pointer * @dev: device pointer used to lookup device OPPs @@ -204,9 +216,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_freq); * This function returns the number of available opps if there are any, * else returns 0 if none or the corresponding error value. * - * Locking: This function must be called under rcu_read_lock(). This function - * internally references two RCU protected structures: device_opp and opp which - * are safe as long as we are under a common RCU locked section. + * Locking: This function takes rcu_read_lock(). */ int dev_pm_opp_get_opp_count(struct device *dev) { @@ -214,11 +224,14 @@ int dev_pm_opp_get_opp_count(struct device *dev) struct dev_pm_opp *temp_opp; int count = 0; + rcu_read_lock(); + dev_opp = find_device_opp(dev); if (IS_ERR(dev_opp)) { - int r = PTR_ERR(dev_opp); - dev_err(dev, "%s: device OPP not found (%d)\n", __func__, r); - return r; + count = PTR_ERR(dev_opp); + dev_err(dev, "%s: device OPP not found (%d)\n", + __func__, count); + goto out_unlock; } list_for_each_entry_rcu(temp_opp, &dev_opp->opp_list, node) { @@ -226,6 +239,8 @@ int dev_pm_opp_get_opp_count(struct device *dev) count++; } +out_unlock: + rcu_read_unlock(); return count; } EXPORT_SYMBOL_GPL(dev_pm_opp_get_opp_count); @@ -263,6 +278,8 @@ struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, struct device_opp *dev_opp; struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE); + opp_rcu_lockdep_assert(); + dev_opp = find_device_opp(dev); if (IS_ERR(dev_opp)) { int r = PTR_ERR(dev_opp); @@ -309,6 +326,8 @@ struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, struct device_opp *dev_opp; struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE); + opp_rcu_lockdep_assert(); + if (!dev || !freq) { dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq); return ERR_PTR(-EINVAL); @@ -357,6 +376,8 @@ struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, struct device_opp *dev_opp; struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE); + opp_rcu_lockdep_assert(); + if (!dev || !freq) { dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq); return ERR_PTR(-EINVAL); @@ -382,12 +403,34 @@ struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, } EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor); +static struct device_opp *add_device_opp(struct device *dev) +{ + struct device_opp *dev_opp; + + /* + * Allocate a new device OPP table. In the infrequent case where a new + * device is needed to be added, we pay this penalty. + */ + dev_opp = kzalloc(sizeof(*dev_opp), GFP_KERNEL); + if (!dev_opp) + return NULL; + + dev_opp->dev = dev; + srcu_init_notifier_head(&dev_opp->srcu_head); + INIT_LIST_HEAD(&dev_opp->opp_list); + + /* Secure the device list modification */ + list_add_rcu(&dev_opp->node, &dev_opp_list); + return dev_opp; +} + static int dev_pm_opp_add_dynamic(struct device *dev, unsigned long freq, unsigned long u_volt, bool dynamic) { struct device_opp *dev_opp = NULL; struct dev_pm_opp *opp, *new_opp; struct list_head *head; + int ret; /* allocate new OPP node */ new_opp = kzalloc(sizeof(*new_opp), GFP_KERNEL); @@ -400,7 +443,6 @@ static int dev_pm_opp_add_dynamic(struct device *dev, unsigned long freq, mutex_lock(&dev_opp_list_lock); /* populate the opp table */ - new_opp->dev_opp = dev_opp; new_opp->rate = freq; new_opp->u_volt = u_volt; new_opp->available = true; @@ -409,27 +451,12 @@ static int dev_pm_opp_add_dynamic(struct device *dev, unsigned long freq, /* Check for existing list for 'dev' */ dev_opp = find_device_opp(dev); if (IS_ERR(dev_opp)) { - /* - * Allocate a new device OPP table. In the infrequent case - * where a new device is needed to be added, we pay this - * penalty. - */ - dev_opp = kzalloc(sizeof(struct device_opp), GFP_KERNEL); + dev_opp = add_device_opp(dev); if (!dev_opp) { - mutex_unlock(&dev_opp_list_lock); - kfree(new_opp); - dev_warn(dev, - "%s: Unable to create device OPP structure\n", - __func__); - return -ENOMEM; + ret = -ENOMEM; + goto free_opp; } - dev_opp->dev = dev; - srcu_init_notifier_head(&dev_opp->srcu_head); - INIT_LIST_HEAD(&dev_opp->opp_list); - - /* Secure the device list modification */ - list_add_rcu(&dev_opp->node, &dev_opp_list); head = &dev_opp->opp_list; goto list_add; } @@ -448,18 +475,17 @@ static int dev_pm_opp_add_dynamic(struct device *dev, unsigned long freq, /* Duplicate OPPs ? */ if (new_opp->rate == opp->rate) { - int ret = opp->available && new_opp->u_volt == opp->u_volt ? + ret = opp->available && new_opp->u_volt == opp->u_volt ? 0 : -EEXIST; dev_warn(dev, "%s: duplicate OPPs detected. Existing: freq: %lu, volt: %lu, enabled: %d. New: freq: %lu, volt: %lu, enabled: %d\n", __func__, opp->rate, opp->u_volt, opp->available, new_opp->rate, new_opp->u_volt, new_opp->available); - mutex_unlock(&dev_opp_list_lock); - kfree(new_opp); - return ret; + goto free_opp; } list_add: + new_opp->dev_opp = dev_opp; list_add_rcu(&new_opp->node, head); mutex_unlock(&dev_opp_list_lock); @@ -469,6 +495,11 @@ list_add: */ srcu_notifier_call_chain(&dev_opp->srcu_head, OPP_EVENT_ADD, new_opp); return 0; + +free_opp: + mutex_unlock(&dev_opp_list_lock); + kfree(new_opp); + return ret; } /** @@ -511,10 +542,11 @@ static void kfree_device_rcu(struct rcu_head *head) { struct device_opp *device_opp = container_of(head, struct device_opp, rcu_head); - kfree(device_opp); + kfree_rcu(device_opp, rcu_head); } -void __dev_pm_opp_remove(struct device_opp *dev_opp, struct dev_pm_opp *opp) +static void __dev_pm_opp_remove(struct device_opp *dev_opp, + struct dev_pm_opp *opp) { /* * Notify the changes in the availability of the operable @@ -592,7 +624,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_remove); static int opp_set_availability(struct device *dev, unsigned long freq, bool availability_req) { - struct device_opp *tmp_dev_opp, *dev_opp = ERR_PTR(-ENODEV); + struct device_opp *dev_opp; struct dev_pm_opp *new_opp, *tmp_opp, *opp = ERR_PTR(-ENODEV); int r = 0; @@ -606,12 +638,7 @@ static int opp_set_availability(struct device *dev, unsigned long freq, mutex_lock(&dev_opp_list_lock); /* Find the device_opp */ - list_for_each_entry(tmp_dev_opp, &dev_opp_list, node) { - if (dev == tmp_dev_opp->dev) { - dev_opp = tmp_dev_opp; - break; - } - } + dev_opp = find_device_opp(dev); if (IS_ERR(dev_opp)) { r = PTR_ERR(dev_opp); dev_warn(dev, "%s: Device OPP not found (%d)\n", __func__, r); @@ -768,14 +795,20 @@ EXPORT_SYMBOL_GPL(of_init_opp_table); */ void of_free_opp_table(struct device *dev) { - struct device_opp *dev_opp = find_device_opp(dev); + struct device_opp *dev_opp; struct dev_pm_opp *opp, *tmp; /* Check for existing list for 'dev' */ dev_opp = find_device_opp(dev); - if (WARN(IS_ERR(dev_opp), "%s: dev_opp: %ld\n", dev_name(dev), - PTR_ERR(dev_opp))) + if (IS_ERR(dev_opp)) { + int error = PTR_ERR(dev_opp); + if (error != -ENODEV) + WARN(1, "%s: dev_opp: %d\n", + IS_ERR_OR_NULL(dev) ? + "Invalid device" : dev_name(dev), + error); return; + } /* Hold our list modification lock here */ mutex_lock(&dev_opp_list_lock); diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c index ae9f615382f6..aa2224aa7caa 100644 --- a/drivers/block/null_blk.c +++ b/drivers/block/null_blk.c @@ -530,7 +530,7 @@ static int null_add_dev(void) goto out_cleanup_queues; nullb->q = blk_mq_init_queue(&nullb->tag_set); - if (!nullb->q) { + if (IS_ERR(nullb->q)) { rv = -ENOMEM; goto out_cleanup_tags; } diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index b1d5d8797315..d826bf3e62c8 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -106,7 +106,7 @@ struct nvme_queue { dma_addr_t cq_dma_addr; u32 __iomem *q_db; u16 q_depth; - u16 cq_vector; + s16 cq_vector; u16 sq_head; u16 sq_tail; u16 cq_head; @@ -215,6 +215,7 @@ static void nvme_set_info(struct nvme_cmd_info *cmd, void *ctx, cmd->fn = handler; cmd->ctx = ctx; cmd->aborted = 0; + blk_mq_start_request(blk_mq_rq_from_pdu(cmd)); } /* Special values must be less than 0x1000 */ @@ -431,8 +432,13 @@ static void req_completion(struct nvme_queue *nvmeq, void *ctx, if (unlikely(status)) { if (!(status & NVME_SC_DNR || blk_noretry_request(req)) && (jiffies - req->start_time) < req->timeout) { + unsigned long flags; + blk_mq_requeue_request(req); - blk_mq_kick_requeue_list(req->q); + spin_lock_irqsave(req->q->queue_lock, flags); + if (!blk_queue_stopped(req->q)) + blk_mq_kick_requeue_list(req->q); + spin_unlock_irqrestore(req->q->queue_lock, flags); return; } req->errors = nvme_error_status(status); @@ -664,8 +670,6 @@ static int nvme_queue_rq(struct blk_mq_hw_ctx *hctx, } } - blk_mq_start_request(req); - nvme_set_info(cmd, iod, req_completion); spin_lock_irq(&nvmeq->q_lock); if (req->cmd_flags & REQ_DISCARD) @@ -835,6 +839,7 @@ static int nvme_submit_async_admin_req(struct nvme_dev *dev) if (IS_ERR(req)) return PTR_ERR(req); + req->cmd_flags |= REQ_NO_TIMEOUT; cmd_info = blk_mq_rq_to_pdu(req); nvme_set_info(cmd_info, req, async_req_completion); @@ -1016,14 +1021,19 @@ static void nvme_abort_req(struct request *req) struct nvme_command cmd; if (!nvmeq->qid || cmd_rq->aborted) { + unsigned long flags; + + spin_lock_irqsave(&dev_list_lock, flags); if (work_busy(&dev->reset_work)) - return; + goto out; list_del_init(&dev->node); dev_warn(&dev->pci_dev->dev, "I/O %d QID %d timeout, reset controller\n", req->tag, nvmeq->qid); dev->reset_workfn = nvme_reset_failed_dev; queue_work(nvme_workq, &dev->reset_work); + out: + spin_unlock_irqrestore(&dev_list_lock, flags); return; } @@ -1064,15 +1074,22 @@ static void nvme_cancel_queue_ios(struct blk_mq_hw_ctx *hctx, void *ctx; nvme_completion_fn fn; struct nvme_cmd_info *cmd; - static struct nvme_completion cqe = { - .status = cpu_to_le16(NVME_SC_ABORT_REQ << 1), - }; + struct nvme_completion cqe; + + if (!blk_mq_request_started(req)) + return; cmd = blk_mq_rq_to_pdu(req); if (cmd->ctx == CMD_CTX_CANCELLED) return; + if (blk_queue_dying(req->q)) + cqe.status = cpu_to_le16((NVME_SC_ABORT_REQ | NVME_SC_DNR) << 1); + else + cqe.status = cpu_to_le16(NVME_SC_ABORT_REQ << 1); + + dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d QID %d\n", req->tag, nvmeq->qid); ctx = cancel_cmd_info(cmd, &fn); @@ -1084,17 +1101,29 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved) struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req); struct nvme_queue *nvmeq = cmd->nvmeq; - dev_warn(nvmeq->q_dmadev, "Timeout I/O %d QID %d\n", req->tag, - nvmeq->qid); - if (nvmeq->dev->initialized) - nvme_abort_req(req); - /* * The aborted req will be completed on receiving the abort req. * We enable the timer again. If hit twice, it'll cause a device reset, * as the device then is in a faulty state. */ - return BLK_EH_RESET_TIMER; + int ret = BLK_EH_RESET_TIMER; + + dev_warn(nvmeq->q_dmadev, "Timeout I/O %d QID %d\n", req->tag, + nvmeq->qid); + + spin_lock_irq(&nvmeq->q_lock); + if (!nvmeq->dev->initialized) { + /* + * Force cancelled command frees the request, which requires we + * return BLK_EH_NOT_HANDLED. + */ + nvme_cancel_queue_ios(nvmeq->hctx, req, nvmeq, reserved); + ret = BLK_EH_NOT_HANDLED; + } else + nvme_abort_req(req); + spin_unlock_irq(&nvmeq->q_lock); + + return ret; } static void nvme_free_queue(struct nvme_queue *nvmeq) @@ -1131,10 +1160,16 @@ static void nvme_free_queues(struct nvme_dev *dev, int lowest) */ static int nvme_suspend_queue(struct nvme_queue *nvmeq) { - int vector = nvmeq->dev->entry[nvmeq->cq_vector].vector; + int vector; spin_lock_irq(&nvmeq->q_lock); + if (nvmeq->cq_vector == -1) { + spin_unlock_irq(&nvmeq->q_lock); + return 1; + } + vector = nvmeq->dev->entry[nvmeq->cq_vector].vector; nvmeq->dev->online_queues--; + nvmeq->cq_vector = -1; spin_unlock_irq(&nvmeq->q_lock); irq_set_affinity_hint(vector, NULL); @@ -1169,11 +1204,13 @@ static void nvme_disable_queue(struct nvme_dev *dev, int qid) adapter_delete_sq(dev, qid); adapter_delete_cq(dev, qid); } + if (!qid && dev->admin_q) + blk_mq_freeze_queue_start(dev->admin_q); nvme_clear_queue(nvmeq); } static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, - int depth, int vector) + int depth) { struct device *dmadev = &dev->pci_dev->dev; struct nvme_queue *nvmeq = kzalloc(sizeof(*nvmeq), GFP_KERNEL); @@ -1199,7 +1236,6 @@ static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, nvmeq->cq_phase = 1; nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride]; nvmeq->q_depth = depth; - nvmeq->cq_vector = vector; nvmeq->qid = qid; dev->queue_count++; dev->queues[qid] = nvmeq; @@ -1244,6 +1280,7 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid) struct nvme_dev *dev = nvmeq->dev; int result; + nvmeq->cq_vector = qid - 1; result = adapter_alloc_cq(dev, qid, nvmeq); if (result < 0) return result; @@ -1355,6 +1392,14 @@ static struct blk_mq_ops nvme_mq_ops = { .timeout = nvme_timeout, }; +static void nvme_dev_remove_admin(struct nvme_dev *dev) +{ + if (dev->admin_q && !blk_queue_dying(dev->admin_q)) { + blk_cleanup_queue(dev->admin_q); + blk_mq_free_tag_set(&dev->admin_tagset); + } +} + static int nvme_alloc_admin_tags(struct nvme_dev *dev) { if (!dev->admin_q) { @@ -1370,21 +1415,20 @@ static int nvme_alloc_admin_tags(struct nvme_dev *dev) return -ENOMEM; dev->admin_q = blk_mq_init_queue(&dev->admin_tagset); - if (!dev->admin_q) { + if (IS_ERR(dev->admin_q)) { blk_mq_free_tag_set(&dev->admin_tagset); return -ENOMEM; } - } + if (!blk_get_queue(dev->admin_q)) { + nvme_dev_remove_admin(dev); + return -ENODEV; + } + } else + blk_mq_unfreeze_queue(dev->admin_q); return 0; } -static void nvme_free_admin_tags(struct nvme_dev *dev) -{ - if (dev->admin_q) - blk_mq_free_tag_set(&dev->admin_tagset); -} - static int nvme_configure_admin_queue(struct nvme_dev *dev) { int result; @@ -1416,7 +1460,7 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) nvmeq = dev->queues[0]; if (!nvmeq) { - nvmeq = nvme_alloc_queue(dev, 0, NVME_AQ_DEPTH, 0); + nvmeq = nvme_alloc_queue(dev, 0, NVME_AQ_DEPTH); if (!nvmeq) return -ENOMEM; } @@ -1439,18 +1483,13 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) if (result) goto free_nvmeq; - result = nvme_alloc_admin_tags(dev); - if (result) - goto free_nvmeq; - + nvmeq->cq_vector = 0; result = queue_request_irq(dev, nvmeq, nvmeq->irqname); if (result) - goto free_tags; + goto free_nvmeq; return result; - free_tags: - nvme_free_admin_tags(dev); free_nvmeq: nvme_free_queues(dev, 0); return result; @@ -1944,7 +1983,7 @@ static void nvme_create_io_queues(struct nvme_dev *dev) unsigned i; for (i = dev->queue_count; i <= dev->max_qid; i++) - if (!nvme_alloc_queue(dev, i, dev->q_depth, i - 1)) + if (!nvme_alloc_queue(dev, i, dev->q_depth)) break; for (i = dev->online_queues; i <= dev->queue_count - 1; i++) @@ -2235,13 +2274,18 @@ static void nvme_wait_dq(struct nvme_delq_ctx *dq, struct nvme_dev *dev) break; if (!schedule_timeout(ADMIN_TIMEOUT) || fatal_signal_pending(current)) { + /* + * Disable the controller first since we can't trust it + * at this point, but leave the admin queue enabled + * until all queue deletion requests are flushed. + * FIXME: This may take a while if there are more h/w + * queues than admin tags. + */ set_current_state(TASK_RUNNING); - nvme_disable_ctrl(dev, readq(&dev->bar->cap)); - nvme_disable_queue(dev, 0); - - send_sig(SIGKILL, dq->worker->task, 1); + nvme_clear_queue(dev->queues[0]); flush_kthread_worker(dq->worker); + nvme_disable_queue(dev, 0); return; } } @@ -2318,7 +2362,6 @@ static void nvme_del_queue_start(struct kthread_work *work) { struct nvme_queue *nvmeq = container_of(work, struct nvme_queue, cmdinfo.work); - allow_signal(SIGKILL); if (nvme_delete_sq(nvmeq)) nvme_del_queue_end(nvmeq); } @@ -2376,6 +2419,34 @@ static void nvme_dev_list_remove(struct nvme_dev *dev) kthread_stop(tmp); } +static void nvme_freeze_queues(struct nvme_dev *dev) +{ + struct nvme_ns *ns; + + list_for_each_entry(ns, &dev->namespaces, list) { + blk_mq_freeze_queue_start(ns->queue); + + spin_lock(ns->queue->queue_lock); + queue_flag_set(QUEUE_FLAG_STOPPED, ns->queue); + spin_unlock(ns->queue->queue_lock); + + blk_mq_cancel_requeue_work(ns->queue); + blk_mq_stop_hw_queues(ns->queue); + } +} + +static void nvme_unfreeze_queues(struct nvme_dev *dev) +{ + struct nvme_ns *ns; + + list_for_each_entry(ns, &dev->namespaces, list) { + queue_flag_clear_unlocked(QUEUE_FLAG_STOPPED, ns->queue); + blk_mq_unfreeze_queue(ns->queue); + blk_mq_start_stopped_hw_queues(ns->queue, true); + blk_mq_kick_requeue_list(ns->queue); + } +} + static void nvme_dev_shutdown(struct nvme_dev *dev) { int i; @@ -2384,8 +2455,10 @@ static void nvme_dev_shutdown(struct nvme_dev *dev) dev->initialized = 0; nvme_dev_list_remove(dev); - if (dev->bar) + if (dev->bar) { + nvme_freeze_queues(dev); csts = readl(&dev->bar->csts); + } if (csts & NVME_CSTS_CFS || !(csts & NVME_CSTS_RDY)) { for (i = dev->queue_count - 1; i >= 0; i--) { struct nvme_queue *nvmeq = dev->queues[i]; @@ -2400,12 +2473,6 @@ static void nvme_dev_shutdown(struct nvme_dev *dev) nvme_dev_unmap(dev); } -static void nvme_dev_remove_admin(struct nvme_dev *dev) -{ - if (dev->admin_q && !blk_queue_dying(dev->admin_q)) - blk_cleanup_queue(dev->admin_q); -} - static void nvme_dev_remove(struct nvme_dev *dev) { struct nvme_ns *ns; @@ -2413,8 +2480,10 @@ static void nvme_dev_remove(struct nvme_dev *dev) list_for_each_entry(ns, &dev->namespaces, list) { if (ns->disk->flags & GENHD_FL_UP) del_gendisk(ns->disk); - if (!blk_queue_dying(ns->queue)) + if (!blk_queue_dying(ns->queue)) { + blk_mq_abort_requeue_list(ns->queue); blk_cleanup_queue(ns->queue); + } } } @@ -2495,6 +2564,7 @@ static void nvme_free_dev(struct kref *kref) nvme_free_namespaces(dev); nvme_release_instance(dev); blk_mq_free_tag_set(&dev->tagset); + blk_put_queue(dev->admin_q); kfree(dev->queues); kfree(dev->entry); kfree(dev); @@ -2591,15 +2661,20 @@ static int nvme_dev_start(struct nvme_dev *dev) } nvme_init_queue(dev->queues[0], 0); + result = nvme_alloc_admin_tags(dev); + if (result) + goto disable; result = nvme_setup_io_queues(dev); if (result) - goto disable; + goto free_tags; nvme_set_irq_hints(dev); return result; + free_tags: + nvme_dev_remove_admin(dev); disable: nvme_disable_queue(dev, 0); nvme_dev_list_remove(dev); @@ -2639,6 +2714,9 @@ static int nvme_dev_resume(struct nvme_dev *dev) dev->reset_workfn = nvme_remove_disks; queue_work(nvme_workq, &dev->reset_work); spin_unlock(&dev_list_lock); + } else { + nvme_unfreeze_queues(dev); + nvme_set_irq_hints(dev); } dev->initialized = 1; return 0; @@ -2776,11 +2854,10 @@ static void nvme_remove(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); flush_work(&dev->reset_work); misc_deregister(&dev->miscdev); - nvme_dev_remove(dev); nvme_dev_shutdown(dev); + nvme_dev_remove(dev); nvme_dev_remove_admin(dev); nvme_free_queues(dev, 0); - nvme_free_admin_tags(dev); nvme_release_prp_pools(dev); kref_put(&dev->kref, nvme_free_dev); } diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 27b71a0b72d0..3ec85dfce124 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -2370,8 +2370,12 @@ static void rbd_img_obj_request_fill(struct rbd_obj_request *obj_request, opcode = CEPH_OSD_OP_READ; } - osd_req_op_extent_init(osd_request, num_ops, opcode, offset, length, - 0, 0); + if (opcode == CEPH_OSD_OP_DELETE) + osd_req_op_init(osd_request, num_ops, opcode); + else + osd_req_op_extent_init(osd_request, num_ops, opcode, + offset, length, 0, 0); + if (obj_request->type == OBJ_REQUEST_BIO) osd_req_op_extent_osd_data_bio(osd_request, num_ops, obj_request->bio_list, length); @@ -3405,8 +3409,7 @@ err_rq: if (result) rbd_warn(rbd_dev, "%s %llx at %llx result %d", obj_op_name(op_type), length, offset, result); - if (snapc) - ceph_put_snap_context(snapc); + ceph_put_snap_context(snapc); blk_end_request_all(rq, result); } diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 7ef7c098708f..cdfbd21e3597 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -638,7 +638,7 @@ static int virtblk_probe(struct virtio_device *vdev) goto out_put_disk; q = vblk->disk->queue = blk_mq_init_queue(&vblk->tag_set); - if (!q) { + if (IS_ERR(q)) { err = -ENOMEM; goto out_free_tags; } diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index fce758896280..1ee27ac18de0 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -87,6 +87,7 @@ static const struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x04CA, 0x3007) }, { USB_DEVICE(0x04CA, 0x3008) }, { USB_DEVICE(0x04CA, 0x300b) }, + { USB_DEVICE(0x04CA, 0x3010) }, { USB_DEVICE(0x0930, 0x0219) }, { USB_DEVICE(0x0930, 0x0220) }, { USB_DEVICE(0x0930, 0x0227) }, @@ -140,6 +141,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x04ca, 0x3007), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 31dd24ac9926..19cf2cf22e87 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -167,6 +167,7 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x04ca, 0x3007), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 }, diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c index 860da40b78ef..0ce5e2d65a06 100644 --- a/drivers/bus/arm-cci.c +++ b/drivers/bus/arm-cci.c @@ -1312,6 +1312,9 @@ static int cci_probe(void) if (!np) return -ENODEV; + if (!of_device_is_available(np)) + return -ENODEV; + cci_config = of_match_node(arm_cci_matches, np)->data; if (!cci_config) return -ENODEV; diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index 19db03667650..dcbbb4ea3cc1 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c @@ -417,6 +417,6 @@ static void __exit agp_ali_cleanup(void) module_init(agp_ali_init); module_exit(agp_ali_cleanup); -MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); +MODULE_AUTHOR("Dave Jones"); MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 3b47ed0310e1..0ef350010766 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c @@ -813,6 +813,6 @@ static void __exit agp_amd64_cleanup(void) module_init(agp_amd64_mod_init); module_exit(agp_amd64_cleanup); -MODULE_AUTHOR("Dave Jones <davej@redhat.com>, Andi Kleen"); +MODULE_AUTHOR("Dave Jones, Andi Kleen"); module_param(agp_try_unsupported, bool, 0); MODULE_LICENSE("GPL"); diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index 18a7a6baa304..75a9786a77e6 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c @@ -579,6 +579,6 @@ static void __exit agp_ati_cleanup(void) module_init(agp_ati_init); module_exit(agp_ati_cleanup); -MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); +MODULE_AUTHOR("Dave Jones"); MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index 317c28ce8328..38ffb281df97 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c @@ -356,7 +356,7 @@ static __init int agp_setup(char *s) __setup("agp=", agp_setup); #endif -MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); +MODULE_AUTHOR("Dave Jones, Jeff Hartmann"); MODULE_DESCRIPTION("AGP GART driver"); MODULE_LICENSE("GPL and additional rights"); MODULE_ALIAS_MISCDEV(AGPGART_MINOR); diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index f9b9ca5d31b7..0a21daed5b62 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -920,5 +920,5 @@ static void __exit agp_intel_cleanup(void) module_init(agp_intel_init); module_exit(agp_intel_cleanup); -MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); +MODULE_AUTHOR("Dave Jones, Various @Intel"); MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index f3334829e55a..92aa43fa8d70 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -1438,5 +1438,5 @@ void intel_gmch_remove(void) } EXPORT_SYMBOL(intel_gmch_remove); -MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); +MODULE_AUTHOR("Dave Jones, Various @Intel"); MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index a1861b75eb31..6c8d39cb566e 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c @@ -1,7 +1,7 @@ /* * Nvidia AGPGART routines. * Based upon a 2.4 agpgart diff by the folks from NVIDIA, and hacked up - * to work in 2.5 by Dave Jones <davej@redhat.com> + * to work in 2.5 by Dave Jones. */ #include <linux/module.h> diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c index 228f20cddc05..a4961d35e940 100644 --- a/drivers/char/agp/via-agp.c +++ b/drivers/char/agp/via-agp.c @@ -595,4 +595,4 @@ module_init(agp_via_init); module_exit(agp_via_cleanup); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); +MODULE_AUTHOR("Dave Jones"); diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 5fa83f751378..6b65fa4e0c55 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -199,18 +199,6 @@ struct bmc_device { int guid_set; char name[16]; struct kref usecount; - - /* bmc device attributes */ - struct device_attribute device_id_attr; - struct device_attribute provides_dev_sdrs_attr; - struct device_attribute revision_attr; - struct device_attribute firmware_rev_attr; - struct device_attribute version_attr; - struct device_attribute add_dev_support_attr; - struct device_attribute manufacturer_id_attr; - struct device_attribute product_id_attr; - struct device_attribute guid_attr; - struct device_attribute aux_firmware_rev_attr; }; #define to_bmc_device(x) container_of((x), struct bmc_device, pdev.dev) @@ -2252,7 +2240,7 @@ static ssize_t device_id_show(struct device *dev, return snprintf(buf, 10, "%u\n", bmc->id.device_id); } -DEVICE_ATTR(device_id, S_IRUGO, device_id_show, NULL); +static DEVICE_ATTR(device_id, S_IRUGO, device_id_show, NULL); static ssize_t provides_device_sdrs_show(struct device *dev, struct device_attribute *attr, @@ -2263,7 +2251,8 @@ static ssize_t provides_device_sdrs_show(struct device *dev, return snprintf(buf, 10, "%u\n", (bmc->id.device_revision & 0x80) >> 7); } -DEVICE_ATTR(provides_device_sdrs, S_IRUGO, provides_device_sdrs_show, NULL); +static DEVICE_ATTR(provides_device_sdrs, S_IRUGO, provides_device_sdrs_show, + NULL); static ssize_t revision_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -2273,7 +2262,7 @@ static ssize_t revision_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, 20, "%u\n", bmc->id.device_revision & 0x0F); } -DEVICE_ATTR(revision, S_IRUGO, revision_show, NULL); +static DEVICE_ATTR(revision, S_IRUGO, revision_show, NULL); static ssize_t firmware_revision_show(struct device *dev, struct device_attribute *attr, @@ -2284,7 +2273,7 @@ static ssize_t firmware_revision_show(struct device *dev, return snprintf(buf, 20, "%u.%x\n", bmc->id.firmware_revision_1, bmc->id.firmware_revision_2); } -DEVICE_ATTR(firmware_revision, S_IRUGO, firmware_revision_show, NULL); +static DEVICE_ATTR(firmware_revision, S_IRUGO, firmware_revision_show, NULL); static ssize_t ipmi_version_show(struct device *dev, struct device_attribute *attr, @@ -2296,7 +2285,7 @@ static ssize_t ipmi_version_show(struct device *dev, ipmi_version_major(&bmc->id), ipmi_version_minor(&bmc->id)); } -DEVICE_ATTR(ipmi_version, S_IRUGO, ipmi_version_show, NULL); +static DEVICE_ATTR(ipmi_version, S_IRUGO, ipmi_version_show, NULL); static ssize_t add_dev_support_show(struct device *dev, struct device_attribute *attr, @@ -2307,7 +2296,8 @@ static ssize_t add_dev_support_show(struct device *dev, return snprintf(buf, 10, "0x%02x\n", bmc->id.additional_device_support); } -DEVICE_ATTR(additional_device_support, S_IRUGO, add_dev_support_show, NULL); +static DEVICE_ATTR(additional_device_support, S_IRUGO, add_dev_support_show, + NULL); static ssize_t manufacturer_id_show(struct device *dev, struct device_attribute *attr, @@ -2317,7 +2307,7 @@ static ssize_t manufacturer_id_show(struct device *dev, return snprintf(buf, 20, "0x%6.6x\n", bmc->id.manufacturer_id); } -DEVICE_ATTR(manufacturer_id, S_IRUGO, manufacturer_id_show, NULL); +static DEVICE_ATTR(manufacturer_id, S_IRUGO, manufacturer_id_show, NULL); static ssize_t product_id_show(struct device *dev, struct device_attribute *attr, @@ -2327,7 +2317,7 @@ static ssize_t product_id_show(struct device *dev, return snprintf(buf, 10, "0x%4.4x\n", bmc->id.product_id); } -DEVICE_ATTR(product_id, S_IRUGO, product_id_show, NULL); +static DEVICE_ATTR(product_id, S_IRUGO, product_id_show, NULL); static ssize_t aux_firmware_rev_show(struct device *dev, struct device_attribute *attr, @@ -2341,7 +2331,7 @@ static ssize_t aux_firmware_rev_show(struct device *dev, bmc->id.aux_firmware_revision[1], bmc->id.aux_firmware_revision[0]); } -DEVICE_ATTR(aux_firmware_revision, S_IRUGO, aux_firmware_rev_show, NULL); +static DEVICE_ATTR(aux_firmware_revision, S_IRUGO, aux_firmware_rev_show, NULL); static ssize_t guid_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -2352,7 +2342,7 @@ static ssize_t guid_show(struct device *dev, struct device_attribute *attr, (long long) bmc->guid[0], (long long) bmc->guid[8]); } -DEVICE_ATTR(guid, S_IRUGO, guid_show, NULL); +static DEVICE_ATTR(guid, S_IRUGO, guid_show, NULL); static struct attribute *bmc_dev_attrs[] = { &dev_attr_device_id.attr, @@ -2392,10 +2382,10 @@ cleanup_bmc_device(struct kref *ref) if (bmc->id.aux_firmware_revision_set) device_remove_file(&bmc->pdev.dev, - &bmc->aux_firmware_rev_attr); + &dev_attr_aux_firmware_revision); if (bmc->guid_set) device_remove_file(&bmc->pdev.dev, - &bmc->guid_attr); + &dev_attr_guid); platform_device_unregister(&bmc->pdev); } @@ -2422,16 +2412,14 @@ static int create_bmc_files(struct bmc_device *bmc) int err; if (bmc->id.aux_firmware_revision_set) { - bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision"; err = device_create_file(&bmc->pdev.dev, - &bmc->aux_firmware_rev_attr); + &dev_attr_aux_firmware_revision); if (err) goto out; } if (bmc->guid_set) { - bmc->guid_attr.attr.name = "guid"; err = device_create_file(&bmc->pdev.dev, - &bmc->guid_attr); + &dev_attr_guid); if (err) goto out_aux_firm; } @@ -2441,7 +2429,7 @@ static int create_bmc_files(struct bmc_device *bmc) out_aux_firm: if (bmc->id.aux_firmware_revision_set) device_remove_file(&bmc->pdev.dev, - &bmc->aux_firmware_rev_attr); + &dev_attr_aux_firmware_revision); out: return err; } diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index e178ac27e73c..982b96323f82 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -52,6 +52,7 @@ #include <linux/dmi.h> #include <linux/kthread.h> #include <linux/acpi.h> +#include <linux/ctype.h> #define PFX "ipmi_ssif: " #define DEVICE_NAME "ipmi_ssif" @@ -968,7 +969,8 @@ static void sender(void *send_info, do_gettimeofday(&t); pr_info("**Enqueue %02x %02x: %ld.%6.6ld\n", - msg->data[0], msg->data[1], t.tv_sec, t.tv_usec); + msg->data[0], msg->data[1], + (long) t.tv_sec, (long) t.tv_usec); } } diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c index 62e2509f9df1..bbdb1b985c91 100644 --- a/drivers/clk/at91/clk-programmable.c +++ b/drivers/clk/at91/clk-programmable.c @@ -57,7 +57,7 @@ static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw, static long clk_programmable_determine_rate(struct clk_hw *hw, unsigned long rate, unsigned long *best_parent_rate, - struct clk **best_parent_clk) + struct clk_hw **best_parent_hw) { struct clk *parent = NULL; long best_rate = -EINVAL; @@ -84,7 +84,7 @@ static long clk_programmable_determine_rate(struct clk_hw *hw, if (best_rate < 0 || (rate - tmp_rate) < (rate - best_rate)) { best_rate = tmp_rate; *best_parent_rate = parent_rate; - *best_parent_clk = parent; + *best_parent_hw = __clk_get_hw(parent); } if (!best_rate) diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c index 32f7c1b36204..2f13bd5246b5 100644 --- a/drivers/clk/at91/clk-slow.c +++ b/drivers/clk/at91/clk-slow.c @@ -70,6 +70,7 @@ struct clk_sam9x5_slow { #define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw) +static struct clk *slow_clk; static int clk_slow_osc_prepare(struct clk_hw *hw) { @@ -357,6 +358,8 @@ at91_clk_register_sam9x5_slow(void __iomem *sckcr, clk = clk_register(NULL, &slowck->hw); if (IS_ERR(clk)) kfree(slowck); + else + slow_clk = clk; return clk; } @@ -433,6 +436,8 @@ at91_clk_register_sam9260_slow(struct at91_pmc *pmc, clk = clk_register(NULL, &slowck->hw); if (IS_ERR(clk)) kfree(slowck); + else + slow_clk = clk; return clk; } @@ -465,3 +470,25 @@ void __init of_at91sam9260_clk_slow_setup(struct device_node *np, of_clk_add_provider(np, of_clk_src_simple_get, clk); } + +/* + * FIXME: All slow clk users are not properly claiming it (get + prepare + + * enable) before using it. + * If all users properly claiming this clock decide that they don't need it + * anymore (or are removed), it is disabled while faulty users are still + * requiring it, and the system hangs. + * Prevent this clock from being disabled until all users are properly + * requesting it. + * Once this is done we should remove this function and the slow_clk variable. + */ +static int __init of_at91_clk_slow_retain(void) +{ + if (!slow_clk) + return 0; + + __clk_get(slow_clk); + clk_prepare_enable(slow_clk); + + return 0; +} +arch_initcall(of_at91_clk_slow_retain); diff --git a/drivers/clk/bcm/clk-kona.c b/drivers/clk/bcm/clk-kona.c index 95af2e665dd3..1c06f6f3a8c5 100644 --- a/drivers/clk/bcm/clk-kona.c +++ b/drivers/clk/bcm/clk-kona.c @@ -1032,7 +1032,7 @@ static long kona_peri_clk_round_rate(struct clk_hw *hw, unsigned long rate, } static long kona_peri_clk_determine_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *best_parent_rate, struct clk **best_parent) + unsigned long *best_parent_rate, struct clk_hw **best_parent) { struct kona_clk *bcm_clk = to_kona_clk(hw); struct clk *clk = hw->clk; @@ -1075,7 +1075,7 @@ static long kona_peri_clk_determine_rate(struct clk_hw *hw, unsigned long rate, if (delta < best_delta) { best_delta = delta; best_rate = other_rate; - *best_parent = parent; + *best_parent = __clk_get_hw(parent); *best_parent_rate = parent_rate; } } diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c index 21784e4eb3f0..440ef81ab15c 100644 --- a/drivers/clk/berlin/bg2q.c +++ b/drivers/clk/berlin/bg2q.c @@ -285,7 +285,6 @@ static const struct berlin2_gate_data bg2q_gates[] __initconst = { { "pbridge", "perif", 15, CLK_IGNORE_UNUSED }, { "sdio", "perif", 16, CLK_IGNORE_UNUSED }, { "nfc", "perif", 18 }, - { "smemc", "perif", 19 }, { "pcie", "perif", 22 }, }; diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c index b9355daf8065..4386697236a7 100644 --- a/drivers/clk/clk-composite.c +++ b/drivers/clk/clk-composite.c @@ -57,7 +57,7 @@ static unsigned long clk_composite_recalc_rate(struct clk_hw *hw, static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate, unsigned long *best_parent_rate, - struct clk **best_parent_p) + struct clk_hw **best_parent_p) { struct clk_composite *composite = to_clk_composite(hw); const struct clk_ops *rate_ops = composite->rate_ops; @@ -80,8 +80,9 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate, *best_parent_p = NULL; if (__clk_get_flags(hw->clk) & CLK_SET_RATE_NO_REPARENT) { - *best_parent_p = clk_get_parent(mux_hw->clk); - *best_parent_rate = __clk_get_rate(*best_parent_p); + parent = clk_get_parent(mux_hw->clk); + *best_parent_p = __clk_get_hw(parent); + *best_parent_rate = __clk_get_rate(parent); return rate_ops->round_rate(rate_hw, rate, best_parent_rate); @@ -103,7 +104,7 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate, if (!rate_diff || !*best_parent_p || best_rate_diff > rate_diff) { - *best_parent_p = parent; + *best_parent_p = __clk_get_hw(parent); *best_parent_rate = parent_rate; best_rate_diff = rate_diff; best_rate = tmp_rate; diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index 4f96ff3ba728..6e1ecf94bf58 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c @@ -77,7 +77,7 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index) else { if (mux->flags & CLK_MUX_INDEX_BIT) - index = (1 << ffs(index)); + index = 1 << index; if (mux->flags & CLK_MUX_INDEX_ONE) index++; diff --git a/drivers/clk/clk-ppc-corenet.c b/drivers/clk/clk-ppc-corenet.c index b6e6c85507a5..0a47d6f49cd6 100644 --- a/drivers/clk/clk-ppc-corenet.c +++ b/drivers/clk/clk-ppc-corenet.c @@ -291,7 +291,7 @@ static const struct of_device_id ppc_clk_ids[] __initconst = { {} }; -static struct platform_driver ppc_corenet_clk_driver __initdata = { +static struct platform_driver ppc_corenet_clk_driver = { .driver = { .name = "ppc_corenet_clock", .of_match_table = ppc_clk_ids, diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index 87a41038237d..bfa1e64e267d 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -218,7 +218,7 @@ static int s2mps11_clk_probe(struct platform_device *pdev) default: dev_err(&pdev->dev, "Invalid device type\n"); return -EINVAL; - }; + } /* Store clocks of_node in first element of s2mps11_clks array */ s2mps11_clks->clk_np = s2mps11_clk_parse_dt(pdev, clks_init); diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 4896ae9e23da..d48ac71c6c8b 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -240,7 +240,6 @@ static const struct file_operations clk_dump_fops = { .release = single_release, }; -/* caller must hold prepare_lock */ static int clk_debug_create_one(struct clk *clk, struct dentry *pdentry) { struct dentry *d; @@ -354,13 +353,13 @@ out: mutex_unlock(&clk_debug_lock); } -struct dentry *clk_debugfs_add_file(struct clk *clk, char *name, umode_t mode, +struct dentry *clk_debugfs_add_file(struct clk_hw *hw, char *name, umode_t mode, void *data, const struct file_operations *fops) { struct dentry *d = NULL; - if (clk->dentry) - d = debugfs_create_file(name, mode, clk->dentry, data, fops); + if (hw->clk->dentry) + d = debugfs_create_file(name, mode, hw->clk->dentry, data, fops); return d; } @@ -574,11 +573,6 @@ unsigned int __clk_get_enable_count(struct clk *clk) return !clk ? 0 : clk->enable_count; } -unsigned int __clk_get_prepare_count(struct clk *clk) -{ - return !clk ? 0 : clk->prepare_count; -} - unsigned long __clk_get_rate(struct clk *clk) { unsigned long ret; @@ -601,7 +595,7 @@ out: } EXPORT_SYMBOL_GPL(__clk_get_rate); -unsigned long __clk_get_accuracy(struct clk *clk) +static unsigned long __clk_get_accuracy(struct clk *clk) { if (!clk) return 0; @@ -707,7 +701,7 @@ struct clk *__clk_lookup(const char *name) */ long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate, unsigned long *best_parent_rate, - struct clk **best_parent_p) + struct clk_hw **best_parent_p) { struct clk *clk = hw->clk, *parent, *best_parent = NULL; int i, num_parents; @@ -743,7 +737,7 @@ long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate, out: if (best_parent) - *best_parent_p = best_parent; + *best_parent_p = best_parent->hw; *best_parent_rate = best; return best; @@ -951,6 +945,7 @@ unsigned long __clk_round_rate(struct clk *clk, unsigned long rate) { unsigned long parent_rate = 0; struct clk *parent; + struct clk_hw *parent_hw; if (!clk) return 0; @@ -959,10 +954,11 @@ unsigned long __clk_round_rate(struct clk *clk, unsigned long rate) if (parent) parent_rate = parent->rate; - if (clk->ops->determine_rate) + if (clk->ops->determine_rate) { + parent_hw = parent ? parent->hw : NULL; return clk->ops->determine_rate(clk->hw, rate, &parent_rate, - &parent); - else if (clk->ops->round_rate) + &parent_hw); + } else if (clk->ops->round_rate) return clk->ops->round_rate(clk->hw, rate, &parent_rate); else if (clk->flags & CLK_SET_RATE_PARENT) return __clk_round_rate(clk->parent, rate); @@ -1350,6 +1346,7 @@ static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate) { struct clk *top = clk; struct clk *old_parent, *parent; + struct clk_hw *parent_hw; unsigned long best_parent_rate = 0; unsigned long new_rate; int p_index = 0; @@ -1365,9 +1362,11 @@ static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate) /* find the closest rate and parent clk/rate */ if (clk->ops->determine_rate) { + parent_hw = parent ? parent->hw : NULL; new_rate = clk->ops->determine_rate(clk->hw, rate, &best_parent_rate, - &parent); + &parent_hw); + parent = parent_hw ? parent_hw->clk : NULL; } else if (clk->ops->round_rate) { new_rate = clk->ops->round_rate(clk->hw, rate, &best_parent_rate); @@ -1614,7 +1613,7 @@ static struct clk *__clk_init_parent(struct clk *clk) if (clk->num_parents == 1) { if (IS_ERR_OR_NULL(clk->parent)) - ret = clk->parent = __clk_lookup(clk->parent_names[0]); + clk->parent = __clk_lookup(clk->parent_names[0]); ret = clk->parent; goto out; } @@ -1944,7 +1943,6 @@ int __clk_init(struct device *dev, struct clk *clk) else clk->rate = 0; - clk_debug_register(clk); /* * walk the list of orphan clocks and reparent any that are children of * this clock @@ -1979,6 +1977,9 @@ int __clk_init(struct device *dev, struct clk *clk) out: clk_prepare_unlock(); + if (!ret) + clk_debug_register(clk); + return ret; } @@ -2273,14 +2274,17 @@ int __clk_get(struct clk *clk) void __clk_put(struct clk *clk) { + struct module *owner; + if (!clk || WARN_ON_ONCE(IS_ERR(clk))) return; clk_prepare_lock(); + owner = clk->owner; kref_put(&clk->ref, __clk_release); clk_prepare_unlock(); - module_put(clk->owner); + module_put(owner); } /*** clk rate change notifiers ***/ diff --git a/drivers/clk/hisilicon/clk-hi3620.c b/drivers/clk/hisilicon/clk-hi3620.c index 339945d2503b..007144f81f50 100644 --- a/drivers/clk/hisilicon/clk-hi3620.c +++ b/drivers/clk/hisilicon/clk-hi3620.c @@ -38,44 +38,44 @@ #include "clk.h" /* clock parent list */ -static const char *timer0_mux_p[] __initdata = { "osc32k", "timerclk01", }; -static const char *timer1_mux_p[] __initdata = { "osc32k", "timerclk01", }; -static const char *timer2_mux_p[] __initdata = { "osc32k", "timerclk23", }; -static const char *timer3_mux_p[] __initdata = { "osc32k", "timerclk23", }; -static const char *timer4_mux_p[] __initdata = { "osc32k", "timerclk45", }; -static const char *timer5_mux_p[] __initdata = { "osc32k", "timerclk45", }; -static const char *timer6_mux_p[] __initdata = { "osc32k", "timerclk67", }; -static const char *timer7_mux_p[] __initdata = { "osc32k", "timerclk67", }; -static const char *timer8_mux_p[] __initdata = { "osc32k", "timerclk89", }; -static const char *timer9_mux_p[] __initdata = { "osc32k", "timerclk89", }; -static const char *uart0_mux_p[] __initdata = { "osc26m", "pclk", }; -static const char *uart1_mux_p[] __initdata = { "osc26m", "pclk", }; -static const char *uart2_mux_p[] __initdata = { "osc26m", "pclk", }; -static const char *uart3_mux_p[] __initdata = { "osc26m", "pclk", }; -static const char *uart4_mux_p[] __initdata = { "osc26m", "pclk", }; -static const char *spi0_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", }; -static const char *spi1_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", }; -static const char *spi2_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", }; +static const char *timer0_mux_p[] __initconst = { "osc32k", "timerclk01", }; +static const char *timer1_mux_p[] __initconst = { "osc32k", "timerclk01", }; +static const char *timer2_mux_p[] __initconst = { "osc32k", "timerclk23", }; +static const char *timer3_mux_p[] __initconst = { "osc32k", "timerclk23", }; +static const char *timer4_mux_p[] __initconst = { "osc32k", "timerclk45", }; +static const char *timer5_mux_p[] __initconst = { "osc32k", "timerclk45", }; +static const char *timer6_mux_p[] __initconst = { "osc32k", "timerclk67", }; +static const char *timer7_mux_p[] __initconst = { "osc32k", "timerclk67", }; +static const char *timer8_mux_p[] __initconst = { "osc32k", "timerclk89", }; +static const char *timer9_mux_p[] __initconst = { "osc32k", "timerclk89", }; +static const char *uart0_mux_p[] __initconst = { "osc26m", "pclk", }; +static const char *uart1_mux_p[] __initconst = { "osc26m", "pclk", }; +static const char *uart2_mux_p[] __initconst = { "osc26m", "pclk", }; +static const char *uart3_mux_p[] __initconst = { "osc26m", "pclk", }; +static const char *uart4_mux_p[] __initconst = { "osc26m", "pclk", }; +static const char *spi0_mux_p[] __initconst = { "osc26m", "rclk_cfgaxi", }; +static const char *spi1_mux_p[] __initconst = { "osc26m", "rclk_cfgaxi", }; +static const char *spi2_mux_p[] __initconst = { "osc26m", "rclk_cfgaxi", }; /* share axi parent */ -static const char *saxi_mux_p[] __initdata = { "armpll3", "armpll2", }; -static const char *pwm0_mux_p[] __initdata = { "osc32k", "osc26m", }; -static const char *pwm1_mux_p[] __initdata = { "osc32k", "osc26m", }; -static const char *sd_mux_p[] __initdata = { "armpll2", "armpll3", }; -static const char *mmc1_mux_p[] __initdata = { "armpll2", "armpll3", }; -static const char *mmc1_mux2_p[] __initdata = { "osc26m", "mmc1_div", }; -static const char *g2d_mux_p[] __initdata = { "armpll2", "armpll3", }; -static const char *venc_mux_p[] __initdata = { "armpll2", "armpll3", }; -static const char *vdec_mux_p[] __initdata = { "armpll2", "armpll3", }; -static const char *vpp_mux_p[] __initdata = { "armpll2", "armpll3", }; -static const char *edc0_mux_p[] __initdata = { "armpll2", "armpll3", }; -static const char *ldi0_mux_p[] __initdata = { "armpll2", "armpll4", +static const char *saxi_mux_p[] __initconst = { "armpll3", "armpll2", }; +static const char *pwm0_mux_p[] __initconst = { "osc32k", "osc26m", }; +static const char *pwm1_mux_p[] __initconst = { "osc32k", "osc26m", }; +static const char *sd_mux_p[] __initconst = { "armpll2", "armpll3", }; +static const char *mmc1_mux_p[] __initconst = { "armpll2", "armpll3", }; +static const char *mmc1_mux2_p[] __initconst = { "osc26m", "mmc1_div", }; +static const char *g2d_mux_p[] __initconst = { "armpll2", "armpll3", }; +static const char *venc_mux_p[] __initconst = { "armpll2", "armpll3", }; +static const char *vdec_mux_p[] __initconst = { "armpll2", "armpll3", }; +static const char *vpp_mux_p[] __initconst = { "armpll2", "armpll3", }; +static const char *edc0_mux_p[] __initconst = { "armpll2", "armpll3", }; +static const char *ldi0_mux_p[] __initconst = { "armpll2", "armpll4", "armpll3", "armpll5", }; -static const char *edc1_mux_p[] __initdata = { "armpll2", "armpll3", }; -static const char *ldi1_mux_p[] __initdata = { "armpll2", "armpll4", +static const char *edc1_mux_p[] __initconst = { "armpll2", "armpll3", }; +static const char *ldi1_mux_p[] __initconst = { "armpll2", "armpll4", "armpll3", "armpll5", }; -static const char *rclk_hsic_p[] __initdata = { "armpll3", "armpll2", }; -static const char *mmc2_mux_p[] __initdata = { "armpll2", "armpll3", }; -static const char *mmc3_mux_p[] __initdata = { "armpll2", "armpll3", }; +static const char *rclk_hsic_p[] __initconst = { "armpll3", "armpll2", }; +static const char *mmc2_mux_p[] __initconst = { "armpll2", "armpll3", }; +static const char *mmc3_mux_p[] __initconst = { "armpll2", "armpll3", }; /* fixed rate clocks */ @@ -296,7 +296,7 @@ static unsigned long mmc_clk_recalc_rate(struct clk_hw *hw, static long mmc_clk_determine_rate(struct clk_hw *hw, unsigned long rate, unsigned long *best_parent_rate, - struct clk **best_parent_p) + struct clk_hw **best_parent_p) { struct clk_mmc *mclk = to_mmc(hw); unsigned long best = 0; diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile index 392d78044ce3..3caaf7cc169c 100644 --- a/drivers/clk/mmp/Makefile +++ b/drivers/clk/mmp/Makefile @@ -2,7 +2,12 @@ # Makefile for mmp specific clk # -obj-y += clk-apbc.o clk-apmu.o clk-frac.o +obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o + +obj-$(CONFIG_RESET_CONTROLLER) += reset.o + +obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o clk-of-pxa910.o +obj-$(CONFIG_MACH_MMP2_DT) += clk-of-mmp2.o obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c index 23a56f561812..584a9927993b 100644 --- a/drivers/clk/mmp/clk-frac.c +++ b/drivers/clk/mmp/clk-frac.c @@ -22,19 +22,12 @@ * numerator/denominator = Fin / (Fout * factor) */ -#define to_clk_factor(hw) container_of(hw, struct clk_factor, hw) -struct clk_factor { - struct clk_hw hw; - void __iomem *base; - struct clk_factor_masks *masks; - struct clk_factor_tbl *ftbl; - unsigned int ftbl_cnt; -}; +#define to_clk_factor(hw) container_of(hw, struct mmp_clk_factor, hw) static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate, unsigned long *prate) { - struct clk_factor *factor = to_clk_factor(hw); + struct mmp_clk_factor *factor = to_clk_factor(hw); unsigned long rate = 0, prev_rate; int i; @@ -58,8 +51,8 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate, static unsigned long clk_factor_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { - struct clk_factor *factor = to_clk_factor(hw); - struct clk_factor_masks *masks = factor->masks; + struct mmp_clk_factor *factor = to_clk_factor(hw); + struct mmp_clk_factor_masks *masks = factor->masks; unsigned int val, num, den; val = readl_relaxed(factor->base); @@ -81,11 +74,12 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw, static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate, unsigned long prate) { - struct clk_factor *factor = to_clk_factor(hw); - struct clk_factor_masks *masks = factor->masks; + struct mmp_clk_factor *factor = to_clk_factor(hw); + struct mmp_clk_factor_masks *masks = factor->masks; int i; unsigned long val; unsigned long prev_rate, rate = 0; + unsigned long flags = 0; for (i = 0; i < factor->ftbl_cnt; i++) { prev_rate = rate; @@ -97,6 +91,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate, if (i > 0) i--; + if (factor->lock) + spin_lock_irqsave(factor->lock, flags); + val = readl_relaxed(factor->base); val &= ~(masks->num_mask << masks->num_shift); @@ -107,21 +104,65 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate, writel_relaxed(val, factor->base); + if (factor->lock) + spin_unlock_irqrestore(factor->lock, flags); + return 0; } +static void clk_factor_init(struct clk_hw *hw) +{ + struct mmp_clk_factor *factor = to_clk_factor(hw); + struct mmp_clk_factor_masks *masks = factor->masks; + u32 val, num, den; + int i; + unsigned long flags = 0; + + if (factor->lock) + spin_lock_irqsave(factor->lock, flags); + + val = readl(factor->base); + + /* calculate numerator */ + num = (val >> masks->num_shift) & masks->num_mask; + + /* calculate denominator */ + den = (val >> masks->den_shift) & masks->den_mask; + + for (i = 0; i < factor->ftbl_cnt; i++) + if (den == factor->ftbl[i].den && num == factor->ftbl[i].num) + break; + + if (i >= factor->ftbl_cnt) { + val &= ~(masks->num_mask << masks->num_shift); + val |= (factor->ftbl[0].num & masks->num_mask) << + masks->num_shift; + + val &= ~(masks->den_mask << masks->den_shift); + val |= (factor->ftbl[0].den & masks->den_mask) << + masks->den_shift; + + writel(val, factor->base); + } + + if (factor->lock) + spin_unlock_irqrestore(factor->lock, flags); +} + static struct clk_ops clk_factor_ops = { .recalc_rate = clk_factor_recalc_rate, .round_rate = clk_factor_round_rate, .set_rate = clk_factor_set_rate, + .init = clk_factor_init, }; struct clk *mmp_clk_register_factor(const char *name, const char *parent_name, unsigned long flags, void __iomem *base, - struct clk_factor_masks *masks, struct clk_factor_tbl *ftbl, - unsigned int ftbl_cnt) + struct mmp_clk_factor_masks *masks, + struct mmp_clk_factor_tbl *ftbl, + unsigned int ftbl_cnt, spinlock_t *lock) { - struct clk_factor *factor; + struct mmp_clk_factor *factor; struct clk_init_data init; struct clk *clk; @@ -142,6 +183,7 @@ struct clk *mmp_clk_register_factor(const char *name, const char *parent_name, factor->ftbl = ftbl; factor->ftbl_cnt = ftbl_cnt; factor->hw.init = &init; + factor->lock = lock; init.name = name; init.ops = &clk_factor_ops; diff --git a/drivers/clk/mmp/clk-gate.c b/drivers/clk/mmp/clk-gate.c new file mode 100644 index 000000000000..adbd9d64ded2 --- /dev/null +++ b/drivers/clk/mmp/clk-gate.c @@ -0,0 +1,133 @@ +/* + * mmp gate clock operation source file + * + * Copyright (C) 2014 Marvell + * Chao Xie <chao.xie@marvell.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/clk-provider.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/err.h> +#include <linux/delay.h> + +#include "clk.h" + +/* + * Some clocks will have mutiple bits to enable the clocks, and + * the bits to disable the clock is not same as enabling bits. + */ + +#define to_clk_mmp_gate(hw) container_of(hw, struct mmp_clk_gate, hw) + +static int mmp_clk_gate_enable(struct clk_hw *hw) +{ + struct mmp_clk_gate *gate = to_clk_mmp_gate(hw); + struct clk *clk = hw->clk; + unsigned long flags = 0; + unsigned long rate; + u32 tmp; + + if (gate->lock) + spin_lock_irqsave(gate->lock, flags); + + tmp = readl(gate->reg); + tmp &= ~gate->mask; + tmp |= gate->val_enable; + writel(tmp, gate->reg); + + if (gate->lock) + spin_unlock_irqrestore(gate->lock, flags); + + if (gate->flags & MMP_CLK_GATE_NEED_DELAY) { + rate = __clk_get_rate(clk); + /* Need delay 2 cycles. */ + udelay(2000000/rate); + } + + return 0; +} + +static void mmp_clk_gate_disable(struct clk_hw *hw) +{ + struct mmp_clk_gate *gate = to_clk_mmp_gate(hw); + unsigned long flags = 0; + u32 tmp; + + if (gate->lock) + spin_lock_irqsave(gate->lock, flags); + + tmp = readl(gate->reg); + tmp &= ~gate->mask; + tmp |= gate->val_disable; + writel(tmp, gate->reg); + + if (gate->lock) + spin_unlock_irqrestore(gate->lock, flags); +} + +static int mmp_clk_gate_is_enabled(struct clk_hw *hw) +{ + struct mmp_clk_gate *gate = to_clk_mmp_gate(hw); + unsigned long flags = 0; + u32 tmp; + + if (gate->lock) + spin_lock_irqsave(gate->lock, flags); + + tmp = readl(gate->reg); + + if (gate->lock) + spin_unlock_irqrestore(gate->lock, flags); + + return (tmp & gate->mask) == gate->val_enable; +} + +const struct clk_ops mmp_clk_gate_ops = { + .enable = mmp_clk_gate_enable, + .disable = mmp_clk_gate_disable, + .is_enabled = mmp_clk_gate_is_enabled, +}; + +struct clk *mmp_clk_register_gate(struct device *dev, const char *name, + const char *parent_name, unsigned long flags, + void __iomem *reg, u32 mask, u32 val_enable, u32 val_disable, + unsigned int gate_flags, spinlock_t *lock) +{ + struct mmp_clk_gate *gate; + struct clk *clk; + struct clk_init_data init; + + /* allocate the gate */ + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) { + pr_err("%s:%s could not allocate gate clk\n", __func__, name); + return ERR_PTR(-ENOMEM); + } + + init.name = name; + init.ops = &mmp_clk_gate_ops; + init.flags = flags | CLK_IS_BASIC; + init.parent_names = (parent_name ? &parent_name : NULL); + init.num_parents = (parent_name ? 1 : 0); + + /* struct clk_gate assignments */ + gate->reg = reg; + gate->mask = mask; + gate->val_enable = val_enable; + gate->val_disable = val_disable; + gate->flags = gate_flags; + gate->lock = lock; + gate->hw.init = &init; + + clk = clk_register(dev, &gate->hw); + + if (IS_ERR(clk)) + kfree(gate); + + return clk; +} diff --git a/drivers/clk/mmp/clk-mix.c b/drivers/clk/mmp/clk-mix.c new file mode 100644 index 000000000000..48fa53c7ce5e --- /dev/null +++ b/drivers/clk/mmp/clk-mix.c @@ -0,0 +1,513 @@ +/* + * mmp mix(div and mux) clock operation source file + * + * Copyright (C) 2014 Marvell + * Chao Xie <chao.xie@marvell.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/clk-provider.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/err.h> + +#include "clk.h" + +/* + * The mix clock is a clock combined mux and div type clock. + * Because the div field and mux field need to be set at same + * time, we can not divide it into 2 types of clock + */ + +#define to_clk_mix(hw) container_of(hw, struct mmp_clk_mix, hw) + +static unsigned int _get_maxdiv(struct mmp_clk_mix *mix) +{ + unsigned int div_mask = (1 << mix->reg_info.width_div) - 1; + unsigned int maxdiv = 0; + struct clk_div_table *clkt; + + if (mix->div_flags & CLK_DIVIDER_ONE_BASED) + return div_mask; + if (mix->div_flags & CLK_DIVIDER_POWER_OF_TWO) + return 1 << div_mask; + if (mix->div_table) { + for (clkt = mix->div_table; clkt->div; clkt++) + if (clkt->div > maxdiv) + maxdiv = clkt->div; + return maxdiv; + } + return div_mask + 1; +} + +static unsigned int _get_div(struct mmp_clk_mix *mix, unsigned int val) +{ + struct clk_div_table *clkt; + + if (mix->div_flags & CLK_DIVIDER_ONE_BASED) + return val; + if (mix->div_flags & CLK_DIVIDER_POWER_OF_TWO) + return 1 << val; + if (mix->div_table) { + for (clkt = mix->div_table; clkt->div; clkt++) + if (clkt->val == val) + return clkt->div; + if (clkt->div == 0) + return 0; + } + return val + 1; +} + +static unsigned int _get_mux(struct mmp_clk_mix *mix, unsigned int val) +{ + int num_parents = __clk_get_num_parents(mix->hw.clk); + int i; + + if (mix->mux_flags & CLK_MUX_INDEX_BIT) + return ffs(val) - 1; + if (mix->mux_flags & CLK_MUX_INDEX_ONE) + return val - 1; + if (mix->mux_table) { + for (i = 0; i < num_parents; i++) + if (mix->mux_table[i] == val) + return i; + if (i == num_parents) + return 0; + } + + return val; +} +static unsigned int _get_div_val(struct mmp_clk_mix *mix, unsigned int div) +{ + struct clk_div_table *clkt; + + if (mix->div_flags & CLK_DIVIDER_ONE_BASED) + return div; + if (mix->div_flags & CLK_DIVIDER_POWER_OF_TWO) + return __ffs(div); + if (mix->div_table) { + for (clkt = mix->div_table; clkt->div; clkt++) + if (clkt->div == div) + return clkt->val; + if (clkt->div == 0) + return 0; + } + + return div - 1; +} + +static unsigned int _get_mux_val(struct mmp_clk_mix *mix, unsigned int mux) +{ + if (mix->mux_table) + return mix->mux_table[mux]; + + return mux; +} + +static void _filter_clk_table(struct mmp_clk_mix *mix, + struct mmp_clk_mix_clk_table *table, + unsigned int table_size) +{ + int i; + struct mmp_clk_mix_clk_table *item; + struct clk *parent, *clk; + unsigned long parent_rate; + + clk = mix->hw.clk; + + for (i = 0; i < table_size; i++) { + item = &table[i]; + parent = clk_get_parent_by_index(clk, item->parent_index); + parent_rate = __clk_get_rate(parent); + if (parent_rate % item->rate) { + item->valid = 0; + } else { + item->divisor = parent_rate / item->rate; + item->valid = 1; + } + } +} + +static int _set_rate(struct mmp_clk_mix *mix, u32 mux_val, u32 div_val, + unsigned int change_mux, unsigned int change_div) +{ + struct mmp_clk_mix_reg_info *ri = &mix->reg_info; + u8 width, shift; + u32 mux_div, fc_req; + int ret, timeout = 50; + unsigned long flags = 0; + + if (!change_mux && !change_div) + return -EINVAL; + + if (mix->lock) + spin_lock_irqsave(mix->lock, flags); + + if (mix->type == MMP_CLK_MIX_TYPE_V1 + || mix->type == MMP_CLK_MIX_TYPE_V2) + mux_div = readl(ri->reg_clk_ctrl); + else + mux_div = readl(ri->reg_clk_sel); + + if (change_div) { + width = ri->width_div; + shift = ri->shift_div; + mux_div &= ~MMP_CLK_BITS_MASK(width, shift); + mux_div |= MMP_CLK_BITS_SET_VAL(div_val, width, shift); + } + + if (change_mux) { + width = ri->width_mux; + shift = ri->shift_mux; + mux_div &= ~MMP_CLK_BITS_MASK(width, shift); + mux_div |= MMP_CLK_BITS_SET_VAL(mux_val, width, shift); + } + + if (mix->type == MMP_CLK_MIX_TYPE_V1) { + writel(mux_div, ri->reg_clk_ctrl); + } else if (mix->type == MMP_CLK_MIX_TYPE_V2) { + mux_div |= (1 << ri->bit_fc); + writel(mux_div, ri->reg_clk_ctrl); + + do { + fc_req = readl(ri->reg_clk_ctrl); + timeout--; + if (!(fc_req & (1 << ri->bit_fc))) + break; + } while (timeout); + + if (timeout == 0) { + pr_err("%s:%s cannot do frequency change\n", + __func__, __clk_get_name(mix->hw.clk)); + ret = -EBUSY; + goto error; + } + } else { + fc_req = readl(ri->reg_clk_ctrl); + fc_req |= 1 << ri->bit_fc; + writel(fc_req, ri->reg_clk_ctrl); + writel(mux_div, ri->reg_clk_sel); + fc_req &= ~(1 << ri->bit_fc); + } + + ret = 0; +error: + if (mix->lock) + spin_unlock_irqrestore(mix->lock, flags); + + return ret; +} + +static long mmp_clk_mix_determine_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *best_parent_rate, + struct clk_hw **best_parent_clk) +{ + struct mmp_clk_mix *mix = to_clk_mix(hw); + struct mmp_clk_mix_clk_table *item; + struct clk *parent, *parent_best, *mix_clk; + unsigned long parent_rate, mix_rate, mix_rate_best, parent_rate_best; + unsigned long gap, gap_best; + u32 div_val_max; + unsigned int div; + int i, j; + + mix_clk = hw->clk; + + parent = NULL; + mix_rate_best = 0; + parent_rate_best = 0; + gap_best = rate; + parent_best = NULL; + + if (mix->table) { + for (i = 0; i < mix->table_size; i++) { + item = &mix->table[i]; + if (item->valid == 0) + continue; + parent = clk_get_parent_by_index(mix_clk, + item->parent_index); + parent_rate = __clk_get_rate(parent); + mix_rate = parent_rate / item->divisor; + gap = abs(mix_rate - rate); + if (parent_best == NULL || gap < gap_best) { + parent_best = parent; + parent_rate_best = parent_rate; + mix_rate_best = mix_rate; + gap_best = gap; + if (gap_best == 0) + goto found; + } + } + } else { + for (i = 0; i < __clk_get_num_parents(mix_clk); i++) { + parent = clk_get_parent_by_index(mix_clk, i); + parent_rate = __clk_get_rate(parent); + div_val_max = _get_maxdiv(mix); + for (j = 0; j < div_val_max; j++) { + div = _get_div(mix, j); + mix_rate = parent_rate / div; + gap = abs(mix_rate - rate); + if (parent_best == NULL || gap < gap_best) { + parent_best = parent; + parent_rate_best = parent_rate; + mix_rate_best = mix_rate; + gap_best = gap; + if (gap_best == 0) + goto found; + } + } + } + } + +found: + *best_parent_rate = parent_rate_best; + *best_parent_clk = __clk_get_hw(parent_best); + + return mix_rate_best; +} + +static int mmp_clk_mix_set_rate_and_parent(struct clk_hw *hw, + unsigned long rate, + unsigned long parent_rate, + u8 index) +{ + struct mmp_clk_mix *mix = to_clk_mix(hw); + unsigned int div; + u32 div_val, mux_val; + + div = parent_rate / rate; + div_val = _get_div_val(mix, div); + mux_val = _get_mux_val(mix, index); + + return _set_rate(mix, mux_val, div_val, 1, 1); +} + +static u8 mmp_clk_mix_get_parent(struct clk_hw *hw) +{ + struct mmp_clk_mix *mix = to_clk_mix(hw); + struct mmp_clk_mix_reg_info *ri = &mix->reg_info; + unsigned long flags = 0; + u32 mux_div = 0; + u8 width, shift; + u32 mux_val; + + if (mix->lock) + spin_lock_irqsave(mix->lock, flags); + + if (mix->type == MMP_CLK_MIX_TYPE_V1 + || mix->type == MMP_CLK_MIX_TYPE_V2) + mux_div = readl(ri->reg_clk_ctrl); + else + mux_div = readl(ri->reg_clk_sel); + + if (mix->lock) + spin_unlock_irqrestore(mix->lock, flags); + + width = mix->reg_info.width_mux; + shift = mix->reg_info.shift_mux; + + mux_val = MMP_CLK_BITS_GET_VAL(mux_div, width, shift); + + return _get_mux(mix, mux_val); +} + +static unsigned long mmp_clk_mix_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct mmp_clk_mix *mix = to_clk_mix(hw); + struct mmp_clk_mix_reg_info *ri = &mix->reg_info; + unsigned long flags = 0; + u32 mux_div = 0; + u8 width, shift; + unsigned int div; + + if (mix->lock) + spin_lock_irqsave(mix->lock, flags); + + if (mix->type == MMP_CLK_MIX_TYPE_V1 + || mix->type == MMP_CLK_MIX_TYPE_V2) + mux_div = readl(ri->reg_clk_ctrl); + else + mux_div = readl(ri->reg_clk_sel); + + if (mix->lock) + spin_unlock_irqrestore(mix->lock, flags); + + width = mix->reg_info.width_div; + shift = mix->reg_info.shift_div; + + div = _get_div(mix, MMP_CLK_BITS_GET_VAL(mux_div, width, shift)); + + return parent_rate / div; +} + +static int mmp_clk_set_parent(struct clk_hw *hw, u8 index) +{ + struct mmp_clk_mix *mix = to_clk_mix(hw); + struct mmp_clk_mix_clk_table *item; + int i; + u32 div_val, mux_val; + + if (mix->table) { + for (i = 0; i < mix->table_size; i++) { + item = &mix->table[i]; + if (item->valid == 0) + continue; + if (item->parent_index == index) + break; + } + if (i < mix->table_size) { + div_val = _get_div_val(mix, item->divisor); + mux_val = _get_mux_val(mix, item->parent_index); + } else + return -EINVAL; + } else { + mux_val = _get_mux_val(mix, index); + div_val = 0; + } + + return _set_rate(mix, mux_val, div_val, 1, div_val ? 1 : 0); +} + +static int mmp_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long best_parent_rate) +{ + struct mmp_clk_mix *mix = to_clk_mix(hw); + struct mmp_clk_mix_clk_table *item; + unsigned long parent_rate; + unsigned int best_divisor; + struct clk *mix_clk, *parent; + int i; + + best_divisor = best_parent_rate / rate; + + mix_clk = hw->clk; + if (mix->table) { + for (i = 0; i < mix->table_size; i++) { + item = &mix->table[i]; + if (item->valid == 0) + continue; + parent = clk_get_parent_by_index(mix_clk, + item->parent_index); + parent_rate = __clk_get_rate(parent); + if (parent_rate == best_parent_rate + && item->divisor == best_divisor) + break; + } + if (i < mix->table_size) + return _set_rate(mix, + _get_mux_val(mix, item->parent_index), + _get_div_val(mix, item->divisor), + 1, 1); + else + return -EINVAL; + } else { + for (i = 0; i < __clk_get_num_parents(mix_clk); i++) { + parent = clk_get_parent_by_index(mix_clk, i); + parent_rate = __clk_get_rate(parent); + if (parent_rate == best_parent_rate) + break; + } + if (i < __clk_get_num_parents(mix_clk)) + return _set_rate(mix, _get_mux_val(mix, i), + _get_div_val(mix, best_divisor), 1, 1); + else + return -EINVAL; + } +} + +static void mmp_clk_mix_init(struct clk_hw *hw) +{ + struct mmp_clk_mix *mix = to_clk_mix(hw); + + if (mix->table) + _filter_clk_table(mix, mix->table, mix->table_size); +} + +const struct clk_ops mmp_clk_mix_ops = { + .determine_rate = mmp_clk_mix_determine_rate, + .set_rate_and_parent = mmp_clk_mix_set_rate_and_parent, + .set_rate = mmp_clk_set_rate, + .set_parent = mmp_clk_set_parent, + .get_parent = mmp_clk_mix_get_parent, + .recalc_rate = mmp_clk_mix_recalc_rate, + .init = mmp_clk_mix_init, +}; + +struct clk *mmp_clk_register_mix(struct device *dev, + const char *name, + const char **parent_names, + u8 num_parents, + unsigned long flags, + struct mmp_clk_mix_config *config, + spinlock_t *lock) +{ + struct mmp_clk_mix *mix; + struct clk *clk; + struct clk_init_data init; + size_t table_bytes; + + mix = kzalloc(sizeof(*mix), GFP_KERNEL); + if (!mix) { + pr_err("%s:%s: could not allocate mmp mix clk\n", + __func__, name); + return ERR_PTR(-ENOMEM); + } + + init.name = name; + init.flags = flags | CLK_GET_RATE_NOCACHE; + init.parent_names = parent_names; + init.num_parents = num_parents; + init.ops = &mmp_clk_mix_ops; + + memcpy(&mix->reg_info, &config->reg_info, sizeof(config->reg_info)); + if (config->table) { + table_bytes = sizeof(*config->table) * config->table_size; + mix->table = kzalloc(table_bytes, GFP_KERNEL); + if (!mix->table) { + pr_err("%s:%s: could not allocate mmp mix table\n", + __func__, name); + kfree(mix); + return ERR_PTR(-ENOMEM); + } + memcpy(mix->table, config->table, table_bytes); + mix->table_size = config->table_size; + } + + if (config->mux_table) { + table_bytes = sizeof(u32) * num_parents; + mix->mux_table = kzalloc(table_bytes, GFP_KERNEL); + if (!mix->mux_table) { + pr_err("%s:%s: could not allocate mmp mix mux-table\n", + __func__, name); + kfree(mix->table); + kfree(mix); + return ERR_PTR(-ENOMEM); + } + memcpy(mix->mux_table, config->mux_table, table_bytes); + } + + mix->div_flags = config->div_flags; + mix->mux_flags = config->mux_flags; + mix->lock = lock; + mix->hw.init = &init; + + if (config->reg_info.bit_fc >= 32) + mix->type = MMP_CLK_MIX_TYPE_V1; + else if (config->reg_info.reg_clk_sel) + mix->type = MMP_CLK_MIX_TYPE_V3; + else + mix->type = MMP_CLK_MIX_TYPE_V2; + clk = clk_register(dev, &mix->hw); + + if (IS_ERR(clk)) { + kfree(mix->mux_table); + kfree(mix->table); + kfree(mix); + } + + return clk; +} diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c index b2721cae257a..5c90a4230fa3 100644 --- a/drivers/clk/mmp/clk-mmp2.c +++ b/drivers/clk/mmp/clk-mmp2.c @@ -54,7 +54,7 @@ static DEFINE_SPINLOCK(clk_lock); -static struct clk_factor_masks uart_factor_masks = { +static struct mmp_clk_factor_masks uart_factor_masks = { .factor = 2, .num_mask = 0x1fff, .den_mask = 0x1fff, @@ -62,7 +62,7 @@ static struct clk_factor_masks uart_factor_masks = { .den_shift = 0, }; -static struct clk_factor_tbl uart_factor_tbl[] = { +static struct mmp_clk_factor_tbl uart_factor_tbl[] = { {.num = 14634, .den = 2165}, /*14.745MHZ */ {.num = 3521, .den = 689}, /*19.23MHZ */ {.num = 9679, .den = 5728}, /*58.9824MHZ */ @@ -191,7 +191,7 @@ void __init mmp2_clk_init(void) clk = mmp_clk_register_factor("uart_pll", "pll1_4", 0, mpmu_base + MPMU_UART_PLL, &uart_factor_masks, uart_factor_tbl, - ARRAY_SIZE(uart_factor_tbl)); + ARRAY_SIZE(uart_factor_tbl), &clk_lock); clk_set_rate(clk, 14745600); clk_register_clkdev(clk, "uart_pll", NULL); diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c new file mode 100644 index 000000000000..2cbc2b43ae52 --- /dev/null +++ b/drivers/clk/mmp/clk-of-mmp2.c @@ -0,0 +1,334 @@ +/* + * mmp2 clock framework source file + * + * Copyright (C) 2012 Marvell + * Chao Xie <xiechao.mail@gmail.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/spinlock.h> +#include <linux/io.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/of_address.h> + +#include <dt-bindings/clock/marvell,mmp2.h> + +#include "clk.h" +#include "reset.h" + +#define APBC_RTC 0x0 +#define APBC_TWSI0 0x4 +#define APBC_TWSI1 0x8 +#define APBC_TWSI2 0xc +#define APBC_TWSI3 0x10 +#define APBC_TWSI4 0x7c +#define APBC_TWSI5 0x80 +#define APBC_KPC 0x18 +#define APBC_UART0 0x2c +#define APBC_UART1 0x30 +#define APBC_UART2 0x34 +#define APBC_UART3 0x88 +#define APBC_GPIO 0x38 +#define APBC_PWM0 0x3c +#define APBC_PWM1 0x40 +#define APBC_PWM2 0x44 +#define APBC_PWM3 0x48 +#define APBC_SSP0 0x50 +#define APBC_SSP1 0x54 +#define APBC_SSP2 0x58 +#define APBC_SSP3 0x5c +#define APMU_SDH0 0x54 +#define APMU_SDH1 0x58 +#define APMU_SDH2 0xe8 +#define APMU_SDH3 0xec +#define APMU_USB 0x5c +#define APMU_DISP0 0x4c +#define APMU_DISP1 0x110 +#define APMU_CCIC0 0x50 +#define APMU_CCIC1 0xf4 +#define MPMU_UART_PLL 0x14 + +struct mmp2_clk_unit { + struct mmp_clk_unit unit; + void __iomem *mpmu_base; + void __iomem *apmu_base; + void __iomem *apbc_base; +}; + +static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = { + {MMP2_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768}, + {MMP2_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000}, + {MMP2_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 800000000}, + {MMP2_CLK_PLL2, "pll2", NULL, CLK_IS_ROOT, 960000000}, + {MMP2_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 480000000}, +}; + +static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = { + {MMP2_CLK_PLL1_2, "pll1_2", "pll1", 1, 2, 0}, + {MMP2_CLK_PLL1_4, "pll1_4", "pll1_2", 1, 2, 0}, + {MMP2_CLK_PLL1_8, "pll1_8", "pll1_4", 1, 2, 0}, + {MMP2_CLK_PLL1_16, "pll1_16", "pll1_8", 1, 2, 0}, + {MMP2_CLK_PLL1_20, "pll1_20", "pll1_4", 1, 5, 0}, + {MMP2_CLK_PLL1_3, "pll1_3", "pll1", 1, 3, 0}, + {MMP2_CLK_PLL1_6, "pll1_6", "pll1_3", 1, 2, 0}, + {MMP2_CLK_PLL1_12, "pll1_12", "pll1_6", 1, 2, 0}, + {MMP2_CLK_PLL2_2, "pll2_2", "pll2", 1, 2, 0}, + {MMP2_CLK_PLL2_4, "pll2_4", "pll2_2", 1, 2, 0}, + {MMP2_CLK_PLL2_8, "pll2_8", "pll2_4", 1, 2, 0}, + {MMP2_CLK_PLL2_16, "pll2_16", "pll2_8", 1, 2, 0}, + {MMP2_CLK_PLL2_3, "pll2_3", "pll2", 1, 3, 0}, + {MMP2_CLK_PLL2_6, "pll2_6", "pll2_3", 1, 2, 0}, + {MMP2_CLK_PLL2_12, "pll2_12", "pll2_6", 1, 2, 0}, + {MMP2_CLK_VCTCXO_2, "vctcxo_2", "vctcxo", 1, 2, 0}, + {MMP2_CLK_VCTCXO_4, "vctcxo_4", "vctcxo_2", 1, 2, 0}, +}; + +static struct mmp_clk_factor_masks uart_factor_masks = { + .factor = 2, + .num_mask = 0x1fff, + .den_mask = 0x1fff, + .num_shift = 16, + .den_shift = 0, +}; + +static struct mmp_clk_factor_tbl uart_factor_tbl[] = { + {.num = 14634, .den = 2165}, /*14.745MHZ */ + {.num = 3521, .den = 689}, /*19.23MHZ */ + {.num = 9679, .den = 5728}, /*58.9824MHZ */ + {.num = 15850, .den = 9451}, /*59.429MHZ */ +}; + +static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit) +{ + struct clk *clk; + struct mmp_clk_unit *unit = &pxa_unit->unit; + + mmp_register_fixed_rate_clks(unit, fixed_rate_clks, + ARRAY_SIZE(fixed_rate_clks)); + + mmp_register_fixed_factor_clks(unit, fixed_factor_clks, + ARRAY_SIZE(fixed_factor_clks)); + + clk = mmp_clk_register_factor("uart_pll", "pll1_4", + CLK_SET_RATE_PARENT, + pxa_unit->mpmu_base + MPMU_UART_PLL, + &uart_factor_masks, uart_factor_tbl, + ARRAY_SIZE(uart_factor_tbl), NULL); + mmp_clk_add(unit, MMP2_CLK_UART_PLL, clk); +} + +static DEFINE_SPINLOCK(uart0_lock); +static DEFINE_SPINLOCK(uart1_lock); +static DEFINE_SPINLOCK(uart2_lock); +static const char *uart_parent_names[] = {"uart_pll", "vctcxo"}; + +static DEFINE_SPINLOCK(ssp0_lock); +static DEFINE_SPINLOCK(ssp1_lock); +static DEFINE_SPINLOCK(ssp2_lock); +static DEFINE_SPINLOCK(ssp3_lock); +static const char *ssp_parent_names[] = {"vctcxo_4", "vctcxo_2", "vctcxo", "pll1_16"}; + +static DEFINE_SPINLOCK(reset_lock); + +static struct mmp_param_mux_clk apbc_mux_clks[] = { + {0, "uart0_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART0, 4, 3, 0, &uart0_lock}, + {0, "uart1_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART1, 4, 3, 0, &uart1_lock}, + {0, "uart2_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART2, 4, 3, 0, &uart2_lock}, + {0, "uart3_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART3, 4, 3, 0, &uart2_lock}, + {0, "ssp0_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP0, 4, 3, 0, &ssp0_lock}, + {0, "ssp1_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP1, 4, 3, 0, &ssp1_lock}, + {0, "ssp2_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP2, 4, 3, 0, &ssp2_lock}, + {0, "ssp3_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP3, 4, 3, 0, &ssp3_lock}, +}; + +static struct mmp_param_gate_clk apbc_gate_clks[] = { + {MMP2_CLK_TWSI0, "twsi0_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI0, 0x7, 0x3, 0x0, 0, &reset_lock}, + {MMP2_CLK_TWSI1, "twsi1_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI1, 0x7, 0x3, 0x0, 0, &reset_lock}, + {MMP2_CLK_TWSI2, "twsi2_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI2, 0x7, 0x3, 0x0, 0, &reset_lock}, + {MMP2_CLK_TWSI3, "twsi3_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI3, 0x7, 0x3, 0x0, 0, &reset_lock}, + {MMP2_CLK_TWSI4, "twsi4_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI4, 0x7, 0x3, 0x0, 0, &reset_lock}, + {MMP2_CLK_TWSI5, "twsi5_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI5, 0x7, 0x3, 0x0, 0, &reset_lock}, + {MMP2_CLK_GPIO, "gpio_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_GPIO, 0x7, 0x3, 0x0, 0, &reset_lock}, + {MMP2_CLK_KPC, "kpc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_KPC, 0x7, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, &reset_lock}, + {MMP2_CLK_RTC, "rtc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_RTC, 0x87, 0x83, 0x0, MMP_CLK_GATE_NEED_DELAY, &reset_lock}, + {MMP2_CLK_PWM0, "pwm0_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM0, 0x7, 0x3, 0x0, 0, &reset_lock}, + {MMP2_CLK_PWM1, "pwm1_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM1, 0x7, 0x3, 0x0, 0, &reset_lock}, + {MMP2_CLK_PWM2, "pwm2_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM2, 0x7, 0x3, 0x0, 0, &reset_lock}, + {MMP2_CLK_PWM3, "pwm3_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM3, 0x7, 0x3, 0x0, 0, &reset_lock}, + /* The gate clocks has mux parent. */ + {MMP2_CLK_UART0, "uart0_clk", "uart0_mux", CLK_SET_RATE_PARENT, APBC_UART0, 0x7, 0x3, 0x0, 0, &uart0_lock}, + {MMP2_CLK_UART1, "uart1_clk", "uart1_mux", CLK_SET_RATE_PARENT, APBC_UART1, 0x7, 0x3, 0x0, 0, &uart1_lock}, + {MMP2_CLK_UART2, "uart2_clk", "uart2_mux", CLK_SET_RATE_PARENT, APBC_UART2, 0x7, 0x3, 0x0, 0, &uart2_lock}, + {MMP2_CLK_UART3, "uart3_clk", "uart3_mux", CLK_SET_RATE_PARENT, APBC_UART3, 0x7, 0x3, 0x0, 0, &uart2_lock}, + {MMP2_CLK_SSP0, "ssp0_clk", "ssp0_mux", CLK_SET_RATE_PARENT, APBC_SSP0, 0x7, 0x3, 0x0, 0, &ssp0_lock}, + {MMP2_CLK_SSP1, "ssp1_clk", "ssp1_mux", CLK_SET_RATE_PARENT, APBC_SSP1, 0x7, 0x3, 0x0, 0, &ssp1_lock}, + {MMP2_CLK_SSP2, "ssp2_clk", "ssp2_mux", CLK_SET_RATE_PARENT, APBC_SSP2, 0x7, 0x3, 0x0, 0, &ssp2_lock}, + {MMP2_CLK_SSP3, "ssp3_clk", "ssp3_mux", CLK_SET_RATE_PARENT, APBC_SSP3, 0x7, 0x3, 0x0, 0, &ssp3_lock}, +}; + +static void mmp2_apb_periph_clk_init(struct mmp2_clk_unit *pxa_unit) +{ + struct mmp_clk_unit *unit = &pxa_unit->unit; + + mmp_register_mux_clks(unit, apbc_mux_clks, pxa_unit->apbc_base, + ARRAY_SIZE(apbc_mux_clks)); + + mmp_register_gate_clks(unit, apbc_gate_clks, pxa_unit->apbc_base, + ARRAY_SIZE(apbc_gate_clks)); +} + +static DEFINE_SPINLOCK(sdh_lock); +static const char *sdh_parent_names[] = {"pll1_4", "pll2", "usb_pll", "pll1"}; +static struct mmp_clk_mix_config sdh_mix_config = { + .reg_info = DEFINE_MIX_REG_INFO(4, 10, 2, 8, 32), +}; + +static DEFINE_SPINLOCK(usb_lock); + +static DEFINE_SPINLOCK(disp0_lock); +static DEFINE_SPINLOCK(disp1_lock); +static const char *disp_parent_names[] = {"pll1", "pll1_16", "pll2", "vctcxo"}; + +static DEFINE_SPINLOCK(ccic0_lock); +static DEFINE_SPINLOCK(ccic1_lock); +static const char *ccic_parent_names[] = {"pll1_2", "pll1_16", "vctcxo"}; +static struct mmp_clk_mix_config ccic0_mix_config = { + .reg_info = DEFINE_MIX_REG_INFO(4, 17, 2, 6, 32), +}; +static struct mmp_clk_mix_config ccic1_mix_config = { + .reg_info = DEFINE_MIX_REG_INFO(4, 16, 2, 6, 32), +}; + +static struct mmp_param_mux_clk apmu_mux_clks[] = { + {MMP2_CLK_DISP0_MUX, "disp0_mux", disp_parent_names, ARRAY_SIZE(disp_parent_names), CLK_SET_RATE_PARENT, APMU_DISP0, 6, 2, 0, &disp0_lock}, + {MMP2_CLK_DISP1_MUX, "disp1_mux", disp_parent_names, ARRAY_SIZE(disp_parent_names), CLK_SET_RATE_PARENT, APMU_DISP1, 6, 2, 0, &disp1_lock}, +}; + +static struct mmp_param_div_clk apmu_div_clks[] = { + {0, "disp0_div", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 8, 4, 0, &disp0_lock}, + {0, "disp0_sphy_div", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 15, 5, 0, &disp0_lock}, + {0, "disp1_div", "disp1_mux", CLK_SET_RATE_PARENT, APMU_DISP1, 8, 4, 0, &disp1_lock}, + {0, "ccic0_sphy_div", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 10, 5, 0, &ccic0_lock}, + {0, "ccic1_sphy_div", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 10, 5, 0, &ccic1_lock}, +}; + +static struct mmp_param_gate_clk apmu_gate_clks[] = { + {MMP2_CLK_USB, "usb_clk", "usb_pll", 0, APMU_USB, 0x9, 0x9, 0x0, 0, &usb_lock}, + /* The gate clocks has mux parent. */ + {MMP2_CLK_SDH0, "sdh0_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH0, 0x1b, 0x1b, 0x0, 0, &sdh_lock}, + {MMP2_CLK_SDH1, "sdh1_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH1, 0x1b, 0x1b, 0x0, 0, &sdh_lock}, + {MMP2_CLK_SDH1, "sdh2_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH2, 0x1b, 0x1b, 0x0, 0, &sdh_lock}, + {MMP2_CLK_SDH1, "sdh3_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH3, 0x1b, 0x1b, 0x0, 0, &sdh_lock}, + {MMP2_CLK_DISP0, "disp0_clk", "disp0_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1b, 0x1b, 0x0, 0, &disp0_lock}, + {MMP2_CLK_DISP0_SPHY, "disp0_sphy_clk", "disp0_sphy_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1024, 0x1024, 0x0, 0, &disp0_lock}, + {MMP2_CLK_DISP1, "disp1_clk", "disp1_div", CLK_SET_RATE_PARENT, APMU_DISP1, 0x1b, 0x1b, 0x0, 0, &disp1_lock}, + {MMP2_CLK_CCIC_ARBITER, "ccic_arbiter", "vctcxo", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1800, 0x1800, 0x0, 0, &ccic0_lock}, + {MMP2_CLK_CCIC0, "ccic0_clk", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1b, 0x1b, 0x0, 0, &ccic0_lock}, + {MMP2_CLK_CCIC0_PHY, "ccic0_phy_clk", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x24, 0x24, 0x0, 0, &ccic0_lock}, + {MMP2_CLK_CCIC0_SPHY, "ccic0_sphy_clk", "ccic0_sphy_div", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x300, 0x300, 0x0, 0, &ccic0_lock}, + {MMP2_CLK_CCIC1, "ccic1_clk", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x1b, 0x1b, 0x0, 0, &ccic1_lock}, + {MMP2_CLK_CCIC1_PHY, "ccic1_phy_clk", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x24, 0x24, 0x0, 0, &ccic1_lock}, + {MMP2_CLK_CCIC1_SPHY, "ccic1_sphy_clk", "ccic1_sphy_div", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x300, 0x300, 0x0, 0, &ccic1_lock}, +}; + +static void mmp2_axi_periph_clk_init(struct mmp2_clk_unit *pxa_unit) +{ + struct clk *clk; + struct mmp_clk_unit *unit = &pxa_unit->unit; + + sdh_mix_config.reg_info.reg_clk_ctrl = pxa_unit->apmu_base + APMU_SDH0; + clk = mmp_clk_register_mix(NULL, "sdh_mix_clk", sdh_parent_names, + ARRAY_SIZE(sdh_parent_names), + CLK_SET_RATE_PARENT, + &sdh_mix_config, &sdh_lock); + + ccic0_mix_config.reg_info.reg_clk_ctrl = pxa_unit->apmu_base + APMU_CCIC0; + clk = mmp_clk_register_mix(NULL, "ccic0_mix_clk", ccic_parent_names, + ARRAY_SIZE(ccic_parent_names), + CLK_SET_RATE_PARENT, + &ccic0_mix_config, &ccic0_lock); + mmp_clk_add(unit, MMP2_CLK_CCIC0_MIX, clk); + + ccic1_mix_config.reg_info.reg_clk_ctrl = pxa_unit->apmu_base + APMU_CCIC1; + clk = mmp_clk_register_mix(NULL, "ccic1_mix_clk", ccic_parent_names, + ARRAY_SIZE(ccic_parent_names), + CLK_SET_RATE_PARENT, + &ccic1_mix_config, &ccic1_lock); + mmp_clk_add(unit, MMP2_CLK_CCIC1_MIX, clk); + + mmp_register_mux_clks(unit, apmu_mux_clks, pxa_unit->apmu_base, + ARRAY_SIZE(apmu_mux_clks)); + + mmp_register_div_clks(unit, apmu_div_clks, pxa_unit->apmu_base, + ARRAY_SIZE(apmu_div_clks)); + + mmp_register_gate_clks(unit, apmu_gate_clks, pxa_unit->apmu_base, + ARRAY_SIZE(apmu_gate_clks)); +} + +static void mmp2_clk_reset_init(struct device_node *np, + struct mmp2_clk_unit *pxa_unit) +{ + struct mmp_clk_reset_cell *cells; + int i, nr_resets; + + nr_resets = ARRAY_SIZE(apbc_gate_clks); + cells = kcalloc(nr_resets, sizeof(*cells), GFP_KERNEL); + if (!cells) + return; + + for (i = 0; i < nr_resets; i++) { + cells[i].clk_id = apbc_gate_clks[i].id; + cells[i].reg = pxa_unit->apbc_base + apbc_gate_clks[i].offset; + cells[i].flags = 0; + cells[i].lock = apbc_gate_clks[i].lock; + cells[i].bits = 0x4; + } + + mmp_clk_reset_register(np, cells, nr_resets); +} + +static void __init mmp2_clk_init(struct device_node *np) +{ + struct mmp2_clk_unit *pxa_unit; + + pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL); + if (!pxa_unit) + return; + + pxa_unit->mpmu_base = of_iomap(np, 0); + if (!pxa_unit->mpmu_base) { + pr_err("failed to map mpmu registers\n"); + return; + } + + pxa_unit->apmu_base = of_iomap(np, 1); + if (!pxa_unit->mpmu_base) { + pr_err("failed to map apmu registers\n"); + return; + } + + pxa_unit->apbc_base = of_iomap(np, 2); + if (!pxa_unit->apbc_base) { + pr_err("failed to map apbc registers\n"); + return; + } + + mmp_clk_init(np, &pxa_unit->unit, MMP2_NR_CLKS); + + mmp2_pll_init(pxa_unit); + + mmp2_apb_periph_clk_init(pxa_unit); + + mmp2_axi_periph_clk_init(pxa_unit); + + mmp2_clk_reset_init(np, pxa_unit); +} + +CLK_OF_DECLARE(mmp2_clk, "marvell,mmp2-clock", mmp2_clk_init); diff --git a/drivers/clk/mmp/clk-of-pxa168.c b/drivers/clk/mmp/clk-of-pxa168.c new file mode 100644 index 000000000000..5b1810dc4bd2 --- /dev/null +++ b/drivers/clk/mmp/clk-of-pxa168.c @@ -0,0 +1,279 @@ +/* + * pxa168 clock framework source file + * + * Copyright (C) 2012 Marvell + * Chao Xie <xiechao.mail@gmail.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/spinlock.h> +#include <linux/io.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/of_address.h> + +#include <dt-bindings/clock/marvell,pxa168.h> + +#include "clk.h" +#include "reset.h" + +#define APBC_RTC 0x28 +#define APBC_TWSI0 0x2c +#define APBC_KPC 0x30 +#define APBC_UART0 0x0 +#define APBC_UART1 0x4 +#define APBC_GPIO 0x8 +#define APBC_PWM0 0xc +#define APBC_PWM1 0x10 +#define APBC_PWM2 0x14 +#define APBC_PWM3 0x18 +#define APBC_SSP0 0x81c +#define APBC_SSP1 0x820 +#define APBC_SSP2 0x84c +#define APBC_SSP3 0x858 +#define APBC_SSP4 0x85c +#define APBC_TWSI1 0x6c +#define APBC_UART2 0x70 +#define APMU_SDH0 0x54 +#define APMU_SDH1 0x58 +#define APMU_USB 0x5c +#define APMU_DISP0 0x4c +#define APMU_CCIC0 0x50 +#define APMU_DFC 0x60 +#define MPMU_UART_PLL 0x14 + +struct pxa168_clk_unit { + struct mmp_clk_unit unit; + void __iomem *mpmu_base; + void __iomem *apmu_base; + void __iomem *apbc_base; +}; + +static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = { + {PXA168_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768}, + {PXA168_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000}, + {PXA168_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 624000000}, +}; + +static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = { + {PXA168_CLK_PLL1_2, "pll1_2", "pll1", 1, 2, 0}, + {PXA168_CLK_PLL1_4, "pll1_4", "pll1_2", 1, 2, 0}, + {PXA168_CLK_PLL1_8, "pll1_8", "pll1_4", 1, 2, 0}, + {PXA168_CLK_PLL1_16, "pll1_16", "pll1_8", 1, 2, 0}, + {PXA168_CLK_PLL1_6, "pll1_6", "pll1_2", 1, 3, 0}, + {PXA168_CLK_PLL1_12, "pll1_12", "pll1_6", 1, 2, 0}, + {PXA168_CLK_PLL1_24, "pll1_24", "pll1_12", 1, 2, 0}, + {PXA168_CLK_PLL1_48, "pll1_48", "pll1_24", 1, 2, 0}, + {PXA168_CLK_PLL1_96, "pll1_96", "pll1_48", 1, 2, 0}, + {PXA168_CLK_PLL1_13, "pll1_13", "pll1", 1, 13, 0}, + {PXA168_CLK_PLL1_13_1_5, "pll1_13_1_5", "pll1_13", 2, 3, 0}, + {PXA168_CLK_PLL1_2_1_5, "pll1_2_1_5", "pll1_2", 2, 3, 0}, + {PXA168_CLK_PLL1_3_16, "pll1_3_16", "pll1", 3, 16, 0}, +}; + +static struct mmp_clk_factor_masks uart_factor_masks = { + .factor = 2, + .num_mask = 0x1fff, + .den_mask = 0x1fff, + .num_shift = 16, + .den_shift = 0, +}; + +static struct mmp_clk_factor_tbl uart_factor_tbl[] = { + {.num = 8125, .den = 1536}, /*14.745MHZ */ +}; + +static void pxa168_pll_init(struct pxa168_clk_unit *pxa_unit) +{ + struct clk *clk; + struct mmp_clk_unit *unit = &pxa_unit->unit; + + mmp_register_fixed_rate_clks(unit, fixed_rate_clks, + ARRAY_SIZE(fixed_rate_clks)); + + mmp_register_fixed_factor_clks(unit, fixed_factor_clks, + ARRAY_SIZE(fixed_factor_clks)); + + clk = mmp_clk_register_factor("uart_pll", "pll1_4", + CLK_SET_RATE_PARENT, + pxa_unit->mpmu_base + MPMU_UART_PLL, + &uart_factor_masks, uart_factor_tbl, + ARRAY_SIZE(uart_factor_tbl), NULL); + mmp_clk_add(unit, PXA168_CLK_UART_PLL, clk); +} + +static DEFINE_SPINLOCK(uart0_lock); +static DEFINE_SPINLOCK(uart1_lock); +static DEFINE_SPINLOCK(uart2_lock); +static const char *uart_parent_names[] = {"pll1_3_16", "uart_pll"}; + +static DEFINE_SPINLOCK(ssp0_lock); +static DEFINE_SPINLOCK(ssp1_lock); +static DEFINE_SPINLOCK(ssp2_lock); +static DEFINE_SPINLOCK(ssp3_lock); +static DEFINE_SPINLOCK(ssp4_lock); +static const char *ssp_parent_names[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"}; + +static DEFINE_SPINLOCK(reset_lock); + +static struct mmp_param_mux_clk apbc_mux_clks[] = { + {0, "uart0_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART0, 4, 3, 0, &uart0_lock}, + {0, "uart1_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART1, 4, 3, 0, &uart1_lock}, + {0, "uart2_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART2, 4, 3, 0, &uart2_lock}, + {0, "ssp0_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP0, 4, 3, 0, &ssp0_lock}, + {0, "ssp1_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP1, 4, 3, 0, &ssp1_lock}, + {0, "ssp2_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP2, 4, 3, 0, &ssp2_lock}, + {0, "ssp3_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP3, 4, 3, 0, &ssp3_lock}, + {0, "ssp4_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP4, 4, 3, 0, &ssp4_lock}, +}; + +static struct mmp_param_gate_clk apbc_gate_clks[] = { + {PXA168_CLK_TWSI0, "twsi0_clk", "pll1_13_1_5", CLK_SET_RATE_PARENT, APBC_TWSI0, 0x3, 0x3, 0x0, 0, &reset_lock}, + {PXA168_CLK_TWSI1, "twsi1_clk", "pll1_13_1_5", CLK_SET_RATE_PARENT, APBC_TWSI1, 0x3, 0x3, 0x0, 0, &reset_lock}, + {PXA168_CLK_GPIO, "gpio_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_GPIO, 0x3, 0x3, 0x0, 0, &reset_lock}, + {PXA168_CLK_KPC, "kpc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_KPC, 0x3, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, NULL}, + {PXA168_CLK_RTC, "rtc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_RTC, 0x83, 0x83, 0x0, MMP_CLK_GATE_NEED_DELAY, NULL}, + {PXA168_CLK_PWM0, "pwm0_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM0, 0x3, 0x3, 0x0, 0, &reset_lock}, + {PXA168_CLK_PWM1, "pwm1_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM1, 0x3, 0x3, 0x0, 0, &reset_lock}, + {PXA168_CLK_PWM2, "pwm2_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM2, 0x3, 0x3, 0x0, 0, &reset_lock}, + {PXA168_CLK_PWM3, "pwm3_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM3, 0x3, 0x3, 0x0, 0, &reset_lock}, + /* The gate clocks has mux parent. */ + {PXA168_CLK_UART0, "uart0_clk", "uart0_mux", CLK_SET_RATE_PARENT, APBC_UART0, 0x3, 0x3, 0x0, 0, &uart0_lock}, + {PXA168_CLK_UART1, "uart1_clk", "uart1_mux", CLK_SET_RATE_PARENT, APBC_UART1, 0x3, 0x3, 0x0, 0, &uart1_lock}, + {PXA168_CLK_UART2, "uart2_clk", "uart2_mux", CLK_SET_RATE_PARENT, APBC_UART2, 0x3, 0x3, 0x0, 0, &uart2_lock}, + {PXA168_CLK_SSP0, "ssp0_clk", "ssp0_mux", CLK_SET_RATE_PARENT, APBC_SSP0, 0x3, 0x3, 0x0, 0, &ssp0_lock}, + {PXA168_CLK_SSP1, "ssp1_clk", "ssp1_mux", CLK_SET_RATE_PARENT, APBC_SSP1, 0x3, 0x3, 0x0, 0, &ssp1_lock}, + {PXA168_CLK_SSP2, "ssp2_clk", "ssp2_mux", CLK_SET_RATE_PARENT, APBC_SSP2, 0x3, 0x3, 0x0, 0, &ssp2_lock}, + {PXA168_CLK_SSP3, "ssp3_clk", "ssp3_mux", CLK_SET_RATE_PARENT, APBC_SSP3, 0x3, 0x3, 0x0, 0, &ssp3_lock}, + {PXA168_CLK_SSP4, "ssp4_clk", "ssp4_mux", CLK_SET_RATE_PARENT, APBC_SSP4, 0x3, 0x3, 0x0, 0, &ssp4_lock}, +}; + +static void pxa168_apb_periph_clk_init(struct pxa168_clk_unit *pxa_unit) +{ + struct mmp_clk_unit *unit = &pxa_unit->unit; + + mmp_register_mux_clks(unit, apbc_mux_clks, pxa_unit->apbc_base, + ARRAY_SIZE(apbc_mux_clks)); + + mmp_register_gate_clks(unit, apbc_gate_clks, pxa_unit->apbc_base, + ARRAY_SIZE(apbc_gate_clks)); + +} + +static DEFINE_SPINLOCK(sdh0_lock); +static DEFINE_SPINLOCK(sdh1_lock); +static const char *sdh_parent_names[] = {"pll1_12", "pll1_13"}; + +static DEFINE_SPINLOCK(usb_lock); + +static DEFINE_SPINLOCK(disp0_lock); +static const char *disp_parent_names[] = {"pll1_2", "pll1_12"}; + +static DEFINE_SPINLOCK(ccic0_lock); +static const char *ccic_parent_names[] = {"pll1_2", "pll1_12"}; +static const char *ccic_phy_parent_names[] = {"pll1_6", "pll1_12"}; + +static struct mmp_param_mux_clk apmu_mux_clks[] = { + {0, "sdh0_mux", sdh_parent_names, ARRAY_SIZE(sdh_parent_names), CLK_SET_RATE_PARENT, APMU_SDH0, 6, 1, 0, &sdh0_lock}, + {0, "sdh1_mux", sdh_parent_names, ARRAY_SIZE(sdh_parent_names), CLK_SET_RATE_PARENT, APMU_SDH1, 6, 1, 0, &sdh1_lock}, + {0, "disp0_mux", disp_parent_names, ARRAY_SIZE(disp_parent_names), CLK_SET_RATE_PARENT, APMU_DISP0, 6, 1, 0, &disp0_lock}, + {0, "ccic0_mux", ccic_parent_names, ARRAY_SIZE(ccic_parent_names), CLK_SET_RATE_PARENT, APMU_CCIC0, 6, 1, 0, &ccic0_lock}, + {0, "ccic0_phy_mux", ccic_phy_parent_names, ARRAY_SIZE(ccic_phy_parent_names), CLK_SET_RATE_PARENT, APMU_CCIC0, 7, 1, 0, &ccic0_lock}, +}; + +static struct mmp_param_div_clk apmu_div_clks[] = { + {0, "ccic0_sphy_div", "ccic0_mux", CLK_SET_RATE_PARENT, APMU_CCIC0, 10, 5, 0, &ccic0_lock}, +}; + +static struct mmp_param_gate_clk apmu_gate_clks[] = { + {PXA168_CLK_DFC, "dfc_clk", "pll1_4", CLK_SET_RATE_PARENT, APMU_DFC, 0x19b, 0x19b, 0x0, 0, NULL}, + {PXA168_CLK_USB, "usb_clk", "usb_pll", 0, APMU_USB, 0x9, 0x9, 0x0, 0, &usb_lock}, + {PXA168_CLK_SPH, "sph_clk", "usb_pll", 0, APMU_USB, 0x12, 0x12, 0x0, 0, &usb_lock}, + /* The gate clocks has mux parent. */ + {PXA168_CLK_SDH0, "sdh0_clk", "sdh0_mux", CLK_SET_RATE_PARENT, APMU_SDH0, 0x1b, 0x1b, 0x0, 0, &sdh0_lock}, + {PXA168_CLK_SDH1, "sdh1_clk", "sdh1_mux", CLK_SET_RATE_PARENT, APMU_SDH1, 0x1b, 0x1b, 0x0, 0, &sdh1_lock}, + {PXA168_CLK_DISP0, "disp0_clk", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1b, 0x1b, 0x0, 0, &disp0_lock}, + {PXA168_CLK_CCIC0, "ccic0_clk", "ccic0_mux", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1b, 0x1b, 0x0, 0, &ccic0_lock}, + {PXA168_CLK_CCIC0_PHY, "ccic0_phy_clk", "ccic0_phy_mux", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x24, 0x24, 0x0, 0, &ccic0_lock}, + {PXA168_CLK_CCIC0_SPHY, "ccic0_sphy_clk", "ccic0_sphy_div", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x300, 0x300, 0x0, 0, &ccic0_lock}, +}; + +static void pxa168_axi_periph_clk_init(struct pxa168_clk_unit *pxa_unit) +{ + struct mmp_clk_unit *unit = &pxa_unit->unit; + + mmp_register_mux_clks(unit, apmu_mux_clks, pxa_unit->apmu_base, + ARRAY_SIZE(apmu_mux_clks)); + + mmp_register_div_clks(unit, apmu_div_clks, pxa_unit->apmu_base, + ARRAY_SIZE(apmu_div_clks)); + + mmp_register_gate_clks(unit, apmu_gate_clks, pxa_unit->apmu_base, + ARRAY_SIZE(apmu_gate_clks)); +} + +static void pxa168_clk_reset_init(struct device_node *np, + struct pxa168_clk_unit *pxa_unit) +{ + struct mmp_clk_reset_cell *cells; + int i, nr_resets; + + nr_resets = ARRAY_SIZE(apbc_gate_clks); + cells = kcalloc(nr_resets, sizeof(*cells), GFP_KERNEL); + if (!cells) + return; + + for (i = 0; i < nr_resets; i++) { + cells[i].clk_id = apbc_gate_clks[i].id; + cells[i].reg = pxa_unit->apbc_base + apbc_gate_clks[i].offset; + cells[i].flags = 0; + cells[i].lock = apbc_gate_clks[i].lock; + cells[i].bits = 0x4; + } + + mmp_clk_reset_register(np, cells, nr_resets); +} + +static void __init pxa168_clk_init(struct device_node *np) +{ + struct pxa168_clk_unit *pxa_unit; + + pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL); + if (!pxa_unit) + return; + + pxa_unit->mpmu_base = of_iomap(np, 0); + if (!pxa_unit->mpmu_base) { + pr_err("failed to map mpmu registers\n"); + return; + } + + pxa_unit->apmu_base = of_iomap(np, 1); + if (!pxa_unit->mpmu_base) { + pr_err("failed to map apmu registers\n"); + return; + } + + pxa_unit->apbc_base = of_iomap(np, 2); + if (!pxa_unit->apbc_base) { + pr_err("failed to map apbc registers\n"); + return; + } + + mmp_clk_init(np, &pxa_unit->unit, PXA168_NR_CLKS); + + pxa168_pll_init(pxa_unit); + + pxa168_apb_periph_clk_init(pxa_unit); + + pxa168_axi_periph_clk_init(pxa_unit); + + pxa168_clk_reset_init(np, pxa_unit); +} + +CLK_OF_DECLARE(pxa168_clk, "marvell,pxa168-clock", pxa168_clk_init); diff --git a/drivers/clk/mmp/clk-of-pxa910.c b/drivers/clk/mmp/clk-of-pxa910.c new file mode 100644 index 000000000000..5e3c80dad336 --- /dev/null +++ b/drivers/clk/mmp/clk-of-pxa910.c @@ -0,0 +1,301 @@ +/* + * pxa910 clock framework source file + * + * Copyright (C) 2012 Marvell + * Chao Xie <xiechao.mail@gmail.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/spinlock.h> +#include <linux/io.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/of_address.h> + +#include <dt-bindings/clock/marvell,pxa910.h> + +#include "clk.h" +#include "reset.h" + +#define APBC_RTC 0x28 +#define APBC_TWSI0 0x2c +#define APBC_KPC 0x18 +#define APBC_UART0 0x0 +#define APBC_UART1 0x4 +#define APBC_GPIO 0x8 +#define APBC_PWM0 0xc +#define APBC_PWM1 0x10 +#define APBC_PWM2 0x14 +#define APBC_PWM3 0x18 +#define APBC_SSP0 0x1c +#define APBC_SSP1 0x20 +#define APBC_SSP2 0x4c +#define APBCP_TWSI1 0x28 +#define APBCP_UART2 0x1c +#define APMU_SDH0 0x54 +#define APMU_SDH1 0x58 +#define APMU_USB 0x5c +#define APMU_DISP0 0x4c +#define APMU_CCIC0 0x50 +#define APMU_DFC 0x60 +#define MPMU_UART_PLL 0x14 + +struct pxa910_clk_unit { + struct mmp_clk_unit unit; + void __iomem *mpmu_base; + void __iomem *apmu_base; + void __iomem *apbc_base; + void __iomem *apbcp_base; +}; + +static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = { + {PXA910_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768}, + {PXA910_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000}, + {PXA910_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 624000000}, +}; + +static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = { + {PXA910_CLK_PLL1_2, "pll1_2", "pll1", 1, 2, 0}, + {PXA910_CLK_PLL1_4, "pll1_4", "pll1_2", 1, 2, 0}, + {PXA910_CLK_PLL1_8, "pll1_8", "pll1_4", 1, 2, 0}, + {PXA910_CLK_PLL1_16, "pll1_16", "pll1_8", 1, 2, 0}, + {PXA910_CLK_PLL1_6, "pll1_6", "pll1_2", 1, 3, 0}, + {PXA910_CLK_PLL1_12, "pll1_12", "pll1_6", 1, 2, 0}, + {PXA910_CLK_PLL1_24, "pll1_24", "pll1_12", 1, 2, 0}, + {PXA910_CLK_PLL1_48, "pll1_48", "pll1_24", 1, 2, 0}, + {PXA910_CLK_PLL1_96, "pll1_96", "pll1_48", 1, 2, 0}, + {PXA910_CLK_PLL1_13, "pll1_13", "pll1", 1, 13, 0}, + {PXA910_CLK_PLL1_13_1_5, "pll1_13_1_5", "pll1_13", 2, 3, 0}, + {PXA910_CLK_PLL1_2_1_5, "pll1_2_1_5", "pll1_2", 2, 3, 0}, + {PXA910_CLK_PLL1_3_16, "pll1_3_16", "pll1", 3, 16, 0}, +}; + +static struct mmp_clk_factor_masks uart_factor_masks = { + .factor = 2, + .num_mask = 0x1fff, + .den_mask = 0x1fff, + .num_shift = 16, + .den_shift = 0, +}; + +static struct mmp_clk_factor_tbl uart_factor_tbl[] = { + {.num = 8125, .den = 1536}, /*14.745MHZ */ +}; + +static void pxa910_pll_init(struct pxa910_clk_unit *pxa_unit) +{ + struct clk *clk; + struct mmp_clk_unit *unit = &pxa_unit->unit; + + mmp_register_fixed_rate_clks(unit, fixed_rate_clks, + ARRAY_SIZE(fixed_rate_clks)); + + mmp_register_fixed_factor_clks(unit, fixed_factor_clks, + ARRAY_SIZE(fixed_factor_clks)); + + clk = mmp_clk_register_factor("uart_pll", "pll1_4", + CLK_SET_RATE_PARENT, + pxa_unit->mpmu_base + MPMU_UART_PLL, + &uart_factor_masks, uart_factor_tbl, + ARRAY_SIZE(uart_factor_tbl), NULL); + mmp_clk_add(unit, PXA910_CLK_UART_PLL, clk); +} + +static DEFINE_SPINLOCK(uart0_lock); +static DEFINE_SPINLOCK(uart1_lock); +static DEFINE_SPINLOCK(uart2_lock); +static const char *uart_parent_names[] = {"pll1_3_16", "uart_pll"}; + +static DEFINE_SPINLOCK(ssp0_lock); +static DEFINE_SPINLOCK(ssp1_lock); +static const char *ssp_parent_names[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"}; + +static DEFINE_SPINLOCK(reset_lock); + +static struct mmp_param_mux_clk apbc_mux_clks[] = { + {0, "uart0_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART0, 4, 3, 0, &uart0_lock}, + {0, "uart1_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART1, 4, 3, 0, &uart1_lock}, + {0, "ssp0_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP0, 4, 3, 0, &ssp0_lock}, + {0, "ssp1_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP1, 4, 3, 0, &ssp1_lock}, +}; + +static struct mmp_param_mux_clk apbcp_mux_clks[] = { + {0, "uart2_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBCP_UART2, 4, 3, 0, &uart2_lock}, +}; + +static struct mmp_param_gate_clk apbc_gate_clks[] = { + {PXA910_CLK_TWSI0, "twsi0_clk", "pll1_13_1_5", CLK_SET_RATE_PARENT, APBC_TWSI0, 0x3, 0x3, 0x0, 0, &reset_lock}, + {PXA910_CLK_GPIO, "gpio_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_GPIO, 0x3, 0x3, 0x0, 0, &reset_lock}, + {PXA910_CLK_KPC, "kpc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_KPC, 0x3, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, NULL}, + {PXA910_CLK_RTC, "rtc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_RTC, 0x83, 0x83, 0x0, MMP_CLK_GATE_NEED_DELAY, NULL}, + {PXA910_CLK_PWM0, "pwm0_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM0, 0x3, 0x3, 0x0, 0, &reset_lock}, + {PXA910_CLK_PWM1, "pwm1_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM1, 0x3, 0x3, 0x0, 0, &reset_lock}, + {PXA910_CLK_PWM2, "pwm2_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM2, 0x3, 0x3, 0x0, 0, &reset_lock}, + {PXA910_CLK_PWM3, "pwm3_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM3, 0x3, 0x3, 0x0, 0, &reset_lock}, + /* The gate clocks has mux parent. */ + {PXA910_CLK_UART0, "uart0_clk", "uart0_mux", CLK_SET_RATE_PARENT, APBC_UART0, 0x3, 0x3, 0x0, 0, &uart0_lock}, + {PXA910_CLK_UART1, "uart1_clk", "uart1_mux", CLK_SET_RATE_PARENT, APBC_UART1, 0x3, 0x3, 0x0, 0, &uart1_lock}, + {PXA910_CLK_SSP0, "ssp0_clk", "ssp0_mux", CLK_SET_RATE_PARENT, APBC_SSP0, 0x3, 0x3, 0x0, 0, &ssp0_lock}, + {PXA910_CLK_SSP1, "ssp1_clk", "ssp1_mux", CLK_SET_RATE_PARENT, APBC_SSP1, 0x3, 0x3, 0x0, 0, &ssp1_lock}, +}; + +static struct mmp_param_gate_clk apbcp_gate_clks[] = { + {PXA910_CLK_TWSI1, "twsi1_clk", "pll1_13_1_5", CLK_SET_RATE_PARENT, APBCP_TWSI1, 0x3, 0x3, 0x0, 0, &reset_lock}, + /* The gate clocks has mux parent. */ + {PXA910_CLK_UART2, "uart2_clk", "uart2_mux", CLK_SET_RATE_PARENT, APBCP_UART2, 0x3, 0x3, 0x0, 0, &uart2_lock}, +}; + +static void pxa910_apb_periph_clk_init(struct pxa910_clk_unit *pxa_unit) +{ + struct mmp_clk_unit *unit = &pxa_unit->unit; + + mmp_register_mux_clks(unit, apbc_mux_clks, pxa_unit->apbc_base, + ARRAY_SIZE(apbc_mux_clks)); + + mmp_register_mux_clks(unit, apbcp_mux_clks, pxa_unit->apbcp_base, + ARRAY_SIZE(apbcp_mux_clks)); + + mmp_register_gate_clks(unit, apbc_gate_clks, pxa_unit->apbc_base, + ARRAY_SIZE(apbc_gate_clks)); + + mmp_register_gate_clks(unit, apbcp_gate_clks, pxa_unit->apbcp_base, + ARRAY_SIZE(apbcp_gate_clks)); +} + +static DEFINE_SPINLOCK(sdh0_lock); +static DEFINE_SPINLOCK(sdh1_lock); +static const char *sdh_parent_names[] = {"pll1_12", "pll1_13"}; + +static DEFINE_SPINLOCK(usb_lock); + +static DEFINE_SPINLOCK(disp0_lock); +static const char *disp_parent_names[] = {"pll1_2", "pll1_12"}; + +static DEFINE_SPINLOCK(ccic0_lock); +static const char *ccic_parent_names[] = {"pll1_2", "pll1_12"}; +static const char *ccic_phy_parent_names[] = {"pll1_6", "pll1_12"}; + +static struct mmp_param_mux_clk apmu_mux_clks[] = { + {0, "sdh0_mux", sdh_parent_names, ARRAY_SIZE(sdh_parent_names), CLK_SET_RATE_PARENT, APMU_SDH0, 6, 1, 0, &sdh0_lock}, + {0, "sdh1_mux", sdh_parent_names, ARRAY_SIZE(sdh_parent_names), CLK_SET_RATE_PARENT, APMU_SDH1, 6, 1, 0, &sdh1_lock}, + {0, "disp0_mux", disp_parent_names, ARRAY_SIZE(disp_parent_names), CLK_SET_RATE_PARENT, APMU_DISP0, 6, 1, 0, &disp0_lock}, + {0, "ccic0_mux", ccic_parent_names, ARRAY_SIZE(ccic_parent_names), CLK_SET_RATE_PARENT, APMU_CCIC0, 6, 1, 0, &ccic0_lock}, + {0, "ccic0_phy_mux", ccic_phy_parent_names, ARRAY_SIZE(ccic_phy_parent_names), CLK_SET_RATE_PARENT, APMU_CCIC0, 7, 1, 0, &ccic0_lock}, +}; + +static struct mmp_param_div_clk apmu_div_clks[] = { + {0, "ccic0_sphy_div", "ccic0_mux", CLK_SET_RATE_PARENT, APMU_CCIC0, 10, 5, 0, &ccic0_lock}, +}; + +static struct mmp_param_gate_clk apmu_gate_clks[] = { + {PXA910_CLK_DFC, "dfc_clk", "pll1_4", CLK_SET_RATE_PARENT, APMU_DFC, 0x19b, 0x19b, 0x0, 0, NULL}, + {PXA910_CLK_USB, "usb_clk", "usb_pll", 0, APMU_USB, 0x9, 0x9, 0x0, 0, &usb_lock}, + {PXA910_CLK_SPH, "sph_clk", "usb_pll", 0, APMU_USB, 0x12, 0x12, 0x0, 0, &usb_lock}, + /* The gate clocks has mux parent. */ + {PXA910_CLK_SDH0, "sdh0_clk", "sdh0_mux", CLK_SET_RATE_PARENT, APMU_SDH0, 0x1b, 0x1b, 0x0, 0, &sdh0_lock}, + {PXA910_CLK_SDH1, "sdh1_clk", "sdh1_mux", CLK_SET_RATE_PARENT, APMU_SDH1, 0x1b, 0x1b, 0x0, 0, &sdh1_lock}, + {PXA910_CLK_DISP0, "disp0_clk", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1b, 0x1b, 0x0, 0, &disp0_lock}, + {PXA910_CLK_CCIC0, "ccic0_clk", "ccic0_mux", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1b, 0x1b, 0x0, 0, &ccic0_lock}, + {PXA910_CLK_CCIC0_PHY, "ccic0_phy_clk", "ccic0_phy_mux", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x24, 0x24, 0x0, 0, &ccic0_lock}, + {PXA910_CLK_CCIC0_SPHY, "ccic0_sphy_clk", "ccic0_sphy_div", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x300, 0x300, 0x0, 0, &ccic0_lock}, +}; + +static void pxa910_axi_periph_clk_init(struct pxa910_clk_unit *pxa_unit) +{ + struct mmp_clk_unit *unit = &pxa_unit->unit; + + mmp_register_mux_clks(unit, apmu_mux_clks, pxa_unit->apmu_base, + ARRAY_SIZE(apmu_mux_clks)); + + mmp_register_div_clks(unit, apmu_div_clks, pxa_unit->apmu_base, + ARRAY_SIZE(apmu_div_clks)); + + mmp_register_gate_clks(unit, apmu_gate_clks, pxa_unit->apmu_base, + ARRAY_SIZE(apmu_gate_clks)); +} + +static void pxa910_clk_reset_init(struct device_node *np, + struct pxa910_clk_unit *pxa_unit) +{ + struct mmp_clk_reset_cell *cells; + int i, base, nr_resets_apbc, nr_resets_apbcp, nr_resets; + + nr_resets_apbc = ARRAY_SIZE(apbc_gate_clks); + nr_resets_apbcp = ARRAY_SIZE(apbcp_gate_clks); + nr_resets = nr_resets_apbc + nr_resets_apbcp; + cells = kcalloc(nr_resets, sizeof(*cells), GFP_KERNEL); + if (!cells) + return; + + base = 0; + for (i = 0; i < nr_resets_apbc; i++) { + cells[base + i].clk_id = apbc_gate_clks[i].id; + cells[base + i].reg = + pxa_unit->apbc_base + apbc_gate_clks[i].offset; + cells[base + i].flags = 0; + cells[base + i].lock = apbc_gate_clks[i].lock; + cells[base + i].bits = 0x4; + } + + base = nr_resets_apbc; + for (i = 0; i < nr_resets_apbcp; i++) { + cells[base + i].clk_id = apbcp_gate_clks[i].id; + cells[base + i].reg = + pxa_unit->apbc_base + apbc_gate_clks[i].offset; + cells[base + i].flags = 0; + cells[base + i].lock = apbc_gate_clks[i].lock; + cells[base + i].bits = 0x4; + } + + mmp_clk_reset_register(np, cells, nr_resets); +} + +static void __init pxa910_clk_init(struct device_node *np) +{ + struct pxa910_clk_unit *pxa_unit; + + pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL); + if (!pxa_unit) + return; + + pxa_unit->mpmu_base = of_iomap(np, 0); + if (!pxa_unit->mpmu_base) { + pr_err("failed to map mpmu registers\n"); + return; + } + + pxa_unit->apmu_base = of_iomap(np, 1); + if (!pxa_unit->mpmu_base) { + pr_err("failed to map apmu registers\n"); + return; + } + + pxa_unit->apbc_base = of_iomap(np, 2); + if (!pxa_unit->apbc_base) { + pr_err("failed to map apbc registers\n"); + return; + } + + pxa_unit->apbcp_base = of_iomap(np, 3); + if (!pxa_unit->mpmu_base) { + pr_err("failed to map apbcp registers\n"); + return; + } + + mmp_clk_init(np, &pxa_unit->unit, PXA910_NR_CLKS); + + pxa910_pll_init(pxa_unit); + + pxa910_apb_periph_clk_init(pxa_unit); + + pxa910_axi_periph_clk_init(pxa_unit); + + pxa910_clk_reset_init(np, pxa_unit); +} + +CLK_OF_DECLARE(pxa910_clk, "marvell,pxa910-clock", pxa910_clk_init); diff --git a/drivers/clk/mmp/clk-pxa168.c b/drivers/clk/mmp/clk-pxa168.c index 014396b028a2..93e967c0f972 100644 --- a/drivers/clk/mmp/clk-pxa168.c +++ b/drivers/clk/mmp/clk-pxa168.c @@ -47,7 +47,7 @@ static DEFINE_SPINLOCK(clk_lock); -static struct clk_factor_masks uart_factor_masks = { +static struct mmp_clk_factor_masks uart_factor_masks = { .factor = 2, .num_mask = 0x1fff, .den_mask = 0x1fff, @@ -55,7 +55,7 @@ static struct clk_factor_masks uart_factor_masks = { .den_shift = 0, }; -static struct clk_factor_tbl uart_factor_tbl[] = { +static struct mmp_clk_factor_tbl uart_factor_tbl[] = { {.num = 8125, .den = 1536}, /*14.745MHZ */ }; @@ -158,7 +158,7 @@ void __init pxa168_clk_init(void) uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0, mpmu_base + MPMU_UART_PLL, &uart_factor_masks, uart_factor_tbl, - ARRAY_SIZE(uart_factor_tbl)); + ARRAY_SIZE(uart_factor_tbl), &clk_lock); clk_set_rate(uart_pll, 14745600); clk_register_clkdev(uart_pll, "uart_pll", NULL); diff --git a/drivers/clk/mmp/clk-pxa910.c b/drivers/clk/mmp/clk-pxa910.c index 9efc6a47535d..993abcdb32cc 100644 --- a/drivers/clk/mmp/clk-pxa910.c +++ b/drivers/clk/mmp/clk-pxa910.c @@ -45,7 +45,7 @@ static DEFINE_SPINLOCK(clk_lock); -static struct clk_factor_masks uart_factor_masks = { +static struct mmp_clk_factor_masks uart_factor_masks = { .factor = 2, .num_mask = 0x1fff, .den_mask = 0x1fff, @@ -53,7 +53,7 @@ static struct clk_factor_masks uart_factor_masks = { .den_shift = 0, }; -static struct clk_factor_tbl uart_factor_tbl[] = { +static struct mmp_clk_factor_tbl uart_factor_tbl[] = { {.num = 8125, .den = 1536}, /*14.745MHZ */ }; @@ -163,7 +163,7 @@ void __init pxa910_clk_init(void) uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0, mpmu_base + MPMU_UART_PLL, &uart_factor_masks, uart_factor_tbl, - ARRAY_SIZE(uart_factor_tbl)); + ARRAY_SIZE(uart_factor_tbl), &clk_lock); clk_set_rate(uart_pll, 14745600); clk_register_clkdev(uart_pll, "uart_pll", NULL); diff --git a/drivers/clk/mmp/clk.c b/drivers/clk/mmp/clk.c new file mode 100644 index 000000000000..cf038ef54c59 --- /dev/null +++ b/drivers/clk/mmp/clk.c @@ -0,0 +1,192 @@ +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/clkdev.h> +#include <linux/of.h> +#include <linux/of_address.h> + +#include "clk.h" + +void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit, + int nr_clks) +{ + static struct clk **clk_table; + + clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL); + if (!clk_table) + return; + + unit->clk_table = clk_table; + unit->nr_clks = nr_clks; + unit->clk_data.clks = clk_table; + unit->clk_data.clk_num = nr_clks; + of_clk_add_provider(np, of_clk_src_onecell_get, &unit->clk_data); +} + +void mmp_register_fixed_rate_clks(struct mmp_clk_unit *unit, + struct mmp_param_fixed_rate_clk *clks, + int size) +{ + int i; + struct clk *clk; + + for (i = 0; i < size; i++) { + clk = clk_register_fixed_rate(NULL, clks[i].name, + clks[i].parent_name, + clks[i].flags, + clks[i].fixed_rate); + if (IS_ERR(clk)) { + pr_err("%s: failed to register clock %s\n", + __func__, clks[i].name); + continue; + } + if (clks[i].id) + unit->clk_table[clks[i].id] = clk; + } +} + +void mmp_register_fixed_factor_clks(struct mmp_clk_unit *unit, + struct mmp_param_fixed_factor_clk *clks, + int size) +{ + struct clk *clk; + int i; + + for (i = 0; i < size; i++) { + clk = clk_register_fixed_factor(NULL, clks[i].name, + clks[i].parent_name, + clks[i].flags, clks[i].mult, + clks[i].div); + if (IS_ERR(clk)) { + pr_err("%s: failed to register clock %s\n", + __func__, clks[i].name); + continue; + } + if (clks[i].id) + unit->clk_table[clks[i].id] = clk; + } +} + +void mmp_register_general_gate_clks(struct mmp_clk_unit *unit, + struct mmp_param_general_gate_clk *clks, + void __iomem *base, int size) +{ + struct clk *clk; + int i; + + for (i = 0; i < size; i++) { + clk = clk_register_gate(NULL, clks[i].name, + clks[i].parent_name, + clks[i].flags, + base + clks[i].offset, + clks[i].bit_idx, + clks[i].gate_flags, + clks[i].lock); + + if (IS_ERR(clk)) { + pr_err("%s: failed to register clock %s\n", + __func__, clks[i].name); + continue; + } + if (clks[i].id) + unit->clk_table[clks[i].id] = clk; + } +} + +void mmp_register_gate_clks(struct mmp_clk_unit *unit, + struct mmp_param_gate_clk *clks, + void __iomem *base, int size) +{ + struct clk *clk; + int i; + + for (i = 0; i < size; i++) { + clk = mmp_clk_register_gate(NULL, clks[i].name, + clks[i].parent_name, + clks[i].flags, + base + clks[i].offset, + clks[i].mask, + clks[i].val_enable, + clks[i].val_disable, + clks[i].gate_flags, + clks[i].lock); + + if (IS_ERR(clk)) { + pr_err("%s: failed to register clock %s\n", + __func__, clks[i].name); + continue; + } + if (clks[i].id) + unit->clk_table[clks[i].id] = clk; + } +} + +void mmp_register_mux_clks(struct mmp_clk_unit *unit, + struct mmp_param_mux_clk *clks, + void __iomem *base, int size) +{ + struct clk *clk; + int i; + + for (i = 0; i < size; i++) { + clk = clk_register_mux(NULL, clks[i].name, + clks[i].parent_name, + clks[i].num_parents, + clks[i].flags, + base + clks[i].offset, + clks[i].shift, + clks[i].width, + clks[i].mux_flags, + clks[i].lock); + + if (IS_ERR(clk)) { + pr_err("%s: failed to register clock %s\n", + __func__, clks[i].name); + continue; + } + if (clks[i].id) + unit->clk_table[clks[i].id] = clk; + } +} + +void mmp_register_div_clks(struct mmp_clk_unit *unit, + struct mmp_param_div_clk *clks, + void __iomem *base, int size) +{ + struct clk *clk; + int i; + + for (i = 0; i < size; i++) { + clk = clk_register_divider(NULL, clks[i].name, + clks[i].parent_name, + clks[i].flags, + base + clks[i].offset, + clks[i].shift, + clks[i].width, + clks[i].div_flags, + clks[i].lock); + + if (IS_ERR(clk)) { + pr_err("%s: failed to register clock %s\n", + __func__, clks[i].name); + continue; + } + if (clks[i].id) + unit->clk_table[clks[i].id] = clk; + } +} + +void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id, + struct clk *clk) +{ + if (IS_ERR_OR_NULL(clk)) { + pr_err("CLK %d has invalid pointer %p\n", id, clk); + return; + } + if (id > unit->nr_clks) { + pr_err("CLK %d is invalid\n", id); + return; + } + + unit->clk_table[id] = clk; +} diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h index ab86dd4a416a..adf9b711b037 100644 --- a/drivers/clk/mmp/clk.h +++ b/drivers/clk/mmp/clk.h @@ -7,19 +7,123 @@ #define APBC_NO_BUS_CTRL BIT(0) #define APBC_POWER_CTRL BIT(1) -struct clk_factor_masks { - unsigned int factor; - unsigned int num_mask; - unsigned int den_mask; - unsigned int num_shift; - unsigned int den_shift; + +/* Clock type "factor" */ +struct mmp_clk_factor_masks { + unsigned int factor; + unsigned int num_mask; + unsigned int den_mask; + unsigned int num_shift; + unsigned int den_shift; }; -struct clk_factor_tbl { +struct mmp_clk_factor_tbl { unsigned int num; unsigned int den; }; +struct mmp_clk_factor { + struct clk_hw hw; + void __iomem *base; + struct mmp_clk_factor_masks *masks; + struct mmp_clk_factor_tbl *ftbl; + unsigned int ftbl_cnt; + spinlock_t *lock; +}; + +extern struct clk *mmp_clk_register_factor(const char *name, + const char *parent_name, unsigned long flags, + void __iomem *base, struct mmp_clk_factor_masks *masks, + struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt, + spinlock_t *lock); + +/* Clock type "mix" */ +#define MMP_CLK_BITS_MASK(width, shift) \ + (((1 << (width)) - 1) << (shift)) +#define MMP_CLK_BITS_GET_VAL(data, width, shift) \ + ((data & MMP_CLK_BITS_MASK(width, shift)) >> (shift)) +#define MMP_CLK_BITS_SET_VAL(val, width, shift) \ + (((val) << (shift)) & MMP_CLK_BITS_MASK(width, shift)) + +enum { + MMP_CLK_MIX_TYPE_V1, + MMP_CLK_MIX_TYPE_V2, + MMP_CLK_MIX_TYPE_V3, +}; + +/* The register layout */ +struct mmp_clk_mix_reg_info { + void __iomem *reg_clk_ctrl; + void __iomem *reg_clk_sel; + u8 width_div; + u8 shift_div; + u8 width_mux; + u8 shift_mux; + u8 bit_fc; +}; + +/* The suggested clock table from user. */ +struct mmp_clk_mix_clk_table { + unsigned long rate; + u8 parent_index; + unsigned int divisor; + unsigned int valid; +}; + +struct mmp_clk_mix_config { + struct mmp_clk_mix_reg_info reg_info; + struct mmp_clk_mix_clk_table *table; + unsigned int table_size; + u32 *mux_table; + struct clk_div_table *div_table; + u8 div_flags; + u8 mux_flags; +}; + +struct mmp_clk_mix { + struct clk_hw hw; + struct mmp_clk_mix_reg_info reg_info; + struct mmp_clk_mix_clk_table *table; + u32 *mux_table; + struct clk_div_table *div_table; + unsigned int table_size; + u8 div_flags; + u8 mux_flags; + unsigned int type; + spinlock_t *lock; +}; + +extern const struct clk_ops mmp_clk_mix_ops; +extern struct clk *mmp_clk_register_mix(struct device *dev, + const char *name, + const char **parent_names, + u8 num_parents, + unsigned long flags, + struct mmp_clk_mix_config *config, + spinlock_t *lock); + + +/* Clock type "gate". MMP private gate */ +#define MMP_CLK_GATE_NEED_DELAY BIT(0) + +struct mmp_clk_gate { + struct clk_hw hw; + void __iomem *reg; + u32 mask; + u32 val_enable; + u32 val_disable; + unsigned int flags; + spinlock_t *lock; +}; + +extern const struct clk_ops mmp_clk_gate_ops; +extern struct clk *mmp_clk_register_gate(struct device *dev, const char *name, + const char *parent_name, unsigned long flags, + void __iomem *reg, u32 mask, u32 val_enable, + u32 val_disable, unsigned int gate_flags, + spinlock_t *lock); + + extern struct clk *mmp_clk_register_pll2(const char *name, const char *parent_name, unsigned long flags); extern struct clk *mmp_clk_register_apbc(const char *name, @@ -28,8 +132,108 @@ extern struct clk *mmp_clk_register_apbc(const char *name, extern struct clk *mmp_clk_register_apmu(const char *name, const char *parent_name, void __iomem *base, u32 enable_mask, spinlock_t *lock); -extern struct clk *mmp_clk_register_factor(const char *name, - const char *parent_name, unsigned long flags, - void __iomem *base, struct clk_factor_masks *masks, - struct clk_factor_tbl *ftbl, unsigned int ftbl_cnt); + +struct mmp_clk_unit { + unsigned int nr_clks; + struct clk **clk_table; + struct clk_onecell_data clk_data; +}; + +struct mmp_param_fixed_rate_clk { + unsigned int id; + char *name; + const char *parent_name; + unsigned long flags; + unsigned long fixed_rate; +}; +void mmp_register_fixed_rate_clks(struct mmp_clk_unit *unit, + struct mmp_param_fixed_rate_clk *clks, + int size); + +struct mmp_param_fixed_factor_clk { + unsigned int id; + char *name; + const char *parent_name; + unsigned long mult; + unsigned long div; + unsigned long flags; +}; +void mmp_register_fixed_factor_clks(struct mmp_clk_unit *unit, + struct mmp_param_fixed_factor_clk *clks, + int size); + +struct mmp_param_general_gate_clk { + unsigned int id; + const char *name; + const char *parent_name; + unsigned long flags; + unsigned long offset; + u8 bit_idx; + u8 gate_flags; + spinlock_t *lock; +}; +void mmp_register_general_gate_clks(struct mmp_clk_unit *unit, + struct mmp_param_general_gate_clk *clks, + void __iomem *base, int size); + +struct mmp_param_gate_clk { + unsigned int id; + char *name; + const char *parent_name; + unsigned long flags; + unsigned long offset; + u32 mask; + u32 val_enable; + u32 val_disable; + unsigned int gate_flags; + spinlock_t *lock; +}; +void mmp_register_gate_clks(struct mmp_clk_unit *unit, + struct mmp_param_gate_clk *clks, + void __iomem *base, int size); + +struct mmp_param_mux_clk { + unsigned int id; + char *name; + const char **parent_name; + u8 num_parents; + unsigned long flags; + unsigned long offset; + u8 shift; + u8 width; + u8 mux_flags; + spinlock_t *lock; +}; +void mmp_register_mux_clks(struct mmp_clk_unit *unit, + struct mmp_param_mux_clk *clks, + void __iomem *base, int size); + +struct mmp_param_div_clk { + unsigned int id; + char *name; + const char *parent_name; + unsigned long flags; + unsigned long offset; + u8 shift; + u8 width; + u8 div_flags; + spinlock_t *lock; +}; +void mmp_register_div_clks(struct mmp_clk_unit *unit, + struct mmp_param_div_clk *clks, + void __iomem *base, int size); + +#define DEFINE_MIX_REG_INFO(w_d, s_d, w_m, s_m, fc) \ +{ \ + .width_div = (w_d), \ + .shift_div = (s_d), \ + .width_mux = (w_m), \ + .shift_mux = (s_m), \ + .bit_fc = (fc), \ +} + +void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit, + int nr_clks); +void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id, + struct clk *clk); #endif diff --git a/drivers/clk/mmp/reset.c b/drivers/clk/mmp/reset.c new file mode 100644 index 000000000000..b54da1fe73f0 --- /dev/null +++ b/drivers/clk/mmp/reset.c @@ -0,0 +1,99 @@ +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/reset-controller.h> + +#include "reset.h" + +#define rcdev_to_unit(rcdev) container_of(rcdev, struct mmp_clk_reset_unit, rcdev) + +static int mmp_of_reset_xlate(struct reset_controller_dev *rcdev, + const struct of_phandle_args *reset_spec) +{ + struct mmp_clk_reset_unit *unit = rcdev_to_unit(rcdev); + struct mmp_clk_reset_cell *cell; + int i; + + if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells)) + return -EINVAL; + + for (i = 0; i < rcdev->nr_resets; i++) { + cell = &unit->cells[i]; + if (cell->clk_id == reset_spec->args[0]) + break; + } + + if (i == rcdev->nr_resets) + return -EINVAL; + + return i; +} + +static int mmp_clk_reset_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct mmp_clk_reset_unit *unit = rcdev_to_unit(rcdev); + struct mmp_clk_reset_cell *cell; + unsigned long flags = 0; + u32 val; + + cell = &unit->cells[id]; + if (cell->lock) + spin_lock_irqsave(cell->lock, flags); + + val = readl(cell->reg); + val |= cell->bits; + writel(val, cell->reg); + + if (cell->lock) + spin_unlock_irqrestore(cell->lock, flags); + + return 0; +} + +static int mmp_clk_reset_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct mmp_clk_reset_unit *unit = rcdev_to_unit(rcdev); + struct mmp_clk_reset_cell *cell; + unsigned long flags = 0; + u32 val; + + cell = &unit->cells[id]; + if (cell->lock) + spin_lock_irqsave(cell->lock, flags); + + val = readl(cell->reg); + val &= ~cell->bits; + writel(val, cell->reg); + + if (cell->lock) + spin_unlock_irqrestore(cell->lock, flags); + + return 0; +} + +static struct reset_control_ops mmp_clk_reset_ops = { + .assert = mmp_clk_reset_assert, + .deassert = mmp_clk_reset_deassert, +}; + +void mmp_clk_reset_register(struct device_node *np, + struct mmp_clk_reset_cell *cells, int nr_resets) +{ + struct mmp_clk_reset_unit *unit; + + unit = kzalloc(sizeof(*unit), GFP_KERNEL); + if (!unit) + return; + + unit->cells = cells; + unit->rcdev.of_reset_n_cells = 1; + unit->rcdev.nr_resets = nr_resets; + unit->rcdev.ops = &mmp_clk_reset_ops; + unit->rcdev.of_node = np; + unit->rcdev.of_xlate = mmp_of_reset_xlate; + + reset_controller_register(&unit->rcdev); +} diff --git a/drivers/clk/mmp/reset.h b/drivers/clk/mmp/reset.h new file mode 100644 index 000000000000..be8b1a7000f7 --- /dev/null +++ b/drivers/clk/mmp/reset.h @@ -0,0 +1,31 @@ +#ifndef __MACH_MMP_CLK_RESET_H +#define __MACH_MMP_CLK_RESET_H + +#include <linux/reset-controller.h> + +#define MMP_RESET_INVERT 1 + +struct mmp_clk_reset_cell { + unsigned int clk_id; + void __iomem *reg; + u32 bits; + unsigned int flags; + spinlock_t *lock; +}; + +struct mmp_clk_reset_unit { + struct reset_controller_dev rcdev; + struct mmp_clk_reset_cell *cells; +}; + +#ifdef CONFIG_RESET_CONTROLLER +void mmp_clk_reset_register(struct device_node *np, + struct mmp_clk_reset_cell *cells, int nr_resets); +#else +static inline void mmp_clk_reset_register(struct device_node *np, + struct mmp_clk_reset_cell *cells, int nr_resets) +{ +} +#endif + +#endif diff --git a/drivers/clk/pxa/Makefile b/drivers/clk/pxa/Makefile index 4ff2abcd500b..38e915344605 100644 --- a/drivers/clk/pxa/Makefile +++ b/drivers/clk/pxa/Makefile @@ -1,2 +1,3 @@ obj-y += clk-pxa.o +obj-$(CONFIG_PXA25x) += clk-pxa25x.o obj-$(CONFIG_PXA27x) += clk-pxa27x.o diff --git a/drivers/clk/pxa/clk-pxa.c b/drivers/clk/pxa/clk-pxa.c index ef3c05389c0a..4e834753ab09 100644 --- a/drivers/clk/pxa/clk-pxa.c +++ b/drivers/clk/pxa/clk-pxa.c @@ -26,12 +26,20 @@ static struct clk_onecell_data onecell_data = { .clk_num = CLK_MAX, }; -#define to_pxa_clk(_hw) container_of(_hw, struct pxa_clk_cken, hw) +struct pxa_clk { + struct clk_hw hw; + struct clk_fixed_factor lp; + struct clk_fixed_factor hp; + struct clk_gate gate; + bool (*is_in_low_power)(void); +}; + +#define to_pxa_clk(_hw) container_of(_hw, struct pxa_clk, hw) static unsigned long cken_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { - struct pxa_clk_cken *pclk = to_pxa_clk(hw); + struct pxa_clk *pclk = to_pxa_clk(hw); struct clk_fixed_factor *fix; if (!pclk->is_in_low_power || pclk->is_in_low_power()) @@ -48,7 +56,7 @@ static struct clk_ops cken_rate_ops = { static u8 cken_get_parent(struct clk_hw *hw) { - struct pxa_clk_cken *pclk = to_pxa_clk(hw); + struct pxa_clk *pclk = to_pxa_clk(hw); if (!pclk->is_in_low_power) return 0; @@ -69,29 +77,32 @@ void __init clkdev_pxa_register(int ckid, const char *con_id, clk_register_clkdev(clk, con_id, dev_id); } -int __init clk_pxa_cken_init(struct pxa_clk_cken *clks, int nb_clks) +int __init clk_pxa_cken_init(const struct desc_clk_cken *clks, int nb_clks) { int i; - struct pxa_clk_cken *pclk; + struct pxa_clk *pxa_clk; struct clk *clk; for (i = 0; i < nb_clks; i++) { - pclk = clks + i; - pclk->gate.lock = &lock; - clk = clk_register_composite(NULL, pclk->name, - pclk->parent_names, 2, - &pclk->hw, &cken_mux_ops, - &pclk->hw, &cken_rate_ops, - &pclk->gate.hw, &clk_gate_ops, - pclk->flags); - clkdev_pxa_register(pclk->ckid, pclk->con_id, pclk->dev_id, - clk); + pxa_clk = kzalloc(sizeof(*pxa_clk), GFP_KERNEL); + pxa_clk->is_in_low_power = clks[i].is_in_low_power; + pxa_clk->lp = clks[i].lp; + pxa_clk->hp = clks[i].hp; + pxa_clk->gate = clks[i].gate; + pxa_clk->gate.lock = &lock; + clk = clk_register_composite(NULL, clks[i].name, + clks[i].parent_names, 2, + &pxa_clk->hw, &cken_mux_ops, + &pxa_clk->hw, &cken_rate_ops, + &pxa_clk->gate.hw, &clk_gate_ops, + clks[i].flags); + clkdev_pxa_register(clks[i].ckid, clks[i].con_id, + clks[i].dev_id, clk); } return 0; } -static void __init pxa_dt_clocks_init(struct device_node *np) +void __init clk_pxa_dt_common_init(struct device_node *np) { of_clk_add_provider(np, of_clk_src_onecell_get, &onecell_data); } -CLK_OF_DECLARE(pxa_clks, "marvell,pxa-clocks", pxa_dt_clocks_init); diff --git a/drivers/clk/pxa/clk-pxa.h b/drivers/clk/pxa/clk-pxa.h index 5fe219d06b49..323965430111 100644 --- a/drivers/clk/pxa/clk-pxa.h +++ b/drivers/clk/pxa/clk-pxa.h @@ -25,7 +25,7 @@ static struct clk_ops name ## _rate_ops = { \ .recalc_rate = name ## _get_rate, \ }; \ - static struct clk *clk_register_ ## name(void) \ + static struct clk * __init clk_register_ ## name(void) \ { \ return clk_register_composite(NULL, clk_name, \ name ## _parents, \ @@ -40,7 +40,7 @@ static struct clk_ops name ## _rate_ops = { \ .recalc_rate = name ## _get_rate, \ }; \ - static struct clk *clk_register_ ## name(void) \ + static struct clk * __init clk_register_ ## name(void) \ { \ return clk_register_composite(NULL, clk_name, \ name ## _parents, \ @@ -66,7 +66,7 @@ * | Clock | --- | / div_hp | * +------------+ +-----------+ */ -struct pxa_clk_cken { +struct desc_clk_cken { struct clk_hw hw; int ckid; const char *name; @@ -102,6 +102,7 @@ static int dummy_clk_set_parent(struct clk_hw *hw, u8 index) extern void clkdev_pxa_register(int ckid, const char *con_id, const char *dev_id, struct clk *clk); -extern int clk_pxa_cken_init(struct pxa_clk_cken *clks, int nb_clks); +extern int clk_pxa_cken_init(const struct desc_clk_cken *clks, int nb_clks); +void clk_pxa_dt_common_init(struct device_node *np); #endif diff --git a/drivers/clk/pxa/clk-pxa25x.c b/drivers/clk/pxa/clk-pxa25x.c new file mode 100644 index 000000000000..6cd88d963a7f --- /dev/null +++ b/drivers/clk/pxa/clk-pxa25x.c @@ -0,0 +1,273 @@ +/* + * Marvell PXA25x family clocks + * + * Copyright (C) 2014 Robert Jarzmik + * + * Heavily inspired from former arch/arm/mach-pxa/pxa25x.c. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * For non-devicetree platforms. Once pxa is fully converted to devicetree, this + * should go away. + */ +#include <linux/clk-provider.h> +#include <linux/clk.h> +#include <linux/clkdev.h> +#include <linux/io.h> +#include <linux/of.h> +#include <mach/pxa25x.h> +#include <mach/pxa2xx-regs.h> + +#include <dt-bindings/clock/pxa-clock.h> +#include "clk-pxa.h" + +#define KHz 1000 +#define MHz (1000 * 1000) + +enum { + PXA_CORE_RUN = 0, + PXA_CORE_TURBO, +}; + +/* + * Various clock factors driven by the CCCR register. + */ + +/* Crystal Frequency to Memory Frequency Multiplier (L) */ +static unsigned char L_clk_mult[32] = { 0, 27, 32, 36, 40, 45, 0, }; + +/* Memory Frequency to Run Mode Frequency Multiplier (M) */ +static unsigned char M_clk_mult[4] = { 0, 1, 2, 4 }; + +/* Run Mode Frequency to Turbo Mode Frequency Multiplier (N) */ +/* Note: we store the value N * 2 here. */ +static unsigned char N2_clk_mult[8] = { 0, 0, 2, 3, 4, 0, 6, 0 }; + +static const char * const get_freq_khz[] = { + "core", "run", "cpll", "memory" +}; + +/* + * Get the clock frequency as reflected by CCCR and the turbo flag. + * We assume these values have been applied via a fcs. + * If info is not 0 we also display the current settings. + */ +unsigned int pxa25x_get_clk_frequency_khz(int info) +{ + struct clk *clk; + unsigned long clks[5]; + int i; + + for (i = 0; i < ARRAY_SIZE(get_freq_khz); i++) { + clk = clk_get(NULL, get_freq_khz[i]); + if (IS_ERR(clk)) { + clks[i] = 0; + } else { + clks[i] = clk_get_rate(clk); + clk_put(clk); + } + } + + if (info) { + pr_info("Run Mode clock: %ld.%02ldMHz\n", + clks[1] / 1000000, (clks[1] % 1000000) / 10000); + pr_info("Turbo Mode clock: %ld.%02ldMHz\n", + clks[2] / 1000000, (clks[2] % 1000000) / 10000); + pr_info("Memory clock: %ld.%02ldMHz\n", + clks[3] / 1000000, (clks[3] % 1000000) / 10000); + } + + return (unsigned int)clks[0]; +} + +static unsigned long clk_pxa25x_memory_get_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + unsigned long cccr = CCCR; + unsigned int m = M_clk_mult[(cccr >> 5) & 0x03]; + + return parent_rate / m; +} +PARENTS(clk_pxa25x_memory) = { "run" }; +RATE_RO_OPS(clk_pxa25x_memory, "memory"); + +PARENTS(pxa25x_pbus95) = { "ppll_95_85mhz", "ppll_95_85mhz" }; +PARENTS(pxa25x_pbus147) = { "ppll_147_46mhz", "ppll_147_46mhz" }; +PARENTS(pxa25x_osc3) = { "osc_3_6864mhz", "osc_3_6864mhz" }; + +#define PXA25X_CKEN(dev_id, con_id, parents, mult, div, \ + bit, is_lp, flags) \ + PXA_CKEN(dev_id, con_id, bit, parents, mult, div, mult, div, \ + is_lp, &CKEN, CKEN_ ## bit, flags) +#define PXA25X_PBUS95_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay) \ + PXA25X_CKEN(dev_id, con_id, pxa25x_pbus95_parents, mult_hp, \ + div_hp, bit, NULL, 0) +#define PXA25X_PBUS147_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay)\ + PXA25X_CKEN(dev_id, con_id, pxa25x_pbus147_parents, mult_hp, \ + div_hp, bit, NULL, 0) +#define PXA25X_OSC3_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay) \ + PXA25X_CKEN(dev_id, con_id, pxa25x_osc3_parents, mult_hp, \ + div_hp, bit, NULL, 0) + +#define PXA25X_CKEN_1RATE(dev_id, con_id, bit, parents, delay) \ + PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \ + &CKEN, CKEN_ ## bit, 0) +#define PXA25X_CKEN_1RATE_AO(dev_id, con_id, bit, parents, delay) \ + PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \ + &CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED) + +static struct desc_clk_cken pxa25x_clocks[] __initdata = { + PXA25X_PBUS95_CKEN("pxa2xx-mci.0", NULL, MMC, 1, 5, 0), + PXA25X_PBUS95_CKEN("pxa2xx-i2c.0", NULL, I2C, 1, 3, 0), + PXA25X_PBUS95_CKEN("pxa2xx-ir", "FICPCLK", FICP, 1, 2, 0), + PXA25X_PBUS95_CKEN("pxa25x-udc", NULL, USB, 1, 2, 5), + PXA25X_PBUS147_CKEN("pxa2xx-uart.0", NULL, FFUART, 1, 10, 1), + PXA25X_PBUS147_CKEN("pxa2xx-uart.1", NULL, BTUART, 1, 10, 1), + PXA25X_PBUS147_CKEN("pxa2xx-uart.2", NULL, STUART, 1, 10, 1), + PXA25X_PBUS147_CKEN("pxa2xx-uart.3", NULL, HWUART, 1, 10, 1), + PXA25X_PBUS147_CKEN("pxa2xx-i2s", NULL, I2S, 1, 10, 0), + PXA25X_PBUS147_CKEN(NULL, "AC97CLK", AC97, 1, 12, 0), + PXA25X_OSC3_CKEN("pxa25x-ssp.0", NULL, SSP, 1, 1, 0), + PXA25X_OSC3_CKEN("pxa25x-nssp.1", NULL, NSSP, 1, 1, 0), + PXA25X_OSC3_CKEN("pxa25x-nssp.2", NULL, ASSP, 1, 1, 0), + PXA25X_OSC3_CKEN("pxa25x-pwm.0", NULL, PWM0, 1, 1, 0), + PXA25X_OSC3_CKEN("pxa25x-pwm.1", NULL, PWM1, 1, 1, 0), + + PXA25X_CKEN_1RATE("pxa2xx-fb", NULL, LCD, clk_pxa25x_memory_parents, 0), + PXA25X_CKEN_1RATE_AO("pxa2xx-pcmcia", NULL, MEMC, + clk_pxa25x_memory_parents, 0), +}; + +static u8 clk_pxa25x_core_get_parent(struct clk_hw *hw) +{ + unsigned long clkcfg; + unsigned int t; + + asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); + t = clkcfg & (1 << 0); + if (t) + return PXA_CORE_TURBO; + return PXA_CORE_RUN; +} + +static unsigned long clk_pxa25x_core_get_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return parent_rate; +} +PARENTS(clk_pxa25x_core) = { "run", "cpll" }; +MUX_RO_RATE_RO_OPS(clk_pxa25x_core, "core"); + +static unsigned long clk_pxa25x_run_get_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + unsigned long cccr = CCCR; + unsigned int n2 = N2_clk_mult[(cccr >> 7) & 0x07]; + + return (parent_rate / n2) * 2; +} +PARENTS(clk_pxa25x_run) = { "cpll" }; +RATE_RO_OPS(clk_pxa25x_run, "run"); + +static unsigned long clk_pxa25x_cpll_get_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + unsigned long clkcfg, cccr = CCCR; + unsigned int l, m, n2, t; + + asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); + t = clkcfg & (1 << 0); + l = L_clk_mult[(cccr >> 0) & 0x1f]; + m = M_clk_mult[(cccr >> 5) & 0x03]; + n2 = N2_clk_mult[(cccr >> 7) & 0x07]; + + if (t) + return m * l * n2 * parent_rate / 2; + return m * l * parent_rate; +} +PARENTS(clk_pxa25x_cpll) = { "osc_3_6864mhz" }; +RATE_RO_OPS(clk_pxa25x_cpll, "cpll"); + +static void __init pxa25x_register_core(void) +{ + clk_register_clk_pxa25x_cpll(); + clk_register_clk_pxa25x_run(); + clkdev_pxa_register(CLK_CORE, "core", NULL, + clk_register_clk_pxa25x_core()); +} + +static void __init pxa25x_register_plls(void) +{ + clk_register_fixed_rate(NULL, "osc_3_6864mhz", NULL, + CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, + 3686400); + clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, + CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, + 32768); + clk_register_fixed_rate(NULL, "clk_dummy", NULL, CLK_IS_ROOT, 0); + clk_register_fixed_factor(NULL, "ppll_95_85mhz", "osc_3_6864mhz", + 0, 26, 1); + clk_register_fixed_factor(NULL, "ppll_147_46mhz", "osc_3_6864mhz", + 0, 40, 1); +} + +static void __init pxa25x_base_clocks_init(void) +{ + pxa25x_register_plls(); + pxa25x_register_core(); + clk_register_clk_pxa25x_memory(); +} + +#define DUMMY_CLK(_con_id, _dev_id, _parent) \ + { .con_id = _con_id, .dev_id = _dev_id, .parent = _parent } +struct dummy_clk { + const char *con_id; + const char *dev_id; + const char *parent; +}; +static struct dummy_clk dummy_clks[] __initdata = { + DUMMY_CLK(NULL, "pxa25x-gpio", "osc_32_768khz"), + DUMMY_CLK(NULL, "pxa26x-gpio", "osc_32_768khz"), + DUMMY_CLK("GPIO11_CLK", NULL, "osc_3_6864mhz"), + DUMMY_CLK("GPIO12_CLK", NULL, "osc_32_768khz"), + DUMMY_CLK(NULL, "sa1100-rtc", "osc_32_768khz"), + DUMMY_CLK("OSTIMER0", NULL, "osc_32_768khz"), + DUMMY_CLK("UARTCLK", "pxa2xx-ir", "STUART"), +}; + +static void __init pxa25x_dummy_clocks_init(void) +{ + struct clk *clk; + struct dummy_clk *d; + const char *name; + int i; + + /* + * All pinctrl logic has been wiped out of the clock driver, especially + * for gpio11 and gpio12 outputs. Machine code should ensure proper pin + * control (ie. pxa2xx_mfp_config() invocation). + */ + for (i = 0; i < ARRAY_SIZE(dummy_clks); i++) { + d = &dummy_clks[i]; + name = d->dev_id ? d->dev_id : d->con_id; + clk = clk_register_fixed_factor(NULL, name, d->parent, 0, 1, 1); + clk_register_clkdev(clk, d->con_id, d->dev_id); + } +} + +int __init pxa25x_clocks_init(void) +{ + pxa25x_base_clocks_init(); + pxa25x_dummy_clocks_init(); + return clk_pxa_cken_init(pxa25x_clocks, ARRAY_SIZE(pxa25x_clocks)); +} + +static void __init pxa25x_dt_clocks_init(struct device_node *np) +{ + pxa25x_clocks_init(); + clk_pxa_dt_common_init(np); +} +CLK_OF_DECLARE(pxa25x_clks, "marvell,pxa250-core-clocks", + pxa25x_dt_clocks_init); diff --git a/drivers/clk/pxa/clk-pxa27x.c b/drivers/clk/pxa/clk-pxa27x.c index 88b9fe13fa44..5f9b54b024b9 100644 --- a/drivers/clk/pxa/clk-pxa27x.c +++ b/drivers/clk/pxa/clk-pxa27x.c @@ -111,7 +111,7 @@ PARENTS(pxa27x_membus) = { "lcd_base", "lcd_base" }; PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \ &CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED) -static struct pxa_clk_cken pxa27x_clocks[] = { +static struct desc_clk_cken pxa27x_clocks[] __initdata = { PXA27X_PBUS_CKEN("pxa2xx-uart.0", NULL, FFUART, 2, 42, 1), PXA27X_PBUS_CKEN("pxa2xx-uart.1", NULL, BTUART, 2, 42, 1), PXA27X_PBUS_CKEN("pxa2xx-uart.2", NULL, STUART, 2, 42, 1), @@ -368,3 +368,10 @@ static int __init pxa27x_clocks_init(void) return clk_pxa_cken_init(pxa27x_clocks, ARRAY_SIZE(pxa27x_clocks)); } postcore_initcall(pxa27x_clocks_init); + +static void __init pxa27x_dt_clocks_init(struct device_node *np) +{ + pxa27x_clocks_init(); + clk_pxa_dt_common_init(np); +} +CLK_OF_DECLARE(pxa_clks, "marvell,pxa270-clocks", pxa27x_dt_clocks_init); diff --git a/drivers/clk/qcom/clk-pll.c b/drivers/clk/qcom/clk-pll.c index b823bc3b6250..60873a7f45d9 100644 --- a/drivers/clk/qcom/clk-pll.c +++ b/drivers/clk/qcom/clk-pll.c @@ -141,7 +141,7 @@ struct pll_freq_tbl *find_freq(const struct pll_freq_tbl *f, unsigned long rate) static long clk_pll_determine_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *p_rate, struct clk **p) + unsigned long *p_rate, struct clk_hw **p) { struct clk_pll *pll = to_clk_pll(hw); const struct pll_freq_tbl *f; diff --git a/drivers/clk/qcom/clk-rcg.c b/drivers/clk/qcom/clk-rcg.c index b6e6959e89aa..0b93972c8807 100644 --- a/drivers/clk/qcom/clk-rcg.c +++ b/drivers/clk/qcom/clk-rcg.c @@ -368,16 +368,17 @@ clk_dyn_rcg_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) static long _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f, unsigned long rate, - unsigned long *p_rate, struct clk **p) + unsigned long *p_rate, struct clk_hw **p_hw) { unsigned long clk_flags; + struct clk *p; f = qcom_find_freq(f, rate); if (!f) return -EINVAL; clk_flags = __clk_get_flags(hw->clk); - *p = clk_get_parent_by_index(hw->clk, f->src); + p = clk_get_parent_by_index(hw->clk, f->src); if (clk_flags & CLK_SET_RATE_PARENT) { rate = rate * f->pre_div; if (f->n) { @@ -387,15 +388,16 @@ static long _freq_tbl_determine_rate(struct clk_hw *hw, rate = tmp; } } else { - rate = __clk_get_rate(*p); + rate = __clk_get_rate(p); } + *p_hw = __clk_get_hw(p); *p_rate = rate; return f->freq; } static long clk_rcg_determine_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *p_rate, struct clk **p) + unsigned long *p_rate, struct clk_hw **p) { struct clk_rcg *rcg = to_clk_rcg(hw); @@ -403,7 +405,7 @@ static long clk_rcg_determine_rate(struct clk_hw *hw, unsigned long rate, } static long clk_dyn_rcg_determine_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *p_rate, struct clk **p) + unsigned long *p_rate, struct clk_hw **p) { struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw); @@ -411,13 +413,15 @@ static long clk_dyn_rcg_determine_rate(struct clk_hw *hw, unsigned long rate, } static long clk_rcg_bypass_determine_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *p_rate, struct clk **p) + unsigned long *p_rate, struct clk_hw **p_hw) { struct clk_rcg *rcg = to_clk_rcg(hw); const struct freq_tbl *f = rcg->freq_tbl; + struct clk *p; - *p = clk_get_parent_by_index(hw->clk, f->src); - *p_rate = __clk_round_rate(*p, rate); + p = clk_get_parent_by_index(hw->clk, f->src); + *p_hw = __clk_get_hw(p); + *p_rate = __clk_round_rate(p, rate); return *p_rate; } diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index cfa9eb4fe9ca..08b8b3729f53 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -175,16 +175,17 @@ clk_rcg2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) static long _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f, unsigned long rate, - unsigned long *p_rate, struct clk **p) + unsigned long *p_rate, struct clk_hw **p_hw) { unsigned long clk_flags; + struct clk *p; f = qcom_find_freq(f, rate); if (!f) return -EINVAL; clk_flags = __clk_get_flags(hw->clk); - *p = clk_get_parent_by_index(hw->clk, f->src); + p = clk_get_parent_by_index(hw->clk, f->src); if (clk_flags & CLK_SET_RATE_PARENT) { if (f->pre_div) { rate /= 2; @@ -198,15 +199,16 @@ static long _freq_tbl_determine_rate(struct clk_hw *hw, rate = tmp; } } else { - rate = __clk_get_rate(*p); + rate = __clk_get_rate(p); } + *p_hw = __clk_get_hw(p); *p_rate = rate; return f->freq; } static long clk_rcg2_determine_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *p_rate, struct clk **p) + unsigned long *p_rate, struct clk_hw **p) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); @@ -359,7 +361,7 @@ static int clk_edp_pixel_set_rate_and_parent(struct clk_hw *hw, } static long clk_edp_pixel_determine_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *p_rate, struct clk **p) + unsigned long *p_rate, struct clk_hw **p) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); const struct freq_tbl *f = rcg->freq_tbl; @@ -371,7 +373,7 @@ static long clk_edp_pixel_determine_rate(struct clk_hw *hw, unsigned long rate, u32 hid_div; /* Force the correct parent */ - *p = clk_get_parent_by_index(hw->clk, f->src); + *p = __clk_get_hw(clk_get_parent_by_index(hw->clk, f->src)); if (src_rate == 810000000) frac = frac_table_810m; @@ -410,18 +412,20 @@ const struct clk_ops clk_edp_pixel_ops = { EXPORT_SYMBOL_GPL(clk_edp_pixel_ops); static long clk_byte_determine_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *p_rate, struct clk **p) + unsigned long *p_rate, struct clk_hw **p_hw) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); const struct freq_tbl *f = rcg->freq_tbl; unsigned long parent_rate, div; u32 mask = BIT(rcg->hid_width) - 1; + struct clk *p; if (rate == 0) return -EINVAL; - *p = clk_get_parent_by_index(hw->clk, f->src); - *p_rate = parent_rate = __clk_round_rate(*p, rate); + p = clk_get_parent_by_index(hw->clk, f->src); + *p_hw = __clk_get_hw(p); + *p_rate = parent_rate = __clk_round_rate(p, rate); div = DIV_ROUND_UP((2 * parent_rate), rate) - 1; div = min_t(u32, div, mask); @@ -472,14 +476,16 @@ static const struct frac_entry frac_table_pixel[] = { }; static long clk_pixel_determine_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *p_rate, struct clk **p) + unsigned long *p_rate, struct clk_hw **p) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); unsigned long request, src_rate; int delta = 100000; const struct freq_tbl *f = rcg->freq_tbl; const struct frac_entry *frac = frac_table_pixel; - struct clk *parent = *p = clk_get_parent_by_index(hw->clk, f->src); + struct clk *parent = clk_get_parent_by_index(hw->clk, f->src); + + *p = __clk_get_hw(parent); for (; frac->num; frac++) { request = (rate * frac->den) / frac->num; diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile index bd8514d63634..2714097f90db 100644 --- a/drivers/clk/rockchip/Makefile +++ b/drivers/clk/rockchip/Makefile @@ -6,6 +6,7 @@ obj-y += clk-rockchip.o obj-y += clk.o obj-y += clk-pll.o obj-y += clk-cpu.o +obj-y += clk-mmc-phase.o obj-$(CONFIG_RESET_CONTROLLER) += softrst.o obj-y += clk-rk3188.o diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c index 75c8c45ef728..8539c4fd34cc 100644 --- a/drivers/clk/rockchip/clk-cpu.c +++ b/drivers/clk/rockchip/clk-cpu.c @@ -124,10 +124,11 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk, { const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data; unsigned long alt_prate, alt_div; + unsigned long flags; alt_prate = clk_get_rate(cpuclk->alt_parent); - spin_lock(cpuclk->lock); + spin_lock_irqsave(cpuclk->lock, flags); /* * If the old parent clock speed is less than the clock speed @@ -164,7 +165,7 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk, cpuclk->reg_base + reg_data->core_reg); } - spin_unlock(cpuclk->lock); + spin_unlock_irqrestore(cpuclk->lock, flags); return 0; } @@ -173,6 +174,7 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk, { const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data; const struct rockchip_cpuclk_rate_table *rate; + unsigned long flags; rate = rockchip_get_cpuclk_settings(cpuclk, ndata->new_rate); if (!rate) { @@ -181,7 +183,7 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk, return -EINVAL; } - spin_lock(cpuclk->lock); + spin_lock_irqsave(cpuclk->lock, flags); if (ndata->old_rate < ndata->new_rate) rockchip_cpuclk_set_dividers(cpuclk, rate); @@ -201,7 +203,7 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk, if (ndata->old_rate > ndata->new_rate) rockchip_cpuclk_set_dividers(cpuclk, rate); - spin_unlock(cpuclk->lock); + spin_unlock_irqrestore(cpuclk->lock, flags); return 0; } diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c new file mode 100644 index 000000000000..c842e3b60f21 --- /dev/null +++ b/drivers/clk/rockchip/clk-mmc-phase.c @@ -0,0 +1,154 @@ +/* + * Copyright 2014 Google, Inc + * Author: Alexandru M Stan <amstan@chromium.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/slab.h> +#include <linux/clk-provider.h> +#include "clk.h" + +struct rockchip_mmc_clock { + struct clk_hw hw; + void __iomem *reg; + int id; + int shift; +}; + +#define to_mmc_clock(_hw) container_of(_hw, struct rockchip_mmc_clock, hw) + +#define RK3288_MMC_CLKGEN_DIV 2 + +static unsigned long rockchip_mmc_recalc(struct clk_hw *hw, + unsigned long parent_rate) +{ + return parent_rate / RK3288_MMC_CLKGEN_DIV; +} + +#define ROCKCHIP_MMC_DELAY_SEL BIT(10) +#define ROCKCHIP_MMC_DEGREE_MASK 0x3 +#define ROCKCHIP_MMC_DELAYNUM_OFFSET 2 +#define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) + +#define PSECS_PER_SEC 1000000000000LL + +/* + * Each fine delay is between 40ps-80ps. Assume each fine delay is 60ps to + * simplify calculations. So 45degs could be anywhere between 33deg and 66deg. + */ +#define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60 + +static int rockchip_mmc_get_phase(struct clk_hw *hw) +{ + struct rockchip_mmc_clock *mmc_clock = to_mmc_clock(hw); + unsigned long rate = clk_get_rate(hw->clk); + u32 raw_value; + u16 degrees; + u32 delay_num = 0; + + raw_value = readl(mmc_clock->reg) >> (mmc_clock->shift); + + degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; + + if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { + /* degrees/delaynum * 10000 */ + unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * + 36 * (rate / 1000000); + + delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); + delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET; + degrees += delay_num * factor / 10000; + } + + return degrees % 360; +} + +static int rockchip_mmc_set_phase(struct clk_hw *hw, int degrees) +{ + struct rockchip_mmc_clock *mmc_clock = to_mmc_clock(hw); + unsigned long rate = clk_get_rate(hw->clk); + u8 nineties, remainder; + u8 delay_num; + u32 raw_value; + u64 delay; + + /* allow 22 to be 22.5 */ + degrees++; + /* floor to 22.5 increment */ + degrees -= ((degrees) * 10 % 225) / 10; + + nineties = degrees / 90; + /* 22.5 multiples */ + remainder = (degrees % 90) / 22; + + delay = PSECS_PER_SEC; + do_div(delay, rate); + /* / 360 / 22.5 */ + do_div(delay, 16); + do_div(delay, ROCKCHIP_MMC_DELAY_ELEMENT_PSEC); + + delay *= remainder; + delay_num = (u8) min(delay, 255ULL); + + raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; + raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; + raw_value |= nineties; + writel(HIWORD_UPDATE(raw_value, 0x07ff, mmc_clock->shift), mmc_clock->reg); + + pr_debug("%s->set_phase(%d) delay_nums=%u reg[0x%p]=0x%03x actual_degrees=%d\n", + __clk_get_name(hw->clk), degrees, delay_num, + mmc_clock->reg, raw_value>>(mmc_clock->shift), + rockchip_mmc_get_phase(hw) + ); + + return 0; +} + +static const struct clk_ops rockchip_mmc_clk_ops = { + .recalc_rate = rockchip_mmc_recalc, + .get_phase = rockchip_mmc_get_phase, + .set_phase = rockchip_mmc_set_phase, +}; + +struct clk *rockchip_clk_register_mmc(const char *name, + const char **parent_names, u8 num_parents, + void __iomem *reg, int shift) +{ + struct clk_init_data init; + struct rockchip_mmc_clock *mmc_clock; + struct clk *clk; + + mmc_clock = kmalloc(sizeof(*mmc_clock), GFP_KERNEL); + if (!mmc_clock) + return NULL; + + init.num_parents = num_parents; + init.parent_names = parent_names; + init.ops = &rockchip_mmc_clk_ops; + + mmc_clock->hw.init = &init; + mmc_clock->reg = reg; + mmc_clock->shift = shift; + + if (name) + init.name = name; + + clk = clk_register(NULL, &mmc_clock->hw); + if (IS_ERR(clk)) + goto err_free; + + return clk; + +err_free: + kfree(mmc_clock); + return NULL; +} diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index a3e886a38480..f8d3baf275b2 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -39,6 +39,7 @@ struct rockchip_clk_pll { int lock_offset; unsigned int lock_shift; enum rockchip_pll_type type; + u8 flags; const struct rockchip_pll_rate_table *rate_table; unsigned int rate_count; spinlock_t *lock; @@ -257,6 +258,55 @@ static int rockchip_rk3066_pll_is_enabled(struct clk_hw *hw) return !(pllcon & RK3066_PLLCON3_PWRDOWN); } +static void rockchip_rk3066_pll_init(struct clk_hw *hw) +{ + struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); + const struct rockchip_pll_rate_table *rate; + unsigned int nf, nr, no, bwadj; + unsigned long drate; + u32 pllcon; + + if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE)) + return; + + drate = __clk_get_rate(hw->clk); + rate = rockchip_get_pll_settings(pll, drate); + + /* when no rate setting for the current rate, rely on clk_set_rate */ + if (!rate) + return; + + pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0)); + nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK) + 1; + no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK) + 1; + + pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1)); + nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK) + 1; + + pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2)); + bwadj = (pllcon >> RK3066_PLLCON2_BWADJ_SHIFT) & RK3066_PLLCON2_BWADJ_MASK; + + pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), bwadj(%d:%d)\n", + __func__, __clk_get_name(hw->clk), drate, rate->nr, nr, + rate->no, no, rate->nf, nf, rate->bwadj, bwadj); + if (rate->nr != nr || rate->no != no || rate->nf != nf + || rate->bwadj != bwadj) { + struct clk *parent = __clk_get_parent(hw->clk); + unsigned long prate; + + if (!parent) { + pr_warn("%s: parent of %s not available\n", + __func__, __clk_get_name(hw->clk)); + return; + } + + pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n", + __func__, __clk_get_name(hw->clk)); + prate = __clk_get_rate(parent); + rockchip_rk3066_pll_set_rate(hw, drate, prate); + } +} + static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = { .recalc_rate = rockchip_rk3066_pll_recalc_rate, .enable = rockchip_rk3066_pll_enable, @@ -271,6 +321,7 @@ static const struct clk_ops rockchip_rk3066_pll_clk_ops = { .enable = rockchip_rk3066_pll_enable, .disable = rockchip_rk3066_pll_disable, .is_enabled = rockchip_rk3066_pll_is_enabled, + .init = rockchip_rk3066_pll_init, }; /* @@ -282,7 +333,7 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, void __iomem *base, int con_offset, int grf_lock_offset, int lock_shift, int mode_offset, int mode_shift, struct rockchip_pll_rate_table *rate_table, - spinlock_t *lock) + u8 clk_pll_flags, spinlock_t *lock) { const char *pll_parents[3]; struct clk_init_data init; @@ -345,8 +396,22 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, pll->reg_base = base + con_offset; pll->lock_offset = grf_lock_offset; pll->lock_shift = lock_shift; + pll->flags = clk_pll_flags; pll->lock = lock; + /* create the mux on top of the real pll */ + pll->pll_mux_ops = &clk_mux_ops; + pll_mux = &pll->pll_mux; + pll_mux->reg = base + mode_offset; + pll_mux->shift = mode_shift; + pll_mux->mask = PLL_MODE_MASK; + pll_mux->flags = 0; + pll_mux->lock = lock; + pll_mux->hw.init = &init; + + if (pll_type == pll_rk3066) + pll_mux->flags |= CLK_MUX_HIWORD_MASK; + pll_clk = clk_register(NULL, &pll->hw); if (IS_ERR(pll_clk)) { pr_err("%s: failed to register pll clock %s : %ld\n", @@ -355,10 +420,6 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, goto err_pll; } - /* create the mux on top of the real pll */ - pll->pll_mux_ops = &clk_mux_ops; - pll_mux = &pll->pll_mux; - /* the actual muxing is xin24m, pll-output, xin32k */ pll_parents[0] = parent_names[0]; pll_parents[1] = pll_name; @@ -370,16 +431,6 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, init.parent_names = pll_parents; init.num_parents = ARRAY_SIZE(pll_parents); - pll_mux->reg = base + mode_offset; - pll_mux->shift = mode_shift; - pll_mux->mask = PLL_MODE_MASK; - pll_mux->flags = 0; - pll_mux->lock = lock; - pll_mux->hw.init = &init; - - if (pll_type == pll_rk3066) - pll_mux->flags |= CLK_MUX_HIWORD_MASK; - mux_clk = clk_register(NULL, &pll_mux->hw); if (IS_ERR(mux_clk)) goto err_mux; diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index beed49c79126..7eb684c50d42 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -210,15 +210,26 @@ PNAME(mux_sclk_hsadc_p) = { "hsadc_src", "hsadc_frac", "ext_hsadc" }; PNAME(mux_mac_p) = { "gpll", "dpll" }; PNAME(mux_sclk_macref_p) = { "mac_src", "ext_rmii" }; +static struct rockchip_pll_clock rk3066_pll_clks[] __initdata = { + [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0), + RK2928_MODE_CON, 0, 5, 0, rk3188_pll_rates), + [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK2928_PLL_CON(4), + RK2928_MODE_CON, 4, 4, 0, NULL), + [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK2928_PLL_CON(8), + RK2928_MODE_CON, 8, 6, ROCKCHIP_PLL_SYNC_RATE, rk3188_pll_rates), + [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(12), + RK2928_MODE_CON, 12, 7, ROCKCHIP_PLL_SYNC_RATE, rk3188_pll_rates), +}; + static struct rockchip_pll_clock rk3188_pll_clks[] __initdata = { [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0), - RK2928_MODE_CON, 0, 6, rk3188_pll_rates), + RK2928_MODE_CON, 0, 6, 0, rk3188_pll_rates), [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK2928_PLL_CON(4), - RK2928_MODE_CON, 4, 5, NULL), + RK2928_MODE_CON, 4, 5, 0, NULL), [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK2928_PLL_CON(8), - RK2928_MODE_CON, 8, 7, rk3188_pll_rates), + RK2928_MODE_CON, 8, 7, ROCKCHIP_PLL_SYNC_RATE, rk3188_pll_rates), [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(12), - RK2928_MODE_CON, 12, 8, rk3188_pll_rates), + RK2928_MODE_CON, 12, 8, ROCKCHIP_PLL_SYNC_RATE, rk3188_pll_rates), }; #define MFLAGS CLK_MUX_HIWORD_MASK @@ -257,9 +268,9 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { GATE(0, "hclk_vdpu", "aclk_vdpu", 0, RK2928_CLKGATE_CON(3), 12, GFLAGS), - GATE(0, "gpll_ddr", "gpll", 0, + GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(1), 7, GFLAGS), - COMPOSITE(0, "ddrphy", mux_ddrphy_p, 0, + COMPOSITE(0, "ddrphy", mux_ddrphy_p, CLK_IGNORE_UNUSED, RK2928_CLKSEL_CON(26), 8, 1, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, RK2928_CLKGATE_CON(0), 2, GFLAGS), @@ -270,10 +281,10 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { RK2928_CLKGATE_CON(0), 6, GFLAGS), GATE(0, "pclk_cpu", "pclk_cpu_pre", 0, RK2928_CLKGATE_CON(0), 5, GFLAGS), - GATE(0, "hclk_cpu", "hclk_cpu_pre", 0, + GATE(0, "hclk_cpu", "hclk_cpu_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(0), 4, GFLAGS), - COMPOSITE(0, "aclk_lcdc0_pre", mux_pll_src_cpll_gpll_p, 0, + COMPOSITE(0, "aclk_lcdc0_pre", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED, RK2928_CLKSEL_CON(31), 7, 1, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(3), 0, GFLAGS), COMPOSITE(0, "aclk_lcdc1_pre", mux_pll_src_cpll_gpll_p, 0, @@ -304,9 +315,9 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { * the 480m are generated inside the usb block from these clocks, * but they are also a source for the hsicphy clock. */ - GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", 0, + GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(1), 5, GFLAGS), - GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", 0, + GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(1), 6, GFLAGS), COMPOSITE(0, "mac_src", mux_mac_p, 0, @@ -320,9 +331,9 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { COMPOSITE(0, "hsadc_src", mux_pll_src_gpll_cpll_p, 0, RK2928_CLKSEL_CON(22), 0, 1, MFLAGS, 8, 8, DFLAGS, RK2928_CLKGATE_CON(2), 6, GFLAGS), - COMPOSITE_FRAC(0, "hsadc_frac", "hsadc_src", + COMPOSITE_FRAC(0, "hsadc_frac", "hsadc_src", 0, RK2928_CLKSEL_CON(23), 0, - RK2928_CLKGATE_CON(2), 7, 0, GFLAGS), + RK2928_CLKGATE_CON(2), 7, GFLAGS), MUX(SCLK_HSADC, "sclk_hsadc", mux_sclk_hsadc_p, 0, RK2928_CLKSEL_CON(22), 4, 2, MFLAGS), @@ -330,6 +341,15 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { RK2928_CLKSEL_CON(24), 8, 8, DFLAGS, RK2928_CLKGATE_CON(2), 8, GFLAGS), + COMPOSITE_NOMUX(0, "spdif_pre", "i2s_src", 0, + RK2928_CLKSEL_CON(5), 0, 7, DFLAGS, + RK2928_CLKGATE_CON(0), 13, GFLAGS), + COMPOSITE_FRAC(0, "spdif_frac", "spdif_pll", 0, + RK2928_CLKSEL_CON(9), 0, + RK2928_CLKGATE_CON(0), 14, GFLAGS), + MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, 0, + RK2928_CLKSEL_CON(5), 8, 2, MFLAGS), + /* * Clock-Architecture Diagram 4 */ @@ -399,8 +419,8 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { /* aclk_cpu gates */ GATE(ACLK_DMA1, "aclk_dma1", "aclk_cpu", 0, RK2928_CLKGATE_CON(5), 0, GFLAGS), - GATE(0, "aclk_intmem", "aclk_cpu", 0, RK2928_CLKGATE_CON(4), 12, GFLAGS), - GATE(0, "aclk_strc_sys", "aclk_cpu", 0, RK2928_CLKGATE_CON(4), 10, GFLAGS), + GATE(0, "aclk_intmem", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 12, GFLAGS), + GATE(0, "aclk_strc_sys", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 10, GFLAGS), /* hclk_cpu gates */ GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", 0, RK2928_CLKGATE_CON(5), 6, GFLAGS), @@ -410,19 +430,19 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { /* hclk_ahb2apb is part of a clk branch */ GATE(0, "hclk_vio_bus", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 12, GFLAGS), GATE(HCLK_LCDC0, "hclk_lcdc0", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 1, GFLAGS), - GATE(HCLK_LCDC1, "hclk_lcdc1", "aclk_cpu", 0, RK2928_CLKGATE_CON(6), 2, GFLAGS), + GATE(HCLK_LCDC1, "hclk_lcdc1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 2, GFLAGS), GATE(HCLK_CIF0, "hclk_cif0", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 4, GFLAGS), GATE(HCLK_IPP, "hclk_ipp", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 9, GFLAGS), GATE(HCLK_RGA, "hclk_rga", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 10, GFLAGS), /* hclk_peri gates */ - GATE(0, "hclk_peri_axi_matrix", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 0, GFLAGS), - GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 6, GFLAGS), - GATE(0, "hclk_emem_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 7, GFLAGS), + GATE(0, "hclk_peri_axi_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS), + GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 6, GFLAGS), + GATE(0, "hclk_emem_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 7, GFLAGS), GATE(HCLK_EMAC, "hclk_emac", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS), GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS), - GATE(0, "hclk_usb_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 5, GFLAGS), - GATE(HCLK_OTG0, "hclk_usbotg0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 13, GFLAGS), + GATE(0, "hclk_usb_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 5, GFLAGS), + GATE(HCLK_OTG0, "hclk_usbotg0", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 13, GFLAGS), GATE(HCLK_HSADC, "hclk_hsadc", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 5, GFLAGS), GATE(HCLK_PIDF, "hclk_pidfilter", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 6, GFLAGS), GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 10, GFLAGS), @@ -457,18 +477,18 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { GATE(0, "pclk_ddrupctl", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 7, GFLAGS), GATE(0, "pclk_ddrpubl", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS), GATE(0, "pclk_dbg", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 1, GFLAGS), - GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 4, GFLAGS), - GATE(PCLK_PMU, "pclk_pmu", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 5, GFLAGS), + GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS), + GATE(PCLK_PMU, "pclk_pmu", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 5, GFLAGS), /* aclk_peri */ GATE(ACLK_DMA2, "aclk_dma2", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS), GATE(ACLK_SMC, "aclk_smc", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 8, GFLAGS), - GATE(0, "aclk_peri_niu", "aclk_peri", 0, RK2928_CLKGATE_CON(4), 4, GFLAGS), - GATE(0, "aclk_cpu_peri", "aclk_peri", 0, RK2928_CLKGATE_CON(4), 2, GFLAGS), - GATE(0, "aclk_peri_axi_matrix", "aclk_peri", 0, RK2928_CLKGATE_CON(4), 3, GFLAGS), + GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 4, GFLAGS), + GATE(0, "aclk_cpu_peri", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 2, GFLAGS), + GATE(0, "aclk_peri_axi_matrix", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 3, GFLAGS), /* pclk_peri gates */ - GATE(0, "pclk_peri_axi_matrix", "pclk_peri", 0, RK2928_CLKGATE_CON(4), 1, GFLAGS), + GATE(0, "pclk_peri_axi_matrix", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 1, GFLAGS), GATE(PCLK_PWM23, "pclk_pwm23", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 11, GFLAGS), GATE(PCLK_WDT, "pclk_wdt", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 15, GFLAGS), GATE(PCLK_SPI0, "pclk_spi0", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 12, GFLAGS), @@ -511,7 +531,7 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = { | CLK_DIVIDER_READ_ONLY, RK2928_CLKGATE_CON(4), 9, GFLAGS), - GATE(CORE_L2C, "core_l2c", "aclk_cpu", 0, + GATE(CORE_L2C, "core_l2c", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 4, GFLAGS), COMPOSITE(0, "aclk_peri_pre", mux_pll_src_gpll_cpll_p, 0, @@ -577,21 +597,14 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = { RK2928_CLKGATE_CON(0), 12, GFLAGS), MUX(SCLK_I2S2, "sclk_i2s2", mux_sclk_i2s2_p, 0, RK2928_CLKSEL_CON(4), 8, 2, MFLAGS), - COMPOSITE_NOMUX(0, "spdif_pre", "i2s_src", 0, - RK2928_CLKSEL_CON(5), 0, 7, DFLAGS, - RK2928_CLKGATE_CON(0), 13, GFLAGS), - COMPOSITE_FRAC(0, "spdif_frac", "spdif_pll", 0, - RK2928_CLKSEL_CON(9), 0, - RK2928_CLKGATE_CON(0), 14, GFLAGS), - MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, 0, - RK2928_CLKSEL_CON(5), 8, 2, MFLAGS), GATE(HCLK_I2S1, "hclk_i2s1", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS), GATE(HCLK_I2S2, "hclk_i2s2", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), GATE(0, "hclk_cif1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 6, GFLAGS), GATE(0, "hclk_hdmi", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), - GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS), + GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", CLK_IGNORE_UNUSED, + RK2928_CLKGATE_CON(5), 14, GFLAGS), GATE(0, "aclk_cif1", "aclk_vio1", 0, RK2928_CLKGATE_CON(6), 7, GFLAGS), @@ -618,7 +631,7 @@ PNAME(mux_hsicphy_p) = { "sclk_otgphy0", "sclk_otgphy1", "gpll", "cpll" }; static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { - COMPOSITE_NOMUX_DIVTBL(0, "aclk_core", "armclk", 0, + COMPOSITE_NOMUX_DIVTBL(0, "aclk_core", "armclk", CLK_IGNORE_UNUSED, RK2928_CLKSEL_CON(1), 3, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, div_rk3188_aclk_core_t, RK2928_CLKGATE_CON(0), 7, GFLAGS), @@ -633,7 +646,7 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { RK2928_CLKSEL_CON(1), 14, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, RK2928_CLKGATE_CON(4), 9, GFLAGS), - GATE(CORE_L2C, "core_l2c", "armclk", 0, + GATE(CORE_L2C, "core_l2c", "armclk", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 4, GFLAGS), COMPOSITE(0, "aclk_peri_pre", mux_pll_src_cpll_gpll_p, 0, @@ -663,7 +676,7 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { RK2928_CLKSEL_CON(30), 0, 2, DFLAGS, RK2928_CLKGATE_CON(3), 6, GFLAGS), DIV(0, "sclk_hsicphy_12m", "sclk_hsicphy_480m", 0, - RK2928_CLKGATE_CON(11), 8, 6, DFLAGS), + RK2928_CLKSEL_CON(11), 8, 6, DFLAGS), MUX(0, "i2s_src", mux_pll_src_gpll_cpll_p, 0, RK2928_CLKSEL_CON(2), 15, 1, MFLAGS), @@ -675,19 +688,12 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { RK2928_CLKGATE_CON(0), 10, GFLAGS), MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, 0, RK2928_CLKSEL_CON(3), 8, 2, MFLAGS), - COMPOSITE_NOMUX(0, "spdif_pre", "i2s_src", 0, - RK2928_CLKSEL_CON(5), 0, 7, DFLAGS, - RK2928_CLKGATE_CON(13), 13, GFLAGS), - COMPOSITE_FRAC(0, "spdif_frac", "spdif_pll", 0, - RK2928_CLKSEL_CON(9), 0, - RK2928_CLKGATE_CON(0), 14, GFLAGS), - MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, 0, - RK2928_CLKSEL_CON(5), 8, 2, MFLAGS), GATE(0, "hclk_imem0", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), GATE(0, "hclk_imem1", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 15, GFLAGS), - GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS), + GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", CLK_IGNORE_UNUSED, + RK2928_CLKGATE_CON(7), 3, GFLAGS), GATE(HCLK_HSIC, "hclk_hsic", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), GATE(PCLK_TIMER3, "pclk_timer3", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 9, GFLAGS), @@ -742,8 +748,8 @@ static void __init rk3188_common_clk_init(struct device_node *np) static void __init rk3066a_clk_init(struct device_node *np) { rk3188_common_clk_init(np); - rockchip_clk_register_plls(rk3188_pll_clks, - ARRAY_SIZE(rk3188_pll_clks), + rockchip_clk_register_plls(rk3066_pll_clks, + ARRAY_SIZE(rk3066_pll_clks), RK3066_GRF_SOC_STATUS); rockchip_clk_register_branches(rk3066a_clk_branches, ARRAY_SIZE(rk3066a_clk_branches)); diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 23278291da44..11194b8329fe 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -16,6 +16,7 @@ #include <linux/clk-provider.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/syscore_ops.h> #include <dt-bindings/clock/rk3288-cru.h> #include "clk.h" @@ -83,11 +84,13 @@ struct rockchip_pll_rate_table rk3288_pll_rates[] = { RK3066_PLL_RATE( 742500000, 8, 495, 2), RK3066_PLL_RATE( 696000000, 1, 58, 2), RK3066_PLL_RATE( 600000000, 1, 50, 2), - RK3066_PLL_RATE( 594000000, 2, 198, 4), + RK3066_PLL_RATE_BWADJ(594000000, 1, 198, 8, 1), RK3066_PLL_RATE( 552000000, 1, 46, 2), RK3066_PLL_RATE( 504000000, 1, 84, 4), + RK3066_PLL_RATE( 500000000, 3, 125, 2), RK3066_PLL_RATE( 456000000, 1, 76, 4), RK3066_PLL_RATE( 408000000, 1, 68, 4), + RK3066_PLL_RATE( 400000000, 3, 100, 2), RK3066_PLL_RATE( 384000000, 2, 128, 4), RK3066_PLL_RATE( 360000000, 1, 60, 4), RK3066_PLL_RATE( 312000000, 1, 52, 4), @@ -142,20 +145,20 @@ struct rockchip_pll_rate_table rk3288_pll_rates[] = { } static struct rockchip_cpuclk_rate_table rk3288_cpuclk_rates[] __initdata = { - RK3288_CPUCLK_RATE(1800000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE(1704000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE(1608000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE(1512000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE(1416000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE(1200000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE(1008000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE( 816000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE( 696000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE( 600000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE( 408000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE( 312000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE( 216000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE( 126000000, 2, 4, 2, 4, 4), + RK3288_CPUCLK_RATE(1800000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE(1704000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE(1608000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE(1512000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE(1416000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE(1200000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE(1008000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE( 816000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE( 696000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE( 600000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE( 408000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE( 312000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE( 216000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE( 126000000, 1, 3, 1, 3, 3), }; static const struct rockchip_cpuclk_reg_data rk3288_cpuclk_data = { @@ -173,14 +176,14 @@ PNAME(mux_aclk_cpu_src_p) = { "cpll_aclk_cpu", "gpll_aclk_cpu" }; PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" }; PNAME(mux_pll_src_npll_cpll_gpll_p) = { "npll", "cpll", "gpll" }; PNAME(mux_pll_src_cpll_gpll_npll_p) = { "cpll", "gpll", "npll" }; -PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "usb480m" }; +PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "usbphy480m_src" }; +PNAME(mux_pll_src_cpll_gll_usb_npll_p) = { "cpll", "gpll", "usbphy480m_src", "npll" }; PNAME(mux_mmc_src_p) = { "cpll", "gpll", "xin24m", "xin24m" }; PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" }; PNAME(mux_i2s_clkout_p) = { "i2s_pre", "xin12m" }; PNAME(mux_spdif_p) = { "spdif_pre", "spdif_frac", "xin12m" }; PNAME(mux_spdif_8ch_p) = { "spdif_8ch_pre", "spdif_8ch_frac", "xin12m" }; -PNAME(mux_uart0_pll_p) = { "cpll", "gpll", "usbphy_480m_src", "npll" }; PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" }; PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" }; PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" }; @@ -192,22 +195,22 @@ PNAME(mux_hsadcout_p) = { "hsadc_src", "ext_hsadc" }; PNAME(mux_edp_24m_p) = { "ext_edp_24m", "xin24m" }; PNAME(mux_tspout_p) = { "cpll", "gpll", "npll", "xin27m" }; -PNAME(mux_usbphy480m_p) = { "sclk_otgphy0", "sclk_otgphy1", - "sclk_otgphy2" }; +PNAME(mux_usbphy480m_p) = { "sclk_otgphy1", "sclk_otgphy2", + "sclk_otgphy0" }; PNAME(mux_hsicphy480m_p) = { "cpll", "gpll", "usbphy480m_src" }; PNAME(mux_hsicphy12m_p) = { "hsicphy12m_xin12m", "hsicphy12m_usbphy" }; static struct rockchip_pll_clock rk3288_pll_clks[] __initdata = { [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK3288_PLL_CON(0), - RK3288_MODE_CON, 0, 6, rk3288_pll_rates), + RK3288_MODE_CON, 0, 6, 0, rk3288_pll_rates), [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK3288_PLL_CON(4), - RK3288_MODE_CON, 4, 5, NULL), + RK3288_MODE_CON, 4, 5, 0, NULL), [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK3288_PLL_CON(8), - RK3288_MODE_CON, 8, 7, rk3288_pll_rates), + RK3288_MODE_CON, 8, 7, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates), [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK3288_PLL_CON(12), - RK3288_MODE_CON, 12, 8, rk3288_pll_rates), + RK3288_MODE_CON, 12, 8, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates), [npll] = PLL(pll_rk3066, PLL_NPLL, "npll", mux_pll_p, 0, RK3288_PLL_CON(16), - RK3288_MODE_CON, 14, 9, rk3288_pll_rates), + RK3288_MODE_CON, 14, 9, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates), }; static struct clk_div_table div_hclk_cpu_t[] = { @@ -226,67 +229,67 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { * Clock-Architecture Diagram 1 */ - GATE(0, "apll_core", "apll", 0, + GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 1, GFLAGS), - GATE(0, "gpll_core", "gpll", 0, + GATE(0, "gpll_core", "gpll", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 2, GFLAGS), - COMPOSITE_NOMUX(0, "armcore0", "armclk", 0, + COMPOSITE_NOMUX(0, "armcore0", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(36), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 0, GFLAGS), - COMPOSITE_NOMUX(0, "armcore1", "armclk", 0, + COMPOSITE_NOMUX(0, "armcore1", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(36), 4, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 1, GFLAGS), - COMPOSITE_NOMUX(0, "armcore2", "armclk", 0, + COMPOSITE_NOMUX(0, "armcore2", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(36), 8, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 2, GFLAGS), - COMPOSITE_NOMUX(0, "armcore3", "armclk", 0, + COMPOSITE_NOMUX(0, "armcore3", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(36), 12, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 3, GFLAGS), - COMPOSITE_NOMUX(0, "l2ram", "armclk", 0, + COMPOSITE_NOMUX(0, "l2ram", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(37), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 4, GFLAGS), - COMPOSITE_NOMUX(0, "aclk_core_m0", "armclk", 0, + COMPOSITE_NOMUX(0, "aclk_core_m0", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(0), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 5, GFLAGS), - COMPOSITE_NOMUX(0, "aclk_core_mp", "armclk", 0, + COMPOSITE_NOMUX(0, "aclk_core_mp", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(0), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 6, GFLAGS), COMPOSITE_NOMUX(0, "atclk", "armclk", 0, RK3288_CLKSEL_CON(37), 4, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 7, GFLAGS), - COMPOSITE_NOMUX(0, "pclk_dbg_pre", "armclk", 0, + COMPOSITE_NOMUX(0, "pclk_dbg_pre", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(37), 9, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 8, GFLAGS), GATE(0, "pclk_dbg", "pclk_dbg_pre", 0, RK3288_CLKGATE_CON(12), 9, GFLAGS), - GATE(0, "cs_dbg", "pclk_dbg_pre", 0, + GATE(0, "cs_dbg", "pclk_dbg_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(12), 10, GFLAGS), GATE(0, "pclk_core_niu", "pclk_dbg_pre", 0, RK3288_CLKGATE_CON(12), 11, GFLAGS), - GATE(0, "dpll_ddr", "dpll", 0, + GATE(0, "dpll_ddr", "dpll", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 8, GFLAGS), GATE(0, "gpll_ddr", "gpll", 0, RK3288_CLKGATE_CON(0), 9, GFLAGS), - COMPOSITE_NOGATE(0, "ddrphy", mux_ddrphy_p, 0, + COMPOSITE_NOGATE(0, "ddrphy", mux_ddrphy_p, CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(26), 2, 1, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO), - GATE(0, "gpll_aclk_cpu", "gpll", 0, + GATE(0, "gpll_aclk_cpu", "gpll", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 10, GFLAGS), - GATE(0, "cpll_aclk_cpu", "cpll", 0, + GATE(0, "cpll_aclk_cpu", "cpll", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 11, GFLAGS), - COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, 0, + COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(1), 15, 1, MFLAGS, 3, 5, DFLAGS), - DIV(0, "aclk_cpu_pre", "aclk_cpu_src", 0, + DIV(0, "aclk_cpu_pre", "aclk_cpu_src", CLK_SET_RATE_PARENT, RK3288_CLKSEL_CON(1), 0, 3, DFLAGS), - GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_pre", 0, + GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 3, GFLAGS), - COMPOSITE_NOMUX(PCLK_CPU, "pclk_cpu", "aclk_cpu_pre", 0, + COMPOSITE_NOMUX(PCLK_CPU, "pclk_cpu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(1), 12, 3, DFLAGS, RK3288_CLKGATE_CON(0), 5, GFLAGS), - COMPOSITE_NOMUX_DIVTBL(HCLK_CPU, "hclk_cpu", "aclk_cpu_pre", 0, + COMPOSITE_NOMUX_DIVTBL(HCLK_CPU, "hclk_cpu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(1), 8, 2, DFLAGS, div_hclk_cpu_t, RK3288_CLKGATE_CON(0), 4, GFLAGS), GATE(0, "c2c_host", "aclk_cpu_src", 0, @@ -294,7 +297,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "crypto", "aclk_cpu_pre", 0, RK3288_CLKSEL_CON(26), 6, 2, DFLAGS, RK3288_CLKGATE_CON(5), 4, GFLAGS), - GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", 0, + GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 7, GFLAGS), COMPOSITE(0, "i2s_src", mux_pll_src_cpll_gpll_p, 0, @@ -305,7 +308,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKGATE_CON(4), 2, GFLAGS), MUX(0, "i2s_pre", mux_i2s_pre_p, CLK_SET_RATE_PARENT, RK3288_CLKSEL_CON(4), 8, 2, MFLAGS), - COMPOSITE_NODIV(0, "i2s0_clkout", mux_i2s_clkout_p, CLK_SET_RATE_PARENT, + COMPOSITE_NODIV(SCLK_I2S0_OUT, "i2s0_clkout", mux_i2s_clkout_p, 0, RK3288_CLKSEL_CON(4), 12, 1, MFLAGS, RK3288_CLKGATE_CON(4), 0, GFLAGS), GATE(SCLK_I2S0, "sclk_i2s0", "i2s_pre", CLK_SET_RATE_PARENT, @@ -325,7 +328,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "spdif_8ch_pre", "spdif_src", 0, RK3288_CLKSEL_CON(40), 0, 7, DFLAGS, RK3288_CLKGATE_CON(4), 7, GFLAGS), - COMPOSITE_FRAC(0, "spdif_8ch_frac", "spdif_8ch_src", 0, + COMPOSITE_FRAC(0, "spdif_8ch_frac", "spdif_8ch_pre", 0, RK3288_CLKSEL_CON(41), 0, RK3288_CLKGATE_CON(4), 8, GFLAGS), COMPOSITE_NODIV(SCLK_SPDIF8CH, "sclk_spdif_8ch", mux_spdif_8ch_p, 0, @@ -373,12 +376,12 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0, RK3288_CLKGATE_CON(9), 1, GFLAGS), - COMPOSITE(0, "aclk_vio0", mux_pll_src_cpll_gpll_usb480m_p, 0, + COMPOSITE(0, "aclk_vio0", mux_pll_src_cpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(31), 6, 2, MFLAGS, 0, 5, DFLAGS, RK3288_CLKGATE_CON(3), 0, GFLAGS), DIV(0, "hclk_vio", "aclk_vio0", 0, RK3288_CLKSEL_CON(28), 8, 5, DFLAGS), - COMPOSITE(0, "aclk_vio1", mux_pll_src_cpll_gpll_usb480m_p, 0, + COMPOSITE(0, "aclk_vio1", mux_pll_src_cpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(31), 14, 2, MFLAGS, 8, 5, DFLAGS, RK3288_CLKGATE_CON(3), 2, GFLAGS), @@ -436,24 +439,24 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { DIV(0, "pclk_pd_alive", "gpll", 0, RK3288_CLKSEL_CON(33), 8, 5, DFLAGS), - COMPOSITE_NOMUX(0, "pclk_pd_pmu", "gpll", 0, + COMPOSITE_NOMUX(0, "pclk_pd_pmu", "gpll", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(33), 0, 5, DFLAGS, RK3288_CLKGATE_CON(5), 8, GFLAGS), - COMPOSITE(SCLK_GPU, "sclk_gpu", mux_pll_src_cpll_gpll_usb480m_p, 0, + COMPOSITE(SCLK_GPU, "sclk_gpu", mux_pll_src_cpll_gll_usb_npll_p, 0, RK3288_CLKSEL_CON(34), 6, 2, MFLAGS, 0, 5, DFLAGS, RK3288_CLKGATE_CON(5), 7, GFLAGS), - COMPOSITE(0, "aclk_peri_src", mux_pll_src_cpll_gpll_p, 0, + COMPOSITE(0, "aclk_peri_src", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(10), 15, 1, MFLAGS, 0, 5, DFLAGS, RK3288_CLKGATE_CON(2), 0, GFLAGS), COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_src", 0, RK3288_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, RK3288_CLKGATE_CON(2), 3, GFLAGS), - COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_src", 0, + COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_src", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, RK3288_CLKGATE_CON(2), 2, GFLAGS), - GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", 0, + GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(2), 1, GFLAGS), /* @@ -483,6 +486,18 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKSEL_CON(12), 14, 2, MFLAGS, 8, 6, DFLAGS, RK3288_CLKGATE_CON(13), 3, GFLAGS), + MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RK3288_SDMMC_CON0, 1), + MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3288_SDMMC_CON1, 0), + + MMC(SCLK_SDIO0_DRV, "sdio0_drv", "sclk_sdio0", RK3288_SDIO0_CON0, 1), + MMC(SCLK_SDIO0_SAMPLE, "sdio0_sample", "sclk_sdio0", RK3288_SDIO0_CON1, 0), + + MMC(SCLK_SDIO1_DRV, "sdio1_drv", "sclk_sdio1", RK3288_SDIO1_CON0, 1), + MMC(SCLK_SDIO1_SAMPLE, "sdio1_sample", "sclk_sdio1", RK3288_SDIO1_CON1, 0), + + MMC(SCLK_EMMC_DRV, "emmc_drv", "sclk_emmc", RK3288_EMMC_CON0, 1), + MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3288_EMMC_CON1, 0), + COMPOSITE(0, "sclk_tspout", mux_tspout_p, 0, RK3288_CLKSEL_CON(35), 14, 2, MFLAGS, 8, 5, DFLAGS, RK3288_CLKGATE_CON(4), 11, GFLAGS), @@ -490,13 +505,13 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS, RK3288_CLKGATE_CON(4), 10, GFLAGS), - GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", 0, + GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 4, GFLAGS), - GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", 0, + GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 5, GFLAGS), - GATE(SCLK_OTGPHY2, "sclk_otgphy2", "usb480m", 0, + GATE(SCLK_OTGPHY2, "sclk_otgphy2", "usb480m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 6, GFLAGS), - GATE(SCLK_OTG_ADP, "sclk_otg_adp", "xin32k", 0, + GATE(SCLK_OTG_ADP, "sclk_otg_adp", "xin32k", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 7, GFLAGS), COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin32k", 0, @@ -517,7 +532,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKSEL_CON(38), 15, 1, MFLAGS, 8, 5, DFLAGS, RK3288_CLKGATE_CON(5), 6, GFLAGS), - COMPOSITE(0, "uart0_src", mux_uart0_pll_p, 0, + COMPOSITE(0, "uart0_src", mux_pll_src_cpll_gll_usb_npll_p, 0, RK3288_CLKSEL_CON(13), 13, 2, MFLAGS, 0, 7, DFLAGS, RK3288_CLKGATE_CON(1), 8, GFLAGS), COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", 0, @@ -585,7 +600,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { COMPOSITE_NODIV(0, "usbphy480m_src", mux_usbphy480m_p, 0, RK3288_CLKSEL_CON(13), 11, 2, MFLAGS, - RK3288_CLKGATE_CON(5), 15, GFLAGS), + RK3288_CLKGATE_CON(5), 14, GFLAGS), COMPOSITE_NODIV(SCLK_HSICPHY480M, "sclk_hsicphy480m", mux_hsicphy480m_p, 0, RK3288_CLKSEL_CON(29), 0, 2, MFLAGS, RK3288_CLKGATE_CON(3), 6, GFLAGS), @@ -601,19 +616,19 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { */ /* aclk_cpu gates */ - GATE(0, "sclk_intmem0", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 5, GFLAGS), - GATE(0, "sclk_intmem1", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 6, GFLAGS), - GATE(0, "sclk_intmem2", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 7, GFLAGS), + GATE(0, "sclk_intmem0", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 5, GFLAGS), + GATE(0, "sclk_intmem1", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 6, GFLAGS), + GATE(0, "sclk_intmem2", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 7, GFLAGS), GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 12, GFLAGS), - GATE(0, "aclk_strc_sys", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 13, GFLAGS), - GATE(0, "aclk_intmem", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 4, GFLAGS), + GATE(0, "aclk_strc_sys", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 13, GFLAGS), + GATE(0, "aclk_intmem", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 4, GFLAGS), GATE(ACLK_CRYPTO, "aclk_crypto", "aclk_cpu", 0, RK3288_CLKGATE_CON(11), 6, GFLAGS), GATE(0, "aclk_ccp", "aclk_cpu", 0, RK3288_CLKGATE_CON(11), 8, GFLAGS), /* hclk_cpu gates */ GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_cpu", 0, RK3288_CLKGATE_CON(11), 7, GFLAGS), GATE(HCLK_I2S0, "hclk_i2s0", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 8, GFLAGS), - GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 9, GFLAGS), + GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 9, GFLAGS), GATE(HCLK_SPDIF, "hclk_spdif", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 10, GFLAGS), GATE(HCLK_SPDIF8CH, "hclk_spdif_8ch", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 11, GFLAGS), @@ -622,42 +637,42 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { GATE(PCLK_TIMER, "pclk_timer", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 1, GFLAGS), GATE(PCLK_I2C0, "pclk_i2c0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 2, GFLAGS), GATE(PCLK_I2C2, "pclk_i2c2", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 3, GFLAGS), - GATE(0, "pclk_ddrupctl0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 14, GFLAGS), - GATE(0, "pclk_publ0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 15, GFLAGS), - GATE(0, "pclk_ddrupctl1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 0, GFLAGS), - GATE(0, "pclk_publ1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 1, GFLAGS), + GATE(PCLK_DDRUPCTL0, "pclk_ddrupctl0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 14, GFLAGS), + GATE(PCLK_PUBL0, "pclk_publ0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 15, GFLAGS), + GATE(PCLK_DDRUPCTL1, "pclk_ddrupctl1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 0, GFLAGS), + GATE(PCLK_PUBL1, "pclk_publ1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 1, GFLAGS), GATE(0, "pclk_efuse_1024", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 2, GFLAGS), GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 3, GFLAGS), GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 9, GFLAGS), GATE(0, "pclk_efuse_256", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 10, GFLAGS), - GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 11, GFLAGS), + GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 11, GFLAGS), /* ddrctrl [DDR Controller PHY clock] gates */ - GATE(0, "nclk_ddrupctl0", "ddrphy", 0, RK3288_CLKGATE_CON(11), 4, GFLAGS), - GATE(0, "nclk_ddrupctl1", "ddrphy", 0, RK3288_CLKGATE_CON(11), 5, GFLAGS), + GATE(0, "nclk_ddrupctl0", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 4, GFLAGS), + GATE(0, "nclk_ddrupctl1", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 5, GFLAGS), /* ddrphy gates */ - GATE(0, "sclk_ddrphy0", "ddrphy", 0, RK3288_CLKGATE_CON(4), 12, GFLAGS), - GATE(0, "sclk_ddrphy1", "ddrphy", 0, RK3288_CLKGATE_CON(4), 13, GFLAGS), + GATE(0, "sclk_ddrphy0", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(4), 12, GFLAGS), + GATE(0, "sclk_ddrphy1", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(4), 13, GFLAGS), /* aclk_peri gates */ - GATE(0, "aclk_peri_axi_matrix", "aclk_peri", 0, RK3288_CLKGATE_CON(6), 2, GFLAGS), + GATE(0, "aclk_peri_axi_matrix", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 2, GFLAGS), GATE(ACLK_DMAC2, "aclk_dmac2", "aclk_peri", 0, RK3288_CLKGATE_CON(6), 3, GFLAGS), - GATE(0, "aclk_peri_niu", "aclk_peri", 0, RK3288_CLKGATE_CON(7), 11, GFLAGS), - GATE(ACLK_MMU, "aclk_mmu", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 12, GFLAGS), + GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 11, GFLAGS), + GATE(ACLK_MMU, "aclk_mmu", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(8), 12, GFLAGS), GATE(ACLK_GMAC, "aclk_gmac", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 0, GFLAGS), GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 2, GFLAGS), /* hclk_peri gates */ - GATE(0, "hclk_peri_matrix", "hclk_peri", 0, RK3288_CLKGATE_CON(6), 0, GFLAGS), - GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 4, GFLAGS), + GATE(0, "hclk_peri_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 0, GFLAGS), + GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 4, GFLAGS), GATE(HCLK_USBHOST0, "hclk_host0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 6, GFLAGS), - GATE(HCLK_USBHOST1, "hclk_host1", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 7, GFLAGS), + GATE(HCLK_USBHOST1, "hclk_host1", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 7, GFLAGS), GATE(HCLK_HSIC, "hclk_hsic", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 8, GFLAGS), - GATE(0, "hclk_usb_peri", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 9, GFLAGS), - GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 10, GFLAGS), - GATE(0, "hclk_emem", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 12, GFLAGS), - GATE(0, "hclk_mem", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 13, GFLAGS), + GATE(0, "hclk_usb_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 9, GFLAGS), + GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 10, GFLAGS), + GATE(0, "hclk_emem", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 12, GFLAGS), + GATE(0, "hclk_mem", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 13, GFLAGS), GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 14, GFLAGS), GATE(HCLK_NANDC1, "hclk_nandc1", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 15, GFLAGS), GATE(HCLK_TSP, "hclk_tsp", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 8, GFLAGS), @@ -669,7 +684,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { GATE(0, "pmu_hclk_otg0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 5, GFLAGS), /* pclk_peri gates */ - GATE(0, "pclk_peri_matrix", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 1, GFLAGS), + GATE(0, "pclk_peri_matrix", "pclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 1, GFLAGS), GATE(PCLK_SPI0, "pclk_spi0", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 4, GFLAGS), GATE(PCLK_SPI1, "pclk_spi1", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 5, GFLAGS), GATE(PCLK_SPI2, "pclk_spi2", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 6, GFLAGS), @@ -705,48 +720,48 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 4, GFLAGS), GATE(PCLK_GPIO5, "pclk_gpio5", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 5, GFLAGS), GATE(PCLK_GPIO6, "pclk_gpio6", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 6, GFLAGS), - GATE(PCLK_GRF, "pclk_grf", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 11, GFLAGS), - GATE(0, "pclk_alive_niu", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 12, GFLAGS), + GATE(PCLK_GRF, "pclk_grf", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(14), 11, GFLAGS), + GATE(0, "pclk_alive_niu", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(14), 12, GFLAGS), /* pclk_pd_pmu gates */ - GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 0, GFLAGS), - GATE(0, "pclk_intmem1", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 1, GFLAGS), - GATE(0, "pclk_pmu_niu", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 2, GFLAGS), - GATE(PCLK_SGRF, "pclk_sgrf", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 3, GFLAGS), + GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 0, GFLAGS), + GATE(0, "pclk_intmem1", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 1, GFLAGS), + GATE(0, "pclk_pmu_niu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 2, GFLAGS), + GATE(PCLK_SGRF, "pclk_sgrf", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 3, GFLAGS), GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 4, GFLAGS), /* hclk_vio gates */ GATE(HCLK_RGA, "hclk_rga", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 1, GFLAGS), GATE(HCLK_VOP0, "hclk_vop0", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 6, GFLAGS), GATE(HCLK_VOP1, "hclk_vop1", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 8, GFLAGS), - GATE(HCLK_VIO_AHB_ARBI, "hclk_vio_ahb_arbi", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 9, GFLAGS), - GATE(HCLK_VIO_NIU, "hclk_vio_niu", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 10, GFLAGS), + GATE(HCLK_VIO_AHB_ARBI, "hclk_vio_ahb_arbi", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 9, GFLAGS), + GATE(HCLK_VIO_NIU, "hclk_vio_niu", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 10, GFLAGS), GATE(HCLK_VIP, "hclk_vip", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 15, GFLAGS), GATE(HCLK_IEP, "hclk_iep", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 3, GFLAGS), GATE(HCLK_ISP, "hclk_isp", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 1, GFLAGS), - GATE(HCLK_VIO2_H2P, "hclk_vio2_h2p", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 10, GFLAGS), + GATE(HCLK_VIO2_H2P, "hclk_vio2_h2p", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(16), 10, GFLAGS), GATE(PCLK_MIPI_DSI0, "pclk_mipi_dsi0", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 4, GFLAGS), GATE(PCLK_MIPI_DSI1, "pclk_mipi_dsi1", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 5, GFLAGS), GATE(PCLK_MIPI_CSI, "pclk_mipi_csi", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 6, GFLAGS), GATE(PCLK_LVDS_PHY, "pclk_lvds_phy", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 7, GFLAGS), - GATE(PCLK_EDP_CTRL, "pclk_edp_ctrl", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 8, GFLAGS), + GATE(PCLK_EDP_CTRL, "pclk_edp_ctrl", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(16), 8, GFLAGS), GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 9, GFLAGS), - GATE(PCLK_VIO2_H2P, "pclk_vio2_h2p", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 11, GFLAGS), + GATE(PCLK_VIO2_H2P, "pclk_vio2_h2p", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(16), 11, GFLAGS), /* aclk_vio0 gates */ GATE(ACLK_VOP0, "aclk_vop0", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 5, GFLAGS), GATE(ACLK_IEP, "aclk_iep", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 2, GFLAGS), - GATE(ACLK_VIO0_NIU, "aclk_vio0_niu", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 11, GFLAGS), + GATE(ACLK_VIO0_NIU, "aclk_vio0_niu", "aclk_vio0", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 11, GFLAGS), GATE(ACLK_VIP, "aclk_vip", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 14, GFLAGS), /* aclk_vio1 gates */ GATE(ACLK_VOP1, "aclk_vop1", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 7, GFLAGS), GATE(ACLK_ISP, "aclk_isp", "aclk_vio1", 0, RK3288_CLKGATE_CON(16), 2, GFLAGS), - GATE(ACLK_VIO1_NIU, "aclk_vio1_niu", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 12, GFLAGS), + GATE(ACLK_VIO1_NIU, "aclk_vio1_niu", "aclk_vio1", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 12, GFLAGS), /* aclk_rga_pre gates */ GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 0, GFLAGS), - GATE(ACLK_RGA_NIU, "aclk_rga_niu", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 13, GFLAGS), + GATE(ACLK_RGA_NIU, "aclk_rga_niu", "aclk_rga_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 13, GFLAGS), /* * Other ungrouped clocks. @@ -762,6 +777,64 @@ static const char *rk3288_critical_clocks[] __initconst = { "hclk_peri", }; +#ifdef CONFIG_PM_SLEEP +static void __iomem *rk3288_cru_base; + +/* Some CRU registers will be reset in maskrom when the system + * wakes up from fastboot. + * So save them before suspend, restore them after resume. + */ +static const int rk3288_saved_cru_reg_ids[] = { + RK3288_MODE_CON, + RK3288_CLKSEL_CON(0), + RK3288_CLKSEL_CON(1), + RK3288_CLKSEL_CON(10), + RK3288_CLKSEL_CON(33), + RK3288_CLKSEL_CON(37), +}; + +static u32 rk3288_saved_cru_regs[ARRAY_SIZE(rk3288_saved_cru_reg_ids)]; + +static int rk3288_clk_suspend(void) +{ + int i, reg_id; + + for (i = 0; i < ARRAY_SIZE(rk3288_saved_cru_reg_ids); i++) { + reg_id = rk3288_saved_cru_reg_ids[i]; + + rk3288_saved_cru_regs[i] = + readl_relaxed(rk3288_cru_base + reg_id); + } + return 0; +} + +static void rk3288_clk_resume(void) +{ + int i, reg_id; + + for (i = ARRAY_SIZE(rk3288_saved_cru_reg_ids) - 1; i >= 0; i--) { + reg_id = rk3288_saved_cru_reg_ids[i]; + + writel_relaxed(rk3288_saved_cru_regs[i] | 0xffff0000, + rk3288_cru_base + reg_id); + } +} + +static struct syscore_ops rk3288_clk_syscore_ops = { + .suspend = rk3288_clk_suspend, + .resume = rk3288_clk_resume, +}; + +static void rk3288_clk_sleep_init(void __iomem *reg_base) +{ + rk3288_cru_base = reg_base; + register_syscore_ops(&rk3288_clk_syscore_ops); +} + +#else /* CONFIG_PM_SLEEP */ +static void rk3288_clk_sleep_init(void __iomem *reg_base) {} +#endif + static void __init rk3288_clk_init(struct device_node *np) { void __iomem *reg_base; @@ -810,5 +883,6 @@ static void __init rk3288_clk_init(struct device_node *np) ROCKCHIP_SOFTRST_HIWORD_MASK); rockchip_register_restart_notifier(RK3288_GLB_SRST_FST); + rk3288_clk_sleep_init(reg_base); } CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init); diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index 880a266f0143..20e05bbb3a67 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -197,7 +197,8 @@ void __init rockchip_clk_register_plls(struct rockchip_pll_clock *list, list->parent_names, list->num_parents, reg_base, list->con_offset, grf_lock_offset, list->lock_shift, list->mode_offset, - list->mode_shift, list->rate_table, &clk_lock); + list->mode_shift, list->rate_table, + list->pll_flags, &clk_lock); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, list->name); @@ -244,9 +245,6 @@ void __init rockchip_clk_register_branches( list->div_flags, &clk_lock); break; case branch_fraction_divider: - /* keep all gates untouched for now */ - flags |= CLK_IGNORE_UNUSED; - clk = rockchip_clk_register_frac_branch(list->name, list->parent_names, list->num_parents, reg_base, list->muxdiv_offset, list->div_flags, @@ -256,18 +254,12 @@ void __init rockchip_clk_register_branches( case branch_gate: flags |= CLK_SET_RATE_PARENT; - /* keep all gates untouched for now */ - flags |= CLK_IGNORE_UNUSED; - clk = clk_register_gate(NULL, list->name, list->parent_names[0], flags, reg_base + list->gate_offset, list->gate_shift, list->gate_flags, &clk_lock); break; case branch_composite: - /* keep all gates untouched for now */ - flags |= CLK_IGNORE_UNUSED; - clk = rockchip_clk_register_branch(list->name, list->parent_names, list->num_parents, reg_base, list->muxdiv_offset, list->mux_shift, @@ -277,6 +269,14 @@ void __init rockchip_clk_register_branches( list->gate_offset, list->gate_shift, list->gate_flags, flags, &clk_lock); break; + case branch_mmc: + clk = rockchip_clk_register_mmc( + list->name, + list->parent_names, list->num_parents, + reg_base + list->muxdiv_offset, + list->div_shift + ); + break; } /* none of the cases above matched */ diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index ca009ab0a33a..58d2e3bdf22f 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -48,6 +48,14 @@ #define RK3288_GLB_SRST_SND 0x1b4 #define RK3288_SOFTRST_CON(x) (x * 0x4 + 0x1b8) #define RK3288_MISC_CON 0x1e8 +#define RK3288_SDMMC_CON0 0x200 +#define RK3288_SDMMC_CON1 0x204 +#define RK3288_SDIO0_CON0 0x208 +#define RK3288_SDIO0_CON1 0x20c +#define RK3288_SDIO1_CON0 0x210 +#define RK3288_SDIO1_CON1 0x214 +#define RK3288_EMMC_CON0 0x218 +#define RK3288_EMMC_CON1 0x21c enum rockchip_pll_type { pll_rk3066, @@ -62,6 +70,15 @@ enum rockchip_pll_type { .bwadj = (_nf >> 1), \ } +#define RK3066_PLL_RATE_BWADJ(_rate, _nr, _nf, _no, _bw) \ +{ \ + .rate = _rate##U, \ + .nr = _nr, \ + .nf = _nf, \ + .no = _no, \ + .bwadj = _bw, \ +} + struct rockchip_pll_rate_table { unsigned long rate; unsigned int nr; @@ -81,7 +98,12 @@ struct rockchip_pll_rate_table { * @mode_shift: offset inside the mode-register for the mode of this pll. * @lock_shift: offset inside the lock register for the lock status. * @type: Type of PLL to be registered. + * @pll_flags: hardware-specific flags * @rate_table: Table of usable pll rates + * + * Flags: + * ROCKCHIP_PLL_SYNC_RATE - check rate parameters to match against the + * rate_table parameters and ajust them if necessary. */ struct rockchip_pll_clock { unsigned int id; @@ -94,11 +116,14 @@ struct rockchip_pll_clock { int mode_shift; int lock_shift; enum rockchip_pll_type type; + u8 pll_flags; struct rockchip_pll_rate_table *rate_table; }; +#define ROCKCHIP_PLL_SYNC_RATE BIT(0) + #define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift, \ - _lshift, _rtable) \ + _lshift, _pflags, _rtable) \ { \ .id = _id, \ .type = _type, \ @@ -110,6 +135,7 @@ struct rockchip_pll_clock { .mode_offset = _mode, \ .mode_shift = _mshift, \ .lock_shift = _lshift, \ + .pll_flags = _pflags, \ .rate_table = _rtable, \ } @@ -118,7 +144,7 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, void __iomem *base, int con_offset, int grf_lock_offset, int lock_shift, int reg_mode, int mode_shift, struct rockchip_pll_rate_table *rate_table, - spinlock_t *lock); + u8 clk_pll_flags, spinlock_t *lock); struct rockchip_cpuclk_clksel { int reg; @@ -152,6 +178,10 @@ struct clk *rockchip_clk_register_cpuclk(const char *name, const struct rockchip_cpuclk_rate_table *rates, int nrates, void __iomem *reg_base, spinlock_t *lock); +struct clk *rockchip_clk_register_mmc(const char *name, + const char **parent_names, u8 num_parents, + void __iomem *reg, int shift); + #define PNAME(x) static const char *x[] __initconst enum rockchip_clk_branch_type { @@ -160,6 +190,7 @@ enum rockchip_clk_branch_type { branch_divider, branch_fraction_divider, branch_gate, + branch_mmc, }; struct rockchip_clk_branch { @@ -352,6 +383,16 @@ struct rockchip_clk_branch { .gate_flags = gf, \ } +#define MMC(_id, cname, pname, offset, shift) \ + { \ + .id = _id, \ + .branch_type = branch_mmc, \ + .name = cname, \ + .parent_names = (const char *[]){ pname }, \ + .num_parents = 1, \ + .muxdiv_offset = offset, \ + .div_shift = shift, \ + } void rockchip_clk_init(struct device_node *np, void __iomem *base, unsigned long nr_clks); diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile index 6fb4bc602e8a..006c6f294310 100644 --- a/drivers/clk/samsung/Makefile +++ b/drivers/clk/samsung/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o obj-$(CONFIG_SOC_EXYNOS3250) += clk-exynos3250.o obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o +obj-$(CONFIG_SOC_EXYNOS4415) += clk-exynos4415.o obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o @@ -12,6 +13,7 @@ obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-clkout.o +obj-$(CONFIG_ARCH_EXYNOS7) += clk-exynos7.o obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c index acce708ace18..f2c2ccce49bb 100644 --- a/drivers/clk/samsung/clk-exynos-audss.c +++ b/drivers/clk/samsung/clk-exynos-audss.c @@ -29,6 +29,13 @@ static DEFINE_SPINLOCK(lock); static struct clk **clk_table; static void __iomem *reg_base; static struct clk_onecell_data clk_data; +/* + * On Exynos5420 this will be a clock which has to be enabled before any + * access to audss registers. Typically a child of EPLL. + * + * On other platforms this will be -ENODEV. + */ +static struct clk *epll; #define ASS_CLK_SRC 0x0 #define ASS_CLK_DIV 0x4 @@ -98,6 +105,8 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) dev_err(&pdev->dev, "failed to map audss registers\n"); return PTR_ERR(reg_base); } + /* EPLL don't have to be enabled for boards other than Exynos5420 */ + epll = ERR_PTR(-ENODEV); clk_table = devm_kzalloc(&pdev->dev, sizeof(struct clk *) * EXYNOS_AUDSS_MAX_CLKS, @@ -115,8 +124,20 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) pll_in = devm_clk_get(&pdev->dev, "pll_in"); if (!IS_ERR(pll_ref)) mout_audss_p[0] = __clk_get_name(pll_ref); - if (!IS_ERR(pll_in)) + if (!IS_ERR(pll_in)) { mout_audss_p[1] = __clk_get_name(pll_in); + + if (variant == TYPE_EXYNOS5420) { + epll = pll_in; + + ret = clk_prepare_enable(epll); + if (ret) { + dev_err(&pdev->dev, + "failed to prepare the epll clock\n"); + return ret; + } + } + } clk_table[EXYNOS_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss", mout_audss_p, ARRAY_SIZE(mout_audss_p), CLK_SET_RATE_NO_REPARENT, @@ -203,6 +224,9 @@ unregister: clk_unregister(clk_table[i]); } + if (!IS_ERR(epll)) + clk_disable_unprepare(epll); + return ret; } @@ -210,6 +234,10 @@ static int exynos_audss_clk_remove(struct platform_device *pdev) { int i; +#ifdef CONFIG_PM_SLEEP + unregister_syscore_ops(&exynos_audss_clk_syscore_ops); +#endif + of_clk_del_provider(pdev->dev.of_node); for (i = 0; i < clk_data.clk_num; i++) { @@ -217,6 +245,9 @@ static int exynos_audss_clk_remove(struct platform_device *pdev) clk_unregister(clk_table[i]); } + if (!IS_ERR(epll)) + clk_disable_unprepare(epll); + return 0; } diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 940f02837b82..88e8c6bbd77f 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -505,7 +505,7 @@ static struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] __initdata /* fixed rate clocks generated inside the soc */ static struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] __initdata = { FRATE(0, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000), - FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000), + FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", "hdmi", 0, 27000000), FRATE(0, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000), }; diff --git a/drivers/clk/samsung/clk-exynos4415.c b/drivers/clk/samsung/clk-exynos4415.c new file mode 100644 index 000000000000..2123fc251e0f --- /dev/null +++ b/drivers/clk/samsung/clk-exynos4415.c @@ -0,0 +1,1144 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Author: Chanwoo Choi <cw00.choi@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Common Clock Framework support for Exynos4415 SoC. + */ + +#include <linux/clk.h> +#include <linux/clkdev.h> +#include <linux/clk-provider.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/platform_device.h> +#include <linux/syscore_ops.h> + +#include <dt-bindings/clock/exynos4415.h> + +#include "clk.h" +#include "clk-pll.h" + +#define SRC_LEFTBUS 0x4200 +#define DIV_LEFTBUS 0x4500 +#define GATE_IP_LEFTBUS 0x4800 +#define GATE_IP_IMAGE 0x4930 +#define SRC_RIGHTBUS 0x8200 +#define DIV_RIGHTBUS 0x8500 +#define GATE_IP_RIGHTBUS 0x8800 +#define GATE_IP_PERIR 0x8960 +#define EPLL_LOCK 0xc010 +#define G3D_PLL_LOCK 0xc020 +#define DISP_PLL_LOCK 0xc030 +#define ISP_PLL_LOCK 0xc040 +#define EPLL_CON0 0xc110 +#define EPLL_CON1 0xc114 +#define EPLL_CON2 0xc118 +#define G3D_PLL_CON0 0xc120 +#define G3D_PLL_CON1 0xc124 +#define G3D_PLL_CON2 0xc128 +#define ISP_PLL_CON0 0xc130 +#define ISP_PLL_CON1 0xc134 +#define ISP_PLL_CON2 0xc138 +#define DISP_PLL_CON0 0xc140 +#define DISP_PLL_CON1 0xc144 +#define DISP_PLL_CON2 0xc148 +#define SRC_TOP0 0xc210 +#define SRC_TOP1 0xc214 +#define SRC_CAM 0xc220 +#define SRC_TV 0xc224 +#define SRC_MFC 0xc228 +#define SRC_G3D 0xc22c +#define SRC_LCD 0xc234 +#define SRC_ISP 0xc238 +#define SRC_MAUDIO 0xc23c +#define SRC_FSYS 0xc240 +#define SRC_PERIL0 0xc250 +#define SRC_PERIL1 0xc254 +#define SRC_CAM1 0xc258 +#define SRC_TOP_ISP0 0xc25c +#define SRC_TOP_ISP1 0xc260 +#define SRC_MASK_TOP 0xc310 +#define SRC_MASK_CAM 0xc320 +#define SRC_MASK_TV 0xc324 +#define SRC_MASK_LCD 0xc334 +#define SRC_MASK_ISP 0xc338 +#define SRC_MASK_MAUDIO 0xc33c +#define SRC_MASK_FSYS 0xc340 +#define SRC_MASK_PERIL0 0xc350 +#define SRC_MASK_PERIL1 0xc354 +#define DIV_TOP 0xc510 +#define DIV_CAM 0xc520 +#define DIV_TV 0xc524 +#define DIV_MFC 0xc528 +#define DIV_G3D 0xc52c +#define DIV_LCD 0xc534 +#define DIV_ISP 0xc538 +#define DIV_MAUDIO 0xc53c +#define DIV_FSYS0 0xc540 +#define DIV_FSYS1 0xc544 +#define DIV_FSYS2 0xc548 +#define DIV_PERIL0 0xc550 +#define DIV_PERIL1 0xc554 +#define DIV_PERIL2 0xc558 +#define DIV_PERIL3 0xc55c +#define DIV_PERIL4 0xc560 +#define DIV_PERIL5 0xc564 +#define DIV_CAM1 0xc568 +#define DIV_TOP_ISP1 0xc56c +#define DIV_TOP_ISP0 0xc570 +#define CLKDIV2_RATIO 0xc580 +#define GATE_SCLK_CAM 0xc820 +#define GATE_SCLK_TV 0xc824 +#define GATE_SCLK_MFC 0xc828 +#define GATE_SCLK_G3D 0xc82c +#define GATE_SCLK_LCD 0xc834 +#define GATE_SCLK_MAUDIO 0xc83c +#define GATE_SCLK_FSYS 0xc840 +#define GATE_SCLK_PERIL 0xc850 +#define GATE_IP_CAM 0xc920 +#define GATE_IP_TV 0xc924 +#define GATE_IP_MFC 0xc928 +#define GATE_IP_G3D 0xc92c +#define GATE_IP_LCD 0xc934 +#define GATE_IP_FSYS 0xc940 +#define GATE_IP_PERIL 0xc950 +#define GATE_BLOCK 0xc970 +#define APLL_LOCK 0x14000 +#define APLL_CON0 0x14100 +#define SRC_CPU 0x14200 +#define DIV_CPU0 0x14500 +#define DIV_CPU1 0x14504 + +enum exynos4415_plls { + apll, epll, g3d_pll, isp_pll, disp_pll, + nr_plls, +}; + +static struct samsung_clk_provider *exynos4415_ctx; + +/* + * Support for CMU save/restore across system suspends + */ +#ifdef CONFIG_PM_SLEEP +static struct samsung_clk_reg_dump *exynos4415_clk_regs; + +static unsigned long exynos4415_cmu_clk_regs[] __initdata = { + SRC_LEFTBUS, + DIV_LEFTBUS, + GATE_IP_LEFTBUS, + GATE_IP_IMAGE, + SRC_RIGHTBUS, + DIV_RIGHTBUS, + GATE_IP_RIGHTBUS, + GATE_IP_PERIR, + EPLL_LOCK, + G3D_PLL_LOCK, + DISP_PLL_LOCK, + ISP_PLL_LOCK, + EPLL_CON0, + EPLL_CON1, + EPLL_CON2, + G3D_PLL_CON0, + G3D_PLL_CON1, + G3D_PLL_CON2, + ISP_PLL_CON0, + ISP_PLL_CON1, + ISP_PLL_CON2, + DISP_PLL_CON0, + DISP_PLL_CON1, + DISP_PLL_CON2, + SRC_TOP0, + SRC_TOP1, + SRC_CAM, + SRC_TV, + SRC_MFC, + SRC_G3D, + SRC_LCD, + SRC_ISP, + SRC_MAUDIO, + SRC_FSYS, + SRC_PERIL0, + SRC_PERIL1, + SRC_CAM1, + SRC_TOP_ISP0, + SRC_TOP_ISP1, + SRC_MASK_TOP, + SRC_MASK_CAM, + SRC_MASK_TV, + SRC_MASK_LCD, + SRC_MASK_ISP, + SRC_MASK_MAUDIO, + SRC_MASK_FSYS, + SRC_MASK_PERIL0, + SRC_MASK_PERIL1, + DIV_TOP, + DIV_CAM, + DIV_TV, + DIV_MFC, + DIV_G3D, + DIV_LCD, + DIV_ISP, + DIV_MAUDIO, + DIV_FSYS0, + DIV_FSYS1, + DIV_FSYS2, + DIV_PERIL0, + DIV_PERIL1, + DIV_PERIL2, + DIV_PERIL3, + DIV_PERIL4, + DIV_PERIL5, + DIV_CAM1, + DIV_TOP_ISP1, + DIV_TOP_ISP0, + CLKDIV2_RATIO, + GATE_SCLK_CAM, + GATE_SCLK_TV, + GATE_SCLK_MFC, + GATE_SCLK_G3D, + GATE_SCLK_LCD, + GATE_SCLK_MAUDIO, + GATE_SCLK_FSYS, + GATE_SCLK_PERIL, + GATE_IP_CAM, + GATE_IP_TV, + GATE_IP_MFC, + GATE_IP_G3D, + GATE_IP_LCD, + GATE_IP_FSYS, + GATE_IP_PERIL, + GATE_BLOCK, + APLL_LOCK, + APLL_CON0, + SRC_CPU, + DIV_CPU0, + DIV_CPU1, +}; + +static int exynos4415_clk_suspend(void) +{ + samsung_clk_save(exynos4415_ctx->reg_base, exynos4415_clk_regs, + ARRAY_SIZE(exynos4415_cmu_clk_regs)); + + return 0; +} + +static void exynos4415_clk_resume(void) +{ + samsung_clk_restore(exynos4415_ctx->reg_base, exynos4415_clk_regs, + ARRAY_SIZE(exynos4415_cmu_clk_regs)); +} + +static struct syscore_ops exynos4415_clk_syscore_ops = { + .suspend = exynos4415_clk_suspend, + .resume = exynos4415_clk_resume, +}; + +static void exynos4415_clk_sleep_init(void) +{ + exynos4415_clk_regs = + samsung_clk_alloc_reg_dump(exynos4415_cmu_clk_regs, + ARRAY_SIZE(exynos4415_cmu_clk_regs)); + if (!exynos4415_clk_regs) { + pr_warn("%s: Failed to allocate sleep save data\n", __func__); + return; + } + + register_syscore_ops(&exynos4415_clk_syscore_ops); +} +#else +static inline void exynos4415_clk_sleep_init(void) { } +#endif + +/* list of all parent clock list */ +PNAME(mout_g3d_pllsrc_p) = { "fin_pll", }; + +PNAME(mout_apll_p) = { "fin_pll", "fout_apll", }; +PNAME(mout_g3d_pll_p) = { "fin_pll", "fout_g3d_pll", }; +PNAME(mout_isp_pll_p) = { "fin_pll", "fout_isp_pll", }; +PNAME(mout_disp_pll_p) = { "fin_pll", "fout_disp_pll", }; + +PNAME(mout_mpll_user_p) = { "fin_pll", "div_mpll_pre", }; +PNAME(mout_epll_p) = { "fin_pll", "fout_epll", }; +PNAME(mout_core_p) = { "mout_apll", "mout_mpll_user_c", }; +PNAME(mout_hpm_p) = { "mout_apll", "mout_mpll_user_c", }; + +PNAME(mout_ebi_p) = { "div_aclk_200", "div_aclk_160", }; +PNAME(mout_ebi_1_p) = { "mout_ebi", "mout_g3d_pll", }; + +PNAME(mout_gdl_p) = { "mout_mpll_user_l", }; +PNAME(mout_gdr_p) = { "mout_mpll_user_r", }; + +PNAME(mout_aclk_266_p) = { "mout_mpll_user_t", "mout_g3d_pll", }; + +PNAME(group_epll_g3dpll_p) = { "mout_epll", "mout_g3d_pll" }; +PNAME(group_sclk_p) = { "xxti", "xusbxti", + "none", "mout_isp_pll", + "none", "none", "div_mpll_pre", + "mout_epll", "mout_g3d_pll", }; +PNAME(group_spdif_p) = { "mout_audio0", "mout_audio1", + "mout_audio2", "spdif_extclk", }; +PNAME(group_sclk_audio2_p) = { "audiocdclk2", "none", + "none", "mout_isp_pll", + "mout_disp_pll", "xusbxti", + "div_mpll_pre", "mout_epll", + "mout_g3d_pll", }; +PNAME(group_sclk_audio1_p) = { "audiocdclk1", "none", + "none", "mout_isp_pll", + "mout_disp_pll", "xusbxti", + "div_mpll_pre", "mout_epll", + "mout_g3d_pll", }; +PNAME(group_sclk_audio0_p) = { "audiocdclk0", "none", + "none", "mout_isp_pll", + "mout_disp_pll", "xusbxti", + "div_mpll_pre", "mout_epll", + "mout_g3d_pll", }; +PNAME(group_fimc_lclk_p) = { "xxti", "xusbxti", + "none", "mout_isp_pll", + "none", "mout_disp_pll", + "mout_mpll_user_t", "mout_epll", + "mout_g3d_pll", }; +PNAME(group_sclk_fimd0_p) = { "xxti", "xusbxti", + "m_bitclkhsdiv4_4l", "mout_isp_pll", + "mout_disp_pll", "sclk_hdmiphy", + "div_mpll_pre", "mout_epll", + "mout_g3d_pll", }; +PNAME(mout_hdmi_p) = { "sclk_pixel", "sclk_hdmiphy" }; +PNAME(mout_mfc_p) = { "mout_mfc_0", "mout_mfc_1" }; +PNAME(mout_g3d_p) = { "mout_g3d_0", "mout_g3d_1" }; +PNAME(mout_jpeg_p) = { "mout_jpeg_0", "mout_jpeg_1" }; +PNAME(mout_jpeg1_p) = { "mout_epll", "mout_g3d_pll" }; +PNAME(group_aclk_isp0_300_p) = { "mout_isp_pll", "div_mpll_pre" }; +PNAME(group_aclk_isp0_400_user_p) = { "fin_pll", "div_aclk_400_mcuisp" }; +PNAME(group_aclk_isp0_300_user_p) = { "fin_pll", "mout_aclk_isp0_300" }; +PNAME(group_aclk_isp1_300_user_p) = { "fin_pll", "mout_aclk_isp1_300" }; +PNAME(group_mout_mpll_user_t_p) = { "mout_mpll_user_t" }; + +static struct samsung_fixed_factor_clock exynos4415_fixed_factor_clks[] __initdata = { + /* HACK: fin_pll hardcoded to xusbxti until detection is implemented. */ + FFACTOR(CLK_FIN_PLL, "fin_pll", "xusbxti", 1, 1, 0), +}; + +static struct samsung_fixed_rate_clock exynos4415_fixed_rate_clks[] __initdata = { + FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000), +}; + +static struct samsung_mux_clock exynos4415_mux_clks[] __initdata = { + /* + * NOTE: Following table is sorted by register address in ascending + * order and then bitfield shift in descending order, as it is done + * in the User's Manual. When adding new entries, please make sure + * that the order is preserved, to avoid merge conflicts and make + * further work with defined data easier. + */ + + /* SRC_LEFTBUS */ + MUX(CLK_MOUT_MPLL_USER_L, "mout_mpll_user_l", mout_mpll_user_p, + SRC_LEFTBUS, 4, 1), + MUX(CLK_MOUT_GDL, "mout_gdl", mout_gdl_p, SRC_LEFTBUS, 0, 1), + + /* SRC_RIGHTBUS */ + MUX(CLK_MOUT_MPLL_USER_R, "mout_mpll_user_r", mout_mpll_user_p, + SRC_RIGHTBUS, 4, 1), + MUX(CLK_MOUT_GDR, "mout_gdr", mout_gdr_p, SRC_RIGHTBUS, 0, 1), + + /* SRC_TOP0 */ + MUX(CLK_MOUT_EBI, "mout_ebi", mout_ebi_p, SRC_TOP0, 28, 1), + MUX(CLK_MOUT_ACLK_200, "mout_aclk_200", group_mout_mpll_user_t_p, + SRC_TOP0, 24, 1), + MUX(CLK_MOUT_ACLK_160, "mout_aclk_160", group_mout_mpll_user_t_p, + SRC_TOP0, 20, 1), + MUX(CLK_MOUT_ACLK_100, "mout_aclk_100", group_mout_mpll_user_t_p, + SRC_TOP0, 16, 1), + MUX(CLK_MOUT_ACLK_266, "mout_aclk_266", mout_aclk_266_p, + SRC_TOP0, 12, 1), + MUX(CLK_MOUT_G3D_PLL, "mout_g3d_pll", mout_g3d_pll_p, + SRC_TOP0, 8, 1), + MUX(CLK_MOUT_EPLL, "mout_epll", mout_epll_p, SRC_TOP0, 4, 1), + MUX(CLK_MOUT_EBI_1, "mout_ebi_1", mout_ebi_1_p, SRC_TOP0, 0, 1), + + /* SRC_TOP1 */ + MUX(CLK_MOUT_ISP_PLL, "mout_isp_pll", mout_isp_pll_p, + SRC_TOP1, 28, 1), + MUX(CLK_MOUT_DISP_PLL, "mout_disp_pll", mout_disp_pll_p, + SRC_TOP1, 16, 1), + MUX(CLK_MOUT_MPLL_USER_T, "mout_mpll_user_t", mout_mpll_user_p, + SRC_TOP1, 12, 1), + MUX(CLK_MOUT_ACLK_400_MCUISP, "mout_aclk_400_mcuisp", + group_mout_mpll_user_t_p, SRC_TOP1, 8, 1), + MUX(CLK_MOUT_G3D_PLLSRC, "mout_g3d_pllsrc", mout_g3d_pllsrc_p, + SRC_TOP1, 0, 1), + + /* SRC_CAM */ + MUX(CLK_MOUT_CSIS1, "mout_csis1", group_fimc_lclk_p, SRC_CAM, 28, 4), + MUX(CLK_MOUT_CSIS0, "mout_csis0", group_fimc_lclk_p, SRC_CAM, 24, 4), + MUX(CLK_MOUT_CAM1, "mout_cam1", group_fimc_lclk_p, SRC_CAM, 20, 4), + MUX(CLK_MOUT_FIMC3_LCLK, "mout_fimc3_lclk", group_fimc_lclk_p, SRC_CAM, + 12, 4), + MUX(CLK_MOUT_FIMC2_LCLK, "mout_fimc2_lclk", group_fimc_lclk_p, SRC_CAM, + 8, 4), + MUX(CLK_MOUT_FIMC1_LCLK, "mout_fimc1_lclk", group_fimc_lclk_p, SRC_CAM, + 4, 4), + MUX(CLK_MOUT_FIMC0_LCLK, "mout_fimc0_lclk", group_fimc_lclk_p, SRC_CAM, + 0, 4), + + /* SRC_TV */ + MUX(CLK_MOUT_HDMI, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1), + + /* SRC_MFC */ + MUX(CLK_MOUT_MFC, "mout_mfc", mout_mfc_p, SRC_MFC, 8, 1), + MUX(CLK_MOUT_MFC_1, "mout_mfc_1", group_epll_g3dpll_p, SRC_MFC, 4, 1), + MUX(CLK_MOUT_MFC_0, "mout_mfc_0", group_mout_mpll_user_t_p, SRC_MFC, 0, + 1), + + /* SRC_G3D */ + MUX(CLK_MOUT_G3D, "mout_g3d", mout_g3d_p, SRC_G3D, 8, 1), + MUX(CLK_MOUT_G3D_1, "mout_g3d_1", group_epll_g3dpll_p, SRC_G3D, 4, 1), + MUX(CLK_MOUT_G3D_0, "mout_g3d_0", group_mout_mpll_user_t_p, SRC_G3D, 0, + 1), + + /* SRC_LCD */ + MUX(CLK_MOUT_MIPI0, "mout_mipi0", group_fimc_lclk_p, SRC_LCD, 12, 4), + MUX(CLK_MOUT_FIMD0, "mout_fimd0", group_sclk_fimd0_p, SRC_LCD, 0, 4), + + /* SRC_ISP */ + MUX(CLK_MOUT_TSADC_ISP, "mout_tsadc_isp", group_fimc_lclk_p, SRC_ISP, + 16, 4), + MUX(CLK_MOUT_UART_ISP, "mout_uart_isp", group_fimc_lclk_p, SRC_ISP, + 12, 4), + MUX(CLK_MOUT_SPI1_ISP, "mout_spi1_isp", group_fimc_lclk_p, SRC_ISP, + 8, 4), + MUX(CLK_MOUT_SPI0_ISP, "mout_spi0_isp", group_fimc_lclk_p, SRC_ISP, + 4, 4), + MUX(CLK_MOUT_PWM_ISP, "mout_pwm_isp", group_fimc_lclk_p, SRC_ISP, + 0, 4), + + /* SRC_MAUDIO */ + MUX(CLK_MOUT_AUDIO0, "mout_audio0", group_sclk_audio0_p, SRC_MAUDIO, + 0, 4), + + /* SRC_FSYS */ + MUX(CLK_MOUT_TSADC, "mout_tsadc", group_sclk_p, SRC_FSYS, 28, 4), + MUX(CLK_MOUT_MMC2, "mout_mmc2", group_sclk_p, SRC_FSYS, 8, 4), + MUX(CLK_MOUT_MMC1, "mout_mmc1", group_sclk_p, SRC_FSYS, 4, 4), + MUX(CLK_MOUT_MMC0, "mout_mmc0", group_sclk_p, SRC_FSYS, 0, 4), + + /* SRC_PERIL0 */ + MUX(CLK_MOUT_UART3, "mout_uart3", group_sclk_p, SRC_PERIL0, 12, 4), + MUX(CLK_MOUT_UART2, "mout_uart2", group_sclk_p, SRC_PERIL0, 8, 4), + MUX(CLK_MOUT_UART1, "mout_uart1", group_sclk_p, SRC_PERIL0, 4, 4), + MUX(CLK_MOUT_UART0, "mout_uart0", group_sclk_p, SRC_PERIL0, 0, 4), + + /* SRC_PERIL1 */ + MUX(CLK_MOUT_SPI2, "mout_spi2", group_sclk_p, SRC_PERIL1, 24, 4), + MUX(CLK_MOUT_SPI1, "mout_spi1", group_sclk_p, SRC_PERIL1, 20, 4), + MUX(CLK_MOUT_SPI0, "mout_spi0", group_sclk_p, SRC_PERIL1, 16, 4), + MUX(CLK_MOUT_SPDIF, "mout_spdif", group_spdif_p, SRC_PERIL1, 8, 4), + MUX(CLK_MOUT_AUDIO2, "mout_audio2", group_sclk_audio2_p, SRC_PERIL1, + 4, 4), + MUX(CLK_MOUT_AUDIO1, "mout_audio1", group_sclk_audio1_p, SRC_PERIL1, + 0, 4), + + /* SRC_CPU */ + MUX(CLK_MOUT_MPLL_USER_C, "mout_mpll_user_c", mout_mpll_user_p, + SRC_CPU, 24, 1), + MUX(CLK_MOUT_HPM, "mout_hpm", mout_hpm_p, SRC_CPU, 20, 1), + MUX_F(CLK_MOUT_CORE, "mout_core", mout_core_p, SRC_CPU, 16, 1, 0, + CLK_MUX_READ_ONLY), + MUX_F(CLK_MOUT_APLL, "mout_apll", mout_apll_p, SRC_CPU, 0, 1, + CLK_SET_RATE_PARENT, 0), + + /* SRC_CAM1 */ + MUX(CLK_MOUT_PXLASYNC_CSIS1_FIMC, "mout_pxlasync_csis1", + group_fimc_lclk_p, SRC_CAM1, 20, 1), + MUX(CLK_MOUT_PXLASYNC_CSIS0_FIMC, "mout_pxlasync_csis0", + group_fimc_lclk_p, SRC_CAM1, 16, 1), + MUX(CLK_MOUT_JPEG, "mout_jpeg", mout_jpeg_p, SRC_CAM1, 8, 1), + MUX(CLK_MOUT_JPEG1, "mout_jpeg_1", mout_jpeg1_p, SRC_CAM1, 4, 1), + MUX(CLK_MOUT_JPEG0, "mout_jpeg_0", group_mout_mpll_user_t_p, SRC_CAM1, + 0, 1), + + /* SRC_TOP_ISP0 */ + MUX(CLK_MOUT_ACLK_ISP0_300, "mout_aclk_isp0_300", + group_aclk_isp0_300_p, SRC_TOP_ISP0, 8, 1), + MUX(CLK_MOUT_ACLK_ISP0_400, "mout_aclk_isp0_400_user", + group_aclk_isp0_400_user_p, SRC_TOP_ISP0, 4, 1), + MUX(CLK_MOUT_ACLK_ISP0_300_USER, "mout_aclk_isp0_300_user", + group_aclk_isp0_300_user_p, SRC_TOP_ISP0, 0, 1), + + /* SRC_TOP_ISP1 */ + MUX(CLK_MOUT_ACLK_ISP1_300, "mout_aclk_isp1_300", + group_aclk_isp0_300_p, SRC_TOP_ISP1, 4, 1), + MUX(CLK_MOUT_ACLK_ISP1_300_USER, "mout_aclk_isp1_300_user", + group_aclk_isp1_300_user_p, SRC_TOP_ISP1, 0, 1), +}; + +static struct samsung_div_clock exynos4415_div_clks[] __initdata = { + /* + * NOTE: Following table is sorted by register address in ascending + * order and then bitfield shift in descending order, as it is done + * in the User's Manual. When adding new entries, please make sure + * that the order is preserved, to avoid merge conflicts and make + * further work with defined data easier. + */ + + /* DIV_LEFTBUS */ + DIV(CLK_DIV_GPL, "div_gpl", "div_gdl", DIV_LEFTBUS, 4, 3), + DIV(CLK_DIV_GDL, "div_gdl", "mout_gdl", DIV_LEFTBUS, 0, 4), + + /* DIV_RIGHTBUS */ + DIV(CLK_DIV_GPR, "div_gpr", "div_gdr", DIV_RIGHTBUS, 4, 3), + DIV(CLK_DIV_GDR, "div_gdr", "mout_gdr", DIV_RIGHTBUS, 0, 4), + + /* DIV_TOP */ + DIV(CLK_DIV_ACLK_400_MCUISP, "div_aclk_400_mcuisp", + "mout_aclk_400_mcuisp", DIV_TOP, 24, 3), + DIV(CLK_DIV_EBI, "div_ebi", "mout_ebi_1", DIV_TOP, 16, 3), + DIV(CLK_DIV_ACLK_200, "div_aclk_200", "mout_aclk_200", DIV_TOP, 12, 3), + DIV(CLK_DIV_ACLK_160, "div_aclk_160", "mout_aclk_160", DIV_TOP, 8, 3), + DIV(CLK_DIV_ACLK_100, "div_aclk_100", "mout_aclk_100", DIV_TOP, 4, 4), + DIV(CLK_DIV_ACLK_266, "div_aclk_266", "mout_aclk_266", DIV_TOP, 0, 3), + + /* DIV_CAM */ + DIV(CLK_DIV_CSIS1, "div_csis1", "mout_csis1", DIV_CAM, 28, 4), + DIV(CLK_DIV_CSIS0, "div_csis0", "mout_csis0", DIV_CAM, 24, 4), + DIV(CLK_DIV_CAM1, "div_cam1", "mout_cam1", DIV_CAM, 20, 4), + DIV(CLK_DIV_FIMC3_LCLK, "div_fimc3_lclk", "mout_fimc3_lclk", DIV_CAM, + 12, 4), + DIV(CLK_DIV_FIMC2_LCLK, "div_fimc2_lclk", "mout_fimc2_lclk", DIV_CAM, + 8, 4), + DIV(CLK_DIV_FIMC1_LCLK, "div_fimc1_lclk", "mout_fimc1_lclk", DIV_CAM, + 4, 4), + DIV(CLK_DIV_FIMC0_LCLK, "div_fimc0_lclk", "mout_fimc0_lclk", DIV_CAM, + 0, 4), + + /* DIV_TV */ + DIV(CLK_DIV_TV_BLK, "div_tv_blk", "mout_g3d_pll", DIV_TV, 0, 4), + + /* DIV_MFC */ + DIV(CLK_DIV_MFC, "div_mfc", "mout_mfc", DIV_MFC, 0, 4), + + /* DIV_G3D */ + DIV(CLK_DIV_G3D, "div_g3d", "mout_g3d", DIV_G3D, 0, 4), + + /* DIV_LCD */ + DIV_F(CLK_DIV_MIPI0_PRE, "div_mipi0_pre", "div_mipi0", DIV_LCD, 20, 4, + CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_MIPI0, "div_mipi0", "mout_mipi0", DIV_LCD, 16, 4), + DIV(CLK_DIV_FIMD0, "div_fimd0", "mout_fimd0", DIV_LCD, 0, 4), + + /* DIV_ISP */ + DIV(CLK_DIV_UART_ISP, "div_uart_isp", "mout_uart_isp", DIV_ISP, 28, 4), + DIV_F(CLK_DIV_SPI1_ISP_PRE, "div_spi1_isp_pre", "div_spi1_isp", + DIV_ISP, 20, 8, CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_SPI1_ISP, "div_spi1_isp", "mout_spi1_isp", DIV_ISP, 16, 4), + DIV_F(CLK_DIV_SPI0_ISP_PRE, "div_spi0_isp_pre", "div_spi0_isp", + DIV_ISP, 8, 8, CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_SPI0_ISP, "div_spi0_isp", "mout_spi0_isp", DIV_ISP, 4, 4), + DIV(CLK_DIV_PWM_ISP, "div_pwm_isp", "mout_pwm_isp", DIV_ISP, 0, 4), + + /* DIV_MAUDIO */ + DIV(CLK_DIV_PCM0, "div_pcm0", "div_audio0", DIV_MAUDIO, 4, 8), + DIV(CLK_DIV_AUDIO0, "div_audio0", "mout_audio0", DIV_MAUDIO, 0, 4), + + /* DIV_FSYS0 */ + DIV_F(CLK_DIV_TSADC_PRE, "div_tsadc_pre", "div_tsadc", DIV_FSYS0, 8, 8, + CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_TSADC, "div_tsadc", "mout_tsadc", DIV_FSYS0, 0, 4), + + /* DIV_FSYS1 */ + DIV_F(CLK_DIV_MMC1_PRE, "div_mmc1_pre", "div_mmc1", DIV_FSYS1, 24, 8, + CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_MMC1, "div_mmc1", "mout_mmc1", DIV_FSYS1, 16, 4), + DIV_F(CLK_DIV_MMC0_PRE, "div_mmc0_pre", "div_mmc0", DIV_FSYS1, 8, 8, + CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_MMC0, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4), + + /* DIV_FSYS2 */ + DIV_F(CLK_DIV_MMC2_PRE, "div_mmc2_pre", "div_mmc2", DIV_FSYS2, 8, 8, + CLK_SET_RATE_PARENT, 0), + DIV_F(CLK_DIV_MMC2_PRE, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4, + CLK_SET_RATE_PARENT, 0), + + /* DIV_PERIL0 */ + DIV(CLK_DIV_UART3, "div_uart3", "mout_uart3", DIV_PERIL0, 12, 4), + DIV(CLK_DIV_UART2, "div_uart2", "mout_uart2", DIV_PERIL0, 8, 4), + DIV(CLK_DIV_UART1, "div_uart1", "mout_uart1", DIV_PERIL0, 4, 4), + DIV(CLK_DIV_UART0, "div_uart0", "mout_uart0", DIV_PERIL0, 0, 4), + + /* DIV_PERIL1 */ + DIV_F(CLK_DIV_SPI1_PRE, "div_spi1_pre", "div_spi1", DIV_PERIL1, 24, 8, + CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_SPI1, "div_spi1", "mout_spi1", DIV_PERIL1, 16, 4), + DIV_F(CLK_DIV_SPI0_PRE, "div_spi0_pre", "div_spi0", DIV_PERIL1, 8, 8, + CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_SPI0, "div_spi0", "mout_spi0", DIV_PERIL1, 0, 4), + + /* DIV_PERIL2 */ + DIV_F(CLK_DIV_SPI2_PRE, "div_spi2_pre", "div_spi2", DIV_PERIL2, 8, 8, + CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_SPI2, "div_spi2", "mout_spi2", DIV_PERIL2, 0, 4), + + /* DIV_PERIL4 */ + DIV(CLK_DIV_PCM2, "div_pcm2", "div_audio2", DIV_PERIL4, 20, 8), + DIV(CLK_DIV_AUDIO2, "div_audio2", "mout_audio2", DIV_PERIL4, 16, 4), + DIV(CLK_DIV_PCM1, "div_pcm1", "div_audio1", DIV_PERIL4, 20, 8), + DIV(CLK_DIV_AUDIO1, "div_audio1", "mout_audio1", DIV_PERIL4, 0, 4), + + /* DIV_PERIL5 */ + DIV(CLK_DIV_I2S1, "div_i2s1", "div_audio1", DIV_PERIL5, 0, 6), + + /* DIV_CAM1 */ + DIV(CLK_DIV_PXLASYNC_CSIS1_FIMC, "div_pxlasync_csis1_fimc", + "mout_pxlasync_csis1", DIV_CAM1, 24, 4), + DIV(CLK_DIV_PXLASYNC_CSIS0_FIMC, "div_pxlasync_csis0_fimc", + "mout_pxlasync_csis0", DIV_CAM1, 20, 4), + DIV(CLK_DIV_JPEG, "div_jpeg", "mout_jpeg", DIV_CAM1, 0, 4), + + /* DIV_CPU0 */ + DIV(CLK_DIV_CORE2, "div_core2", "div_core", DIV_CPU0, 28, 3), + DIV_F(CLK_DIV_APLL, "div_apll", "mout_apll", DIV_CPU0, 24, 3, + CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY), + DIV(CLK_DIV_PCLK_DBG, "div_pclk_dbg", "div_core2", DIV_CPU0, 20, 3), + DIV(CLK_DIV_ATB, "div_atb", "div_core2", DIV_CPU0, 16, 3), + DIV(CLK_DIV_PERIPH, "div_periph", "div_core2", DIV_CPU0, 12, 3), + DIV(CLK_DIV_COREM1, "div_corem1", "div_core2", DIV_CPU0, 8, 3), + DIV(CLK_DIV_COREM0, "div_corem0", "div_core2", DIV_CPU0, 4, 3), + DIV_F(CLK_DIV_CORE, "div_core", "mout_core", DIV_CPU0, 0, 3, + CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY), + + /* DIV_CPU1 */ + DIV(CLK_DIV_HPM, "div_hpm", "div_copy", DIV_CPU1, 4, 3), + DIV(CLK_DIV_COPY, "div_copy", "mout_hpm", DIV_CPU1, 0, 3), +}; + +static struct samsung_gate_clock exynos4415_gate_clks[] __initdata = { + /* + * NOTE: Following table is sorted by register address in ascending + * order and then bitfield shift in descending order, as it is done + * in the User's Manual. When adding new entries, please make sure + * that the order is preserved, to avoid merge conflicts and make + * further work with defined data easier. + */ + + /* GATE_IP_LEFTBUS */ + GATE(CLK_ASYNC_G3D, "async_g3d", "div_aclk_100", GATE_IP_LEFTBUS, 6, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_ASYNC_MFCL, "async_mfcl", "div_aclk_100", GATE_IP_LEFTBUS, 4, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_ASYNC_TVX, "async_tvx", "div_aclk_100", GATE_IP_LEFTBUS, 3, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_PPMULEFT, "ppmuleft", "div_aclk_100", GATE_IP_LEFTBUS, 1, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_GPIO_LEFT, "gpio_left", "div_aclk_100", GATE_IP_LEFTBUS, 0, + CLK_IGNORE_UNUSED, 0), + + /* GATE_IP_IMAGE */ + GATE(CLK_PPMUIMAGE, "ppmuimage", "div_aclk_100", GATE_IP_IMAGE, + 9, 0, 0), + GATE(CLK_QEMDMA2, "qe_mdma2", "div_aclk_100", GATE_IP_IMAGE, + 8, 0, 0), + GATE(CLK_QEROTATOR, "qe_rotator", "div_aclk_100", GATE_IP_IMAGE, + 7, 0, 0), + GATE(CLK_SMMUMDMA2, "smmu_mdam2", "div_aclk_100", GATE_IP_IMAGE, + 5, 0, 0), + GATE(CLK_SMMUROTATOR, "smmu_rotator", "div_aclk_100", GATE_IP_IMAGE, + 4, 0, 0), + GATE(CLK_MDMA2, "mdma2", "div_aclk_100", GATE_IP_IMAGE, 2, 0, 0), + GATE(CLK_ROTATOR, "rotator", "div_aclk_100", GATE_IP_IMAGE, 1, 0, 0), + + /* GATE_IP_RIGHTBUS */ + GATE(CLK_ASYNC_ISPMX, "async_ispmx", "div_aclk_100", + GATE_IP_RIGHTBUS, 9, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ASYNC_MAUDIOX, "async_maudiox", "div_aclk_100", + GATE_IP_RIGHTBUS, 7, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ASYNC_MFCR, "async_mfcr", "div_aclk_100", + GATE_IP_RIGHTBUS, 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ASYNC_FSYSD, "async_fsysd", "div_aclk_100", + GATE_IP_RIGHTBUS, 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ASYNC_LCD0X, "async_lcd0x", "div_aclk_100", + GATE_IP_RIGHTBUS, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ASYNC_CAMX, "async_camx", "div_aclk_100", + GATE_IP_RIGHTBUS, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PPMURIGHT, "ppmuright", "div_aclk_100", + GATE_IP_RIGHTBUS, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_GPIO_RIGHT, "gpio_right", "div_aclk_100", + GATE_IP_RIGHTBUS, 0, CLK_IGNORE_UNUSED, 0), + + /* GATE_IP_PERIR */ + GATE(CLK_ANTIRBK_APBIF, "antirbk_apbif", "div_aclk_100", + GATE_IP_PERIR, 24, CLK_IGNORE_UNUSED, 0), + GATE(CLK_EFUSE_WRITER_APBIF, "efuse_writer_apbif", "div_aclk_100", + GATE_IP_PERIR, 23, CLK_IGNORE_UNUSED, 0), + GATE(CLK_MONOCNT, "monocnt", "div_aclk_100", GATE_IP_PERIR, 22, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC6, "tzpc6", "div_aclk_100", GATE_IP_PERIR, 21, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_PROVISIONKEY1, "provisionkey1", "div_aclk_100", + GATE_IP_PERIR, 20, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PROVISIONKEY0, "provisionkey0", "div_aclk_100", + GATE_IP_PERIR, 19, CLK_IGNORE_UNUSED, 0), + GATE(CLK_CMU_ISPPART, "cmu_isppart", "div_aclk_100", GATE_IP_PERIR, 18, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TMU_APBIF, "tmu_apbif", "div_aclk_100", + GATE_IP_PERIR, 17, 0, 0), + GATE(CLK_KEYIF, "keyif", "div_aclk_100", GATE_IP_PERIR, 16, 0, 0), + GATE(CLK_RTC, "rtc", "div_aclk_100", GATE_IP_PERIR, 15, 0, 0), + GATE(CLK_WDT, "wdt", "div_aclk_100", GATE_IP_PERIR, 14, 0, 0), + GATE(CLK_MCT, "mct", "div_aclk_100", GATE_IP_PERIR, 13, 0, 0), + GATE(CLK_SECKEY, "seckey", "div_aclk_100", GATE_IP_PERIR, 12, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_HDMI_CEC, "hdmi_cec", "div_aclk_100", GATE_IP_PERIR, 11, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC5, "tzpc5", "div_aclk_100", GATE_IP_PERIR, 10, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC4, "tzpc4", "div_aclk_100", GATE_IP_PERIR, 9, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC3, "tzpc3", "div_aclk_100", GATE_IP_PERIR, 8, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC2, "tzpc2", "div_aclk_100", GATE_IP_PERIR, 7, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC1, "tzpc1", "div_aclk_100", GATE_IP_PERIR, 6, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC0, "tzpc0", "div_aclk_100", GATE_IP_PERIR, 5, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_CMU_COREPART, "cmu_corepart", "div_aclk_100", GATE_IP_PERIR, 4, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_CMU_TOPPART, "cmu_toppart", "div_aclk_100", GATE_IP_PERIR, 3, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_PMU_APBIF, "pmu_apbif", "div_aclk_100", GATE_IP_PERIR, 2, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_SYSREG, "sysreg", "div_aclk_100", GATE_IP_PERIR, 1, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_CHIP_ID, "chip_id", "div_aclk_100", GATE_IP_PERIR, 0, + CLK_IGNORE_UNUSED, 0), + + /* GATE_SCLK_CAM - non-completed */ + GATE(CLK_SCLK_PXLAYSNC_CSIS1_FIMC, "sclk_pxlasync_csis1_fimc", + "div_pxlasync_csis1_fimc", GATE_SCLK_CAM, 11, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_PXLAYSNC_CSIS0_FIMC, "sclk_pxlasync_csis0_fimc", + "div_pxlasync_csis0_fimc", GATE_SCLK_CAM, + 10, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_JPEG, "sclk_jpeg", "div_jpeg", + GATE_SCLK_CAM, 8, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_CSIS1, "sclk_csis1", "div_csis1", + GATE_SCLK_CAM, 7, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_CSIS0, "sclk_csis0", "div_csis0", + GATE_SCLK_CAM, 6, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_CAM1, "sclk_cam1", "div_cam1", + GATE_SCLK_CAM, 5, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_FIMC3_LCLK, "sclk_fimc3_lclk", "div_fimc3_lclk", + GATE_SCLK_CAM, 3, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_FIMC2_LCLK, "sclk_fimc2_lclk", "div_fimc2_lclk", + GATE_SCLK_CAM, 2, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_FIMC1_LCLK, "sclk_fimc1_lclk", "div_fimc1_lclk", + GATE_SCLK_CAM, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_FIMC0_LCLK, "sclk_fimc0_lclk", "div_fimc0_lclk", + GATE_SCLK_CAM, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_SCLK_TV */ + GATE(CLK_SCLK_PIXEL, "sclk_pixel", "div_tv_blk", + GATE_SCLK_TV, 3, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_HDMI, "sclk_hdmi", "mout_hdmi", + GATE_SCLK_TV, 2, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MIXER, "sclk_mixer", "div_tv_blk", + GATE_SCLK_TV, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_SCLK_MFC */ + GATE(CLK_SCLK_MFC, "sclk_mfc", "div_mfc", + GATE_SCLK_MFC, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_SCLK_G3D */ + GATE(CLK_SCLK_G3D, "sclk_g3d", "div_g3d", + GATE_SCLK_G3D, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_SCLK_LCD */ + GATE(CLK_SCLK_MIPIDPHY4L, "sclk_mipidphy4l", "div_mipi0", + GATE_SCLK_LCD, 4, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MIPI0, "sclk_mipi0", "div_mipi0_pre", + GATE_SCLK_LCD, 3, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MDNIE0, "sclk_mdnie0", "div_fimd0", + GATE_SCLK_LCD, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_FIMD0, "sclk_fimd0", "div_fimd0", + GATE_SCLK_LCD, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_SCLK_MAUDIO */ + GATE(CLK_SCLK_PCM0, "sclk_pcm0", "div_pcm0", + GATE_SCLK_MAUDIO, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_AUDIO0, "sclk_audio0", "div_audio0", + GATE_SCLK_MAUDIO, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_SCLK_FSYS */ + GATE(CLK_SCLK_TSADC, "sclk_tsadc", "div_tsadc_pre", + GATE_SCLK_FSYS, 9, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_EBI, "sclk_ebi", "div_ebi", + GATE_SCLK_FSYS, 6, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MMC2, "sclk_mmc2", "div_mmc2_pre", + GATE_SCLK_FSYS, 2, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MMC1, "sclk_mmc1", "div_mmc1_pre", + GATE_SCLK_FSYS, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MMC0, "sclk_mmc0", "div_mmc0_pre", + GATE_SCLK_FSYS, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_SCLK_PERIL */ + GATE(CLK_SCLK_I2S, "sclk_i2s1", "div_i2s1", + GATE_SCLK_PERIL, 18, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_PCM2, "sclk_pcm2", "div_pcm2", + GATE_SCLK_PERIL, 16, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_PCM1, "sclk_pcm1", "div_pcm1", + GATE_SCLK_PERIL, 15, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_AUDIO2, "sclk_audio2", "div_audio2", + GATE_SCLK_PERIL, 14, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_AUDIO1, "sclk_audio1", "div_audio1", + GATE_SCLK_PERIL, 13, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPDIF, "sclk_spdif", "mout_spdif", + GATE_SCLK_PERIL, 10, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPI2, "sclk_spi2", "div_spi2_pre", + GATE_SCLK_PERIL, 8, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPI1, "sclk_spi1", "div_spi1_pre", + GATE_SCLK_PERIL, 7, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPI0, "sclk_spi0", "div_spi0_pre", + GATE_SCLK_PERIL, 6, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_UART3, "sclk_uart3", "div_uart3", + GATE_SCLK_PERIL, 3, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_UART2, "sclk_uart2", "div_uart2", + GATE_SCLK_PERIL, 2, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_UART1, "sclk_uart1", "div_uart1", + GATE_SCLK_PERIL, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_UART0, "sclk_uart0", "div_uart0", + GATE_SCLK_PERIL, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_IP_CAM */ + GATE(CLK_SMMUFIMC_LITE2, "smmufimc_lite2", "div_aclk_160", GATE_IP_CAM, + 22, CLK_IGNORE_UNUSED, 0), + GATE(CLK_FIMC_LITE2, "fimc_lite2", "div_aclk_160", GATE_IP_CAM, + 20, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PIXELASYNCM1, "pixelasyncm1", "div_aclk_160", GATE_IP_CAM, + 18, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PIXELASYNCM0, "pixelasyncm0", "div_aclk_160", GATE_IP_CAM, + 17, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PPMUCAMIF, "ppmucamif", "div_aclk_160", GATE_IP_CAM, + 16, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SMMUJPEG, "smmujpeg", "div_aclk_160", GATE_IP_CAM, 11, 0, 0), + GATE(CLK_SMMUFIMC3, "smmufimc3", "div_aclk_160", GATE_IP_CAM, 10, 0, 0), + GATE(CLK_SMMUFIMC2, "smmufimc2", "div_aclk_160", GATE_IP_CAM, 9, 0, 0), + GATE(CLK_SMMUFIMC1, "smmufimc1", "div_aclk_160", GATE_IP_CAM, 8, 0, 0), + GATE(CLK_SMMUFIMC0, "smmufimc0", "div_aclk_160", GATE_IP_CAM, 7, 0, 0), + GATE(CLK_JPEG, "jpeg", "div_aclk_160", GATE_IP_CAM, 6, 0, 0), + GATE(CLK_CSIS1, "csis1", "div_aclk_160", GATE_IP_CAM, 5, 0, 0), + GATE(CLK_CSIS0, "csis0", "div_aclk_160", GATE_IP_CAM, 4, 0, 0), + GATE(CLK_FIMC3, "fimc3", "div_aclk_160", GATE_IP_CAM, 3, 0, 0), + GATE(CLK_FIMC2, "fimc2", "div_aclk_160", GATE_IP_CAM, 2, 0, 0), + GATE(CLK_FIMC1, "fimc1", "div_aclk_160", GATE_IP_CAM, 1, 0, 0), + GATE(CLK_FIMC0, "fimc0", "div_aclk_160", GATE_IP_CAM, 0, 0, 0), + + /* GATE_IP_TV */ + GATE(CLK_PPMUTV, "ppmutv", "div_aclk_100", GATE_IP_TV, 5, 0, 0), + GATE(CLK_SMMUTV, "smmutv", "div_aclk_100", GATE_IP_TV, 4, 0, 0), + GATE(CLK_HDMI, "hdmi", "div_aclk_100", GATE_IP_TV, 3, 0, 0), + GATE(CLK_MIXER, "mixer", "div_aclk_100", GATE_IP_TV, 1, 0, 0), + GATE(CLK_VP, "vp", "div_aclk_100", GATE_IP_TV, 0, 0, 0), + + /* GATE_IP_MFC */ + GATE(CLK_PPMUMFC_R, "ppmumfc_r", "div_aclk_200", GATE_IP_MFC, 4, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_PPMUMFC_L, "ppmumfc_l", "div_aclk_200", GATE_IP_MFC, 3, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_SMMUMFC_R, "smmumfc_r", "div_aclk_200", GATE_IP_MFC, 2, 0, 0), + GATE(CLK_SMMUMFC_L, "smmumfc_l", "div_aclk_200", GATE_IP_MFC, 1, 0, 0), + GATE(CLK_MFC, "mfc", "div_aclk_200", GATE_IP_MFC, 0, 0, 0), + + /* GATE_IP_G3D */ + GATE(CLK_PPMUG3D, "ppmug3d", "div_aclk_200", GATE_IP_G3D, 1, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_G3D, "g3d", "div_aclk_200", GATE_IP_G3D, 0, 0, 0), + + /* GATE_IP_LCD */ + GATE(CLK_PPMULCD0, "ppmulcd0", "div_aclk_160", GATE_IP_LCD, 5, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_SMMUFIMD0, "smmufimd0", "div_aclk_160", GATE_IP_LCD, 4, 0, 0), + GATE(CLK_DSIM0, "dsim0", "div_aclk_160", GATE_IP_LCD, 3, 0, 0), + GATE(CLK_SMIES, "smies", "div_aclk_160", GATE_IP_LCD, 2, 0, 0), + GATE(CLK_MIE0, "mie0", "div_aclk_160", GATE_IP_LCD, 1, 0, 0), + GATE(CLK_FIMD0, "fimd0", "div_aclk_160", GATE_IP_LCD, 0, 0, 0), + + /* GATE_IP_FSYS */ + GATE(CLK_TSADC, "tsadc", "div_aclk_200", GATE_IP_FSYS, 20, 0, 0), + GATE(CLK_PPMUFILE, "ppmufile", "div_aclk_200", GATE_IP_FSYS, 17, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_NFCON, "nfcon", "div_aclk_200", GATE_IP_FSYS, 16, 0, 0), + GATE(CLK_USBDEVICE, "usbdevice", "div_aclk_200", GATE_IP_FSYS, 13, + 0, 0), + GATE(CLK_USBHOST, "usbhost", "div_aclk_200", GATE_IP_FSYS, 12, 0, 0), + GATE(CLK_SROMC, "sromc", "div_aclk_200", GATE_IP_FSYS, 11, 0, 0), + GATE(CLK_SDMMC2, "sdmmc2", "div_aclk_200", GATE_IP_FSYS, 7, 0, 0), + GATE(CLK_SDMMC1, "sdmmc1", "div_aclk_200", GATE_IP_FSYS, 6, 0, 0), + GATE(CLK_SDMMC0, "sdmmc0", "div_aclk_200", GATE_IP_FSYS, 5, 0, 0), + GATE(CLK_PDMA1, "pdma1", "div_aclk_200", GATE_IP_FSYS, 1, 0, 0), + GATE(CLK_PDMA0, "pdma0", "div_aclk_200", GATE_IP_FSYS, 0, 0, 0), + + /* GATE_IP_PERIL */ + GATE(CLK_SPDIF, "spdif", "div_aclk_100", GATE_IP_PERIL, 26, 0, 0), + GATE(CLK_PWM, "pwm", "div_aclk_100", GATE_IP_PERIL, 24, 0, 0), + GATE(CLK_PCM2, "pcm2", "div_aclk_100", GATE_IP_PERIL, 23, 0, 0), + GATE(CLK_PCM1, "pcm1", "div_aclk_100", GATE_IP_PERIL, 22, 0, 0), + GATE(CLK_I2S1, "i2s1", "div_aclk_100", GATE_IP_PERIL, 20, 0, 0), + GATE(CLK_SPI2, "spi2", "div_aclk_100", GATE_IP_PERIL, 18, 0, 0), + GATE(CLK_SPI1, "spi1", "div_aclk_100", GATE_IP_PERIL, 17, 0, 0), + GATE(CLK_SPI0, "spi0", "div_aclk_100", GATE_IP_PERIL, 16, 0, 0), + GATE(CLK_I2CHDMI, "i2chdmi", "div_aclk_100", GATE_IP_PERIL, 14, 0, 0), + GATE(CLK_I2C7, "i2c7", "div_aclk_100", GATE_IP_PERIL, 13, 0, 0), + GATE(CLK_I2C6, "i2c6", "div_aclk_100", GATE_IP_PERIL, 12, 0, 0), + GATE(CLK_I2C5, "i2c5", "div_aclk_100", GATE_IP_PERIL, 11, 0, 0), + GATE(CLK_I2C4, "i2c4", "div_aclk_100", GATE_IP_PERIL, 10, 0, 0), + GATE(CLK_I2C3, "i2c3", "div_aclk_100", GATE_IP_PERIL, 9, 0, 0), + GATE(CLK_I2C2, "i2c2", "div_aclk_100", GATE_IP_PERIL, 8, 0, 0), + GATE(CLK_I2C1, "i2c1", "div_aclk_100", GATE_IP_PERIL, 7, 0, 0), + GATE(CLK_I2C0, "i2c0", "div_aclk_100", GATE_IP_PERIL, 6, 0, 0), + GATE(CLK_UART3, "uart3", "div_aclk_100", GATE_IP_PERIL, 3, 0, 0), + GATE(CLK_UART2, "uart2", "div_aclk_100", GATE_IP_PERIL, 2, 0, 0), + GATE(CLK_UART1, "uart1", "div_aclk_100", GATE_IP_PERIL, 1, 0, 0), + GATE(CLK_UART0, "uart0", "div_aclk_100", GATE_IP_PERIL, 0, 0, 0), +}; + +/* + * APLL & MPLL & BPLL & ISP_PLL & DISP_PLL & G3D_PLL + */ +static struct samsung_pll_rate_table exynos4415_pll_rates[] = { + PLL_35XX_RATE(1600000000, 400, 3, 1), + PLL_35XX_RATE(1500000000, 250, 2, 1), + PLL_35XX_RATE(1400000000, 175, 3, 0), + PLL_35XX_RATE(1300000000, 325, 3, 1), + PLL_35XX_RATE(1200000000, 400, 4, 1), + PLL_35XX_RATE(1100000000, 275, 3, 1), + PLL_35XX_RATE(1066000000, 533, 6, 1), + PLL_35XX_RATE(1000000000, 250, 3, 1), + PLL_35XX_RATE(960000000, 320, 4, 1), + PLL_35XX_RATE(900000000, 300, 4, 1), + PLL_35XX_RATE(850000000, 425, 6, 1), + PLL_35XX_RATE(800000000, 200, 3, 1), + PLL_35XX_RATE(700000000, 175, 3, 1), + PLL_35XX_RATE(667000000, 667, 12, 1), + PLL_35XX_RATE(600000000, 400, 4, 2), + PLL_35XX_RATE(550000000, 275, 3, 2), + PLL_35XX_RATE(533000000, 533, 6, 2), + PLL_35XX_RATE(520000000, 260, 3, 2), + PLL_35XX_RATE(500000000, 250, 3, 2), + PLL_35XX_RATE(440000000, 220, 3, 2), + PLL_35XX_RATE(400000000, 200, 3, 2), + PLL_35XX_RATE(350000000, 175, 3, 2), + PLL_35XX_RATE(300000000, 300, 3, 3), + PLL_35XX_RATE(266000000, 266, 3, 3), + PLL_35XX_RATE(200000000, 200, 3, 3), + PLL_35XX_RATE(160000000, 160, 3, 3), + PLL_35XX_RATE(100000000, 200, 3, 4), + { /* sentinel */ } +}; + +/* EPLL */ +static struct samsung_pll_rate_table exynos4415_epll_rates[] = { + PLL_36XX_RATE(800000000, 200, 3, 1, 0), + PLL_36XX_RATE(288000000, 96, 2, 2, 0), + PLL_36XX_RATE(192000000, 128, 2, 3, 0), + PLL_36XX_RATE(144000000, 96, 2, 3, 0), + PLL_36XX_RATE(96000000, 128, 2, 4, 0), + PLL_36XX_RATE(84000000, 112, 2, 4, 0), + PLL_36XX_RATE(80750011, 107, 2, 4, 43691), + PLL_36XX_RATE(73728004, 98, 2, 4, 19923), + PLL_36XX_RATE(67987602, 271, 3, 5, 62285), + PLL_36XX_RATE(65911004, 175, 2, 5, 49982), + PLL_36XX_RATE(50000000, 200, 3, 5, 0), + PLL_36XX_RATE(49152003, 131, 2, 5, 4719), + PLL_36XX_RATE(48000000, 128, 2, 5, 0), + PLL_36XX_RATE(45250000, 181, 3, 5, 0), + { /* sentinel */ } +}; + +static struct samsung_pll_clock exynos4415_plls[nr_plls] __initdata = { + [apll] = PLL(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll", + APLL_LOCK, APLL_CON0, NULL), + [epll] = PLL(pll_36xx, CLK_FOUT_EPLL, "fout_epll", "fin_pll", + EPLL_LOCK, EPLL_CON0, NULL), + [g3d_pll] = PLL(pll_35xx, CLK_FOUT_G3D_PLL, "fout_g3d_pll", + "mout_g3d_pllsrc", G3D_PLL_LOCK, G3D_PLL_CON0, NULL), + [isp_pll] = PLL(pll_35xx, CLK_FOUT_ISP_PLL, "fout_isp_pll", "fin_pll", + ISP_PLL_LOCK, ISP_PLL_CON0, NULL), + [disp_pll] = PLL(pll_35xx, CLK_FOUT_DISP_PLL, "fout_disp_pll", + "fin_pll", DISP_PLL_LOCK, DISP_PLL_CON0, NULL), +}; + +static void __init exynos4415_cmu_init(struct device_node *np) +{ + void __iomem *reg_base; + + reg_base = of_iomap(np, 0); + if (!reg_base) + panic("%s: failed to map registers\n", __func__); + + exynos4415_ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS); + if (!exynos4415_ctx) + panic("%s: unable to allocate context.\n", __func__); + + exynos4415_plls[apll].rate_table = exynos4415_pll_rates; + exynos4415_plls[epll].rate_table = exynos4415_epll_rates; + exynos4415_plls[g3d_pll].rate_table = exynos4415_pll_rates; + exynos4415_plls[isp_pll].rate_table = exynos4415_pll_rates; + exynos4415_plls[disp_pll].rate_table = exynos4415_pll_rates; + + samsung_clk_register_fixed_factor(exynos4415_ctx, + exynos4415_fixed_factor_clks, + ARRAY_SIZE(exynos4415_fixed_factor_clks)); + samsung_clk_register_fixed_rate(exynos4415_ctx, + exynos4415_fixed_rate_clks, + ARRAY_SIZE(exynos4415_fixed_rate_clks)); + + samsung_clk_register_pll(exynos4415_ctx, exynos4415_plls, + ARRAY_SIZE(exynos4415_plls), reg_base); + samsung_clk_register_mux(exynos4415_ctx, exynos4415_mux_clks, + ARRAY_SIZE(exynos4415_mux_clks)); + samsung_clk_register_div(exynos4415_ctx, exynos4415_div_clks, + ARRAY_SIZE(exynos4415_div_clks)); + samsung_clk_register_gate(exynos4415_ctx, exynos4415_gate_clks, + ARRAY_SIZE(exynos4415_gate_clks)); + + exynos4415_clk_sleep_init(); + + samsung_clk_of_add_provider(np, exynos4415_ctx); +} +CLK_OF_DECLARE(exynos4415_cmu, "samsung,exynos4415-cmu", exynos4415_cmu_init); + +/* + * CMU DMC + */ + +#define MPLL_LOCK 0x008 +#define MPLL_CON0 0x108 +#define MPLL_CON1 0x10c +#define MPLL_CON2 0x110 +#define BPLL_LOCK 0x118 +#define BPLL_CON0 0x218 +#define BPLL_CON1 0x21c +#define BPLL_CON2 0x220 +#define SRC_DMC 0x300 +#define DIV_DMC1 0x504 + +enum exynos4415_dmc_plls { + mpll, bpll, + nr_dmc_plls, +}; + +static struct samsung_clk_provider *exynos4415_dmc_ctx; + +#ifdef CONFIG_PM_SLEEP +static struct samsung_clk_reg_dump *exynos4415_dmc_clk_regs; + +static unsigned long exynos4415_cmu_dmc_clk_regs[] __initdata = { + MPLL_LOCK, + MPLL_CON0, + MPLL_CON1, + MPLL_CON2, + BPLL_LOCK, + BPLL_CON0, + BPLL_CON1, + BPLL_CON2, + SRC_DMC, + DIV_DMC1, +}; + +static int exynos4415_dmc_clk_suspend(void) +{ + samsung_clk_save(exynos4415_dmc_ctx->reg_base, + exynos4415_dmc_clk_regs, + ARRAY_SIZE(exynos4415_cmu_dmc_clk_regs)); + return 0; +} + +static void exynos4415_dmc_clk_resume(void) +{ + samsung_clk_restore(exynos4415_dmc_ctx->reg_base, + exynos4415_dmc_clk_regs, + ARRAY_SIZE(exynos4415_cmu_dmc_clk_regs)); +} + +static struct syscore_ops exynos4415_dmc_clk_syscore_ops = { + .suspend = exynos4415_dmc_clk_suspend, + .resume = exynos4415_dmc_clk_resume, +}; + +static void exynos4415_dmc_clk_sleep_init(void) +{ + exynos4415_dmc_clk_regs = + samsung_clk_alloc_reg_dump(exynos4415_cmu_dmc_clk_regs, + ARRAY_SIZE(exynos4415_cmu_dmc_clk_regs)); + if (!exynos4415_dmc_clk_regs) { + pr_warn("%s: Failed to allocate sleep save data\n", __func__); + return; + } + + register_syscore_ops(&exynos4415_dmc_clk_syscore_ops); +} +#else +static inline void exynos4415_dmc_clk_sleep_init(void) { } +#endif /* CONFIG_PM_SLEEP */ + +PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", }; +PNAME(mout_bpll_p) = { "fin_pll", "fout_bpll", }; +PNAME(mbpll_p) = { "mout_mpll", "mout_bpll", }; + +static struct samsung_mux_clock exynos4415_dmc_mux_clks[] __initdata = { + MUX(CLK_DMC_MOUT_MPLL, "mout_mpll", mout_mpll_p, SRC_DMC, 12, 1), + MUX(CLK_DMC_MOUT_BPLL, "mout_bpll", mout_bpll_p, SRC_DMC, 10, 1), + MUX(CLK_DMC_MOUT_DPHY, "mout_dphy", mbpll_p, SRC_DMC, 8, 1), + MUX(CLK_DMC_MOUT_DMC_BUS, "mout_dmc_bus", mbpll_p, SRC_DMC, 4, 1), +}; + +static struct samsung_div_clock exynos4415_dmc_div_clks[] __initdata = { + DIV(CLK_DMC_DIV_DMC, "div_dmc", "div_dmc_pre", DIV_DMC1, 27, 3), + DIV(CLK_DMC_DIV_DPHY, "div_dphy", "mout_dphy", DIV_DMC1, 23, 3), + DIV(CLK_DMC_DIV_DMC_PRE, "div_dmc_pre", "mout_dmc_bus", + DIV_DMC1, 19, 2), + DIV(CLK_DMC_DIV_DMCP, "div_dmcp", "div_dmcd", DIV_DMC1, 15, 3), + DIV(CLK_DMC_DIV_DMCD, "div_dmcd", "div_dmc", DIV_DMC1, 11, 3), + DIV(CLK_DMC_DIV_MPLL_PRE, "div_mpll_pre", "mout_mpll", DIV_DMC1, 8, 2), +}; + +static struct samsung_pll_clock exynos4415_dmc_plls[nr_dmc_plls] __initdata = { + [mpll] = PLL(pll_35xx, CLK_DMC_FOUT_MPLL, "fout_mpll", "fin_pll", + MPLL_LOCK, MPLL_CON0, NULL), + [bpll] = PLL(pll_35xx, CLK_DMC_FOUT_BPLL, "fout_bpll", "fin_pll", + BPLL_LOCK, BPLL_CON0, NULL), +}; + +static void __init exynos4415_cmu_dmc_init(struct device_node *np) +{ + void __iomem *reg_base; + + reg_base = of_iomap(np, 0); + if (!reg_base) + panic("%s: failed to map registers\n", __func__); + + exynos4415_dmc_ctx = samsung_clk_init(np, reg_base, NR_CLKS_DMC); + if (!exynos4415_dmc_ctx) + panic("%s: unable to allocate context.\n", __func__); + + exynos4415_dmc_plls[mpll].rate_table = exynos4415_pll_rates; + exynos4415_dmc_plls[bpll].rate_table = exynos4415_pll_rates; + + samsung_clk_register_pll(exynos4415_dmc_ctx, exynos4415_dmc_plls, + ARRAY_SIZE(exynos4415_dmc_plls), reg_base); + samsung_clk_register_mux(exynos4415_dmc_ctx, exynos4415_dmc_mux_clks, + ARRAY_SIZE(exynos4415_dmc_mux_clks)); + samsung_clk_register_div(exynos4415_dmc_ctx, exynos4415_dmc_div_clks, + ARRAY_SIZE(exynos4415_dmc_div_clks)); + + exynos4415_dmc_clk_sleep_init(); + + samsung_clk_of_add_provider(np, exynos4415_dmc_ctx); +} +CLK_OF_DECLARE(exynos4415_cmu_dmc, "samsung,exynos4415-cmu-dmc", + exynos4415_cmu_dmc_init); diff --git a/drivers/clk/samsung/clk-exynos5260.c b/drivers/clk/samsung/clk-exynos5260.c index 2527e39aadcf..e2e5193d1049 100644 --- a/drivers/clk/samsung/clk-exynos5260.c +++ b/drivers/clk/samsung/clk-exynos5260.c @@ -11,10 +11,8 @@ #include <linux/clk.h> #include <linux/clkdev.h> -#include <linux/clk-provider.h> #include <linux/of.h> #include <linux/of_address.h> -#include <linux/syscore_ops.h> #include "clk-exynos5260.h" #include "clk.h" @@ -22,39 +20,6 @@ #include <dt-bindings/clock/exynos5260-clk.h> -static LIST_HEAD(clock_reg_cache_list); - -struct exynos5260_clock_reg_cache { - struct list_head node; - void __iomem *reg_base; - struct samsung_clk_reg_dump *rdump; - unsigned int rd_num; -}; - -struct exynos5260_cmu_info { - /* list of pll clocks and respective count */ - struct samsung_pll_clock *pll_clks; - unsigned int nr_pll_clks; - /* list of mux clocks and respective count */ - struct samsung_mux_clock *mux_clks; - unsigned int nr_mux_clks; - /* list of div clocks and respective count */ - struct samsung_div_clock *div_clks; - unsigned int nr_div_clks; - /* list of gate clocks and respective count */ - struct samsung_gate_clock *gate_clks; - unsigned int nr_gate_clks; - /* list of fixed clocks and respective count */ - struct samsung_fixed_rate_clock *fixed_clks; - unsigned int nr_fixed_clks; - /* total number of clocks with IDs assigned*/ - unsigned int nr_clk_ids; - - /* list and number of clocks registers */ - unsigned long *clk_regs; - unsigned int nr_clk_regs; -}; - /* * Applicable for all 2550 Type PLLS for Exynos5260, listed below * DISP_PLL, EGL_PLL, KFC_PLL, MEM_PLL, BUS_PLL, MEDIA_PLL, G3D_PLL. @@ -113,104 +78,6 @@ static struct samsung_pll_rate_table pll2650_24mhz_tbl[] __initdata = { PLL_36XX_RATE(66000000, 176, 2, 5, 0), }; -#ifdef CONFIG_PM_SLEEP - -static int exynos5260_clk_suspend(void) -{ - struct exynos5260_clock_reg_cache *cache; - - list_for_each_entry(cache, &clock_reg_cache_list, node) - samsung_clk_save(cache->reg_base, cache->rdump, - cache->rd_num); - - return 0; -} - -static void exynos5260_clk_resume(void) -{ - struct exynos5260_clock_reg_cache *cache; - - list_for_each_entry(cache, &clock_reg_cache_list, node) - samsung_clk_restore(cache->reg_base, cache->rdump, - cache->rd_num); -} - -static struct syscore_ops exynos5260_clk_syscore_ops = { - .suspend = exynos5260_clk_suspend, - .resume = exynos5260_clk_resume, -}; - -static void exynos5260_clk_sleep_init(void __iomem *reg_base, - unsigned long *rdump, - unsigned long nr_rdump) -{ - struct exynos5260_clock_reg_cache *reg_cache; - - reg_cache = kzalloc(sizeof(struct exynos5260_clock_reg_cache), - GFP_KERNEL); - if (!reg_cache) - panic("could not allocate register cache.\n"); - - reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump); - - if (!reg_cache->rdump) - panic("could not allocate register dump storage.\n"); - - if (list_empty(&clock_reg_cache_list)) - register_syscore_ops(&exynos5260_clk_syscore_ops); - - reg_cache->rd_num = nr_rdump; - reg_cache->reg_base = reg_base; - list_add_tail(®_cache->node, &clock_reg_cache_list); -} - -#else -static void exynos5260_clk_sleep_init(void __iomem *reg_base, - unsigned long *rdump, - unsigned long nr_rdump){} -#endif - -/* - * Common function which registers plls, muxes, dividers and gates - * for each CMU. It also add CMU register list to register cache. - */ - -void __init exynos5260_cmu_register_one(struct device_node *np, - struct exynos5260_cmu_info *cmu) -{ - void __iomem *reg_base; - struct samsung_clk_provider *ctx; - - reg_base = of_iomap(np, 0); - if (!reg_base) - panic("%s: failed to map registers\n", __func__); - - ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids); - if (!ctx) - panic("%s: unable to alllocate ctx\n", __func__); - - if (cmu->pll_clks) - samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks, - reg_base); - if (cmu->mux_clks) - samsung_clk_register_mux(ctx, cmu->mux_clks, - cmu->nr_mux_clks); - if (cmu->div_clks) - samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks); - if (cmu->gate_clks) - samsung_clk_register_gate(ctx, cmu->gate_clks, - cmu->nr_gate_clks); - if (cmu->fixed_clks) - samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks, - cmu->nr_fixed_clks); - if (cmu->clk_regs) - exynos5260_clk_sleep_init(reg_base, cmu->clk_regs, - cmu->nr_clk_regs); - - samsung_clk_of_add_provider(np, ctx); -} - - /* CMU_AUD */ static unsigned long aud_clk_regs[] __initdata = { @@ -268,7 +135,7 @@ struct samsung_gate_clock aud_gate_clks[] __initdata = { static void __init exynos5260_clk_aud_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.mux_clks = aud_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(aud_mux_clks); @@ -280,7 +147,7 @@ static void __init exynos5260_clk_aud_init(struct device_node *np) cmu.clk_regs = aud_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(aud_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_aud, "samsung,exynos5260-clock-aud", @@ -458,7 +325,7 @@ struct samsung_gate_clock disp_gate_clks[] __initdata = { static void __init exynos5260_clk_disp_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.mux_clks = disp_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(disp_mux_clks); @@ -470,7 +337,7 @@ static void __init exynos5260_clk_disp_init(struct device_node *np) cmu.clk_regs = disp_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(disp_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_disp, "samsung,exynos5260-clock-disp", @@ -522,7 +389,7 @@ static struct samsung_pll_clock egl_pll_clks[] __initdata = { static void __init exynos5260_clk_egl_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.pll_clks = egl_pll_clks; cmu.nr_pll_clks = ARRAY_SIZE(egl_pll_clks); @@ -534,7 +401,7 @@ static void __init exynos5260_clk_egl_init(struct device_node *np) cmu.clk_regs = egl_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(egl_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_egl, "samsung,exynos5260-clock-egl", @@ -624,7 +491,7 @@ struct samsung_gate_clock fsys_gate_clks[] __initdata = { static void __init exynos5260_clk_fsys_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.mux_clks = fsys_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(fsys_mux_clks); @@ -634,7 +501,7 @@ static void __init exynos5260_clk_fsys_init(struct device_node *np) cmu.clk_regs = fsys_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(fsys_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_fsys, "samsung,exynos5260-clock-fsys", @@ -713,7 +580,7 @@ struct samsung_gate_clock g2d_gate_clks[] __initdata = { static void __init exynos5260_clk_g2d_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.mux_clks = g2d_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(g2d_mux_clks); @@ -725,7 +592,7 @@ static void __init exynos5260_clk_g2d_init(struct device_node *np) cmu.clk_regs = g2d_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(g2d_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_g2d, "samsung,exynos5260-clock-g2d", @@ -774,7 +641,7 @@ static struct samsung_pll_clock g3d_pll_clks[] __initdata = { static void __init exynos5260_clk_g3d_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.pll_clks = g3d_pll_clks; cmu.nr_pll_clks = ARRAY_SIZE(g3d_pll_clks); @@ -788,7 +655,7 @@ static void __init exynos5260_clk_g3d_init(struct device_node *np) cmu.clk_regs = g3d_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(g3d_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_g3d, "samsung,exynos5260-clock-g3d", @@ -909,7 +776,7 @@ struct samsung_gate_clock gscl_gate_clks[] __initdata = { static void __init exynos5260_clk_gscl_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.mux_clks = gscl_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(gscl_mux_clks); @@ -921,7 +788,7 @@ static void __init exynos5260_clk_gscl_init(struct device_node *np) cmu.clk_regs = gscl_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(gscl_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_gscl, "samsung,exynos5260-clock-gscl", @@ -1028,7 +895,7 @@ struct samsung_gate_clock isp_gate_clks[] __initdata = { static void __init exynos5260_clk_isp_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.mux_clks = isp_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(isp_mux_clks); @@ -1040,7 +907,7 @@ static void __init exynos5260_clk_isp_init(struct device_node *np) cmu.clk_regs = isp_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(isp_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_isp, "samsung,exynos5260-clock-isp", @@ -1092,7 +959,7 @@ static struct samsung_pll_clock kfc_pll_clks[] __initdata = { static void __init exynos5260_clk_kfc_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.pll_clks = kfc_pll_clks; cmu.nr_pll_clks = ARRAY_SIZE(kfc_pll_clks); @@ -1104,7 +971,7 @@ static void __init exynos5260_clk_kfc_init(struct device_node *np) cmu.clk_regs = kfc_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(kfc_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_kfc, "samsung,exynos5260-clock-kfc", @@ -1148,7 +1015,7 @@ struct samsung_gate_clock mfc_gate_clks[] __initdata = { static void __init exynos5260_clk_mfc_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.mux_clks = mfc_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(mfc_mux_clks); @@ -1160,7 +1027,7 @@ static void __init exynos5260_clk_mfc_init(struct device_node *np) cmu.clk_regs = mfc_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(mfc_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_mfc, "samsung,exynos5260-clock-mfc", @@ -1295,7 +1162,7 @@ static struct samsung_pll_clock mif_pll_clks[] __initdata = { static void __init exynos5260_clk_mif_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.pll_clks = mif_pll_clks; cmu.nr_pll_clks = ARRAY_SIZE(mif_pll_clks); @@ -1309,7 +1176,7 @@ static void __init exynos5260_clk_mif_init(struct device_node *np) cmu.clk_regs = mif_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(mif_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_mif, "samsung,exynos5260-clock-mif", @@ -1503,7 +1370,7 @@ struct samsung_gate_clock peri_gate_clks[] __initdata = { static void __init exynos5260_clk_peri_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.mux_clks = peri_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(peri_mux_clks); @@ -1515,7 +1382,7 @@ static void __init exynos5260_clk_peri_init(struct device_node *np) cmu.clk_regs = peri_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(peri_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_peri, "samsung,exynos5260-clock-peri", @@ -1959,7 +1826,7 @@ static struct samsung_pll_clock top_pll_clks[] __initdata = { static void __init exynos5260_clk_top_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.pll_clks = top_pll_clks; cmu.nr_pll_clks = ARRAY_SIZE(top_pll_clks); @@ -1975,7 +1842,7 @@ static void __init exynos5260_clk_top_init(struct device_node *np) cmu.clk_regs = top_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(top_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_top, "samsung,exynos5260-clock-top", diff --git a/drivers/clk/samsung/clk-exynos7.c b/drivers/clk/samsung/clk-exynos7.c new file mode 100644 index 000000000000..ea4483b8d62e --- /dev/null +++ b/drivers/clk/samsung/clk-exynos7.c @@ -0,0 +1,743 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Author: Naveen Krishna Ch <naveenkrishna.ch@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * +*/ + +#include <linux/clk.h> +#include <linux/clkdev.h> +#include <linux/clk-provider.h> +#include <linux/of.h> + +#include "clk.h" +#include <dt-bindings/clock/exynos7-clk.h> + +/* Register Offset definitions for CMU_TOPC (0x10570000) */ +#define CC_PLL_LOCK 0x0000 +#define BUS0_PLL_LOCK 0x0004 +#define BUS1_DPLL_LOCK 0x0008 +#define MFC_PLL_LOCK 0x000C +#define AUD_PLL_LOCK 0x0010 +#define CC_PLL_CON0 0x0100 +#define BUS0_PLL_CON0 0x0110 +#define BUS1_DPLL_CON0 0x0120 +#define MFC_PLL_CON0 0x0130 +#define AUD_PLL_CON0 0x0140 +#define MUX_SEL_TOPC0 0x0200 +#define MUX_SEL_TOPC1 0x0204 +#define MUX_SEL_TOPC2 0x0208 +#define MUX_SEL_TOPC3 0x020C +#define DIV_TOPC0 0x0600 +#define DIV_TOPC1 0x0604 +#define DIV_TOPC3 0x060C + +static struct samsung_fixed_factor_clock topc_fixed_factor_clks[] __initdata = { + FFACTOR(0, "ffac_topc_bus0_pll_div2", "mout_bus0_pll_ctrl", 1, 2, 0), + FFACTOR(0, "ffac_topc_bus0_pll_div4", + "ffac_topc_bus0_pll_div2", 1, 2, 0), + FFACTOR(0, "ffac_topc_bus1_pll_div2", "mout_bus1_pll_ctrl", 1, 2, 0), + FFACTOR(0, "ffac_topc_cc_pll_div2", "mout_cc_pll_ctrl", 1, 2, 0), + FFACTOR(0, "ffac_topc_mfc_pll_div2", "mout_mfc_pll_ctrl", 1, 2, 0), +}; + +/* List of parent clocks for Muxes in CMU_TOPC */ +PNAME(mout_bus0_pll_ctrl_p) = { "fin_pll", "fout_bus0_pll" }; +PNAME(mout_bus1_pll_ctrl_p) = { "fin_pll", "fout_bus1_pll" }; +PNAME(mout_cc_pll_ctrl_p) = { "fin_pll", "fout_cc_pll" }; +PNAME(mout_mfc_pll_ctrl_p) = { "fin_pll", "fout_mfc_pll" }; + +PNAME(mout_topc_group2) = { "mout_sclk_bus0_pll_cmuc", + "mout_sclk_bus1_pll_cmuc", "mout_sclk_cc_pll_cmuc", + "mout_sclk_mfc_pll_cmuc" }; + +PNAME(mout_sclk_bus0_pll_cmuc_p) = { "mout_bus0_pll_ctrl", + "ffac_topc_bus0_pll_div2", "ffac_topc_bus0_pll_div4"}; +PNAME(mout_sclk_bus1_pll_cmuc_p) = { "mout_bus1_pll_ctrl", + "ffac_topc_bus1_pll_div2"}; +PNAME(mout_sclk_cc_pll_cmuc_p) = { "mout_cc_pll_ctrl", + "ffac_topc_cc_pll_div2"}; +PNAME(mout_sclk_mfc_pll_cmuc_p) = { "mout_mfc_pll_ctrl", + "ffac_topc_mfc_pll_div2"}; + + +PNAME(mout_sclk_bus0_pll_out_p) = {"mout_bus0_pll_ctrl", + "ffac_topc_bus0_pll_div2"}; + +static unsigned long topc_clk_regs[] __initdata = { + CC_PLL_LOCK, + BUS0_PLL_LOCK, + BUS1_DPLL_LOCK, + MFC_PLL_LOCK, + AUD_PLL_LOCK, + CC_PLL_CON0, + BUS0_PLL_CON0, + BUS1_DPLL_CON0, + MFC_PLL_CON0, + AUD_PLL_CON0, + MUX_SEL_TOPC0, + MUX_SEL_TOPC1, + MUX_SEL_TOPC2, + MUX_SEL_TOPC3, + DIV_TOPC0, + DIV_TOPC1, + DIV_TOPC3, +}; + +static struct samsung_mux_clock topc_mux_clks[] __initdata = { + MUX(0, "mout_bus0_pll_ctrl", mout_bus0_pll_ctrl_p, MUX_SEL_TOPC0, 0, 1), + MUX(0, "mout_bus1_pll_ctrl", mout_bus1_pll_ctrl_p, MUX_SEL_TOPC0, 4, 1), + MUX(0, "mout_cc_pll_ctrl", mout_cc_pll_ctrl_p, MUX_SEL_TOPC0, 8, 1), + MUX(0, "mout_mfc_pll_ctrl", mout_mfc_pll_ctrl_p, MUX_SEL_TOPC0, 12, 1), + + MUX(0, "mout_sclk_bus0_pll_cmuc", mout_sclk_bus0_pll_cmuc_p, + MUX_SEL_TOPC0, 16, 2), + MUX(0, "mout_sclk_bus1_pll_cmuc", mout_sclk_bus1_pll_cmuc_p, + MUX_SEL_TOPC0, 20, 1), + MUX(0, "mout_sclk_cc_pll_cmuc", mout_sclk_cc_pll_cmuc_p, + MUX_SEL_TOPC0, 24, 1), + MUX(0, "mout_sclk_mfc_pll_cmuc", mout_sclk_mfc_pll_cmuc_p, + MUX_SEL_TOPC0, 28, 1), + + MUX(0, "mout_sclk_bus0_pll_out", mout_sclk_bus0_pll_out_p, + MUX_SEL_TOPC1, 16, 1), + + MUX(0, "mout_aclk_ccore_133", mout_topc_group2, MUX_SEL_TOPC2, 4, 2), + + MUX(0, "mout_aclk_peris_66", mout_topc_group2, MUX_SEL_TOPC3, 24, 2), +}; + +static struct samsung_div_clock topc_div_clks[] __initdata = { + DIV(DOUT_ACLK_CCORE_133, "dout_aclk_ccore_133", "mout_aclk_ccore_133", + DIV_TOPC0, 4, 4), + + DIV(DOUT_ACLK_PERIS, "dout_aclk_peris_66", "mout_aclk_peris_66", + DIV_TOPC1, 24, 4), + + DIV(DOUT_SCLK_BUS0_PLL, "dout_sclk_bus0_pll", "mout_sclk_bus0_pll_out", + DIV_TOPC3, 0, 3), + DIV(DOUT_SCLK_BUS1_PLL, "dout_sclk_bus1_pll", "mout_bus1_pll_ctrl", + DIV_TOPC3, 8, 3), + DIV(DOUT_SCLK_CC_PLL, "dout_sclk_cc_pll", "mout_cc_pll_ctrl", + DIV_TOPC3, 12, 3), + DIV(DOUT_SCLK_MFC_PLL, "dout_sclk_mfc_pll", "mout_mfc_pll_ctrl", + DIV_TOPC3, 16, 3), +}; + +static struct samsung_pll_clock topc_pll_clks[] __initdata = { + PLL(pll_1451x, 0, "fout_bus0_pll", "fin_pll", BUS0_PLL_LOCK, + BUS0_PLL_CON0, NULL), + PLL(pll_1452x, 0, "fout_cc_pll", "fin_pll", CC_PLL_LOCK, + CC_PLL_CON0, NULL), + PLL(pll_1452x, 0, "fout_bus1_pll", "fin_pll", BUS1_DPLL_LOCK, + BUS1_DPLL_CON0, NULL), + PLL(pll_1452x, 0, "fout_mfc_pll", "fin_pll", MFC_PLL_LOCK, + MFC_PLL_CON0, NULL), + PLL(pll_1460x, 0, "fout_aud_pll", "fin_pll", AUD_PLL_LOCK, + AUD_PLL_CON0, NULL), +}; + +static struct samsung_cmu_info topc_cmu_info __initdata = { + .pll_clks = topc_pll_clks, + .nr_pll_clks = ARRAY_SIZE(topc_pll_clks), + .mux_clks = topc_mux_clks, + .nr_mux_clks = ARRAY_SIZE(topc_mux_clks), + .div_clks = topc_div_clks, + .nr_div_clks = ARRAY_SIZE(topc_div_clks), + .fixed_factor_clks = topc_fixed_factor_clks, + .nr_fixed_factor_clks = ARRAY_SIZE(topc_fixed_factor_clks), + .nr_clk_ids = TOPC_NR_CLK, + .clk_regs = topc_clk_regs, + .nr_clk_regs = ARRAY_SIZE(topc_clk_regs), +}; + +static void __init exynos7_clk_topc_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &topc_cmu_info); +} + +CLK_OF_DECLARE(exynos7_clk_topc, "samsung,exynos7-clock-topc", + exynos7_clk_topc_init); + +/* Register Offset definitions for CMU_TOP0 (0x105D0000) */ +#define MUX_SEL_TOP00 0x0200 +#define MUX_SEL_TOP01 0x0204 +#define MUX_SEL_TOP03 0x020C +#define MUX_SEL_TOP0_PERIC3 0x023C +#define DIV_TOP03 0x060C +#define DIV_TOP0_PERIC3 0x063C +#define ENABLE_SCLK_TOP0_PERIC3 0x0A3C + +/* List of parent clocks for Muxes in CMU_TOP0 */ +PNAME(mout_bus0_pll_p) = { "fin_pll", "dout_sclk_bus0_pll" }; +PNAME(mout_bus1_pll_p) = { "fin_pll", "dout_sclk_bus1_pll" }; +PNAME(mout_cc_pll_p) = { "fin_pll", "dout_sclk_cc_pll" }; +PNAME(mout_mfc_pll_p) = { "fin_pll", "dout_sclk_mfc_pll" }; + +PNAME(mout_top0_half_bus0_pll_p) = {"mout_top0_bus0_pll", + "ffac_top0_bus0_pll_div2"}; +PNAME(mout_top0_half_bus1_pll_p) = {"mout_top0_bus1_pll", + "ffac_top0_bus1_pll_div2"}; +PNAME(mout_top0_half_cc_pll_p) = {"mout_top0_cc_pll", + "ffac_top0_cc_pll_div2"}; +PNAME(mout_top0_half_mfc_pll_p) = {"mout_top0_mfc_pll", + "ffac_top0_mfc_pll_div2"}; + +PNAME(mout_top0_group1) = {"mout_top0_half_bus0_pll", + "mout_top0_half_bus1_pll", "mout_top0_half_cc_pll", + "mout_top0_half_mfc_pll"}; + +static unsigned long top0_clk_regs[] __initdata = { + MUX_SEL_TOP00, + MUX_SEL_TOP01, + MUX_SEL_TOP03, + MUX_SEL_TOP0_PERIC3, + DIV_TOP03, + DIV_TOP0_PERIC3, + ENABLE_SCLK_TOP0_PERIC3, +}; + +static struct samsung_mux_clock top0_mux_clks[] __initdata = { + MUX(0, "mout_top0_mfc_pll", mout_mfc_pll_p, MUX_SEL_TOP00, 4, 1), + MUX(0, "mout_top0_cc_pll", mout_cc_pll_p, MUX_SEL_TOP00, 8, 1), + MUX(0, "mout_top0_bus1_pll", mout_bus1_pll_p, MUX_SEL_TOP00, 12, 1), + MUX(0, "mout_top0_bus0_pll", mout_bus0_pll_p, MUX_SEL_TOP00, 16, 1), + + MUX(0, "mout_top0_half_mfc_pll", mout_top0_half_mfc_pll_p, + MUX_SEL_TOP01, 4, 1), + MUX(0, "mout_top0_half_cc_pll", mout_top0_half_cc_pll_p, + MUX_SEL_TOP01, 8, 1), + MUX(0, "mout_top0_half_bus1_pll", mout_top0_half_bus1_pll_p, + MUX_SEL_TOP01, 12, 1), + MUX(0, "mout_top0_half_bus0_pll", mout_top0_half_bus0_pll_p, + MUX_SEL_TOP01, 16, 1), + + MUX(0, "mout_aclk_peric1_66", mout_top0_group1, MUX_SEL_TOP03, 12, 2), + MUX(0, "mout_aclk_peric0_66", mout_top0_group1, MUX_SEL_TOP03, 20, 2), + + MUX(0, "mout_sclk_uart3", mout_top0_group1, MUX_SEL_TOP0_PERIC3, 4, 2), + MUX(0, "mout_sclk_uart2", mout_top0_group1, MUX_SEL_TOP0_PERIC3, 8, 2), + MUX(0, "mout_sclk_uart1", mout_top0_group1, MUX_SEL_TOP0_PERIC3, 12, 2), + MUX(0, "mout_sclk_uart0", mout_top0_group1, MUX_SEL_TOP0_PERIC3, 16, 2), +}; + +static struct samsung_div_clock top0_div_clks[] __initdata = { + DIV(DOUT_ACLK_PERIC1, "dout_aclk_peric1_66", "mout_aclk_peric1_66", + DIV_TOP03, 12, 6), + DIV(DOUT_ACLK_PERIC0, "dout_aclk_peric0_66", "mout_aclk_peric0_66", + DIV_TOP03, 20, 6), + + DIV(0, "dout_sclk_uart3", "mout_sclk_uart3", DIV_TOP0_PERIC3, 4, 4), + DIV(0, "dout_sclk_uart2", "mout_sclk_uart2", DIV_TOP0_PERIC3, 8, 4), + DIV(0, "dout_sclk_uart1", "mout_sclk_uart1", DIV_TOP0_PERIC3, 12, 4), + DIV(0, "dout_sclk_uart0", "mout_sclk_uart0", DIV_TOP0_PERIC3, 16, 4), +}; + +static struct samsung_gate_clock top0_gate_clks[] __initdata = { + GATE(CLK_SCLK_UART3, "sclk_uart3", "dout_sclk_uart3", + ENABLE_SCLK_TOP0_PERIC3, 4, 0, 0), + GATE(CLK_SCLK_UART2, "sclk_uart2", "dout_sclk_uart2", + ENABLE_SCLK_TOP0_PERIC3, 8, 0, 0), + GATE(CLK_SCLK_UART1, "sclk_uart1", "dout_sclk_uart1", + ENABLE_SCLK_TOP0_PERIC3, 12, 0, 0), + GATE(CLK_SCLK_UART0, "sclk_uart0", "dout_sclk_uart0", + ENABLE_SCLK_TOP0_PERIC3, 16, 0, 0), +}; + +static struct samsung_fixed_factor_clock top0_fixed_factor_clks[] __initdata = { + FFACTOR(0, "ffac_top0_bus0_pll_div2", "mout_top0_bus0_pll", 1, 2, 0), + FFACTOR(0, "ffac_top0_bus1_pll_div2", "mout_top0_bus1_pll", 1, 2, 0), + FFACTOR(0, "ffac_top0_cc_pll_div2", "mout_top0_cc_pll", 1, 2, 0), + FFACTOR(0, "ffac_top0_mfc_pll_div2", "mout_top0_mfc_pll", 1, 2, 0), +}; + +static struct samsung_cmu_info top0_cmu_info __initdata = { + .mux_clks = top0_mux_clks, + .nr_mux_clks = ARRAY_SIZE(top0_mux_clks), + .div_clks = top0_div_clks, + .nr_div_clks = ARRAY_SIZE(top0_div_clks), + .gate_clks = top0_gate_clks, + .nr_gate_clks = ARRAY_SIZE(top0_gate_clks), + .fixed_factor_clks = top0_fixed_factor_clks, + .nr_fixed_factor_clks = ARRAY_SIZE(top0_fixed_factor_clks), + .nr_clk_ids = TOP0_NR_CLK, + .clk_regs = top0_clk_regs, + .nr_clk_regs = ARRAY_SIZE(top0_clk_regs), +}; + +static void __init exynos7_clk_top0_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &top0_cmu_info); +} + +CLK_OF_DECLARE(exynos7_clk_top0, "samsung,exynos7-clock-top0", + exynos7_clk_top0_init); + +/* Register Offset definitions for CMU_TOP1 (0x105E0000) */ +#define MUX_SEL_TOP10 0x0200 +#define MUX_SEL_TOP11 0x0204 +#define MUX_SEL_TOP13 0x020C +#define MUX_SEL_TOP1_FSYS0 0x0224 +#define MUX_SEL_TOP1_FSYS1 0x0228 +#define DIV_TOP13 0x060C +#define DIV_TOP1_FSYS0 0x0624 +#define DIV_TOP1_FSYS1 0x0628 +#define ENABLE_ACLK_TOP13 0x080C +#define ENABLE_SCLK_TOP1_FSYS0 0x0A24 +#define ENABLE_SCLK_TOP1_FSYS1 0x0A28 + +/* List of parent clocks for Muxes in CMU_TOP1 */ +PNAME(mout_top1_bus0_pll_p) = { "fin_pll", "dout_sclk_bus0_pll" }; +PNAME(mout_top1_bus1_pll_p) = { "fin_pll", "dout_sclk_bus1_pll_b" }; +PNAME(mout_top1_cc_pll_p) = { "fin_pll", "dout_sclk_cc_pll_b" }; +PNAME(mout_top1_mfc_pll_p) = { "fin_pll", "dout_sclk_mfc_pll_b" }; + +PNAME(mout_top1_half_bus0_pll_p) = {"mout_top1_bus0_pll", + "ffac_top1_bus0_pll_div2"}; +PNAME(mout_top1_half_bus1_pll_p) = {"mout_top1_bus1_pll", + "ffac_top1_bus1_pll_div2"}; +PNAME(mout_top1_half_cc_pll_p) = {"mout_top1_cc_pll", + "ffac_top1_cc_pll_div2"}; +PNAME(mout_top1_half_mfc_pll_p) = {"mout_top1_mfc_pll", + "ffac_top1_mfc_pll_div2"}; + +PNAME(mout_top1_group1) = {"mout_top1_half_bus0_pll", + "mout_top1_half_bus1_pll", "mout_top1_half_cc_pll", + "mout_top1_half_mfc_pll"}; + +static unsigned long top1_clk_regs[] __initdata = { + MUX_SEL_TOP10, + MUX_SEL_TOP11, + MUX_SEL_TOP13, + MUX_SEL_TOP1_FSYS0, + MUX_SEL_TOP1_FSYS1, + DIV_TOP13, + DIV_TOP1_FSYS0, + DIV_TOP1_FSYS1, + ENABLE_ACLK_TOP13, + ENABLE_SCLK_TOP1_FSYS0, + ENABLE_SCLK_TOP1_FSYS1, +}; + +static struct samsung_mux_clock top1_mux_clks[] __initdata = { + MUX(0, "mout_top1_mfc_pll", mout_top1_mfc_pll_p, MUX_SEL_TOP10, 4, 1), + MUX(0, "mout_top1_cc_pll", mout_top1_cc_pll_p, MUX_SEL_TOP10, 8, 1), + MUX(0, "mout_top1_bus1_pll", mout_top1_bus1_pll_p, + MUX_SEL_TOP10, 12, 1), + MUX(0, "mout_top1_bus0_pll", mout_top1_bus0_pll_p, + MUX_SEL_TOP10, 16, 1), + + MUX(0, "mout_top1_half_mfc_pll", mout_top1_half_mfc_pll_p, + MUX_SEL_TOP11, 4, 1), + MUX(0, "mout_top1_half_cc_pll", mout_top1_half_cc_pll_p, + MUX_SEL_TOP11, 8, 1), + MUX(0, "mout_top1_half_bus1_pll", mout_top1_half_bus1_pll_p, + MUX_SEL_TOP11, 12, 1), + MUX(0, "mout_top1_half_bus0_pll", mout_top1_half_bus0_pll_p, + MUX_SEL_TOP11, 16, 1), + + MUX(0, "mout_aclk_fsys1_200", mout_top1_group1, MUX_SEL_TOP13, 24, 2), + MUX(0, "mout_aclk_fsys0_200", mout_top1_group1, MUX_SEL_TOP13, 28, 2), + + MUX(0, "mout_sclk_mmc2", mout_top1_group1, MUX_SEL_TOP1_FSYS0, 24, 2), + + MUX(0, "mout_sclk_mmc1", mout_top1_group1, MUX_SEL_TOP1_FSYS1, 24, 2), + MUX(0, "mout_sclk_mmc0", mout_top1_group1, MUX_SEL_TOP1_FSYS1, 28, 2), +}; + +static struct samsung_div_clock top1_div_clks[] __initdata = { + DIV(DOUT_ACLK_FSYS1_200, "dout_aclk_fsys1_200", "mout_aclk_fsys1_200", + DIV_TOP13, 24, 4), + DIV(DOUT_ACLK_FSYS0_200, "dout_aclk_fsys0_200", "mout_aclk_fsys0_200", + DIV_TOP13, 28, 4), + + DIV(DOUT_SCLK_MMC2, "dout_sclk_mmc2", "mout_sclk_mmc2", + DIV_TOP1_FSYS0, 24, 4), + + DIV(DOUT_SCLK_MMC1, "dout_sclk_mmc1", "mout_sclk_mmc1", + DIV_TOP1_FSYS1, 24, 4), + DIV(DOUT_SCLK_MMC0, "dout_sclk_mmc0", "mout_sclk_mmc0", + DIV_TOP1_FSYS1, 28, 4), +}; + +static struct samsung_gate_clock top1_gate_clks[] __initdata = { + GATE(CLK_SCLK_MMC2, "sclk_mmc2", "dout_sclk_mmc2", + ENABLE_SCLK_TOP1_FSYS0, 24, CLK_SET_RATE_PARENT, 0), + + GATE(CLK_SCLK_MMC1, "sclk_mmc1", "dout_sclk_mmc1", + ENABLE_SCLK_TOP1_FSYS1, 24, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MMC0, "sclk_mmc0", "dout_sclk_mmc0", + ENABLE_SCLK_TOP1_FSYS1, 28, CLK_SET_RATE_PARENT, 0), +}; + +static struct samsung_fixed_factor_clock top1_fixed_factor_clks[] __initdata = { + FFACTOR(0, "ffac_top1_bus0_pll_div2", "mout_top1_bus0_pll", 1, 2, 0), + FFACTOR(0, "ffac_top1_bus1_pll_div2", "mout_top1_bus1_pll", 1, 2, 0), + FFACTOR(0, "ffac_top1_cc_pll_div2", "mout_top1_cc_pll", 1, 2, 0), + FFACTOR(0, "ffac_top1_mfc_pll_div2", "mout_top1_mfc_pll", 1, 2, 0), +}; + +static struct samsung_cmu_info top1_cmu_info __initdata = { + .mux_clks = top1_mux_clks, + .nr_mux_clks = ARRAY_SIZE(top1_mux_clks), + .div_clks = top1_div_clks, + .nr_div_clks = ARRAY_SIZE(top1_div_clks), + .gate_clks = top1_gate_clks, + .nr_gate_clks = ARRAY_SIZE(top1_gate_clks), + .fixed_factor_clks = top1_fixed_factor_clks, + .nr_fixed_factor_clks = ARRAY_SIZE(top1_fixed_factor_clks), + .nr_clk_ids = TOP1_NR_CLK, + .clk_regs = top1_clk_regs, + .nr_clk_regs = ARRAY_SIZE(top1_clk_regs), +}; + +static void __init exynos7_clk_top1_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &top1_cmu_info); +} + +CLK_OF_DECLARE(exynos7_clk_top1, "samsung,exynos7-clock-top1", + exynos7_clk_top1_init); + +/* Register Offset definitions for CMU_CCORE (0x105B0000) */ +#define MUX_SEL_CCORE 0x0200 +#define DIV_CCORE 0x0600 +#define ENABLE_ACLK_CCORE0 0x0800 +#define ENABLE_ACLK_CCORE1 0x0804 +#define ENABLE_PCLK_CCORE 0x0900 + +/* + * List of parent clocks for Muxes in CMU_CCORE + */ +PNAME(mout_aclk_ccore_133_p) = { "fin_pll", "dout_aclk_ccore_133" }; + +static unsigned long ccore_clk_regs[] __initdata = { + MUX_SEL_CCORE, + ENABLE_PCLK_CCORE, +}; + +static struct samsung_mux_clock ccore_mux_clks[] __initdata = { + MUX(0, "mout_aclk_ccore_133_user", mout_aclk_ccore_133_p, + MUX_SEL_CCORE, 1, 1), +}; + +static struct samsung_gate_clock ccore_gate_clks[] __initdata = { + GATE(PCLK_RTC, "pclk_rtc", "mout_aclk_ccore_133_user", + ENABLE_PCLK_CCORE, 8, 0, 0), +}; + +static struct samsung_cmu_info ccore_cmu_info __initdata = { + .mux_clks = ccore_mux_clks, + .nr_mux_clks = ARRAY_SIZE(ccore_mux_clks), + .gate_clks = ccore_gate_clks, + .nr_gate_clks = ARRAY_SIZE(ccore_gate_clks), + .nr_clk_ids = CCORE_NR_CLK, + .clk_regs = ccore_clk_regs, + .nr_clk_regs = ARRAY_SIZE(ccore_clk_regs), +}; + +static void __init exynos7_clk_ccore_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &ccore_cmu_info); +} + +CLK_OF_DECLARE(exynos7_clk_ccore, "samsung,exynos7-clock-ccore", + exynos7_clk_ccore_init); + +/* Register Offset definitions for CMU_PERIC0 (0x13610000) */ +#define MUX_SEL_PERIC0 0x0200 +#define ENABLE_PCLK_PERIC0 0x0900 +#define ENABLE_SCLK_PERIC0 0x0A00 + +/* List of parent clocks for Muxes in CMU_PERIC0 */ +PNAME(mout_aclk_peric0_66_p) = { "fin_pll", "dout_aclk_peric0_66" }; +PNAME(mout_sclk_uart0_p) = { "fin_pll", "sclk_uart0" }; + +static unsigned long peric0_clk_regs[] __initdata = { + MUX_SEL_PERIC0, + ENABLE_PCLK_PERIC0, + ENABLE_SCLK_PERIC0, +}; + +static struct samsung_mux_clock peric0_mux_clks[] __initdata = { + MUX(0, "mout_aclk_peric0_66_user", mout_aclk_peric0_66_p, + MUX_SEL_PERIC0, 0, 1), + MUX(0, "mout_sclk_uart0_user", mout_sclk_uart0_p, + MUX_SEL_PERIC0, 16, 1), +}; + +static struct samsung_gate_clock peric0_gate_clks[] __initdata = { + GATE(PCLK_HSI2C0, "pclk_hsi2c0", "mout_aclk_peric0_66_user", + ENABLE_PCLK_PERIC0, 8, 0, 0), + GATE(PCLK_HSI2C1, "pclk_hsi2c1", "mout_aclk_peric0_66_user", + ENABLE_PCLK_PERIC0, 9, 0, 0), + GATE(PCLK_HSI2C4, "pclk_hsi2c4", "mout_aclk_peric0_66_user", + ENABLE_PCLK_PERIC0, 10, 0, 0), + GATE(PCLK_HSI2C5, "pclk_hsi2c5", "mout_aclk_peric0_66_user", + ENABLE_PCLK_PERIC0, 11, 0, 0), + GATE(PCLK_HSI2C9, "pclk_hsi2c9", "mout_aclk_peric0_66_user", + ENABLE_PCLK_PERIC0, 12, 0, 0), + GATE(PCLK_HSI2C10, "pclk_hsi2c10", "mout_aclk_peric0_66_user", + ENABLE_PCLK_PERIC0, 13, 0, 0), + GATE(PCLK_HSI2C11, "pclk_hsi2c11", "mout_aclk_peric0_66_user", + ENABLE_PCLK_PERIC0, 14, 0, 0), + GATE(PCLK_UART0, "pclk_uart0", "mout_aclk_peric0_66_user", + ENABLE_PCLK_PERIC0, 16, 0, 0), + GATE(PCLK_ADCIF, "pclk_adcif", "mout_aclk_peric0_66_user", + ENABLE_PCLK_PERIC0, 20, 0, 0), + GATE(PCLK_PWM, "pclk_pwm", "mout_aclk_peric0_66_user", + ENABLE_PCLK_PERIC0, 21, 0, 0), + + GATE(SCLK_UART0, "sclk_uart0_user", "mout_sclk_uart0_user", + ENABLE_SCLK_PERIC0, 16, 0, 0), + GATE(SCLK_PWM, "sclk_pwm", "fin_pll", ENABLE_SCLK_PERIC0, 21, 0, 0), +}; + +static struct samsung_cmu_info peric0_cmu_info __initdata = { + .mux_clks = peric0_mux_clks, + .nr_mux_clks = ARRAY_SIZE(peric0_mux_clks), + .gate_clks = peric0_gate_clks, + .nr_gate_clks = ARRAY_SIZE(peric0_gate_clks), + .nr_clk_ids = PERIC0_NR_CLK, + .clk_regs = peric0_clk_regs, + .nr_clk_regs = ARRAY_SIZE(peric0_clk_regs), +}; + +static void __init exynos7_clk_peric0_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &peric0_cmu_info); +} + +/* Register Offset definitions for CMU_PERIC1 (0x14C80000) */ +#define MUX_SEL_PERIC10 0x0200 +#define MUX_SEL_PERIC11 0x0204 +#define ENABLE_PCLK_PERIC1 0x0900 +#define ENABLE_SCLK_PERIC10 0x0A00 + +CLK_OF_DECLARE(exynos7_clk_peric0, "samsung,exynos7-clock-peric0", + exynos7_clk_peric0_init); + +/* List of parent clocks for Muxes in CMU_PERIC1 */ +PNAME(mout_aclk_peric1_66_p) = { "fin_pll", "dout_aclk_peric1_66" }; +PNAME(mout_sclk_uart1_p) = { "fin_pll", "sclk_uart1" }; +PNAME(mout_sclk_uart2_p) = { "fin_pll", "sclk_uart2" }; +PNAME(mout_sclk_uart3_p) = { "fin_pll", "sclk_uart3" }; + +static unsigned long peric1_clk_regs[] __initdata = { + MUX_SEL_PERIC10, + MUX_SEL_PERIC11, + ENABLE_PCLK_PERIC1, + ENABLE_SCLK_PERIC10, +}; + +static struct samsung_mux_clock peric1_mux_clks[] __initdata = { + MUX(0, "mout_aclk_peric1_66_user", mout_aclk_peric1_66_p, + MUX_SEL_PERIC10, 0, 1), + + MUX(0, "mout_sclk_uart1_user", mout_sclk_uart1_p, + MUX_SEL_PERIC11, 20, 1), + MUX(0, "mout_sclk_uart2_user", mout_sclk_uart2_p, + MUX_SEL_PERIC11, 24, 1), + MUX(0, "mout_sclk_uart3_user", mout_sclk_uart3_p, + MUX_SEL_PERIC11, 28, 1), +}; + +static struct samsung_gate_clock peric1_gate_clks[] __initdata = { + GATE(PCLK_HSI2C2, "pclk_hsi2c2", "mout_aclk_peric1_66_user", + ENABLE_PCLK_PERIC1, 4, 0, 0), + GATE(PCLK_HSI2C3, "pclk_hsi2c3", "mout_aclk_peric1_66_user", + ENABLE_PCLK_PERIC1, 5, 0, 0), + GATE(PCLK_HSI2C6, "pclk_hsi2c6", "mout_aclk_peric1_66_user", + ENABLE_PCLK_PERIC1, 6, 0, 0), + GATE(PCLK_HSI2C7, "pclk_hsi2c7", "mout_aclk_peric1_66_user", + ENABLE_PCLK_PERIC1, 7, 0, 0), + GATE(PCLK_HSI2C8, "pclk_hsi2c8", "mout_aclk_peric1_66_user", + ENABLE_PCLK_PERIC1, 8, 0, 0), + GATE(PCLK_UART1, "pclk_uart1", "mout_aclk_peric1_66_user", + ENABLE_PCLK_PERIC1, 9, 0, 0), + GATE(PCLK_UART2, "pclk_uart2", "mout_aclk_peric1_66_user", + ENABLE_PCLK_PERIC1, 10, 0, 0), + GATE(PCLK_UART3, "pclk_uart3", "mout_aclk_peric1_66_user", + ENABLE_PCLK_PERIC1, 11, 0, 0), + + GATE(SCLK_UART1, "sclk_uart1_user", "mout_sclk_uart1_user", + ENABLE_SCLK_PERIC10, 9, 0, 0), + GATE(SCLK_UART2, "sclk_uart2_user", "mout_sclk_uart2_user", + ENABLE_SCLK_PERIC10, 10, 0, 0), + GATE(SCLK_UART3, "sclk_uart3_user", "mout_sclk_uart3_user", + ENABLE_SCLK_PERIC10, 11, 0, 0), +}; + +static struct samsung_cmu_info peric1_cmu_info __initdata = { + .mux_clks = peric1_mux_clks, + .nr_mux_clks = ARRAY_SIZE(peric1_mux_clks), + .gate_clks = peric1_gate_clks, + .nr_gate_clks = ARRAY_SIZE(peric1_gate_clks), + .nr_clk_ids = PERIC1_NR_CLK, + .clk_regs = peric1_clk_regs, + .nr_clk_regs = ARRAY_SIZE(peric1_clk_regs), +}; + +static void __init exynos7_clk_peric1_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &peric1_cmu_info); +} + +CLK_OF_DECLARE(exynos7_clk_peric1, "samsung,exynos7-clock-peric1", + exynos7_clk_peric1_init); + +/* Register Offset definitions for CMU_PERIS (0x10040000) */ +#define MUX_SEL_PERIS 0x0200 +#define ENABLE_PCLK_PERIS 0x0900 +#define ENABLE_PCLK_PERIS_SECURE_CHIPID 0x0910 +#define ENABLE_SCLK_PERIS 0x0A00 +#define ENABLE_SCLK_PERIS_SECURE_CHIPID 0x0A10 + +/* List of parent clocks for Muxes in CMU_PERIS */ +PNAME(mout_aclk_peris_66_p) = { "fin_pll", "dout_aclk_peris_66" }; + +static unsigned long peris_clk_regs[] __initdata = { + MUX_SEL_PERIS, + ENABLE_PCLK_PERIS, + ENABLE_PCLK_PERIS_SECURE_CHIPID, + ENABLE_SCLK_PERIS, + ENABLE_SCLK_PERIS_SECURE_CHIPID, +}; + +static struct samsung_mux_clock peris_mux_clks[] __initdata = { + MUX(0, "mout_aclk_peris_66_user", + mout_aclk_peris_66_p, MUX_SEL_PERIS, 0, 1), +}; + +static struct samsung_gate_clock peris_gate_clks[] __initdata = { + GATE(PCLK_WDT, "pclk_wdt", "mout_aclk_peris_66_user", + ENABLE_PCLK_PERIS, 6, 0, 0), + GATE(PCLK_TMU, "pclk_tmu_apbif", "mout_aclk_peris_66_user", + ENABLE_PCLK_PERIS, 10, 0, 0), + + GATE(PCLK_CHIPID, "pclk_chipid", "mout_aclk_peris_66_user", + ENABLE_PCLK_PERIS_SECURE_CHIPID, 0, 0, 0), + GATE(SCLK_CHIPID, "sclk_chipid", "fin_pll", + ENABLE_SCLK_PERIS_SECURE_CHIPID, 0, 0, 0), + + GATE(SCLK_TMU, "sclk_tmu", "fin_pll", ENABLE_SCLK_PERIS, 10, 0, 0), +}; + +static struct samsung_cmu_info peris_cmu_info __initdata = { + .mux_clks = peris_mux_clks, + .nr_mux_clks = ARRAY_SIZE(peris_mux_clks), + .gate_clks = peris_gate_clks, + .nr_gate_clks = ARRAY_SIZE(peris_gate_clks), + .nr_clk_ids = PERIS_NR_CLK, + .clk_regs = peris_clk_regs, + .nr_clk_regs = ARRAY_SIZE(peris_clk_regs), +}; + +static void __init exynos7_clk_peris_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &peris_cmu_info); +} + +CLK_OF_DECLARE(exynos7_clk_peris, "samsung,exynos7-clock-peris", + exynos7_clk_peris_init); + +/* Register Offset definitions for CMU_FSYS0 (0x10E90000) */ +#define MUX_SEL_FSYS00 0x0200 +#define MUX_SEL_FSYS01 0x0204 +#define ENABLE_ACLK_FSYS01 0x0804 + +/* + * List of parent clocks for Muxes in CMU_FSYS0 + */ +PNAME(mout_aclk_fsys0_200_p) = { "fin_pll", "dout_aclk_fsys0_200" }; +PNAME(mout_sclk_mmc2_p) = { "fin_pll", "sclk_mmc2" }; + +static unsigned long fsys0_clk_regs[] __initdata = { + MUX_SEL_FSYS00, + MUX_SEL_FSYS01, + ENABLE_ACLK_FSYS01, +}; + +static struct samsung_mux_clock fsys0_mux_clks[] __initdata = { + MUX(0, "mout_aclk_fsys0_200_user", mout_aclk_fsys0_200_p, + MUX_SEL_FSYS00, 24, 1), + + MUX(0, "mout_sclk_mmc2_user", mout_sclk_mmc2_p, MUX_SEL_FSYS01, 24, 1), +}; + +static struct samsung_gate_clock fsys0_gate_clks[] __initdata = { + GATE(ACLK_MMC2, "aclk_mmc2", "mout_aclk_fsys0_200_user", + ENABLE_ACLK_FSYS01, 31, 0, 0), +}; + +static struct samsung_cmu_info fsys0_cmu_info __initdata = { + .mux_clks = fsys0_mux_clks, + .nr_mux_clks = ARRAY_SIZE(fsys0_mux_clks), + .gate_clks = fsys0_gate_clks, + .nr_gate_clks = ARRAY_SIZE(fsys0_gate_clks), + .nr_clk_ids = TOP1_NR_CLK, + .clk_regs = fsys0_clk_regs, + .nr_clk_regs = ARRAY_SIZE(fsys0_clk_regs), +}; + +static void __init exynos7_clk_fsys0_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &fsys0_cmu_info); +} + +CLK_OF_DECLARE(exynos7_clk_fsys0, "samsung,exynos7-clock-fsys0", + exynos7_clk_fsys0_init); + +/* Register Offset definitions for CMU_FSYS1 (0x156E0000) */ +#define MUX_SEL_FSYS10 0x0200 +#define MUX_SEL_FSYS11 0x0204 +#define ENABLE_ACLK_FSYS1 0x0800 + +/* + * List of parent clocks for Muxes in CMU_FSYS1 + */ +PNAME(mout_aclk_fsys1_200_p) = { "fin_pll", "dout_aclk_fsys1_200" }; +PNAME(mout_sclk_mmc0_p) = { "fin_pll", "sclk_mmc0" }; +PNAME(mout_sclk_mmc1_p) = { "fin_pll", "sclk_mmc1" }; + +static unsigned long fsys1_clk_regs[] __initdata = { + MUX_SEL_FSYS10, + MUX_SEL_FSYS11, + ENABLE_ACLK_FSYS1, +}; + +static struct samsung_mux_clock fsys1_mux_clks[] __initdata = { + MUX(0, "mout_aclk_fsys1_200_user", mout_aclk_fsys1_200_p, + MUX_SEL_FSYS10, 28, 1), + + MUX(0, "mout_sclk_mmc1_user", mout_sclk_mmc1_p, MUX_SEL_FSYS11, 24, 1), + MUX(0, "mout_sclk_mmc0_user", mout_sclk_mmc0_p, MUX_SEL_FSYS11, 28, 1), +}; + +static struct samsung_gate_clock fsys1_gate_clks[] __initdata = { + GATE(ACLK_MMC1, "aclk_mmc1", "mout_aclk_fsys1_200_user", + ENABLE_ACLK_FSYS1, 29, 0, 0), + GATE(ACLK_MMC0, "aclk_mmc0", "mout_aclk_fsys1_200_user", + ENABLE_ACLK_FSYS1, 30, 0, 0), +}; + +static struct samsung_cmu_info fsys1_cmu_info __initdata = { + .mux_clks = fsys1_mux_clks, + .nr_mux_clks = ARRAY_SIZE(fsys1_mux_clks), + .gate_clks = fsys1_gate_clks, + .nr_gate_clks = ARRAY_SIZE(fsys1_gate_clks), + .nr_clk_ids = TOP1_NR_CLK, + .clk_regs = fsys1_clk_regs, + .nr_clk_regs = ARRAY_SIZE(fsys1_clk_regs), +}; + +static void __init exynos7_clk_fsys1_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &fsys1_cmu_info); +} + +CLK_OF_DECLARE(exynos7_clk_fsys1, "samsung,exynos7-clock-fsys1", + exynos7_clk_fsys1_init); diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index b07fad2a9167..9d70e5c03804 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -482,6 +482,8 @@ static const struct clk_ops samsung_pll45xx_clk_min_ops = { #define PLL46XX_VSEL_MASK (1) #define PLL46XX_MDIV_MASK (0x1FF) +#define PLL1460X_MDIV_MASK (0x3FF) + #define PLL46XX_PDIV_MASK (0x3F) #define PLL46XX_SDIV_MASK (0x7) #define PLL46XX_VSEL_SHIFT (27) @@ -511,13 +513,15 @@ static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw, pll_con0 = __raw_readl(pll->con_reg); pll_con1 = __raw_readl(pll->con_reg + 4); - mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK; + mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & ((pll->type == pll_1460x) ? + PLL1460X_MDIV_MASK : PLL46XX_MDIV_MASK); pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK; sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK; kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK : pll_con1 & PLL46XX_KDIV_MASK; - shift = pll->type == pll_4600 ? 16 : 10; + shift = ((pll->type == pll_4600) || (pll->type == pll_1460x)) ? 16 : 10; + fvco *= (mdiv << shift) + kdiv; do_div(fvco, (pdiv << sdiv)); fvco >>= shift; @@ -573,14 +577,21 @@ static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate, lock = 0xffff; /* Set PLL PMS and VSEL values. */ - con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) | + if (pll->type == pll_1460x) { + con0 &= ~((PLL1460X_MDIV_MASK << PLL46XX_MDIV_SHIFT) | + (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) | + (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT)); + } else { + con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) | (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) | (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT) | (PLL46XX_VSEL_MASK << PLL46XX_VSEL_SHIFT)); + con0 |= rate->vsel << PLL46XX_VSEL_SHIFT; + } + con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) | (rate->pdiv << PLL46XX_PDIV_SHIFT) | - (rate->sdiv << PLL46XX_SDIV_SHIFT) | - (rate->vsel << PLL46XX_VSEL_SHIFT); + (rate->sdiv << PLL46XX_SDIV_SHIFT); /* Set PLL K, MFR and MRR values. */ con1 = __raw_readl(pll->con_reg + 0x4); @@ -1190,6 +1201,9 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, /* clk_ops for 35xx and 2550 are similar */ case pll_35xx: case pll_2550: + case pll_1450x: + case pll_1451x: + case pll_1452x: if (!pll->rate_table) init.ops = &samsung_pll35xx_clk_min_ops; else @@ -1223,6 +1237,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, case pll_4600: case pll_4650: case pll_4650c: + case pll_1460x: if (!pll->rate_table) init.ops = &samsung_pll46xx_clk_min_ops; else diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h index c0ed4d41fd90..213de9af8b4f 100644 --- a/drivers/clk/samsung/clk-pll.h +++ b/drivers/clk/samsung/clk-pll.h @@ -33,6 +33,10 @@ enum samsung_pll_type { pll_s3c2440_mpll, pll_2550xx, pll_2650xx, + pll_1450x, + pll_1451x, + pll_1452x, + pll_1460x, }; #define PLL_35XX_RATE(_rate, _m, _p, _s) \ diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index deab84d9f37d..4bda54095a16 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -11,9 +11,13 @@ * clock framework for Samsung platforms. */ +#include <linux/of_address.h> #include <linux/syscore_ops.h> + #include "clk.h" +static LIST_HEAD(clock_reg_cache_list); + void samsung_clk_save(void __iomem *base, struct samsung_clk_reg_dump *rd, unsigned int num_regs) @@ -281,7 +285,6 @@ void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, * obtain the clock speed of all external fixed clock sources from device * tree and register it */ -#ifdef CONFIG_OF void __init samsung_clk_of_register_fixed_ext(struct samsung_clk_provider *ctx, struct samsung_fixed_rate_clock *fixed_rate_clk, unsigned int nr_fixed_rate_clk, @@ -298,7 +301,6 @@ void __init samsung_clk_of_register_fixed_ext(struct samsung_clk_provider *ctx, } samsung_clk_register_fixed_rate(ctx, fixed_rate_clk, nr_fixed_rate_clk); } -#endif /* utility function to get the rate of a specified clock */ unsigned long _get_rate(const char *clk_name) @@ -313,3 +315,99 @@ unsigned long _get_rate(const char *clk_name) return clk_get_rate(clk); } + +#ifdef CONFIG_PM_SLEEP +static int samsung_clk_suspend(void) +{ + struct samsung_clock_reg_cache *reg_cache; + + list_for_each_entry(reg_cache, &clock_reg_cache_list, node) + samsung_clk_save(reg_cache->reg_base, reg_cache->rdump, + reg_cache->rd_num); + return 0; +} + +static void samsung_clk_resume(void) +{ + struct samsung_clock_reg_cache *reg_cache; + + list_for_each_entry(reg_cache, &clock_reg_cache_list, node) + samsung_clk_restore(reg_cache->reg_base, reg_cache->rdump, + reg_cache->rd_num); +} + +static struct syscore_ops samsung_clk_syscore_ops = { + .suspend = samsung_clk_suspend, + .resume = samsung_clk_resume, +}; + +static void samsung_clk_sleep_init(void __iomem *reg_base, + const unsigned long *rdump, + unsigned long nr_rdump) +{ + struct samsung_clock_reg_cache *reg_cache; + + reg_cache = kzalloc(sizeof(struct samsung_clock_reg_cache), + GFP_KERNEL); + if (!reg_cache) + panic("could not allocate register reg_cache.\n"); + reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump); + + if (!reg_cache->rdump) + panic("could not allocate register dump storage.\n"); + + if (list_empty(&clock_reg_cache_list)) + register_syscore_ops(&samsung_clk_syscore_ops); + + reg_cache->reg_base = reg_base; + reg_cache->rd_num = nr_rdump; + list_add_tail(®_cache->node, &clock_reg_cache_list); +} + +#else +static void samsung_clk_sleep_init(void __iomem *reg_base, + const unsigned long *rdump, + unsigned long nr_rdump) {} +#endif + +/* + * Common function which registers plls, muxes, dividers and gates + * for each CMU. It also add CMU register list to register cache. + */ +void __init samsung_cmu_register_one(struct device_node *np, + struct samsung_cmu_info *cmu) +{ + void __iomem *reg_base; + struct samsung_clk_provider *ctx; + + reg_base = of_iomap(np, 0); + if (!reg_base) + panic("%s: failed to map registers\n", __func__); + + ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids); + if (!ctx) + panic("%s: unable to alllocate ctx\n", __func__); + + if (cmu->pll_clks) + samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks, + reg_base); + if (cmu->mux_clks) + samsung_clk_register_mux(ctx, cmu->mux_clks, + cmu->nr_mux_clks); + if (cmu->div_clks) + samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks); + if (cmu->gate_clks) + samsung_clk_register_gate(ctx, cmu->gate_clks, + cmu->nr_gate_clks); + if (cmu->fixed_clks) + samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks, + cmu->nr_fixed_clks); + if (cmu->fixed_factor_clks) + samsung_clk_register_fixed_factor(ctx, cmu->fixed_factor_clks, + cmu->nr_fixed_factor_clks); + if (cmu->clk_regs) + samsung_clk_sleep_init(reg_base, cmu->clk_regs, + cmu->nr_clk_regs); + + samsung_clk_of_add_provider(np, ctx); +} diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index 66ab36b5cef1..8acabe1f32c4 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -13,19 +13,15 @@ #ifndef __SAMSUNG_CLK_H #define __SAMSUNG_CLK_H -#include <linux/clk.h> #include <linux/clkdev.h> -#include <linux/io.h> #include <linux/clk-provider.h> -#include <linux/of.h> -#include <linux/of_address.h> #include "clk-pll.h" /** * struct samsung_clk_provider: information about clock provider * @reg_base: virtual address for the register base. * @clk_data: holds clock related data like clk* and number of clocks. - * @lock: maintains exclusion bwtween callbacks for a given clock-provider. + * @lock: maintains exclusion between callbacks for a given clock-provider. */ struct samsung_clk_provider { void __iomem *reg_base; @@ -324,6 +320,40 @@ struct samsung_pll_clock { __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \ _lock, _con, _rtable, _alias) +struct samsung_clock_reg_cache { + struct list_head node; + void __iomem *reg_base; + struct samsung_clk_reg_dump *rdump; + unsigned int rd_num; +}; + +struct samsung_cmu_info { + /* list of pll clocks and respective count */ + struct samsung_pll_clock *pll_clks; + unsigned int nr_pll_clks; + /* list of mux clocks and respective count */ + struct samsung_mux_clock *mux_clks; + unsigned int nr_mux_clks; + /* list of div clocks and respective count */ + struct samsung_div_clock *div_clks; + unsigned int nr_div_clks; + /* list of gate clocks and respective count */ + struct samsung_gate_clock *gate_clks; + unsigned int nr_gate_clks; + /* list of fixed clocks and respective count */ + struct samsung_fixed_rate_clock *fixed_clks; + unsigned int nr_fixed_clks; + /* list of fixed factor clocks and respective count */ + struct samsung_fixed_factor_clock *fixed_factor_clks; + unsigned int nr_fixed_factor_clks; + /* total number of clocks with IDs assigned*/ + unsigned int nr_clk_ids; + + /* list and number of clocks registers */ + unsigned long *clk_regs; + unsigned int nr_clk_regs; +}; + extern struct samsung_clk_provider *__init samsung_clk_init( struct device_node *np, void __iomem *base, unsigned long nr_clks); @@ -362,6 +392,9 @@ extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx, struct samsung_pll_clock *pll_list, unsigned int nr_clk, void __iomem *base); +extern void __init samsung_cmu_register_one(struct device_node *, + struct samsung_cmu_info *); + extern unsigned long _get_rate(const char *clk_name); extern void samsung_clk_save(void __iomem *base, diff --git a/drivers/clk/shmobile/clk-div6.c b/drivers/clk/shmobile/clk-div6.c index f065f694cb65..639241e31e03 100644 --- a/drivers/clk/shmobile/clk-div6.c +++ b/drivers/clk/shmobile/clk-div6.c @@ -32,6 +32,9 @@ struct div6_clock { struct clk_hw hw; void __iomem *reg; unsigned int div; + u32 src_shift; + u32 src_width; + u8 *parents; }; #define to_div6_clock(_hw) container_of(_hw, struct div6_clock, hw) @@ -39,8 +42,11 @@ struct div6_clock { static int cpg_div6_clock_enable(struct clk_hw *hw) { struct div6_clock *clock = to_div6_clock(hw); + u32 val; - clk_writel(CPG_DIV6_DIV(clock->div - 1), clock->reg); + val = (clk_readl(clock->reg) & ~(CPG_DIV6_DIV_MASK | CPG_DIV6_CKSTP)) + | CPG_DIV6_DIV(clock->div - 1); + clk_writel(val, clock->reg); return 0; } @@ -52,7 +58,7 @@ static void cpg_div6_clock_disable(struct clk_hw *hw) /* DIV6 clocks require the divisor field to be non-zero when stopping * the clock. */ - clk_writel(CPG_DIV6_CKSTP | CPG_DIV6_DIV(CPG_DIV6_DIV_MASK), + clk_writel(clk_readl(clock->reg) | CPG_DIV6_CKSTP | CPG_DIV6_DIV_MASK, clock->reg); } @@ -94,12 +100,53 @@ static int cpg_div6_clock_set_rate(struct clk_hw *hw, unsigned long rate, { struct div6_clock *clock = to_div6_clock(hw); unsigned int div = cpg_div6_clock_calc_div(rate, parent_rate); + u32 val; clock->div = div; + val = clk_readl(clock->reg) & ~CPG_DIV6_DIV_MASK; /* Only program the new divisor if the clock isn't stopped. */ - if (!(clk_readl(clock->reg) & CPG_DIV6_CKSTP)) - clk_writel(CPG_DIV6_DIV(clock->div - 1), clock->reg); + if (!(val & CPG_DIV6_CKSTP)) + clk_writel(val | CPG_DIV6_DIV(clock->div - 1), clock->reg); + + return 0; +} + +static u8 cpg_div6_clock_get_parent(struct clk_hw *hw) +{ + struct div6_clock *clock = to_div6_clock(hw); + unsigned int i; + u8 hw_index; + + if (clock->src_width == 0) + return 0; + + hw_index = (clk_readl(clock->reg) >> clock->src_shift) & + (BIT(clock->src_width) - 1); + for (i = 0; i < __clk_get_num_parents(hw->clk); i++) { + if (clock->parents[i] == hw_index) + return i; + } + + pr_err("%s: %s DIV6 clock set to invalid parent %u\n", + __func__, __clk_get_name(hw->clk), hw_index); + return 0; +} + +static int cpg_div6_clock_set_parent(struct clk_hw *hw, u8 index) +{ + struct div6_clock *clock = to_div6_clock(hw); + u8 hw_index; + u32 mask; + + if (index >= __clk_get_num_parents(hw->clk)) + return -EINVAL; + + mask = ~((BIT(clock->src_width) - 1) << clock->src_shift); + hw_index = clock->parents[index]; + + clk_writel((clk_readl(clock->reg) & mask) | + (hw_index << clock->src_shift), clock->reg); return 0; } @@ -108,6 +155,8 @@ static const struct clk_ops cpg_div6_clock_ops = { .enable = cpg_div6_clock_enable, .disable = cpg_div6_clock_disable, .is_enabled = cpg_div6_clock_is_enabled, + .get_parent = cpg_div6_clock_get_parent, + .set_parent = cpg_div6_clock_set_parent, .recalc_rate = cpg_div6_clock_recalc_rate, .round_rate = cpg_div6_clock_round_rate, .set_rate = cpg_div6_clock_set_rate, @@ -115,20 +164,33 @@ static const struct clk_ops cpg_div6_clock_ops = { static void __init cpg_div6_clock_init(struct device_node *np) { + unsigned int num_parents, valid_parents; + const char **parent_names; struct clk_init_data init; struct div6_clock *clock; - const char *parent_name; const char *name; struct clk *clk; + unsigned int i; int ret; clock = kzalloc(sizeof(*clock), GFP_KERNEL); - if (!clock) { - pr_err("%s: failed to allocate %s DIV6 clock\n", + if (!clock) + return; + + num_parents = of_clk_get_parent_count(np); + if (num_parents < 1) { + pr_err("%s: no parent found for %s DIV6 clock\n", __func__, np->name); return; } + clock->parents = kmalloc_array(num_parents, sizeof(*clock->parents), + GFP_KERNEL); + parent_names = kmalloc_array(num_parents, sizeof(*parent_names), + GFP_KERNEL); + if (!parent_names) + return; + /* Remap the clock register and read the divisor. Disabling the * clock overwrites the divisor, so we need to cache its value for the * enable operation. @@ -150,9 +212,34 @@ static void __init cpg_div6_clock_init(struct device_node *np) goto error; } - parent_name = of_clk_get_parent_name(np, 0); - if (parent_name == NULL) { - pr_err("%s: failed to get %s DIV6 clock parent name\n", + + for (i = 0, valid_parents = 0; i < num_parents; i++) { + const char *name = of_clk_get_parent_name(np, i); + + if (name) { + parent_names[valid_parents] = name; + clock->parents[valid_parents] = i; + valid_parents++; + } + } + + switch (num_parents) { + case 1: + /* fixed parent clock */ + clock->src_shift = clock->src_width = 0; + break; + case 4: + /* clock with EXSRC bits 6-7 */ + clock->src_shift = 6; + clock->src_width = 2; + break; + case 8: + /* VCLK with EXSRC bits 12-14 */ + clock->src_shift = 12; + clock->src_width = 3; + break; + default: + pr_err("%s: invalid number of parents for DIV6 clock %s\n", __func__, np->name); goto error; } @@ -161,8 +248,8 @@ static void __init cpg_div6_clock_init(struct device_node *np) init.name = name; init.ops = &cpg_div6_clock_ops; init.flags = CLK_IS_BASIC; - init.parent_names = &parent_name; - init.num_parents = 1; + init.parent_names = parent_names; + init.num_parents = valid_parents; clock->hw.init = &init; @@ -175,11 +262,13 @@ static void __init cpg_div6_clock_init(struct device_node *np) of_clk_add_provider(np, of_clk_src_simple_get, clk); + kfree(parent_names); return; error: if (clock->reg) iounmap(clock->reg); + kfree(parent_names); kfree(clock); } CLK_OF_DECLARE(cpg_div6_clk, "renesas,cpg-div6-clock", cpg_div6_clock_init); diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile index 7ddc2b553846..a66953c0f430 100644 --- a/drivers/clk/sunxi/Makefile +++ b/drivers/clk/sunxi/Makefile @@ -7,6 +7,7 @@ obj-y += clk-a10-hosc.o obj-y += clk-a20-gmac.o obj-y += clk-mod0.o obj-y += clk-sun8i-mbus.o +obj-y += clk-sun9i-core.o obj-$(CONFIG_MFD_SUN6I_PRCM) += \ clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o \ diff --git a/drivers/clk/sunxi/clk-a20-gmac.c b/drivers/clk/sunxi/clk-a20-gmac.c index 5296fd6dd7b3..0dcf4f205fb8 100644 --- a/drivers/clk/sunxi/clk-a20-gmac.c +++ b/drivers/clk/sunxi/clk-a20-gmac.c @@ -53,6 +53,11 @@ static DEFINE_SPINLOCK(gmac_lock); #define SUN7I_A20_GMAC_MASK 0x3 #define SUN7I_A20_GMAC_PARENTS 2 +static u32 sun7i_a20_gmac_mux_table[SUN7I_A20_GMAC_PARENTS] = { + 0x00, /* Select mii_phy_tx_clk */ + 0x02, /* Select gmac_int_tx_clk */ +}; + static void __init sun7i_a20_gmac_clk_setup(struct device_node *node) { struct clk *clk; @@ -90,7 +95,7 @@ static void __init sun7i_a20_gmac_clk_setup(struct device_node *node) gate->lock = &gmac_lock; mux->reg = reg; mux->mask = SUN7I_A20_GMAC_MASK; - mux->flags = CLK_MUX_INDEX_BIT; + mux->table = sun7i_a20_gmac_mux_table; mux->lock = &gmac_lock; clk = clk_register_composite(NULL, clk_name, diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c index f83ba097126c..62e08fb58554 100644 --- a/drivers/clk/sunxi/clk-factors.c +++ b/drivers/clk/sunxi/clk-factors.c @@ -81,7 +81,7 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate, static long clk_factors_determine_rate(struct clk_hw *hw, unsigned long rate, unsigned long *best_parent_rate, - struct clk **best_parent_p) + struct clk_hw **best_parent_p) { struct clk *clk = hw->clk, *parent, *best_parent = NULL; int i, num_parents; @@ -108,7 +108,7 @@ static long clk_factors_determine_rate(struct clk_hw *hw, unsigned long rate, } if (best_parent) - *best_parent_p = best_parent; + *best_parent_p = __clk_get_hw(best_parent); *best_parent_rate = best; return best_child_rate; @@ -224,7 +224,7 @@ struct clk * __init sunxi_factors_register(struct device_node *node, /* set up gate properties */ mux->reg = reg; mux->shift = data->mux; - mux->mask = SUNXI_FACTORS_MUX_MASK; + mux->mask = data->muxmask; mux->lock = factors->lock; mux_hw = &mux->hw; } diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h index 9913840018d3..912238fde132 100644 --- a/drivers/clk/sunxi/clk-factors.h +++ b/drivers/clk/sunxi/clk-factors.h @@ -7,8 +7,6 @@ #define SUNXI_FACTORS_NOT_APPLICABLE (0) -#define SUNXI_FACTORS_MUX_MASK 0x3 - struct clk_factors_config { u8 nshift; u8 nwidth; @@ -24,6 +22,7 @@ struct clk_factors_config { struct factors_data { int enable; int mux; + int muxmask; struct clk_factors_config *table; void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); const char *name; diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c index 4a563850ee6e..da0524eaee94 100644 --- a/drivers/clk/sunxi/clk-mod0.c +++ b/drivers/clk/sunxi/clk-mod0.c @@ -70,6 +70,7 @@ static struct clk_factors_config sun4i_a10_mod0_config = { static const struct factors_data sun4i_a10_mod0_data __initconst = { .enable = 31, .mux = 24, + .muxmask = BIT(1) | BIT(0), .table = &sun4i_a10_mod0_config, .getter = sun4i_a10_get_mod0_factors, }; diff --git a/drivers/clk/sunxi/clk-sun6i-ar100.c b/drivers/clk/sunxi/clk-sun6i-ar100.c index acca53290be2..3d282fb8f85c 100644 --- a/drivers/clk/sunxi/clk-sun6i-ar100.c +++ b/drivers/clk/sunxi/clk-sun6i-ar100.c @@ -46,7 +46,7 @@ static unsigned long ar100_recalc_rate(struct clk_hw *hw, static long ar100_determine_rate(struct clk_hw *hw, unsigned long rate, unsigned long *best_parent_rate, - struct clk **best_parent_clk) + struct clk_hw **best_parent_clk) { int nparents = __clk_get_num_parents(hw->clk); long best_rate = -EINVAL; @@ -100,7 +100,7 @@ static long ar100_determine_rate(struct clk_hw *hw, unsigned long rate, tmp_rate = (parent_rate >> shift) / div; if (!*best_parent_clk || tmp_rate > best_rate) { - *best_parent_clk = parent; + *best_parent_clk = __clk_get_hw(parent); *best_parent_rate = parent_rate; best_rate = tmp_rate; } diff --git a/drivers/clk/sunxi/clk-sun8i-mbus.c b/drivers/clk/sunxi/clk-sun8i-mbus.c index 8e49b44cee41..ef49786eefd3 100644 --- a/drivers/clk/sunxi/clk-sun8i-mbus.c +++ b/drivers/clk/sunxi/clk-sun8i-mbus.c @@ -60,6 +60,7 @@ static struct clk_factors_config sun8i_a23_mbus_config = { static const struct factors_data sun8i_a23_mbus_data __initconst = { .enable = 31, .mux = 24, + .muxmask = BIT(1) | BIT(0), .table = &sun8i_a23_mbus_config, .getter = sun8i_a23_get_mbus_factors, }; diff --git a/drivers/clk/sunxi/clk-sun9i-core.c b/drivers/clk/sunxi/clk-sun9i-core.c new file mode 100644 index 000000000000..3cb9036d91bb --- /dev/null +++ b/drivers/clk/sunxi/clk-sun9i-core.c @@ -0,0 +1,271 @@ +/* + * Copyright 2014 Chen-Yu Tsai + * + * Chen-Yu Tsai <wens@csie.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/clk-provider.h> +#include <linux/clkdev.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/log2.h> + +#include "clk-factors.h" + + +/** + * sun9i_a80_get_pll4_factors() - calculates n, p, m factors for PLL1 + * PLL4 rate is calculated as follows + * rate = (parent_rate * n >> p) / (m + 1); + * parent_rate is always 24Mhz + * + * p and m are named div1 and div2 in Allwinner's SDK + */ + +static void sun9i_a80_get_pll4_factors(u32 *freq, u32 parent_rate, + u8 *n, u8 *k, u8 *m, u8 *p) +{ + int div; + + /* Normalize value to a 6M multiple */ + div = DIV_ROUND_UP(*freq, 6000000); + + /* divs above 256 cannot be odd */ + if (div > 256) + div = round_up(div, 2); + + /* divs above 512 must be a multiple of 4 */ + if (div > 512) + div = round_up(div, 4); + + *freq = 6000000 * div; + + /* we were called to round the frequency, we can now return */ + if (n == NULL) + return; + + /* p will be 1 for divs under 512 */ + if (div < 512) + *p = 1; + else + *p = 0; + + /* m will be 1 if div is odd */ + if (div & 1) + *m = 1; + else + *m = 0; + + /* calculate a suitable n based on m and p */ + *n = div / (*p + 1) / (*m + 1); +} + +static struct clk_factors_config sun9i_a80_pll4_config = { + .mshift = 18, + .mwidth = 1, + .nshift = 8, + .nwidth = 8, + .pshift = 16, + .pwidth = 1, +}; + +static const struct factors_data sun9i_a80_pll4_data __initconst = { + .enable = 31, + .table = &sun9i_a80_pll4_config, + .getter = sun9i_a80_get_pll4_factors, +}; + +static DEFINE_SPINLOCK(sun9i_a80_pll4_lock); + +static void __init sun9i_a80_pll4_setup(struct device_node *node) +{ + sunxi_factors_register(node, &sun9i_a80_pll4_data, &sun9i_a80_pll4_lock); +} +CLK_OF_DECLARE(sun9i_a80_pll4, "allwinner,sun9i-a80-pll4-clk", sun9i_a80_pll4_setup); + + +/** + * sun9i_a80_get_gt_factors() - calculates m factor for GT + * GT rate is calculated as follows + * rate = parent_rate / (m + 1); + */ + +static void sun9i_a80_get_gt_factors(u32 *freq, u32 parent_rate, + u8 *n, u8 *k, u8 *m, u8 *p) +{ + u32 div; + + if (parent_rate < *freq) + *freq = parent_rate; + + div = DIV_ROUND_UP(parent_rate, *freq); + + /* maximum divider is 4 */ + if (div > 4) + div = 4; + + *freq = parent_rate / div; + + /* we were called to round the frequency, we can now return */ + if (!m) + return; + + *m = div; +} + +static struct clk_factors_config sun9i_a80_gt_config = { + .mshift = 0, + .mwidth = 2, +}; + +static const struct factors_data sun9i_a80_gt_data __initconst = { + .mux = 24, + .muxmask = BIT(1) | BIT(0), + .table = &sun9i_a80_gt_config, + .getter = sun9i_a80_get_gt_factors, +}; + +static DEFINE_SPINLOCK(sun9i_a80_gt_lock); + +static void __init sun9i_a80_gt_setup(struct device_node *node) +{ + struct clk *gt = sunxi_factors_register(node, &sun9i_a80_gt_data, + &sun9i_a80_gt_lock); + + /* The GT bus clock needs to be always enabled */ + __clk_get(gt); + clk_prepare_enable(gt); +} +CLK_OF_DECLARE(sun9i_a80_gt, "allwinner,sun9i-a80-gt-clk", sun9i_a80_gt_setup); + + +/** + * sun9i_a80_get_ahb_factors() - calculates p factor for AHB0/1/2 + * AHB rate is calculated as follows + * rate = parent_rate >> p; + */ + +static void sun9i_a80_get_ahb_factors(u32 *freq, u32 parent_rate, + u8 *n, u8 *k, u8 *m, u8 *p) +{ + u32 _p; + + if (parent_rate < *freq) + *freq = parent_rate; + + _p = order_base_2(DIV_ROUND_UP(parent_rate, *freq)); + + /* maximum p is 3 */ + if (_p > 3) + _p = 3; + + *freq = parent_rate >> _p; + + /* we were called to round the frequency, we can now return */ + if (!p) + return; + + *p = _p; +} + +static struct clk_factors_config sun9i_a80_ahb_config = { + .pshift = 0, + .pwidth = 2, +}; + +static const struct factors_data sun9i_a80_ahb_data __initconst = { + .mux = 24, + .muxmask = BIT(1) | BIT(0), + .table = &sun9i_a80_ahb_config, + .getter = sun9i_a80_get_ahb_factors, +}; + +static DEFINE_SPINLOCK(sun9i_a80_ahb_lock); + +static void __init sun9i_a80_ahb_setup(struct device_node *node) +{ + sunxi_factors_register(node, &sun9i_a80_ahb_data, &sun9i_a80_ahb_lock); +} +CLK_OF_DECLARE(sun9i_a80_ahb, "allwinner,sun9i-a80-ahb-clk", sun9i_a80_ahb_setup); + + +static const struct factors_data sun9i_a80_apb0_data __initconst = { + .mux = 24, + .muxmask = BIT(0), + .table = &sun9i_a80_ahb_config, + .getter = sun9i_a80_get_ahb_factors, +}; + +static DEFINE_SPINLOCK(sun9i_a80_apb0_lock); + +static void __init sun9i_a80_apb0_setup(struct device_node *node) +{ + sunxi_factors_register(node, &sun9i_a80_apb0_data, &sun9i_a80_apb0_lock); +} +CLK_OF_DECLARE(sun9i_a80_apb0, "allwinner,sun9i-a80-apb0-clk", sun9i_a80_apb0_setup); + + +/** + * sun9i_a80_get_apb1_factors() - calculates m, p factors for APB1 + * APB1 rate is calculated as follows + * rate = (parent_rate >> p) / (m + 1); + */ + +static void sun9i_a80_get_apb1_factors(u32 *freq, u32 parent_rate, + u8 *n, u8 *k, u8 *m, u8 *p) +{ + u32 div; + u8 calcm, calcp; + + if (parent_rate < *freq) + *freq = parent_rate; + + div = DIV_ROUND_UP(parent_rate, *freq); + + /* Highest possible divider is 256 (p = 3, m = 31) */ + if (div > 256) + div = 256; + + calcp = order_base_2(div); + calcm = (parent_rate >> calcp) - 1; + *freq = (parent_rate >> calcp) / (calcm + 1); + + /* we were called to round the frequency, we can now return */ + if (n == NULL) + return; + + *m = calcm; + *p = calcp; +} + +static struct clk_factors_config sun9i_a80_apb1_config = { + .mshift = 0, + .mwidth = 5, + .pshift = 16, + .pwidth = 2, +}; + +static const struct factors_data sun9i_a80_apb1_data __initconst = { + .mux = 24, + .muxmask = BIT(0), + .table = &sun9i_a80_apb1_config, + .getter = sun9i_a80_get_apb1_factors, +}; + +static DEFINE_SPINLOCK(sun9i_a80_apb1_lock); + +static void __init sun9i_a80_apb1_setup(struct device_node *node) +{ + sunxi_factors_register(node, &sun9i_a80_apb1_data, &sun9i_a80_apb1_lock); +} +CLK_OF_DECLARE(sun9i_a80_apb1, "allwinner,sun9i-a80-apb1-clk", sun9i_a80_apb1_setup); diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index d5dc951264ca..570202582dcf 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -245,9 +245,9 @@ static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate, } /** - * sun6i_a31_get_pll6_factors() - calculates n, k factors for A31 PLL6 - * PLL6 rate is calculated as follows - * rate = parent_rate * n * (k + 1) / 2 + * sun6i_a31_get_pll6_factors() - calculates n, k factors for A31 PLL6x2 + * PLL6x2 rate is calculated as follows + * rate = parent_rate * (n + 1) * (k + 1) * parent_rate is always 24Mhz */ @@ -256,13 +256,7 @@ static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate, { u8 div; - /* - * We always have 24MHz / 2, so we can just say that our - * parent clock is 12MHz. - */ - parent_rate = parent_rate / 2; - - /* Normalize value to a parent_rate multiple (24M / 2) */ + /* Normalize value to a parent_rate multiple (24M) */ div = *freq / parent_rate; *freq = parent_rate * div; @@ -274,7 +268,7 @@ static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate, if (*k > 3) *k = 3; - *n = DIV_ROUND_UP(div, (*k+1)); + *n = DIV_ROUND_UP(div, (*k+1)) - 1; } /** @@ -445,6 +439,7 @@ static struct clk_factors_config sun6i_a31_pll6_config = { .nwidth = 5, .kshift = 4, .kwidth = 2, + .n_start = 1, }; static struct clk_factors_config sun4i_apb1_config = { @@ -504,9 +499,12 @@ static const struct factors_data sun6i_a31_pll6_data __initconst = { .enable = 31, .table = &sun6i_a31_pll6_config, .getter = sun6i_a31_get_pll6_factors, + .name = "pll6x2", }; static const struct factors_data sun4i_apb1_data __initconst = { + .mux = 24, + .muxmask = BIT(1) | BIT(0), .table = &sun4i_apb1_config, .getter = sun4i_get_apb1_factors, }; @@ -514,6 +512,7 @@ static const struct factors_data sun4i_apb1_data __initconst = { static const struct factors_data sun7i_a20_out_data __initconst = { .enable = 31, .mux = 24, + .muxmask = BIT(1) | BIT(0), .table = &sun7i_a20_out_config, .getter = sun7i_a20_get_out_factors, }; @@ -544,10 +543,6 @@ static const struct mux_data sun6i_a31_ahb1_mux_data __initconst = { .shift = 12, }; -static const struct mux_data sun4i_apb1_mux_data __initconst = { - .shift = 24, -}; - static void __init sunxi_mux_clk_setup(struct device_node *node, struct mux_data *data) { @@ -633,12 +628,6 @@ static const struct div_data sun4i_apb0_data __initconst = { .table = sun4i_apb0_table, }; -static const struct div_data sun6i_a31_apb2_div_data __initconst = { - .shift = 0, - .pow = 0, - .width = 4, -}; - static void __init sunxi_divider_clk_setup(struct device_node *node, struct div_data *data) { @@ -757,6 +746,18 @@ static const struct gates_data sun8i_a23_ahb1_gates_data __initconst = { .mask = {0x25386742, 0x2505111}, }; +static const struct gates_data sun9i_a80_ahb0_gates_data __initconst = { + .mask = {0xF5F12B}, +}; + +static const struct gates_data sun9i_a80_ahb1_gates_data __initconst = { + .mask = {0x1E20003}, +}; + +static const struct gates_data sun9i_a80_ahb2_gates_data __initconst = { + .mask = {0x9B7}, +}; + static const struct gates_data sun4i_apb0_gates_data __initconst = { .mask = {0x4EF}, }; @@ -773,6 +774,10 @@ static const struct gates_data sun7i_a20_apb0_gates_data __initconst = { .mask = { 0x4ff }, }; +static const struct gates_data sun9i_a80_apb0_gates_data __initconst = { + .mask = {0xEB822}, +}; + static const struct gates_data sun4i_apb1_gates_data __initconst = { .mask = {0xFF00F7}, }; @@ -801,6 +806,10 @@ static const struct gates_data sun7i_a20_apb1_gates_data __initconst = { .mask = { 0xff80ff }, }; +static const struct gates_data sun9i_a80_apb1_gates_data __initconst = { + .mask = {0x3F001F}, +}; + static const struct gates_data sun8i_a23_apb2_gates_data __initconst = { .mask = {0x1F0007}, }; @@ -893,6 +902,7 @@ static void __init sunxi_gates_clk_setup(struct device_node *node, struct divs_data { const struct factors_data *factors; /* data for the factor clock */ + int ndivs; /* number of children */ struct { u8 fixed; /* is it a fixed divisor? if not... */ struct clk_div_table *table; /* is it a table based divisor? */ @@ -912,6 +922,7 @@ static struct clk_div_table pll6_sata_tbl[] = { static const struct divs_data pll5_divs_data __initconst = { .factors = &sun4i_pll5_data, + .ndivs = 2, .div = { { .shift = 0, .pow = 0, }, /* M, DDR */ { .shift = 16, .pow = 1, }, /* P, other */ @@ -920,12 +931,21 @@ static const struct divs_data pll5_divs_data __initconst = { static const struct divs_data pll6_divs_data __initconst = { .factors = &sun4i_pll6_data, + .ndivs = 2, .div = { { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */ { .fixed = 2 }, /* P, other */ } }; +static const struct divs_data sun6i_a31_pll6_divs_data __initconst = { + .factors = &sun6i_a31_pll6_data, + .ndivs = 1, + .div = { + { .fixed = 2 }, /* normal output */ + } +}; + /** * sunxi_divs_clk_setup() - Setup function for leaf divisors on clocks * @@ -950,7 +970,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node, struct clk_fixed_factor *fix_factor; struct clk_divider *divider; void __iomem *reg; - int i = 0; + int ndivs = SUNXI_DIVS_MAX_QTY, i = 0; int flags, clkflags; /* Set up factor clock that we will be dividing */ @@ -973,7 +993,11 @@ static void __init sunxi_divs_clk_setup(struct device_node *node, * our RAM clock! */ clkflags = !strcmp("pll5", parent) ? 0 : CLK_SET_RATE_PARENT; - for (i = 0; i < SUNXI_DIVS_MAX_QTY; i++) { + /* if number of children known, use it */ + if (data->ndivs) + ndivs = data->ndivs; + + for (i = 0; i < ndivs; i++) { if (of_property_read_string_index(node, "clock-output-names", i, &clk_name) != 0) break; @@ -1062,7 +1086,6 @@ static const struct of_device_id clk_factors_match[] __initconst = { {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,}, {.compatible = "allwinner,sun8i-a23-pll1-clk", .data = &sun8i_a23_pll1_data,}, {.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,}, - {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_data,}, {.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,}, {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,}, {} @@ -1074,7 +1097,6 @@ static const struct of_device_id clk_div_match[] __initconst = { {.compatible = "allwinner,sun8i-a23-axi-clk", .data = &sun8i_a23_axi_data,}, {.compatible = "allwinner,sun4i-a10-ahb-clk", .data = &sun4i_ahb_data,}, {.compatible = "allwinner,sun4i-a10-apb0-clk", .data = &sun4i_apb0_data,}, - {.compatible = "allwinner,sun6i-a31-apb2-div-clk", .data = &sun6i_a31_apb2_div_data,}, {} }; @@ -1082,13 +1104,13 @@ static const struct of_device_id clk_div_match[] __initconst = { static const struct of_device_id clk_divs_match[] __initconst = { {.compatible = "allwinner,sun4i-a10-pll5-clk", .data = &pll5_divs_data,}, {.compatible = "allwinner,sun4i-a10-pll6-clk", .data = &pll6_divs_data,}, + {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_divs_data,}, {} }; /* Matches for mux clocks */ static const struct of_device_id clk_mux_match[] __initconst = { {.compatible = "allwinner,sun4i-a10-cpu-clk", .data = &sun4i_cpu_mux_data,}, - {.compatible = "allwinner,sun4i-a10-apb1-mux-clk", .data = &sun4i_apb1_mux_data,}, {.compatible = "allwinner,sun6i-a31-ahb1-mux-clk", .data = &sun6i_a31_ahb1_mux_data,}, {} }; @@ -1102,16 +1124,21 @@ static const struct of_device_id clk_gates_match[] __initconst = { {.compatible = "allwinner,sun6i-a31-ahb1-gates-clk", .data = &sun6i_a31_ahb1_gates_data,}, {.compatible = "allwinner,sun7i-a20-ahb-gates-clk", .data = &sun7i_a20_ahb_gates_data,}, {.compatible = "allwinner,sun8i-a23-ahb1-gates-clk", .data = &sun8i_a23_ahb1_gates_data,}, + {.compatible = "allwinner,sun9i-a80-ahb0-gates-clk", .data = &sun9i_a80_ahb0_gates_data,}, + {.compatible = "allwinner,sun9i-a80-ahb1-gates-clk", .data = &sun9i_a80_ahb1_gates_data,}, + {.compatible = "allwinner,sun9i-a80-ahb2-gates-clk", .data = &sun9i_a80_ahb2_gates_data,}, {.compatible = "allwinner,sun4i-a10-apb0-gates-clk", .data = &sun4i_apb0_gates_data,}, {.compatible = "allwinner,sun5i-a10s-apb0-gates-clk", .data = &sun5i_a10s_apb0_gates_data,}, {.compatible = "allwinner,sun5i-a13-apb0-gates-clk", .data = &sun5i_a13_apb0_gates_data,}, {.compatible = "allwinner,sun7i-a20-apb0-gates-clk", .data = &sun7i_a20_apb0_gates_data,}, + {.compatible = "allwinner,sun9i-a80-apb0-gates-clk", .data = &sun9i_a80_apb0_gates_data,}, {.compatible = "allwinner,sun4i-a10-apb1-gates-clk", .data = &sun4i_apb1_gates_data,}, {.compatible = "allwinner,sun5i-a10s-apb1-gates-clk", .data = &sun5i_a10s_apb1_gates_data,}, {.compatible = "allwinner,sun5i-a13-apb1-gates-clk", .data = &sun5i_a13_apb1_gates_data,}, {.compatible = "allwinner,sun6i-a31-apb1-gates-clk", .data = &sun6i_a31_apb1_gates_data,}, {.compatible = "allwinner,sun7i-a20-apb1-gates-clk", .data = &sun7i_a20_apb1_gates_data,}, {.compatible = "allwinner,sun8i-a23-apb1-gates-clk", .data = &sun8i_a23_apb1_gates_data,}, + {.compatible = "allwinner,sun9i-a80-apb1-gates-clk", .data = &sun9i_a80_apb1_gates_data,}, {.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,}, {.compatible = "allwinner,sun8i-a23-apb2-gates-clk", .data = &sun8i_a23_apb2_gates_data,}, {.compatible = "allwinner,sun4i-a10-usb-clk", .data = &sun4i_a10_usb_gates_data,}, @@ -1200,3 +1227,9 @@ static void __init sun6i_init_clocks(struct device_node *node) } CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks); CLK_OF_DECLARE(sun8i_a23_clk_init, "allwinner,sun8i-a23", sun6i_init_clocks); + +static void __init sun9i_init_clocks(struct device_node *node) +{ + sunxi_init_clocks(NULL, 0); +} +CLK_OF_DECLARE(sun9i_a80_clk_init, "allwinner,sun9i-a80", sun9i_init_clocks); diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 6a79fc4f900c..095c1774592c 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -462,7 +462,7 @@ static void __init arch_counter_register(unsigned type) /* Register the CP15 based counter if we have one */ if (type & ARCH_CP15_TIMER) { - if (arch_timer_use_virtual) + if (IS_ENABLED(CONFIG_ARM64) || arch_timer_use_virtual) arch_timer_read_counter = arch_counter_get_cntvct; else arch_timer_read_counter = arch_counter_get_cntpct; diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index f56147a1daed..fde97d6e31d6 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -211,6 +211,17 @@ static int cpufreq_init(struct cpufreq_policy *policy) /* OPPs might be populated at runtime, don't check for error here */ of_init_opp_table(cpu_dev); + /* + * But we need OPP table to function so if it is not there let's + * give platform code chance to provide it for us. + */ + ret = dev_pm_opp_get_opp_count(cpu_dev); + if (ret <= 0) { + pr_debug("OPP table is not ready, deferring probe\n"); + ret = -EPROBE_DEFER; + goto out_free_opp; + } + priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { ret = -ENOMEM; diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index a09a29c312a9..46bed4f81cde 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -2028,6 +2028,12 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, /* Don't start any governor operations if we are entering suspend */ if (cpufreq_suspended) return 0; + /* + * Governor might not be initiated here if ACPI _PPC changed + * notification happened, so check it. + */ + if (!policy->governor) + return -EINVAL; if (policy->governor->max_transition_latency && policy->cpuinfo.transition_latency > diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 1405b393c93d..742eefba12c2 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -199,7 +199,14 @@ static signed int pid_calc(struct _pid *pid, int32_t busy) pid->integral += fp_error; - /* limit the integral term */ + /* + * We limit the integral here so that it will never + * get higher than 30. This prevents it from becoming + * too large an input over long periods of time and allows + * it to get factored out sooner. + * + * The value of 30 was chosen through experimentation. + */ integral_limit = int_tofp(30); if (pid->integral > integral_limit) pid->integral = integral_limit; @@ -616,6 +623,11 @@ static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max) if (limits.no_turbo || limits.turbo_disabled) max_perf = cpu->pstate.max_pstate; + /* + * performance can be limited by user through sysfs, by cpufreq + * policy, or by cpu specific default values determined through + * experimentation. + */ max_perf_adj = fp_toint(mul_fp(int_tofp(max_perf), limits.max_perf)); *max = clamp_t(int, max_perf_adj, cpu->pstate.min_pstate, cpu->pstate.turbo_pstate); @@ -717,11 +729,29 @@ static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu) u32 duration_us; u32 sample_time; + /* + * core_busy is the ratio of actual performance to max + * max_pstate is the max non turbo pstate available + * current_pstate was the pstate that was requested during + * the last sample period. + * + * We normalize core_busy, which was our actual percent + * performance to what we requested during the last sample + * period. The result will be a percentage of busy at a + * specified pstate. + */ core_busy = cpu->sample.core_pct_busy; max_pstate = int_tofp(cpu->pstate.max_pstate); current_pstate = int_tofp(cpu->pstate.current_pstate); core_busy = mul_fp(core_busy, div_fp(max_pstate, current_pstate)); + /* + * Since we have a deferred timer, it will not fire unless + * we are in C0. So, determine if the actual elapsed time + * is significantly greater (3x) than our sample interval. If it + * is, then we were idle for a long enough period of time + * to adjust our busyness. + */ sample_time = pid_params.sample_rate_ms * USEC_PER_MSEC; duration_us = (u32) ktime_us_delta(cpu->sample.time, cpu->last_sample_time); @@ -948,6 +978,7 @@ static struct cpufreq_driver intel_pstate_driver = { static int __initdata no_load; static int __initdata no_hwp; +static unsigned int force_load; static int intel_pstate_msrs_not_valid(void) { @@ -1094,7 +1125,8 @@ static bool intel_pstate_platform_pwr_mgmt_exists(void) case PSS: return intel_pstate_no_acpi_pss(); case PPC: - return intel_pstate_has_acpi_ppc(); + return intel_pstate_has_acpi_ppc() && + (!force_load); } } @@ -1175,6 +1207,8 @@ static int __init intel_pstate_setup(char *str) no_load = 1; if (!strcmp(str, "no_hwp")) no_hwp = 1; + if (!strcmp(str, "force")) + force_load = 1; return 0; } early_param("intel_pstate", intel_pstate_setup); diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c index c913906a719e..0f6b229afcb9 100644 --- a/drivers/cpufreq/longhaul.c +++ b/drivers/cpufreq/longhaul.c @@ -1,5 +1,5 @@ /* - * (C) 2001-2004 Dave Jones. <davej@redhat.com> + * (C) 2001-2004 Dave Jones. * (C) 2002 Padraig Brady. <padraig@antefacto.com> * * Licensed under the terms of the GNU GPL License version 2. @@ -1008,7 +1008,7 @@ MODULE_PARM_DESC(revid_errata, "Ignore CPU Revision ID"); module_param(enable, int, 0644); MODULE_PARM_DESC(enable, "Enable driver"); -MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); +MODULE_AUTHOR("Dave Jones"); MODULE_DESCRIPTION("Longhaul driver for VIA Cyrix processors."); MODULE_LICENSE("GPL"); diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c index f91027259c3c..e6f24b281e3e 100644 --- a/drivers/cpufreq/powernow-k6.c +++ b/drivers/cpufreq/powernow-k6.c @@ -300,7 +300,7 @@ static void __exit powernow_k6_exit(void) } -MODULE_AUTHOR("Arjan van de Ven, Dave Jones <davej@redhat.com>, " +MODULE_AUTHOR("Arjan van de Ven, Dave Jones, " "Dominik Brodowski <linux@brodo.de>"); MODULE_DESCRIPTION("PowerNow! driver for AMD K6-2+ / K6-3+ processors."); MODULE_LICENSE("GPL"); diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c index e61e224475ad..37c5742482d8 100644 --- a/drivers/cpufreq/powernow-k7.c +++ b/drivers/cpufreq/powernow-k7.c @@ -1,7 +1,6 @@ /* * AMD K7 Powernow driver. * (C) 2003 Dave Jones on behalf of SuSE Labs. - * (C) 2003-2004 Dave Jones <davej@redhat.com> * * Licensed under the terms of the GNU GPL License version 2. * Based upon datasheets & sample CPUs kindly provided by AMD. @@ -701,7 +700,7 @@ static void __exit powernow_exit(void) module_param(acpi_force, int, 0444); MODULE_PARM_DESC(acpi_force, "Force ACPI to be used."); -MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); +MODULE_AUTHOR("Dave Jones"); MODULE_DESCRIPTION("Powernow driver for AMD K7 processors."); MODULE_LICENSE("GPL"); diff --git a/drivers/cpufreq/speedstep-ich.c b/drivers/cpufreq/speedstep-ich.c index 1a07b5904ed5..e56d632a8b21 100644 --- a/drivers/cpufreq/speedstep-ich.c +++ b/drivers/cpufreq/speedstep-ich.c @@ -378,8 +378,7 @@ static void __exit speedstep_exit(void) } -MODULE_AUTHOR("Dave Jones <davej@redhat.com>, " - "Dominik Brodowski <linux@brodo.de>"); +MODULE_AUTHOR("Dave Jones, Dominik Brodowski <linux@brodo.de>"); MODULE_DESCRIPTION("Speedstep driver for Intel mobile processors on chipsets " "with ICH-M southbridges."); MODULE_LICENSE("GPL"); diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c index e9248bb9173a..aedec0957934 100644 --- a/drivers/cpuidle/cpuidle-powernv.c +++ b/drivers/cpuidle/cpuidle-powernv.c @@ -16,13 +16,10 @@ #include <asm/machdep.h> #include <asm/firmware.h> +#include <asm/opal.h> #include <asm/runlatch.h> -/* Flags and constants used in PowerNV platform */ - #define MAX_POWERNV_IDLE_STATES 8 -#define IDLE_USE_INST_NAP 0x00010000 /* Use nap instruction */ -#define IDLE_USE_INST_SLEEP 0x00020000 /* Use sleep instruction */ struct cpuidle_driver powernv_idle_driver = { .name = "powernv_idle", @@ -197,7 +194,7 @@ static int powernv_add_idle_states(void) * target residency to be 10x exit_latency */ latency_ns = be32_to_cpu(idle_state_latency[i]); - if (flags & IDLE_USE_INST_NAP) { + if (flags & OPAL_PM_NAP_ENABLED) { /* Add NAP state */ strcpy(powernv_states[nr_idle_states].name, "Nap"); strcpy(powernv_states[nr_idle_states].desc, "Nap"); @@ -210,7 +207,8 @@ static int powernv_add_idle_states(void) nr_idle_states++; } - if (flags & IDLE_USE_INST_SLEEP) { + if (flags & OPAL_PM_SLEEP_ENABLED || + flags & OPAL_PM_SLEEP_ENABLED_ER1) { /* Add FASTSLEEP state */ strcpy(powernv_states[nr_idle_states].name, "FastSleep"); strcpy(powernv_states[nr_idle_states].desc, "FastSleep"); diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c index 37263d9a1051..401c0106ed34 100644 --- a/drivers/cpuidle/governors/ladder.c +++ b/drivers/cpuidle/governors/ladder.c @@ -79,12 +79,7 @@ static int ladder_select_state(struct cpuidle_driver *drv, last_state = &ldev->states[last_idx]; - if (!(drv->states[last_idx].flags & CPUIDLE_FLAG_TIME_INVALID)) { - last_residency = cpuidle_get_last_residency(dev) - \ - drv->states[last_idx].exit_latency; - } - else - last_residency = last_state->threshold.promotion_time + 1; + last_residency = cpuidle_get_last_residency(dev) - drv->states[last_idx].exit_latency; /* consider promotion */ if (last_idx < drv->state_count - 1 && diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index 659d7b0c9ebf..40580794e23d 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -396,8 +396,8 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev) * power state and occurrence of the wakeup event. * * If the entered idle state didn't support residency measurements, - * we are basically lost in the dark how much time passed. - * As a compromise, assume we slept for the whole expected time. + * we use them anyway if they are short, and if long, + * truncate to the whole expected time. * * Any measured amount of time will include the exit latency. * Since we are interested in when the wakeup begun, not when it @@ -405,22 +405,17 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev) * the measured amount of time is less than the exit latency, * assume the state was never reached and the exit latency is 0. */ - if (unlikely(target->flags & CPUIDLE_FLAG_TIME_INVALID)) { - /* Use timer value as is */ - measured_us = data->next_timer_us; - } else { - /* Use measured value */ - measured_us = cpuidle_get_last_residency(dev); + /* measured value */ + measured_us = cpuidle_get_last_residency(dev); - /* Deduct exit latency */ - if (measured_us > target->exit_latency) - measured_us -= target->exit_latency; + /* Deduct exit latency */ + if (measured_us > target->exit_latency) + measured_us -= target->exit_latency; - /* Make sure our coefficients do not exceed unity */ - if (measured_us > data->next_timer_us) - measured_us = data->next_timer_us; - } + /* Make sure our coefficients do not exceed unity */ + if (measured_us > data->next_timer_us) + measured_us = data->next_timer_us; /* Update our correction ratio */ new_factor = data->correction_factor[data->bucket]; diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c index 380478562b7d..5c062548957c 100644 --- a/drivers/dma/dw/core.c +++ b/drivers/dma/dw/core.c @@ -1505,7 +1505,6 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata) dw->regs = chip->regs; chip->dw = dw; - pm_runtime_enable(chip->dev); pm_runtime_get_sync(chip->dev); dw_params = dma_read_byaddr(chip->regs, DW_PARAMS); @@ -1703,7 +1702,6 @@ int dw_dma_remove(struct dw_dma_chip *chip) } pm_runtime_put_sync_suspend(chip->dev); - pm_runtime_disable(chip->dev); return 0; } EXPORT_SYMBOL_GPL(dw_dma_remove); diff --git a/drivers/dma/dw/platform.c b/drivers/dma/dw/platform.c index a630161473a4..32ea1aca7a0e 100644 --- a/drivers/dma/dw/platform.c +++ b/drivers/dma/dw/platform.c @@ -15,6 +15,7 @@ #include <linux/module.h> #include <linux/device.h> #include <linux/clk.h> +#include <linux/pm_runtime.h> #include <linux/platform_device.h> #include <linux/dmaengine.h> #include <linux/dma-mapping.h> @@ -185,6 +186,8 @@ static int dw_probe(struct platform_device *pdev) if (err) return err; + pm_runtime_enable(&pdev->dev); + err = dw_dma_probe(chip, pdata); if (err) goto err_dw_dma_probe; @@ -205,6 +208,7 @@ static int dw_probe(struct platform_device *pdev) return 0; err_dw_dma_probe: + pm_runtime_disable(&pdev->dev); clk_disable_unprepare(chip->clk); return err; } @@ -217,6 +221,7 @@ static int dw_remove(struct platform_device *pdev) of_dma_controller_free(pdev->dev.of_node); dw_dma_remove(chip); + pm_runtime_disable(&pdev->dev); clk_disable_unprepare(chip->clk); return 0; diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index 2c6d5e118ac1..f9e3aee6a211 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -115,6 +115,9 @@ static int textual_leaf_to_string(const u32 *block, char *buf, size_t size) * * The string is taken from a minimal ASCII text descriptor leaf after * the immediate entry with @key. The string is zero-terminated. + * An overlong string is silently truncated such that it and the + * zero byte fit into @size. + * * Returns strlen(buf) or a negative error code. */ int fw_csr_string(const u32 *directory, int key, char *buf, size_t size) diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index a66a3217f1d9..aff9018d0658 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -689,8 +689,7 @@ static void ar_context_release(struct ar_context *ctx) { unsigned int i; - if (ctx->buffer) - vm_unmap_ram(ctx->buffer, AR_BUFFERS + AR_WRAPAROUND_PAGES); + vunmap(ctx->buffer); for (i = 0; i < AR_BUFFERS; i++) if (ctx->pages[i]) { @@ -1018,8 +1017,7 @@ static int ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci, pages[i] = ctx->pages[i]; for (i = 0; i < AR_WRAPAROUND_PAGES; i++) pages[AR_BUFFERS + i] = ctx->pages[i]; - ctx->buffer = vm_map_ram(pages, AR_BUFFERS + AR_WRAPAROUND_PAGES, - -1, PAGE_KERNEL); + ctx->buffer = vmap(pages, ARRAY_SIZE(pages), VM_MAP, PAGE_KERNEL); if (!ctx->buffer) goto out_of_memory; diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 7aef911fdc71..64ac8f8f5098 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c @@ -174,6 +174,7 @@ struct sbp2_target { unsigned int mgt_orb_timeout; unsigned int max_payload; + spinlock_t lock; int dont_block; /* counter for each logical unit */ int blocked; /* ditto */ }; @@ -270,6 +271,7 @@ struct sbp2_orb { dma_addr_t request_bus; int rcode; void (*callback)(struct sbp2_orb * orb, struct sbp2_status * status); + struct sbp2_logical_unit *lu; struct list_head link; }; @@ -321,7 +323,6 @@ struct sbp2_command_orb { u8 command_block[SBP2_MAX_CDB_SIZE]; } request; struct scsi_cmnd *cmd; - struct sbp2_logical_unit *lu; struct sbp2_pointer page_table[SG_ALL] __attribute__((aligned(8))); dma_addr_t page_table_bus; @@ -444,7 +445,7 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request, } /* Lookup the orb corresponding to this status write. */ - spin_lock_irqsave(&card->lock, flags); + spin_lock_irqsave(&lu->tgt->lock, flags); list_for_each_entry(orb, &lu->orb_list, link) { if (STATUS_GET_ORB_HIGH(status) == 0 && STATUS_GET_ORB_LOW(status) == orb->request_bus) { @@ -453,7 +454,7 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request, break; } } - spin_unlock_irqrestore(&card->lock, flags); + spin_unlock_irqrestore(&lu->tgt->lock, flags); if (&orb->link != &lu->orb_list) { orb->callback(orb, &status); @@ -480,18 +481,18 @@ static void complete_transaction(struct fw_card *card, int rcode, * been set and only does the cleanup if the transaction * failed and we didn't already get a status write. */ - spin_lock_irqsave(&card->lock, flags); + spin_lock_irqsave(&orb->lu->tgt->lock, flags); if (orb->rcode == -1) orb->rcode = rcode; if (orb->rcode != RCODE_COMPLETE) { list_del(&orb->link); - spin_unlock_irqrestore(&card->lock, flags); + spin_unlock_irqrestore(&orb->lu->tgt->lock, flags); orb->callback(orb, NULL); kref_put(&orb->kref, free_orb); /* orb callback reference */ } else { - spin_unlock_irqrestore(&card->lock, flags); + spin_unlock_irqrestore(&orb->lu->tgt->lock, flags); } kref_put(&orb->kref, free_orb); /* transaction callback reference */ @@ -507,9 +508,10 @@ static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, orb_pointer.high = 0; orb_pointer.low = cpu_to_be32(orb->request_bus); - spin_lock_irqsave(&device->card->lock, flags); + orb->lu = lu; + spin_lock_irqsave(&lu->tgt->lock, flags); list_add_tail(&orb->link, &lu->orb_list); - spin_unlock_irqrestore(&device->card->lock, flags); + spin_unlock_irqrestore(&lu->tgt->lock, flags); kref_get(&orb->kref); /* transaction callback reference */ kref_get(&orb->kref); /* orb callback reference */ @@ -524,13 +526,12 @@ static int sbp2_cancel_orbs(struct sbp2_logical_unit *lu) struct fw_device *device = target_parent_device(lu->tgt); struct sbp2_orb *orb, *next; struct list_head list; - unsigned long flags; int retval = -ENOENT; INIT_LIST_HEAD(&list); - spin_lock_irqsave(&device->card->lock, flags); + spin_lock_irq(&lu->tgt->lock); list_splice_init(&lu->orb_list, &list); - spin_unlock_irqrestore(&device->card->lock, flags); + spin_unlock_irq(&lu->tgt->lock); list_for_each_entry_safe(orb, next, &list, link) { retval = 0; @@ -687,16 +688,11 @@ static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu) &d, 4, complete_agent_reset_write_no_wait, t); } -static inline void sbp2_allow_block(struct sbp2_logical_unit *lu) +static inline void sbp2_allow_block(struct sbp2_target *tgt) { - /* - * We may access dont_block without taking card->lock here: - * All callers of sbp2_allow_block() and all callers of sbp2_unblock() - * are currently serialized against each other. - * And a wrong result in sbp2_conditionally_block()'s access of - * dont_block is rather harmless, it simply misses its first chance. - */ - --lu->tgt->dont_block; + spin_lock_irq(&tgt->lock); + --tgt->dont_block; + spin_unlock_irq(&tgt->lock); } /* @@ -705,7 +701,7 @@ static inline void sbp2_allow_block(struct sbp2_logical_unit *lu) * logical units have been finished (indicated by dont_block == 0). * - lu->generation is stale. * - * Note, scsi_block_requests() must be called while holding card->lock, + * Note, scsi_block_requests() must be called while holding tgt->lock, * otherwise it might foil sbp2_[conditionally_]unblock()'s attempt to * unblock the target. */ @@ -717,20 +713,20 @@ static void sbp2_conditionally_block(struct sbp2_logical_unit *lu) container_of((void *)tgt, struct Scsi_Host, hostdata[0]); unsigned long flags; - spin_lock_irqsave(&card->lock, flags); + spin_lock_irqsave(&tgt->lock, flags); if (!tgt->dont_block && !lu->blocked && lu->generation != card->generation) { lu->blocked = true; if (++tgt->blocked == 1) scsi_block_requests(shost); } - spin_unlock_irqrestore(&card->lock, flags); + spin_unlock_irqrestore(&tgt->lock, flags); } /* * Unblocks lu->tgt as soon as all its logical units can be unblocked. * Note, it is harmless to run scsi_unblock_requests() outside the - * card->lock protected section. On the other hand, running it inside + * tgt->lock protected section. On the other hand, running it inside * the section might clash with shost->host_lock. */ static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu) @@ -739,15 +735,14 @@ static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu) struct fw_card *card = target_parent_device(tgt)->card; struct Scsi_Host *shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]); - unsigned long flags; bool unblock = false; - spin_lock_irqsave(&card->lock, flags); + spin_lock_irq(&tgt->lock); if (lu->blocked && lu->generation == card->generation) { lu->blocked = false; unblock = --tgt->blocked == 0; } - spin_unlock_irqrestore(&card->lock, flags); + spin_unlock_irq(&tgt->lock); if (unblock) scsi_unblock_requests(shost); @@ -756,19 +751,17 @@ static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu) /* * Prevents future blocking of tgt and unblocks it. * Note, it is harmless to run scsi_unblock_requests() outside the - * card->lock protected section. On the other hand, running it inside + * tgt->lock protected section. On the other hand, running it inside * the section might clash with shost->host_lock. */ static void sbp2_unblock(struct sbp2_target *tgt) { - struct fw_card *card = target_parent_device(tgt)->card; struct Scsi_Host *shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]); - unsigned long flags; - spin_lock_irqsave(&card->lock, flags); + spin_lock_irq(&tgt->lock); ++tgt->dont_block; - spin_unlock_irqrestore(&card->lock, flags); + spin_unlock_irq(&tgt->lock); scsi_unblock_requests(shost); } @@ -904,7 +897,7 @@ static void sbp2_login(struct work_struct *work) /* No error during __scsi_add_device() */ lu->has_sdev = true; scsi_device_put(sdev); - sbp2_allow_block(lu); + sbp2_allow_block(tgt); return; @@ -1163,6 +1156,7 @@ static int sbp2_probe(struct fw_unit *unit, const struct ieee1394_device_id *id) dev_set_drvdata(&unit->device, tgt); tgt->unit = unit; INIT_LIST_HEAD(&tgt->lu_list); + spin_lock_init(&tgt->lock); tgt->guid = (u64)device->config_rom[3] << 32 | device->config_rom[4]; if (fw_device_enable_phys_dma(device) < 0) @@ -1359,12 +1353,12 @@ static void complete_command_orb(struct sbp2_orb *base_orb, { struct sbp2_command_orb *orb = container_of(base_orb, struct sbp2_command_orb, base); - struct fw_device *device = target_parent_device(orb->lu->tgt); + struct fw_device *device = target_parent_device(base_orb->lu->tgt); int result; if (status != NULL) { if (STATUS_GET_DEAD(*status)) - sbp2_agent_reset_no_wait(orb->lu); + sbp2_agent_reset_no_wait(base_orb->lu); switch (STATUS_GET_RESPONSE(*status)) { case SBP2_STATUS_REQUEST_COMPLETE: @@ -1390,7 +1384,7 @@ static void complete_command_orb(struct sbp2_orb *base_orb, * or when sending the write (less likely). */ result = DID_BUS_BUSY << 16; - sbp2_conditionally_block(orb->lu); + sbp2_conditionally_block(base_orb->lu); } dma_unmap_single(device->card->device, orb->base.request_bus, @@ -1487,7 +1481,6 @@ static int sbp2_scsi_queuecommand(struct Scsi_Host *shost, /* Initialize rcode to something not RCODE_COMPLETE. */ orb->base.rcode = -1; kref_init(&orb->base.kref); - orb->lu = lu; orb->cmd = cmd; orb->request.next.high = cpu_to_be32(SBP2_ORB_NULL); orb->request.misc = cpu_to_be32( diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c index 55d4803d71b0..3d9e08f7e823 100644 --- a/drivers/gpio/gpio-crystalcove.c +++ b/drivers/gpio/gpio-crystalcove.c @@ -272,7 +272,7 @@ static irqreturn_t crystalcove_gpio_irq_handler(int irq, void *data) for (gpio = 0; gpio < CRYSTALCOVE_GPIO_NUM; gpio++) { if (pending & BIT(gpio)) { virq = irq_find_mapping(cg->chip.irqdomain, gpio); - generic_handle_irq(virq); + handle_nested_irq(virq); } } diff --git a/drivers/gpio/gpio-dln2.c b/drivers/gpio/gpio-dln2.c index 978b51eae2ec..ce3c1558cb0a 100644 --- a/drivers/gpio/gpio-dln2.c +++ b/drivers/gpio/gpio-dln2.c @@ -47,13 +47,6 @@ #define DLN2_GPIO_MAX_PINS 32 -struct dln2_irq_work { - struct work_struct work; - struct dln2_gpio *dln2; - int pin; - int type; -}; - struct dln2_gpio { struct platform_device *pdev; struct gpio_chip gpio; @@ -64,10 +57,12 @@ struct dln2_gpio { */ DECLARE_BITMAP(output_enabled, DLN2_GPIO_MAX_PINS); - DECLARE_BITMAP(irqs_masked, DLN2_GPIO_MAX_PINS); - DECLARE_BITMAP(irqs_enabled, DLN2_GPIO_MAX_PINS); - DECLARE_BITMAP(irqs_pending, DLN2_GPIO_MAX_PINS); - struct dln2_irq_work *irq_work; + /* active IRQs - not synced to hardware */ + DECLARE_BITMAP(unmasked_irqs, DLN2_GPIO_MAX_PINS); + /* active IRQS - synced to hardware */ + DECLARE_BITMAP(enabled_irqs, DLN2_GPIO_MAX_PINS); + int irq_type[DLN2_GPIO_MAX_PINS]; + struct mutex irq_lock; }; struct dln2_gpio_pin { @@ -141,16 +136,16 @@ static int dln2_gpio_pin_get_out_val(struct dln2_gpio *dln2, unsigned int pin) return !!ret; } -static void dln2_gpio_pin_set_out_val(struct dln2_gpio *dln2, - unsigned int pin, int value) +static int dln2_gpio_pin_set_out_val(struct dln2_gpio *dln2, + unsigned int pin, int value) { struct dln2_gpio_pin_val req = { .pin = cpu_to_le16(pin), .value = value, }; - dln2_transfer_tx(dln2->pdev, DLN2_GPIO_PIN_SET_OUT_VAL, &req, - sizeof(req)); + return dln2_transfer_tx(dln2->pdev, DLN2_GPIO_PIN_SET_OUT_VAL, &req, + sizeof(req)); } #define DLN2_GPIO_DIRECTION_IN 0 @@ -267,6 +262,13 @@ static int dln2_gpio_direction_input(struct gpio_chip *chip, unsigned offset) static int dln2_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value) { + struct dln2_gpio *dln2 = container_of(chip, struct dln2_gpio, gpio); + int ret; + + ret = dln2_gpio_pin_set_out_val(dln2, offset, value); + if (ret < 0) + return ret; + return dln2_gpio_set_direction(chip, offset, DLN2_GPIO_DIRECTION_OUT); } @@ -297,36 +299,13 @@ static int dln2_gpio_set_event_cfg(struct dln2_gpio *dln2, unsigned pin, &req, sizeof(req)); } -static void dln2_irq_work(struct work_struct *w) -{ - struct dln2_irq_work *iw = container_of(w, struct dln2_irq_work, work); - struct dln2_gpio *dln2 = iw->dln2; - u8 type = iw->type & DLN2_GPIO_EVENT_MASK; - - if (test_bit(iw->pin, dln2->irqs_enabled)) - dln2_gpio_set_event_cfg(dln2, iw->pin, type, 0); - else - dln2_gpio_set_event_cfg(dln2, iw->pin, DLN2_GPIO_EVENT_NONE, 0); -} - -static void dln2_irq_enable(struct irq_data *irqd) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); - struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); - int pin = irqd_to_hwirq(irqd); - - set_bit(pin, dln2->irqs_enabled); - schedule_work(&dln2->irq_work[pin].work); -} - -static void dln2_irq_disable(struct irq_data *irqd) +static void dln2_irq_unmask(struct irq_data *irqd) { struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); int pin = irqd_to_hwirq(irqd); - clear_bit(pin, dln2->irqs_enabled); - schedule_work(&dln2->irq_work[pin].work); + set_bit(pin, dln2->unmasked_irqs); } static void dln2_irq_mask(struct irq_data *irqd) @@ -335,27 +314,7 @@ static void dln2_irq_mask(struct irq_data *irqd) struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); int pin = irqd_to_hwirq(irqd); - set_bit(pin, dln2->irqs_masked); -} - -static void dln2_irq_unmask(struct irq_data *irqd) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); - struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); - struct device *dev = dln2->gpio.dev; - int pin = irqd_to_hwirq(irqd); - - if (test_and_clear_bit(pin, dln2->irqs_pending)) { - int irq; - - irq = irq_find_mapping(dln2->gpio.irqdomain, pin); - if (!irq) { - dev_err(dev, "pin %d not mapped to IRQ\n", pin); - return; - } - - generic_handle_irq(irq); - } + clear_bit(pin, dln2->unmasked_irqs); } static int dln2_irq_set_type(struct irq_data *irqd, unsigned type) @@ -366,19 +325,19 @@ static int dln2_irq_set_type(struct irq_data *irqd, unsigned type) switch (type) { case IRQ_TYPE_LEVEL_HIGH: - dln2->irq_work[pin].type = DLN2_GPIO_EVENT_LVL_HIGH; + dln2->irq_type[pin] = DLN2_GPIO_EVENT_LVL_HIGH; break; case IRQ_TYPE_LEVEL_LOW: - dln2->irq_work[pin].type = DLN2_GPIO_EVENT_LVL_LOW; + dln2->irq_type[pin] = DLN2_GPIO_EVENT_LVL_LOW; break; case IRQ_TYPE_EDGE_BOTH: - dln2->irq_work[pin].type = DLN2_GPIO_EVENT_CHANGE; + dln2->irq_type[pin] = DLN2_GPIO_EVENT_CHANGE; break; case IRQ_TYPE_EDGE_RISING: - dln2->irq_work[pin].type = DLN2_GPIO_EVENT_CHANGE_RISING; + dln2->irq_type[pin] = DLN2_GPIO_EVENT_CHANGE_RISING; break; case IRQ_TYPE_EDGE_FALLING: - dln2->irq_work[pin].type = DLN2_GPIO_EVENT_CHANGE_FALLING; + dln2->irq_type[pin] = DLN2_GPIO_EVENT_CHANGE_FALLING; break; default: return -EINVAL; @@ -387,13 +346,50 @@ static int dln2_irq_set_type(struct irq_data *irqd, unsigned type) return 0; } +static void dln2_irq_bus_lock(struct irq_data *irqd) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); + struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); + + mutex_lock(&dln2->irq_lock); +} + +static void dln2_irq_bus_unlock(struct irq_data *irqd) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); + struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); + int pin = irqd_to_hwirq(irqd); + int enabled, unmasked; + unsigned type; + int ret; + + enabled = test_bit(pin, dln2->enabled_irqs); + unmasked = test_bit(pin, dln2->unmasked_irqs); + + if (enabled != unmasked) { + if (unmasked) { + type = dln2->irq_type[pin] & DLN2_GPIO_EVENT_MASK; + set_bit(pin, dln2->enabled_irqs); + } else { + type = DLN2_GPIO_EVENT_NONE; + clear_bit(pin, dln2->enabled_irqs); + } + + ret = dln2_gpio_set_event_cfg(dln2, pin, type, 0); + if (ret) + dev_err(dln2->gpio.dev, "failed to set event\n"); + } + + mutex_unlock(&dln2->irq_lock); +} + static struct irq_chip dln2_gpio_irqchip = { .name = "dln2-irq", - .irq_enable = dln2_irq_enable, - .irq_disable = dln2_irq_disable, .irq_mask = dln2_irq_mask, .irq_unmask = dln2_irq_unmask, .irq_set_type = dln2_irq_set_type, + .irq_bus_lock = dln2_irq_bus_lock, + .irq_bus_sync_unlock = dln2_irq_bus_unlock, }; static void dln2_gpio_event(struct platform_device *pdev, u16 echo, @@ -425,14 +421,7 @@ static void dln2_gpio_event(struct platform_device *pdev, u16 echo, return; } - if (!test_bit(pin, dln2->irqs_enabled)) - return; - if (test_bit(pin, dln2->irqs_masked)) { - set_bit(pin, dln2->irqs_pending); - return; - } - - switch (dln2->irq_work[pin].type) { + switch (dln2->irq_type[pin]) { case DLN2_GPIO_EVENT_CHANGE_RISING: if (event->value) generic_handle_irq(irq); @@ -451,7 +440,7 @@ static int dln2_gpio_probe(struct platform_device *pdev) struct dln2_gpio *dln2; struct device *dev = &pdev->dev; int pins; - int i, ret; + int ret; pins = dln2_gpio_get_pin_count(pdev); if (pins < 0) { @@ -467,15 +456,7 @@ static int dln2_gpio_probe(struct platform_device *pdev) if (!dln2) return -ENOMEM; - dln2->irq_work = devm_kcalloc(&pdev->dev, pins, - sizeof(struct dln2_irq_work), GFP_KERNEL); - if (!dln2->irq_work) - return -ENOMEM; - for (i = 0; i < pins; i++) { - INIT_WORK(&dln2->irq_work[i].work, dln2_irq_work); - dln2->irq_work[i].pin = i; - dln2->irq_work[i].dln2 = dln2; - } + mutex_init(&dln2->irq_lock); dln2->pdev = pdev; @@ -529,11 +510,8 @@ out: static int dln2_gpio_remove(struct platform_device *pdev) { struct dln2_gpio *dln2 = platform_get_drvdata(pdev); - int i; dln2_unregister_event_cb(pdev, DLN2_GPIO_CONDITION_MET_EV); - for (i = 0; i < dln2->gpio.ngpio; i++) - flush_work(&dln2->irq_work[i].work); gpiochip_remove(&dln2->gpio); return 0; diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c index 09daaf2aeb56..3a5a71050559 100644 --- a/drivers/gpio/gpio-grgpio.c +++ b/drivers/gpio/gpio-grgpio.c @@ -441,7 +441,8 @@ static int grgpio_probe(struct platform_device *ofdev) err = gpiochip_add(gc); if (err) { dev_err(&ofdev->dev, "Could not add gpiochip\n"); - irq_domain_remove(priv->domain); + if (priv->domain) + irq_domain_remove(priv->domain); return err; } diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 604dbe60bdee..08261f2b3a82 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -45,8 +45,14 @@ static int of_gpiochip_find_and_xlate(struct gpio_chip *gc, void *data) return false; ret = gc->of_xlate(gc, &gg_data->gpiospec, gg_data->flags); - if (ret < 0) - return false; + if (ret < 0) { + /* We've found the gpio chip, but the translation failed. + * Return true to stop looking and return the translation + * error via out_gpio + */ + gg_data->out_gpio = ERR_PTR(ret); + return true; + } gg_data->out_gpio = gpiochip_get_desc(gc, ret); return true; diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index 2ac1800b58bb..f62aa115d79a 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -128,7 +128,7 @@ static ssize_t gpio_value_store(struct device *dev, return status; } -static const DEVICE_ATTR(value, 0644, +static DEVICE_ATTR(value, 0644, gpio_value_show, gpio_value_store); static irqreturn_t gpio_sysfs_irq(int irq, void *priv) @@ -353,17 +353,46 @@ static ssize_t gpio_active_low_store(struct device *dev, return status ? : size; } -static const DEVICE_ATTR(active_low, 0644, +static DEVICE_ATTR(active_low, 0644, gpio_active_low_show, gpio_active_low_store); -static const struct attribute *gpio_attrs[] = { +static umode_t gpio_is_visible(struct kobject *kobj, struct attribute *attr, + int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct gpio_desc *desc = dev_get_drvdata(dev); + umode_t mode = attr->mode; + bool show_direction = test_bit(FLAG_SYSFS_DIR, &desc->flags); + + if (attr == &dev_attr_direction.attr) { + if (!show_direction) + mode = 0; + } else if (attr == &dev_attr_edge.attr) { + if (gpiod_to_irq(desc) < 0) + mode = 0; + if (!show_direction && test_bit(FLAG_IS_OUT, &desc->flags)) + mode = 0; + } + + return mode; +} + +static struct attribute *gpio_attrs[] = { + &dev_attr_direction.attr, + &dev_attr_edge.attr, &dev_attr_value.attr, &dev_attr_active_low.attr, NULL, }; -static const struct attribute_group gpio_attr_group = { - .attrs = (struct attribute **) gpio_attrs, +static const struct attribute_group gpio_group = { + .attrs = gpio_attrs, + .is_visible = gpio_is_visible, +}; + +static const struct attribute_group *gpio_groups[] = { + &gpio_group, + NULL }; /* @@ -400,16 +429,13 @@ static ssize_t chip_ngpio_show(struct device *dev, } static DEVICE_ATTR(ngpio, 0444, chip_ngpio_show, NULL); -static const struct attribute *gpiochip_attrs[] = { +static struct attribute *gpiochip_attrs[] = { &dev_attr_base.attr, &dev_attr_label.attr, &dev_attr_ngpio.attr, NULL, }; - -static const struct attribute_group gpiochip_attr_group = { - .attrs = (struct attribute **) gpiochip_attrs, -}; +ATTRIBUTE_GROUPS(gpiochip); /* * /sys/class/gpio/export ... write-only @@ -556,45 +582,30 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change) goto fail_unlock; } - if (!desc->chip->direction_input || !desc->chip->direction_output) - direction_may_change = false; + if (desc->chip->direction_input && desc->chip->direction_output && + direction_may_change) { + set_bit(FLAG_SYSFS_DIR, &desc->flags); + } + spin_unlock_irqrestore(&gpio_lock, flags); offset = gpio_chip_hwgpio(desc); if (desc->chip->names && desc->chip->names[offset]) ioname = desc->chip->names[offset]; - dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), - desc, ioname ? ioname : "gpio%u", - desc_to_gpio(desc)); + dev = device_create_with_groups(&gpio_class, desc->chip->dev, + MKDEV(0, 0), desc, gpio_groups, + ioname ? ioname : "gpio%u", + desc_to_gpio(desc)); if (IS_ERR(dev)) { status = PTR_ERR(dev); goto fail_unlock; } - status = sysfs_create_group(&dev->kobj, &gpio_attr_group); - if (status) - goto fail_unregister_device; - - if (direction_may_change) { - status = device_create_file(dev, &dev_attr_direction); - if (status) - goto fail_unregister_device; - } - - if (gpiod_to_irq(desc) >= 0 && (direction_may_change || - !test_bit(FLAG_IS_OUT, &desc->flags))) { - status = device_create_file(dev, &dev_attr_edge); - if (status) - goto fail_unregister_device; - } - set_bit(FLAG_EXPORT, &desc->flags); mutex_unlock(&sysfs_lock); return 0; -fail_unregister_device: - device_unregister(dev); fail_unlock: mutex_unlock(&sysfs_lock); gpiod_dbg(desc, "%s: status %d\n", __func__, status); @@ -718,6 +729,7 @@ void gpiod_unexport(struct gpio_desc *desc) dev = class_find_device(&gpio_class, NULL, desc, match_export); if (dev) { gpio_setup_irq(desc, dev, 0); + clear_bit(FLAG_SYSFS_DIR, &desc->flags); clear_bit(FLAG_EXPORT, &desc->flags); } else status = -ENODEV; @@ -750,13 +762,13 @@ int gpiochip_export(struct gpio_chip *chip) /* use chip->base for the ID; it's already known to be unique */ mutex_lock(&sysfs_lock); - dev = device_create(&gpio_class, chip->dev, MKDEV(0, 0), chip, - "gpiochip%d", chip->base); - if (!IS_ERR(dev)) { - status = sysfs_create_group(&dev->kobj, - &gpiochip_attr_group); - } else + dev = device_create_with_groups(&gpio_class, chip->dev, MKDEV(0, 0), + chip, gpiochip_groups, + "gpiochip%d", chip->base); + if (IS_ERR(dev)) status = PTR_ERR(dev); + else + status = 0; chip->exported = (status == 0); mutex_unlock(&sysfs_lock); diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 487afe6f22fc..568aa2b6bdb0 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -248,29 +248,30 @@ int gpiochip_add(struct gpio_chip *chip) base = gpiochip_find_base(chip->ngpio); if (base < 0) { status = base; - goto unlock; + spin_unlock_irqrestore(&gpio_lock, flags); + goto err_free_descs; } chip->base = base; } status = gpiochip_add_to_list(chip); + if (status) { + spin_unlock_irqrestore(&gpio_lock, flags); + goto err_free_descs; + } - if (status == 0) { - for (id = 0; id < chip->ngpio; id++) { - struct gpio_desc *desc = &descs[id]; - desc->chip = chip; - - /* REVISIT: most hardware initializes GPIOs as - * inputs (often with pullups enabled) so power - * usage is minimized. Linux code should set the - * gpio direction first thing; but until it does, - * and in case chip->get_direction is not set, - * we may expose the wrong direction in sysfs. - */ - desc->flags = !chip->direction_input - ? (1 << FLAG_IS_OUT) - : 0; - } + for (id = 0; id < chip->ngpio; id++) { + struct gpio_desc *desc = &descs[id]; + + desc->chip = chip; + + /* REVISIT: most hardware initializes GPIOs as inputs (often + * with pullups enabled) so power usage is minimized. Linux + * code should set the gpio direction first thing; but until + * it does, and in case chip->get_direction is not set, we may + * expose the wrong direction in sysfs. + */ + desc->flags = !chip->direction_input ? (1 << FLAG_IS_OUT) : 0; } chip->desc = descs; @@ -284,12 +285,9 @@ int gpiochip_add(struct gpio_chip *chip) of_gpiochip_add(chip); acpi_gpiochip_add(chip); - if (status) - goto fail; - status = gpiochip_export(chip); if (status) - goto fail; + goto err_remove_chip; pr_debug("%s: registered GPIOs %d to %d on device: %s\n", __func__, chip->base, chip->base + chip->ngpio - 1, @@ -297,11 +295,15 @@ int gpiochip_add(struct gpio_chip *chip) return 0; -unlock: +err_remove_chip: + acpi_gpiochip_remove(chip); + of_gpiochip_remove(chip); + spin_lock_irqsave(&gpio_lock, flags); + list_del(&chip->list); spin_unlock_irqrestore(&gpio_lock, flags); -fail: - kfree(descs); chip->desc = NULL; +err_free_descs: + kfree(descs); /* failures here can mean systems won't boot... */ pr_err("%s: GPIOs %d..%d (%s) failed to register\n", __func__, @@ -325,14 +327,15 @@ void gpiochip_remove(struct gpio_chip *chip) unsigned long flags; unsigned id; - acpi_gpiochip_remove(chip); - - spin_lock_irqsave(&gpio_lock, flags); + gpiochip_unexport(chip); gpiochip_irqchip_remove(chip); + + acpi_gpiochip_remove(chip); gpiochip_remove_pin_ranges(chip); of_gpiochip_remove(chip); + spin_lock_irqsave(&gpio_lock, flags); for (id = 0; id < chip->ngpio; id++) { if (test_bit(FLAG_REQUESTED, &chip->desc[id].flags)) dev_crit(chip->dev, "REMOVING GPIOCHIP WITH GPIOS STILL REQUESTED\n"); @@ -342,7 +345,6 @@ void gpiochip_remove(struct gpio_chip *chip) list_del(&chip->list); spin_unlock_irqrestore(&gpio_lock, flags); - gpiochip_unexport(chip); kfree(chip->desc); chip->desc = NULL; diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index e3a52113a541..550a5eafbd38 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -77,6 +77,7 @@ struct gpio_desc { #define FLAG_OPEN_DRAIN 7 /* Gpio is open drain type */ #define FLAG_OPEN_SOURCE 8 /* Gpio is open source type */ #define FLAG_USED_AS_IRQ 9 /* GPIO is connected to an IRQ */ +#define FLAG_SYSFS_DIR 10 /* show sysfs direction attribute */ #define ID_SHIFT 16 /* add new flags before this one */ diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 66e40398b3d3..e620807418ea 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o obj-$(CONFIG_DRM_TTM) += ttm/ obj-$(CONFIG_DRM_TDFX) += tdfx/ obj-$(CONFIG_DRM_R128) += r128/ +obj-$(CONFIG_HSA_AMD) += amd/amdkfd/ obj-$(CONFIG_DRM_RADEON)+= radeon/ obj-$(CONFIG_DRM_MGA) += mga/ obj-$(CONFIG_DRM_I810) += i810/ @@ -67,4 +68,3 @@ obj-$(CONFIG_DRM_IMX) += imx/ obj-y += i2c/ obj-y += panel/ obj-y += bridge/ -obj-$(CONFIG_HSA_AMD) += amd/amdkfd/ diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile index be6246de5091..307a309110e6 100644 --- a/drivers/gpu/drm/amd/amdkfd/Makefile +++ b/drivers/gpu/drm/amd/amdkfd/Makefile @@ -8,7 +8,6 @@ amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o \ kfd_pasid.o kfd_doorbell.o kfd_flat_memory.o \ kfd_process.o kfd_queue.o kfd_mqd_manager.o \ kfd_kernel_queue.o kfd_packet_manager.o \ - kfd_process_queue_manager.o kfd_device_queue_manager.o \ - kfd_interrupt.o + kfd_process_queue_manager.o kfd_device_queue_manager.o obj-$(CONFIG_HSA_AMD) += amdkfd.o diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 4f7b275f2f7b..fcfdf23e1913 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -31,7 +31,6 @@ #include <uapi/linux/kfd_ioctl.h> #include <linux/time.h> #include <linux/mm.h> -#include <linux/uaccess.h> #include <uapi/asm-generic/mman-common.h> #include <asm/processor.h> #include "kfd_priv.h" @@ -121,27 +120,20 @@ static int kfd_open(struct inode *inode, struct file *filep) if (IS_ERR(process)) return PTR_ERR(process); - process->is_32bit_user_mode = is_32bit_user_mode; - dev_dbg(kfd_device, "process %d opened, compat mode (32 bit) - %d\n", process->pasid, process->is_32bit_user_mode); - kfd_init_apertures(process); - return 0; } -static long kfd_ioctl_get_version(struct file *filep, struct kfd_process *p, - void __user *arg) +static int kfd_ioctl_get_version(struct file *filep, struct kfd_process *p, + void *data) { - struct kfd_ioctl_get_version_args args; + struct kfd_ioctl_get_version_args *args = data; int err = 0; - args.major_version = KFD_IOCTL_MAJOR_VERSION; - args.minor_version = KFD_IOCTL_MINOR_VERSION; - - if (copy_to_user(arg, &args, sizeof(args))) - err = -EFAULT; + args->major_version = KFD_IOCTL_MAJOR_VERSION; + args->minor_version = KFD_IOCTL_MINOR_VERSION; return err; } @@ -225,10 +217,10 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties, return 0; } -static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, - void __user *arg) +static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, + void *data) { - struct kfd_ioctl_create_queue_args args; + struct kfd_ioctl_create_queue_args *args = data; struct kfd_dev *dev; int err = 0; unsigned int queue_id; @@ -237,16 +229,13 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, memset(&q_properties, 0, sizeof(struct queue_properties)); - if (copy_from_user(&args, arg, sizeof(args))) - return -EFAULT; - pr_debug("kfd: creating queue ioctl\n"); - err = set_queue_properties_from_user(&q_properties, &args); + err = set_queue_properties_from_user(&q_properties, args); if (err) return err; - dev = kfd_device_by_id(args.gpu_id); + dev = kfd_device_by_id(args->gpu_id); if (dev == NULL) return -EINVAL; @@ -254,7 +243,7 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, pdd = kfd_bind_process_to_device(dev, p); if (IS_ERR(pdd)) { - err = PTR_ERR(pdd); + err = -ESRCH; goto err_bind_process; } @@ -267,33 +256,26 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, if (err != 0) goto err_create_queue; - args.queue_id = queue_id; + args->queue_id = queue_id; /* Return gpu_id as doorbell offset for mmap usage */ - args.doorbell_offset = args.gpu_id << PAGE_SHIFT; - - if (copy_to_user(arg, &args, sizeof(args))) { - err = -EFAULT; - goto err_copy_args_out; - } + args->doorbell_offset = args->gpu_id << PAGE_SHIFT; mutex_unlock(&p->mutex); - pr_debug("kfd: queue id %d was created successfully\n", args.queue_id); + pr_debug("kfd: queue id %d was created successfully\n", args->queue_id); pr_debug("ring buffer address == 0x%016llX\n", - args.ring_base_address); + args->ring_base_address); pr_debug("read ptr address == 0x%016llX\n", - args.read_pointer_address); + args->read_pointer_address); pr_debug("write ptr address == 0x%016llX\n", - args.write_pointer_address); + args->write_pointer_address); return 0; -err_copy_args_out: - pqm_destroy_queue(&p->pqm, queue_id); err_create_queue: err_bind_process: mutex_unlock(&p->mutex); @@ -301,99 +283,90 @@ err_bind_process: } static int kfd_ioctl_destroy_queue(struct file *filp, struct kfd_process *p, - void __user *arg) + void *data) { int retval; - struct kfd_ioctl_destroy_queue_args args; - - if (copy_from_user(&args, arg, sizeof(args))) - return -EFAULT; + struct kfd_ioctl_destroy_queue_args *args = data; pr_debug("kfd: destroying queue id %d for PASID %d\n", - args.queue_id, + args->queue_id, p->pasid); mutex_lock(&p->mutex); - retval = pqm_destroy_queue(&p->pqm, args.queue_id); + retval = pqm_destroy_queue(&p->pqm, args->queue_id); mutex_unlock(&p->mutex); return retval; } static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p, - void __user *arg) + void *data) { int retval; - struct kfd_ioctl_update_queue_args args; + struct kfd_ioctl_update_queue_args *args = data; struct queue_properties properties; - if (copy_from_user(&args, arg, sizeof(args))) - return -EFAULT; - - if (args.queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) { + if (args->queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) { pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n"); return -EINVAL; } - if (args.queue_priority > KFD_MAX_QUEUE_PRIORITY) { + if (args->queue_priority > KFD_MAX_QUEUE_PRIORITY) { pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n"); return -EINVAL; } - if ((args.ring_base_address) && + if ((args->ring_base_address) && (!access_ok(VERIFY_WRITE, - (const void __user *) args.ring_base_address, + (const void __user *) args->ring_base_address, sizeof(uint64_t)))) { pr_err("kfd: can't access ring base address\n"); return -EFAULT; } - if (!is_power_of_2(args.ring_size) && (args.ring_size != 0)) { + if (!is_power_of_2(args->ring_size) && (args->ring_size != 0)) { pr_err("kfd: ring size must be a power of 2 or 0\n"); return -EINVAL; } - properties.queue_address = args.ring_base_address; - properties.queue_size = args.ring_size; - properties.queue_percent = args.queue_percentage; - properties.priority = args.queue_priority; + properties.queue_address = args->ring_base_address; + properties.queue_size = args->ring_size; + properties.queue_percent = args->queue_percentage; + properties.priority = args->queue_priority; pr_debug("kfd: updating queue id %d for PASID %d\n", - args.queue_id, p->pasid); + args->queue_id, p->pasid); mutex_lock(&p->mutex); - retval = pqm_update_queue(&p->pqm, args.queue_id, &properties); + retval = pqm_update_queue(&p->pqm, args->queue_id, &properties); mutex_unlock(&p->mutex); return retval; } -static long kfd_ioctl_set_memory_policy(struct file *filep, - struct kfd_process *p, void __user *arg) +static int kfd_ioctl_set_memory_policy(struct file *filep, + struct kfd_process *p, void *data) { - struct kfd_ioctl_set_memory_policy_args args; + struct kfd_ioctl_set_memory_policy_args *args = data; struct kfd_dev *dev; int err = 0; struct kfd_process_device *pdd; enum cache_policy default_policy, alternate_policy; - if (copy_from_user(&args, arg, sizeof(args))) - return -EFAULT; - - if (args.default_policy != KFD_IOC_CACHE_POLICY_COHERENT - && args.default_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) { + if (args->default_policy != KFD_IOC_CACHE_POLICY_COHERENT + && args->default_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) { return -EINVAL; } - if (args.alternate_policy != KFD_IOC_CACHE_POLICY_COHERENT - && args.alternate_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) { + if (args->alternate_policy != KFD_IOC_CACHE_POLICY_COHERENT + && args->alternate_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) { return -EINVAL; } - dev = kfd_device_by_id(args.gpu_id); + dev = kfd_device_by_id(args->gpu_id); if (dev == NULL) return -EINVAL; @@ -401,23 +374,23 @@ static long kfd_ioctl_set_memory_policy(struct file *filep, pdd = kfd_bind_process_to_device(dev, p); if (IS_ERR(pdd)) { - err = PTR_ERR(pdd); + err = -ESRCH; goto out; } - default_policy = (args.default_policy == KFD_IOC_CACHE_POLICY_COHERENT) + default_policy = (args->default_policy == KFD_IOC_CACHE_POLICY_COHERENT) ? cache_policy_coherent : cache_policy_noncoherent; alternate_policy = - (args.alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT) + (args->alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT) ? cache_policy_coherent : cache_policy_noncoherent; if (!dev->dqm->set_cache_memory_policy(dev->dqm, &pdd->qpd, default_policy, alternate_policy, - (void __user *)args.alternate_aperture_base, - args.alternate_aperture_size)) + (void __user *)args->alternate_aperture_base, + args->alternate_aperture_size)) err = -EINVAL; out: @@ -426,53 +399,44 @@ out: return err; } -static long kfd_ioctl_get_clock_counters(struct file *filep, - struct kfd_process *p, void __user *arg) +static int kfd_ioctl_get_clock_counters(struct file *filep, + struct kfd_process *p, void *data) { - struct kfd_ioctl_get_clock_counters_args args; + struct kfd_ioctl_get_clock_counters_args *args = data; struct kfd_dev *dev; struct timespec time; - if (copy_from_user(&args, arg, sizeof(args))) - return -EFAULT; - - dev = kfd_device_by_id(args.gpu_id); + dev = kfd_device_by_id(args->gpu_id); if (dev == NULL) return -EINVAL; /* Reading GPU clock counter from KGD */ - args.gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd); + args->gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd); /* No access to rdtsc. Using raw monotonic time */ getrawmonotonic(&time); - args.cpu_clock_counter = (uint64_t)timespec_to_ns(&time); + args->cpu_clock_counter = (uint64_t)timespec_to_ns(&time); get_monotonic_boottime(&time); - args.system_clock_counter = (uint64_t)timespec_to_ns(&time); + args->system_clock_counter = (uint64_t)timespec_to_ns(&time); /* Since the counter is in nano-seconds we use 1GHz frequency */ - args.system_clock_freq = 1000000000; - - if (copy_to_user(arg, &args, sizeof(args))) - return -EFAULT; + args->system_clock_freq = 1000000000; return 0; } static int kfd_ioctl_get_process_apertures(struct file *filp, - struct kfd_process *p, void __user *arg) + struct kfd_process *p, void *data) { - struct kfd_ioctl_get_process_apertures_args args; + struct kfd_ioctl_get_process_apertures_args *args = data; struct kfd_process_device_apertures *pAperture; struct kfd_process_device *pdd; dev_dbg(kfd_device, "get apertures for PASID %d", p->pasid); - if (copy_from_user(&args, arg, sizeof(args))) - return -EFAULT; - - args.num_of_nodes = 0; + args->num_of_nodes = 0; mutex_lock(&p->mutex); @@ -481,7 +445,8 @@ static int kfd_ioctl_get_process_apertures(struct file *filp, /* Run over all pdd of the process */ pdd = kfd_get_first_process_device_data(p); do { - pAperture = &args.process_apertures[args.num_of_nodes]; + pAperture = + &args->process_apertures[args->num_of_nodes]; pAperture->gpu_id = pdd->dev->id; pAperture->lds_base = pdd->lds_base; pAperture->lds_limit = pdd->lds_limit; @@ -491,7 +456,7 @@ static int kfd_ioctl_get_process_apertures(struct file *filp, pAperture->scratch_limit = pdd->scratch_limit; dev_dbg(kfd_device, - "node id %u\n", args.num_of_nodes); + "node id %u\n", args->num_of_nodes); dev_dbg(kfd_device, "gpu id %u\n", pdd->dev->id); dev_dbg(kfd_device, @@ -507,80 +472,131 @@ static int kfd_ioctl_get_process_apertures(struct file *filp, dev_dbg(kfd_device, "scratch_limit %llX\n", pdd->scratch_limit); - args.num_of_nodes++; + args->num_of_nodes++; } while ((pdd = kfd_get_next_process_device_data(p, pdd)) != NULL && - (args.num_of_nodes < NUM_OF_SUPPORTED_GPUS)); + (args->num_of_nodes < NUM_OF_SUPPORTED_GPUS)); } mutex_unlock(&p->mutex); - if (copy_to_user(arg, &args, sizeof(args))) - return -EFAULT; - return 0; } +#define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \ + [_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl} + +/** Ioctl table */ +static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = { + AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_VERSION, + kfd_ioctl_get_version, 0), + + AMDKFD_IOCTL_DEF(AMDKFD_IOC_CREATE_QUEUE, + kfd_ioctl_create_queue, 0), + + AMDKFD_IOCTL_DEF(AMDKFD_IOC_DESTROY_QUEUE, + kfd_ioctl_destroy_queue, 0), + + AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_MEMORY_POLICY, + kfd_ioctl_set_memory_policy, 0), + + AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_CLOCK_COUNTERS, + kfd_ioctl_get_clock_counters, 0), + + AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_PROCESS_APERTURES, + kfd_ioctl_get_process_apertures, 0), + + AMDKFD_IOCTL_DEF(AMDKFD_IOC_UPDATE_QUEUE, + kfd_ioctl_update_queue, 0), +}; + +#define AMDKFD_CORE_IOCTL_COUNT ARRAY_SIZE(amdkfd_ioctls) + static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { struct kfd_process *process; - long err = -EINVAL; + amdkfd_ioctl_t *func; + const struct amdkfd_ioctl_desc *ioctl = NULL; + unsigned int nr = _IOC_NR(cmd); + char stack_kdata[128]; + char *kdata = NULL; + unsigned int usize, asize; + int retcode = -EINVAL; + + if (nr >= AMDKFD_CORE_IOCTL_COUNT) + goto err_i1; + + if ((nr >= AMDKFD_COMMAND_START) && (nr < AMDKFD_COMMAND_END)) { + u32 amdkfd_size; + + ioctl = &amdkfd_ioctls[nr]; - dev_dbg(kfd_device, - "ioctl cmd 0x%x (#%d), arg 0x%lx\n", - cmd, _IOC_NR(cmd), arg); + amdkfd_size = _IOC_SIZE(ioctl->cmd); + usize = asize = _IOC_SIZE(cmd); + if (amdkfd_size > asize) + asize = amdkfd_size; + + cmd = ioctl->cmd; + } else + goto err_i1; + + dev_dbg(kfd_device, "ioctl cmd 0x%x (#%d), arg 0x%lx\n", cmd, nr, arg); process = kfd_get_process(current); - if (IS_ERR(process)) - return PTR_ERR(process); + if (IS_ERR(process)) { + dev_dbg(kfd_device, "no process\n"); + goto err_i1; + } - switch (cmd) { - case KFD_IOC_GET_VERSION: - err = kfd_ioctl_get_version(filep, process, (void __user *)arg); - break; - case KFD_IOC_CREATE_QUEUE: - err = kfd_ioctl_create_queue(filep, process, - (void __user *)arg); - break; - - case KFD_IOC_DESTROY_QUEUE: - err = kfd_ioctl_destroy_queue(filep, process, - (void __user *)arg); - break; - - case KFD_IOC_SET_MEMORY_POLICY: - err = kfd_ioctl_set_memory_policy(filep, process, - (void __user *)arg); - break; - - case KFD_IOC_GET_CLOCK_COUNTERS: - err = kfd_ioctl_get_clock_counters(filep, process, - (void __user *)arg); - break; - - case KFD_IOC_GET_PROCESS_APERTURES: - err = kfd_ioctl_get_process_apertures(filep, process, - (void __user *)arg); - break; - - case KFD_IOC_UPDATE_QUEUE: - err = kfd_ioctl_update_queue(filep, process, - (void __user *)arg); - break; - - default: - dev_err(kfd_device, - "unknown ioctl cmd 0x%x, arg 0x%lx)\n", - cmd, arg); - err = -EINVAL; - break; + /* Do not trust userspace, use our own definition */ + func = ioctl->func; + + if (unlikely(!func)) { + dev_dbg(kfd_device, "no function\n"); + retcode = -EINVAL; + goto err_i1; } - if (err < 0) - dev_err(kfd_device, - "ioctl error %ld for ioctl cmd 0x%x (#%d)\n", - err, cmd, _IOC_NR(cmd)); + if (cmd & (IOC_IN | IOC_OUT)) { + if (asize <= sizeof(stack_kdata)) { + kdata = stack_kdata; + } else { + kdata = kmalloc(asize, GFP_KERNEL); + if (!kdata) { + retcode = -ENOMEM; + goto err_i1; + } + } + if (asize > usize) + memset(kdata + usize, 0, asize - usize); + } - return err; + if (cmd & IOC_IN) { + if (copy_from_user(kdata, (void __user *)arg, usize) != 0) { + retcode = -EFAULT; + goto err_i1; + } + } else if (cmd & IOC_OUT) { + memset(kdata, 0, usize); + } + + retcode = func(filep, process, kdata); + + if (cmd & IOC_OUT) + if (copy_to_user((void __user *)arg, kdata, usize) != 0) + retcode = -EFAULT; + +err_i1: + if (!ioctl) + dev_dbg(kfd_device, "invalid ioctl: pid=%d, cmd=0x%02x, nr=0x%02x\n", + task_pid_nr(current), cmd, nr); + + if (kdata != stack_kdata) + kfree(kdata); + + if (retcode) + dev_dbg(kfd_device, "ret = %d\n", retcode); + + return retcode; } static int kfd_mmap(struct file *filp, struct vm_area_struct *vma) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 43884ebd4303..633532a2e7ec 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -192,13 +192,6 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, goto kfd_topology_add_device_error; } - if (kfd_interrupt_init(kfd)) { - dev_err(kfd_device, - "Error initializing interrupts for device (%x:%x)\n", - kfd->pdev->vendor, kfd->pdev->device); - goto kfd_interrupt_error; - } - if (!device_iommu_pasid_init(kfd)) { dev_err(kfd_device, "Error initializing iommuv2 for device (%x:%x)\n", @@ -237,8 +230,6 @@ dqm_start_error: device_queue_manager_error: amd_iommu_free_device(kfd->pdev); device_iommu_pasid_error: - kfd_interrupt_exit(kfd); -kfd_interrupt_error: kfd_topology_remove_device(kfd); kfd_topology_add_device_error: kfd2kgd->fini_sa_manager(kfd->kgd); @@ -254,7 +245,6 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd) if (kfd->init_complete) { device_queue_manager_uninit(kfd->dqm); amd_iommu_free_device(kfd->pdev); - kfd_interrupt_exit(kfd); kfd_topology_remove_device(kfd); } @@ -296,13 +286,5 @@ int kgd2kfd_resume(struct kfd_dev *kfd) /* This is called directly from KGD at ISR. */ void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry) { - if (kfd->init_complete) { - spin_lock(&kfd->interrupt_lock); - - if (kfd->interrupts_active - && enqueue_ih_ring_entry(kfd, ih_ring_entry)) - schedule_work(&kfd->interrupt_work); - - spin_unlock(&kfd->interrupt_lock); - } + /* Process interrupts / schedule work as necessary */ } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 924e90c072e5..30c8fda9622e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -161,6 +161,9 @@ static void deallocate_vmid(struct device_queue_manager *dqm, { int bit = qpd->vmid - KFD_VMID_START_OFFSET; + /* Release the vmid mapping */ + set_pasid_vmid_mapping(dqm, 0, qpd->vmid); + set_bit(bit, (unsigned long *)&dqm->vmid_bitmap); qpd->vmid = 0; q->properties.vmid = 0; @@ -272,6 +275,18 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm, return retval; } + pr_debug("kfd: loading mqd to hqd on pipe (%d) queue (%d)\n", + q->pipe, + q->queue); + + retval = mqd->load_mqd(mqd, q->mqd, q->pipe, + q->queue, (uint32_t __user *) q->properties.write_ptr); + if (retval != 0) { + deallocate_hqd(dqm, q); + mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj); + return retval; + } + return 0; } @@ -320,6 +335,7 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q) { int retval; struct mqd_manager *mqd; + bool prev_active = false; BUG_ON(!dqm || !q || !q->mqd); @@ -330,10 +346,18 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q) return -ENOMEM; } - retval = mqd->update_mqd(mqd, q->mqd, &q->properties); if (q->properties.is_active == true) + prev_active = true; + + /* + * + * check active state vs. the previous state + * and modify counter accordingly + */ + retval = mqd->update_mqd(mqd, q->mqd, &q->properties); + if ((q->properties.is_active == true) && (prev_active == false)) dqm->queue_count++; - else + else if ((q->properties.is_active == false) && (prev_active == true)) dqm->queue_count--; if (sched_policy != KFD_SCHED_POLICY_NO_HWS) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c index 66df4da01c29..e64aa99e5e41 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c @@ -299,13 +299,13 @@ int kfd_init_apertures(struct kfd_process *process) struct kfd_dev *dev; struct kfd_process_device *pdd; - mutex_lock(&process->mutex); - /*Iterating over all devices*/ while ((dev = kfd_topology_enum_kfd_devices(id)) != NULL && id < NUM_OF_SUPPORTED_GPUS) { pdd = kfd_get_process_device_data(dev, process, 1); + if (!pdd) + return -1; /* * For 64 bit process aperture will be statically reserved in @@ -348,8 +348,6 @@ int kfd_init_apertures(struct kfd_process *process) id++; } - mutex_unlock(&process->mutex); - return 0; } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c deleted file mode 100644 index 5b999095a1f7..000000000000 --- a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2014 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * KFD Interrupts. - * - * AMD GPUs deliver interrupts by pushing an interrupt description onto the - * interrupt ring and then sending an interrupt. KGD receives the interrupt - * in ISR and sends us a pointer to each new entry on the interrupt ring. - * - * We generally can't process interrupt-signaled events from ISR, so we call - * out to each interrupt client module (currently only the scheduler) to ask if - * each interrupt is interesting. If they return true, then it requires further - * processing so we copy it to an internal interrupt ring and call each - * interrupt client again from a work-queue. - * - * There's no acknowledgment for the interrupts we use. The hardware simply - * queues a new interrupt each time without waiting. - * - * The fixed-size internal queue means that it's possible for us to lose - * interrupts because we have no back-pressure to the hardware. - */ - -#include <linux/slab.h> -#include <linux/device.h> -#include "kfd_priv.h" - -#define KFD_INTERRUPT_RING_SIZE 256 - -static void interrupt_wq(struct work_struct *); - -int kfd_interrupt_init(struct kfd_dev *kfd) -{ - void *interrupt_ring = kmalloc_array(KFD_INTERRUPT_RING_SIZE, - kfd->device_info->ih_ring_entry_size, - GFP_KERNEL); - if (!interrupt_ring) - return -ENOMEM; - - kfd->interrupt_ring = interrupt_ring; - kfd->interrupt_ring_size = - KFD_INTERRUPT_RING_SIZE * kfd->device_info->ih_ring_entry_size; - atomic_set(&kfd->interrupt_ring_wptr, 0); - atomic_set(&kfd->interrupt_ring_rptr, 0); - - spin_lock_init(&kfd->interrupt_lock); - - INIT_WORK(&kfd->interrupt_work, interrupt_wq); - - kfd->interrupts_active = true; - - /* - * After this function returns, the interrupt will be enabled. This - * barrier ensures that the interrupt running on a different processor - * sees all the above writes. - */ - smp_wmb(); - - return 0; -} - -void kfd_interrupt_exit(struct kfd_dev *kfd) -{ - /* - * Stop the interrupt handler from writing to the ring and scheduling - * workqueue items. The spinlock ensures that any interrupt running - * after we have unlocked sees interrupts_active = false. - */ - unsigned long flags; - - spin_lock_irqsave(&kfd->interrupt_lock, flags); - kfd->interrupts_active = false; - spin_unlock_irqrestore(&kfd->interrupt_lock, flags); - - /* - * Flush_scheduled_work ensures that there are no outstanding - * work-queue items that will access interrupt_ring. New work items - * can't be created because we stopped interrupt handling above. - */ - flush_scheduled_work(); - - kfree(kfd->interrupt_ring); -} - -/* - * This assumes that it can't be called concurrently with itself - * but only with dequeue_ih_ring_entry. - */ -bool enqueue_ih_ring_entry(struct kfd_dev *kfd, const void *ih_ring_entry) -{ - unsigned int rptr = atomic_read(&kfd->interrupt_ring_rptr); - unsigned int wptr = atomic_read(&kfd->interrupt_ring_wptr); - - if ((rptr - wptr) % kfd->interrupt_ring_size == - kfd->device_info->ih_ring_entry_size) { - /* This is very bad, the system is likely to hang. */ - dev_err_ratelimited(kfd_chardev(), - "Interrupt ring overflow, dropping interrupt.\n"); - return false; - } - - memcpy(kfd->interrupt_ring + wptr, ih_ring_entry, - kfd->device_info->ih_ring_entry_size); - - wptr = (wptr + kfd->device_info->ih_ring_entry_size) % - kfd->interrupt_ring_size; - smp_wmb(); /* Ensure memcpy'd data is visible before wptr update. */ - atomic_set(&kfd->interrupt_ring_wptr, wptr); - - return true; -} - -/* - * This assumes that it can't be called concurrently with itself - * but only with enqueue_ih_ring_entry. - */ -static bool dequeue_ih_ring_entry(struct kfd_dev *kfd, void *ih_ring_entry) -{ - /* - * Assume that wait queues have an implicit barrier, i.e. anything that - * happened in the ISR before it queued work is visible. - */ - - unsigned int wptr = atomic_read(&kfd->interrupt_ring_wptr); - unsigned int rptr = atomic_read(&kfd->interrupt_ring_rptr); - - if (rptr == wptr) - return false; - - memcpy(ih_ring_entry, kfd->interrupt_ring + rptr, - kfd->device_info->ih_ring_entry_size); - - rptr = (rptr + kfd->device_info->ih_ring_entry_size) % - kfd->interrupt_ring_size; - - /* - * Ensure the rptr write update is not visible until - * memcpy has finished reading. - */ - smp_mb(); - atomic_set(&kfd->interrupt_ring_rptr, rptr); - - return true; -} - -static void interrupt_wq(struct work_struct *work) -{ - struct kfd_dev *dev = container_of(work, struct kfd_dev, - interrupt_work); - - uint32_t ih_ring_entry[DIV_ROUND_UP( - dev->device_info->ih_ring_entry_size, - sizeof(uint32_t))]; - - while (dequeue_ih_ring_entry(dev, ih_ring_entry)) - ; -} diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c index adc31474e786..4c3828cf45bf 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c @@ -184,7 +184,7 @@ static bool is_occupied(struct mqd_manager *mm, void *mqd, uint32_t queue_id) { - return kfd2kgd->hqd_is_occupies(mm->dev->kgd, queue_address, + return kfd2kgd->hqd_is_occupied(mm->dev->kgd, queue_address, pipe_id, queue_id); } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c index 71699ad97d74..4c25ef504f79 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c @@ -32,7 +32,7 @@ int kfd_pasid_init(void) { pasid_limit = max_num_of_processes; - pasid_bitmap = kzalloc(BITS_TO_LONGS(pasid_limit), GFP_KERNEL); + pasid_bitmap = kcalloc(BITS_TO_LONGS(pasid_limit), sizeof(long), GFP_KERNEL); if (!pasid_bitmap) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index f9fb81e3bb09..b3dc13c83169 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -135,22 +135,10 @@ struct kfd_dev { struct kgd2kfd_shared_resources shared_resources; - void *interrupt_ring; - size_t interrupt_ring_size; - atomic_t interrupt_ring_rptr; - atomic_t interrupt_ring_wptr; - struct work_struct interrupt_work; - spinlock_t interrupt_lock; - /* QCM Device instance */ struct device_queue_manager *dqm; bool init_complete; - /* - * Interrupts of interest to KFD are copied - * from the HW ring into a SW ring. - */ - bool interrupts_active; }; /* KGD2KFD callbacks */ @@ -463,6 +451,24 @@ struct kfd_process { bool is_32bit_user_mode; }; +/** + * Ioctl function type. + * + * \param filep pointer to file structure. + * \param p amdkfd process pointer. + * \param data pointer to arg that was copied from user. + */ +typedef int amdkfd_ioctl_t(struct file *filep, struct kfd_process *p, + void *data); + +struct amdkfd_ioctl_desc { + unsigned int cmd; + int flags; + amdkfd_ioctl_t *func; + unsigned int cmd_drv; + const char *name; +}; + void kfd_process_create_wq(void); void kfd_process_destroy_wq(void); struct kfd_process *kfd_create_process(const struct task_struct *); @@ -513,10 +519,7 @@ struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev); struct kfd_dev *kfd_topology_enum_kfd_devices(uint8_t idx); /* Interrupts */ -int kfd_interrupt_init(struct kfd_dev *dev); -void kfd_interrupt_exit(struct kfd_dev *dev); void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry); -bool enqueue_ih_ring_entry(struct kfd_dev *kfd, const void *ih_ring_entry); /* Power Management */ void kgd2kfd_suspend(struct kfd_dev *kfd); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index b85eb0b830b4..3c76ef05cbcf 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -26,6 +26,8 @@ #include <linux/slab.h> #include <linux/amd-iommu.h> #include <linux/notifier.h> +#include <linux/compat.h> + struct mm_struct; #include "kfd_priv.h" @@ -285,8 +287,15 @@ static struct kfd_process *create_process(const struct task_struct *thread) if (err != 0) goto err_process_pqm_init; + /* init process apertures*/ + process->is_32bit_user_mode = is_compat_task(); + if (kfd_init_apertures(process) != 0) + goto err_init_apretures; + return process; +err_init_apretures: + pqm_uninit(&process->pqm); err_process_pqm_init: hash_del_rcu(&process->kfd_processes); synchronize_rcu(); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index 5733e2859e8a..cca1708fd811 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -700,8 +700,6 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, dev->node_props.simd_per_cu); sysfs_show_32bit_prop(buffer, "max_slots_scratch_cu", dev->node_props.max_slots_scratch_cu); - sysfs_show_32bit_prop(buffer, "engine_id", - dev->node_props.engine_id); sysfs_show_32bit_prop(buffer, "vendor_id", dev->node_props.vendor_id); sysfs_show_32bit_prop(buffer, "device_id", @@ -715,6 +713,12 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, dev->gpu->kgd)); sysfs_show_64bit_prop(buffer, "local_mem_size", kfd2kgd->get_vmem_size(dev->gpu->kgd)); + + sysfs_show_32bit_prop(buffer, "fw_version", + kfd2kgd->get_fw_version( + dev->gpu->kgd, + KGD_ENGINE_MEC1)); + } ret = sysfs_show_32bit_prop(buffer, "max_engine_clk_ccompute", @@ -917,7 +921,7 @@ static int kfd_build_sysfs_node_tree(void) uint32_t i = 0; list_for_each_entry(dev, &topology_device_list, list) { - ret = kfd_build_sysfs_node_entry(dev, 0); + ret = kfd_build_sysfs_node_entry(dev, i); if (ret < 0) return ret; i++; diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h index 9c729dd8dd50..96a512208fad 100644 --- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h @@ -45,6 +45,17 @@ enum kgd_memory_pool { KGD_POOL_FRAMEBUFFER = 3, }; +enum kgd_engine_type { + KGD_ENGINE_PFP = 1, + KGD_ENGINE_ME, + KGD_ENGINE_CE, + KGD_ENGINE_MEC1, + KGD_ENGINE_MEC2, + KGD_ENGINE_RLC, + KGD_ENGINE_SDMA, + KGD_ENGINE_MAX +}; + struct kgd2kfd_shared_resources { /* Bit n == 1 means VMID n is available for KFD. */ unsigned int compute_vmid_bitmap; @@ -137,6 +148,8 @@ struct kgd2kfd_calls { * * @hqd_destroy: Destructs and preempts the queue assigned to that hqd slot. * + * @get_fw_version: Returns FW versions from the header + * * This structure contains function pointers to services that the kgd driver * provides to amdkfd driver. * @@ -170,12 +183,14 @@ struct kfd2kgd_calls { int (*hqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, uint32_t queue_id, uint32_t __user *wptr); - bool (*hqd_is_occupies)(struct kgd_dev *kgd, uint64_t queue_address, + bool (*hqd_is_occupied)(struct kgd_dev *kgd, uint64_t queue_address, uint32_t pipe_id, uint32_t queue_id); int (*hqd_destroy)(struct kgd_dev *kgd, uint32_t reset_type, unsigned int timeout, uint32_t pipe_id, uint32_t queue_id); + uint16_t (*get_fw_version)(struct kgd_dev *kgd, + enum kgd_engine_type type); }; bool kgd2kfd_init(unsigned interface_version, diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 4a78a773151c..bbdbe4721573 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -61,7 +61,7 @@ drm_atomic_helper_plane_changed(struct drm_atomic_state *state, struct drm_crtc_state *crtc_state; if (plane->state->crtc) { - crtc_state = state->crtc_states[drm_crtc_index(plane->crtc)]; + crtc_state = state->crtc_states[drm_crtc_index(plane->state->crtc)]; if (WARN_ON(!crtc_state)) return; diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 52ce26d6b4fb..cf775a4449c1 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -741,7 +741,9 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info) int i, j, rc = 0; int start; - drm_modeset_lock_all(dev); + if (__drm_modeset_lock_all(dev, !!oops_in_progress)) { + return -EBUSY; + } if (!drm_fb_helper_is_bound(fb_helper)) { drm_modeset_unlock_all(dev); return -EBUSY; @@ -915,7 +917,9 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var, int ret = 0; int i; - drm_modeset_lock_all(dev); + if (__drm_modeset_lock_all(dev, !!oops_in_progress)) { + return -EBUSY; + } if (!drm_fb_helper_is_bound(fb_helper)) { drm_modeset_unlock_all(dev); return -EBUSY; diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index f5a5f18efa5b..4d79dad9d44f 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -830,6 +830,8 @@ drm_get_last_vbltimestamp(struct drm_device *dev, int crtc, * vblank events since the system was booted, including lost events due to * modesetting activity. * + * This is the legacy version of drm_crtc_vblank_count(). + * * Returns: * The software vblank counter. */ @@ -844,6 +846,25 @@ u32 drm_vblank_count(struct drm_device *dev, int crtc) EXPORT_SYMBOL(drm_vblank_count); /** + * drm_crtc_vblank_count - retrieve "cooked" vblank counter value + * @crtc: which counter to retrieve + * + * Fetches the "cooked" vblank count value that represents the number of + * vblank events since the system was booted, including lost events due to + * modesetting activity. + * + * This is the native KMS version of drm_vblank_count(). + * + * Returns: + * The software vblank counter. + */ +u32 drm_crtc_vblank_count(struct drm_crtc *crtc) +{ + return drm_vblank_count(crtc->dev, drm_crtc_index(crtc)); +} +EXPORT_SYMBOL(drm_crtc_vblank_count); + +/** * drm_vblank_count_and_time - retrieve "cooked" vblank counter value * and the system timestamp corresponding to that vblank counter value. * @@ -904,6 +925,8 @@ static void send_vblank_event(struct drm_device *dev, * * Updates sequence # and timestamp on event, and sends it to userspace. * Caller must hold event lock. + * + * This is the legacy version of drm_crtc_send_vblank_event(). */ void drm_send_vblank_event(struct drm_device *dev, int crtc, struct drm_pending_vblank_event *e) @@ -923,6 +946,23 @@ void drm_send_vblank_event(struct drm_device *dev, int crtc, EXPORT_SYMBOL(drm_send_vblank_event); /** + * drm_crtc_send_vblank_event - helper to send vblank event after pageflip + * @crtc: the source CRTC of the vblank event + * @e: the event to send + * + * Updates sequence # and timestamp on event, and sends it to userspace. + * Caller must hold event lock. + * + * This is the native KMS version of drm_send_vblank_event(). + */ +void drm_crtc_send_vblank_event(struct drm_crtc *crtc, + struct drm_pending_vblank_event *e) +{ + drm_send_vblank_event(crtc->dev, drm_crtc_index(crtc), e); +} +EXPORT_SYMBOL(drm_crtc_send_vblank_event); + +/** * drm_vblank_enable - enable the vblank interrupt on a CRTC * @dev: DRM device * @crtc: CRTC in question @@ -1594,6 +1634,8 @@ static void drm_handle_vblank_events(struct drm_device *dev, int crtc) * * Drivers should call this routine in their vblank interrupt handlers to * update the vblank counter and send any signals that may be pending. + * + * This is the legacy version of drm_crtc_handle_vblank(). */ bool drm_handle_vblank(struct drm_device *dev, int crtc) { @@ -1670,3 +1712,21 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc) return true; } EXPORT_SYMBOL(drm_handle_vblank); + +/** + * drm_crtc_handle_vblank - handle a vblank event + * @crtc: where this event occurred + * + * Drivers should call this routine in their vblank interrupt handlers to + * update the vblank counter and send any signals that may be pending. + * + * This is the native KMS version of drm_handle_vblank(). + * + * Returns: + * True if the event was successfully handled, false on failure. + */ +bool drm_crtc_handle_vblank(struct drm_crtc *crtc) +{ + return drm_handle_vblank(crtc->dev, drm_crtc_index(crtc)); +} +EXPORT_SYMBOL(drm_crtc_handle_vblank); diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 121470a83d1a..1bcbe07cecfc 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -645,18 +645,6 @@ static int exynos_drm_init(void) if (!is_exynos) return -ENODEV; - /* - * Register device object only in case of Exynos SoC. - * - * Below codes resolves temporarily infinite loop issue incurred - * by Exynos drm driver when using multi-platform kernel. - * So these codes will be replaced with more generic way later. - */ - if (!of_machine_is_compatible("samsung,exynos3") && - !of_machine_is_compatible("samsung,exynos4") && - !of_machine_is_compatible("samsung,exynos5")) - return -ENODEV; - exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1, NULL, 0); if (IS_ERR(exynos_drm_pdev)) diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 5765a161abdd..98051e8e855a 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -1669,7 +1669,6 @@ static void hdmi_mode_apply(struct hdmi_context *hdata) static void hdmiphy_conf_reset(struct hdmi_context *hdata) { - u8 buffer[2]; u32 reg; clk_disable_unprepare(hdata->res.sclk_hdmi); @@ -1677,11 +1676,8 @@ static void hdmiphy_conf_reset(struct hdmi_context *hdata) clk_prepare_enable(hdata->res.sclk_hdmi); /* operation mode */ - buffer[0] = 0x1f; - buffer[1] = 0x00; - - if (hdata->hdmiphy_port) - i2c_master_send(hdata->hdmiphy_port, buffer, 2); + hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE, + HDMI_PHY_ENABLE_MODE_SET); if (hdata->type == HDMI_TYPE13) reg = HDMI_V13_PHY_RSTOUT; diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 820b76234ef4..064ed6597def 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -1026,6 +1026,7 @@ static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos) static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr) { struct mixer_context *mixer_ctx = mgr_to_mixer(mgr); + int err; mutex_lock(&mixer_ctx->mixer_mutex); if (!mixer_ctx->powered) { @@ -1034,7 +1035,11 @@ static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr) } mutex_unlock(&mixer_ctx->mixer_mutex); - drm_vblank_get(mgr->crtc->dev, mixer_ctx->pipe); + err = drm_vblank_get(mgr->crtc->dev, mixer_ctx->pipe); + if (err < 0) { + DRM_DEBUG_KMS("failed to acquire vblank counter\n"); + return; + } atomic_set(&mixer_ctx->wait_vsync_event, 1); @@ -1262,8 +1267,6 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data) return ret; } - pm_runtime_enable(dev); - return 0; } @@ -1272,8 +1275,6 @@ static void mixer_unbind(struct device *dev, struct device *master, void *data) struct mixer_context *ctx = dev_get_drvdata(dev); mixer_mgr_remove(&ctx->manager); - - pm_runtime_disable(dev); } static const struct component_ops mixer_component_ops = { diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f990ab4c3efb..574057cd1d09 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -811,6 +811,8 @@ int i915_reset(struct drm_device *dev) if (!i915.reset) return 0; + intel_reset_gt_powersave(dev); + mutex_lock(&dev->struct_mutex); i915_gem_reset(dev); @@ -880,7 +882,7 @@ int i915_reset(struct drm_device *dev) * of re-init after reset. */ if (INTEL_INFO(dev)->gen > 5) - intel_reset_gt_powersave(dev); + intel_enable_gt_powersave(dev); } else { mutex_unlock(&dev->struct_mutex); } @@ -1584,7 +1586,7 @@ static struct drm_driver driver = { .gem_prime_import = i915_gem_prime_import, .dumb_create = i915_gem_dumb_create, - .dumb_map_offset = i915_gem_dumb_map_offset, + .dumb_map_offset = i915_gem_mmap_gtt, .dumb_destroy = drm_gem_dumb_destroy, .ioctls = i915_ioctls, .fops = &i915_driver_fops, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 63bcda5541ec..e9f891c432f8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1756,8 +1756,6 @@ struct drm_i915_private { */ struct workqueue_struct *dp_wq; - uint32_t bios_vgacntr; - /* Abstract the submission mechanism (legacy ringbuffer or execlists) away */ struct { int (*do_execbuf)(struct drm_device *dev, struct drm_file *file, @@ -2501,9 +2499,8 @@ void i915_vma_move_to_active(struct i915_vma *vma, int i915_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev, struct drm_mode_create_dumb *args); -int i915_gem_dumb_map_offset(struct drm_file *file_priv, - struct drm_device *dev, uint32_t handle, - uint64_t *offset); +int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev, + uint32_t handle, uint64_t *offset); /** * Returns true if seq1 is later than seq2. */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4a9faea626db..76354d3ba925 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -401,7 +401,6 @@ static int i915_gem_create(struct drm_file *file, struct drm_device *dev, uint64_t size, - bool dumb, uint32_t *handle_p) { struct drm_i915_gem_object *obj; @@ -417,7 +416,6 @@ i915_gem_create(struct drm_file *file, if (obj == NULL) return -ENOMEM; - obj->base.dumb = dumb; ret = drm_gem_handle_create(file, &obj->base, &handle); /* drop reference from allocate - handle holds it now */ drm_gem_object_unreference_unlocked(&obj->base); @@ -437,7 +435,7 @@ i915_gem_dumb_create(struct drm_file *file, args->pitch = ALIGN(args->width * DIV_ROUND_UP(args->bpp, 8), 64); args->size = args->pitch * args->height; return i915_gem_create(file, dev, - args->size, true, &args->handle); + args->size, &args->handle); } /** @@ -450,7 +448,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, struct drm_i915_gem_create *args = data; return i915_gem_create(file, dev, - args->size, false, &args->handle); + args->size, &args->handle); } static inline int @@ -1050,6 +1048,7 @@ int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_pwrite *args = data; struct drm_i915_gem_object *obj; int ret; @@ -1069,9 +1068,11 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, return -EFAULT; } + intel_runtime_pm_get(dev_priv); + ret = i915_mutex_lock_interruptible(dev); if (ret) - return ret; + goto put_rpm; obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); if (&obj->base == NULL) { @@ -1123,6 +1124,9 @@ out: drm_gem_object_unreference(&obj->base); unlock: mutex_unlock(&dev->struct_mutex); +put_rpm: + intel_runtime_pm_put(dev_priv); + return ret; } @@ -1840,10 +1844,10 @@ static void i915_gem_object_free_mmap_offset(struct drm_i915_gem_object *obj) drm_gem_free_mmap_offset(&obj->base); } -static int +int i915_gem_mmap_gtt(struct drm_file *file, struct drm_device *dev, - uint32_t handle, bool dumb, + uint32_t handle, uint64_t *offset) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -1860,13 +1864,6 @@ i915_gem_mmap_gtt(struct drm_file *file, goto unlock; } - /* - * We don't allow dumb mmaps on objects created using another - * interface. - */ - WARN_ONCE(dumb && !(obj->base.dumb || obj->base.import_attach), - "Illegal dumb map of accelerated buffer.\n"); - if (obj->base.size > dev_priv->gtt.mappable_end) { ret = -E2BIG; goto out; @@ -1891,15 +1888,6 @@ unlock: return ret; } -int -i915_gem_dumb_map_offset(struct drm_file *file, - struct drm_device *dev, - uint32_t handle, - uint64_t *offset) -{ - return i915_gem_mmap_gtt(file, dev, handle, true, offset); -} - /** * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing * @dev: DRM device @@ -1921,7 +1909,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, { struct drm_i915_gem_mmap_gtt *args = data; - return i915_gem_mmap_gtt(file, dev, args->handle, false, &args->offset); + return i915_gem_mmap_gtt(file, dev, args->handle, &args->offset); } static inline int @@ -5167,7 +5155,7 @@ static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task) if (!mutex_is_locked(mutex)) return false; -#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_MUTEXES) +#if defined(CONFIG_SMP) && !defined(CONFIG_DEBUG_MUTEXES) return mutex->owner == task; #else /* Since UP may be pre-empted, we cannot assume that we own the lock */ diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index d17ff435f276..d011ec82ef1e 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -473,7 +473,12 @@ mi_set_context(struct intel_engine_cs *ring, u32 hw_flags) { u32 flags = hw_flags | MI_MM_SPACE_GTT; - int ret; + const int num_rings = + /* Use an extended w/a on ivb+ if signalling from other rings */ + i915_semaphore_is_enabled(ring->dev) ? + hweight32(INTEL_INFO(ring->dev)->ring_mask) - 1 : + 0; + int len, i, ret; /* w/a: If Flush TLB Invalidation Mode is enabled, driver must do a TLB * invalidation prior to MI_SET_CONTEXT. On GEN6 we don't set the value @@ -490,15 +495,31 @@ mi_set_context(struct intel_engine_cs *ring, if (!IS_HASWELL(ring->dev) && INTEL_INFO(ring->dev)->gen < 8) flags |= (MI_SAVE_EXT_STATE_EN | MI_RESTORE_EXT_STATE_EN); - ret = intel_ring_begin(ring, 6); + + len = 4; + if (INTEL_INFO(ring->dev)->gen >= 7) + len += 2 + (num_rings ? 4*num_rings + 2 : 0); + + ret = intel_ring_begin(ring, len); if (ret) return ret; /* WaProgramMiArbOnOffAroundMiSetContext:ivb,vlv,hsw,bdw,chv */ - if (INTEL_INFO(ring->dev)->gen >= 7) + if (INTEL_INFO(ring->dev)->gen >= 7) { intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_DISABLE); - else - intel_ring_emit(ring, MI_NOOP); + if (num_rings) { + struct intel_engine_cs *signaller; + + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(num_rings)); + for_each_ring(signaller, to_i915(ring->dev), i) { + if (signaller == ring) + continue; + + intel_ring_emit(ring, RING_PSMI_CTL(signaller->mmio_base)); + intel_ring_emit(ring, _MASKED_BIT_ENABLE(GEN6_PSMI_SLEEP_MSG_DISABLE)); + } + } + } intel_ring_emit(ring, MI_NOOP); intel_ring_emit(ring, MI_SET_CONTEXT); @@ -510,10 +531,21 @@ mi_set_context(struct intel_engine_cs *ring, */ intel_ring_emit(ring, MI_NOOP); - if (INTEL_INFO(ring->dev)->gen >= 7) + if (INTEL_INFO(ring->dev)->gen >= 7) { + if (num_rings) { + struct intel_engine_cs *signaller; + + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(num_rings)); + for_each_ring(signaller, to_i915(ring->dev), i) { + if (signaller == ring) + continue; + + intel_ring_emit(ring, RING_PSMI_CTL(signaller->mmio_base)); + intel_ring_emit(ring, _MASKED_BIT_DISABLE(GEN6_PSMI_SLEEP_MSG_DISABLE)); + } + } intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_ENABLE); - else - intel_ring_emit(ring, MI_NOOP); + } intel_ring_advance(ring); diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index f06027ba3ee5..11738316394a 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -121,9 +121,6 @@ eb_lookup_vmas(struct eb_vmas *eb, goto err; } - WARN_ONCE(obj->base.dumb, - "GPU use of dumb buffer is illegal.\n"); - drm_gem_object_reference(&obj->base); list_add_tail(&obj->obj_exec_link, &objects); } diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 981834b0f9b6..b051a238baf9 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -281,13 +281,34 @@ void gen6_enable_rps_interrupts(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; spin_lock_irq(&dev_priv->irq_lock); + WARN_ON(dev_priv->rps.pm_iir); WARN_ON(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events); dev_priv->rps.interrupts_enabled = true; + I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) | + dev_priv->pm_rps_events); gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); + spin_unlock_irq(&dev_priv->irq_lock); } +u32 gen6_sanitize_rps_pm_mask(struct drm_i915_private *dev_priv, u32 mask) +{ + /* + * SNB,IVB can while VLV,CHV may hard hang on looping batchbuffer + * if GEN6_PM_UP_EI_EXPIRED is masked. + * + * TODO: verify if this can be reproduced on VLV,CHV. + */ + if (INTEL_INFO(dev_priv)->gen <= 7 && !IS_HASWELL(dev_priv)) + mask &= ~GEN6_PM_RP_UP_EI_EXPIRED; + + if (INTEL_INFO(dev_priv)->gen >= 8) + mask &= ~GEN8_PMINTR_REDIRECT_TO_NON_DISP; + + return mask; +} + void gen6_disable_rps_interrupts(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -300,8 +321,7 @@ void gen6_disable_rps_interrupts(struct drm_device *dev) spin_lock_irq(&dev_priv->irq_lock); - I915_WRITE(GEN6_PMINTRMSK, INTEL_INFO(dev_priv)->gen >= 8 ? - ~GEN8_PMINTR_REDIRECT_TO_NON_DISP : ~0); + I915_WRITE(GEN6_PMINTRMSK, gen6_sanitize_rps_pm_mask(dev_priv, ~0)); __gen6_disable_pm_irq(dev_priv, dev_priv->pm_rps_events); I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) & @@ -3307,8 +3327,10 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev) GEN5_IRQ_INIT(GT, dev_priv->gt_irq_mask, gt_irqs); if (INTEL_INFO(dev)->gen >= 6) { - pm_irqs |= dev_priv->pm_rps_events; - + /* + * RPS interrupts will get enabled/disabled on demand when RPS + * itself is enabled/disabled. + */ if (HAS_VEBOX(dev)) pm_irqs |= PM_VEBOX_USER_INTERRUPT; @@ -3520,7 +3542,11 @@ static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv) dev_priv->pm_irq_mask = 0xffffffff; GEN8_IRQ_INIT_NDX(GT, 0, ~gt_interrupts[0], gt_interrupts[0]); GEN8_IRQ_INIT_NDX(GT, 1, ~gt_interrupts[1], gt_interrupts[1]); - GEN8_IRQ_INIT_NDX(GT, 2, dev_priv->pm_irq_mask, dev_priv->pm_rps_events); + /* + * RPS interrupts will get enabled/disabled on demand when RPS itself + * is enabled/disabled. + */ + GEN8_IRQ_INIT_NDX(GT, 2, dev_priv->pm_irq_mask, 0); GEN8_IRQ_INIT_NDX(GT, 3, ~gt_interrupts[3], gt_interrupts[3]); } @@ -3609,7 +3635,7 @@ static void vlv_display_irq_uninstall(struct drm_i915_private *dev_priv) vlv_display_irq_reset(dev_priv); - dev_priv->irq_mask = 0; + dev_priv->irq_mask = ~0; } static void valleyview_irq_uninstall(struct drm_device *dev) @@ -3715,8 +3741,6 @@ static bool i8xx_handle_vblank(struct drm_device *dev, if ((iir & flip_pending) == 0) goto check_page_flip; - intel_prepare_page_flip(dev, plane); - /* We detect FlipDone by looking for the change in PendingFlip from '1' * to '0' on the following vblank, i.e. IIR has the Pendingflip * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence @@ -3726,6 +3750,7 @@ static bool i8xx_handle_vblank(struct drm_device *dev, if (I915_READ16(ISR) & flip_pending) goto check_page_flip; + intel_prepare_page_flip(dev, plane); intel_finish_page_flip(dev, pipe); return true; @@ -3897,8 +3922,6 @@ static bool i915_handle_vblank(struct drm_device *dev, if ((iir & flip_pending) == 0) goto check_page_flip; - intel_prepare_page_flip(dev, plane); - /* We detect FlipDone by looking for the change in PendingFlip from '1' * to '0' on the following vblank, i.e. IIR has the Pendingflip * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence @@ -3908,6 +3931,7 @@ static bool i915_handle_vblank(struct drm_device *dev, if (I915_READ(ISR) & flip_pending) goto check_page_flip; + intel_prepare_page_flip(dev, plane); intel_finish_page_flip(dev, pipe); return true; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index eefdc238f70b..172de3b3433b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -395,6 +395,7 @@ #define PIPE_CONTROL_STORE_DATA_INDEX (1<<21) #define PIPE_CONTROL_CS_STALL (1<<20) #define PIPE_CONTROL_TLB_INVALIDATE (1<<18) +#define PIPE_CONTROL_MEDIA_STATE_CLEAR (1<<16) #define PIPE_CONTROL_QW_WRITE (1<<14) #define PIPE_CONTROL_POST_SYNC_OP_MASK (3<<14) #define PIPE_CONTROL_DEPTH_STALL (1<<13) @@ -1128,6 +1129,7 @@ enum punit_power_well { #define GEN6_VERSYNC (RING_SYNC_1(VEBOX_RING_BASE)) #define GEN6_VEVSYNC (RING_SYNC_2(VEBOX_RING_BASE)) #define GEN6_NOSYNC 0 +#define RING_PSMI_CTL(base) ((base)+0x50) #define RING_MAX_IDLE(base) ((base)+0x54) #define RING_HWS_PGA(base) ((base)+0x80) #define RING_HWS_PGA_GEN6(base) ((base)+0x2080) @@ -1458,6 +1460,7 @@ enum punit_power_well { #define GEN6_BLITTER_FBC_NOTIFY (1<<3) #define GEN6_RC_SLEEP_PSMI_CONTROL 0x2050 +#define GEN6_PSMI_SLEEP_MSG_DISABLE (1 << 0) #define GEN8_RC_SEMA_IDLE_MSG_DISABLE (1 << 12) #define GEN8_FF_DOP_CLOCK_GATE_DISABLE (1<<10) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index fb3e3d429191..e7a16f119a29 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9815,7 +9815,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, if (obj->tiling_mode != work->old_fb_obj->tiling_mode) /* vlv: DISPLAY_FLIP fails to change tiling */ ring = NULL; - } else if (IS_IVYBRIDGE(dev)) { + } else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { ring = &dev_priv->ring[BCS]; } else if (INTEL_INFO(dev)->gen >= 7) { ring = obj->ring; @@ -13057,11 +13057,7 @@ static void i915_disable_vga(struct drm_device *dev) vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); udelay(300); - /* - * Fujitsu-Siemens Lifebook S6010 (830) has problems resuming - * from S3 without preserving (some of?) the other bits. - */ - I915_WRITE(vga_reg, dev_priv->bios_vgacntr | VGA_DISP_DISABLE); + I915_WRITE(vga_reg, VGA_DISP_DISABLE); POSTING_READ(vga_reg); } @@ -13146,8 +13142,6 @@ void intel_modeset_init(struct drm_device *dev) intel_shared_dpll_init(dev); - /* save the BIOS value before clobbering it */ - dev_priv->bios_vgacntr = I915_READ(i915_vgacntrl_reg(dev)); /* Just disable it once at startup */ i915_disable_vga(dev); intel_setup_outputs(dev); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 25fdbb16d4e0..3b40a17b8852 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -794,6 +794,7 @@ void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); void gen6_reset_rps_interrupts(struct drm_device *dev); void gen6_enable_rps_interrupts(struct drm_device *dev); void gen6_disable_rps_interrupts(struct drm_device *dev); +u32 gen6_sanitize_rps_pm_mask(struct drm_i915_private *dev_priv, u32 mask); void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv); void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv); static inline bool intel_irqs_enabled(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 1f4b56e273c8..bf814a64582a 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4363,16 +4363,7 @@ static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val) mask |= dev_priv->pm_rps_events & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED); mask &= dev_priv->pm_rps_events; - /* IVB and SNB hard hangs on looping batchbuffer - * if GEN6_PM_UP_EI_EXPIRED is masked. - */ - if (INTEL_INFO(dev_priv->dev)->gen <= 7 && !IS_HASWELL(dev_priv->dev)) - mask |= GEN6_PM_RP_UP_EI_EXPIRED; - - if (IS_GEN8(dev_priv->dev)) - mask |= GEN8_PMINTR_REDIRECT_TO_NON_DISP; - - return ~mask; + return gen6_sanitize_rps_pm_mask(dev_priv, ~mask); } /* gen6_set_rps is called to update the frequency request, but should also be @@ -4441,7 +4432,8 @@ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) return; /* Mask turbo interrupt so that they will not come in between */ - I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); + I915_WRITE(GEN6_PMINTRMSK, + gen6_sanitize_rps_pm_mask(dev_priv, ~0)); vlv_force_gfx_clock(dev_priv, true); @@ -6191,6 +6183,20 @@ void intel_cleanup_gt_powersave(struct drm_device *dev) valleyview_cleanup_gt_powersave(dev); } +static void gen6_suspend_rps(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + flush_delayed_work(&dev_priv->rps.delayed_resume_work); + + /* + * TODO: disable RPS interrupts on GEN9+ too once RPS support + * is added for it. + */ + if (INTEL_INFO(dev)->gen < 9) + gen6_disable_rps_interrupts(dev); +} + /** * intel_suspend_gt_powersave - suspend PM work and helper threads * @dev: drm device @@ -6206,14 +6212,7 @@ void intel_suspend_gt_powersave(struct drm_device *dev) if (INTEL_INFO(dev)->gen < 6) return; - flush_delayed_work(&dev_priv->rps.delayed_resume_work); - - /* - * TODO: disable RPS interrupts on GEN9+ too once RPS support - * is added for it. - */ - if (INTEL_INFO(dev)->gen < 9) - gen6_disable_rps_interrupts(dev); + gen6_suspend_rps(dev); /* Force GPU to min freq during suspend */ gen6_rps_idle(dev_priv); @@ -6316,8 +6315,11 @@ void intel_reset_gt_powersave(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + if (INTEL_INFO(dev)->gen < 6) + return; + + gen6_suspend_rps(dev); dev_priv->rps.enabled = false; - intel_enable_gt_powersave(dev); } static void ibx_init_clock_gating(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 9f445e9a75d1..c7bc93d28d84 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -362,12 +362,15 @@ gen7_render_ring_flush(struct intel_engine_cs *ring, flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_MEDIA_STATE_CLEAR; /* * TLB invalidate requires a post-sync write. */ flags |= PIPE_CONTROL_QW_WRITE; flags |= PIPE_CONTROL_GLOBAL_GTT_IVB; + flags |= PIPE_CONTROL_STALL_AT_SCOREBOARD; + /* Workaround: we must issue a pipe_control with CS-stall bit * set before a pipe_control command that has the state cache * invalidate bit set. */ diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index f5a78d53e297..ac6da7102fbb 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -615,29 +615,6 @@ static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv, vlv_power_sequencer_reset(dev_priv); } -static void check_power_well_state(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - bool enabled = power_well->ops->is_enabled(dev_priv, power_well); - - if (power_well->always_on || !i915.disable_power_well) { - if (!enabled) - goto mismatch; - - return; - } - - if (enabled != (power_well->count > 0)) - goto mismatch; - - return; - -mismatch: - WARN(1, "state mismatch for '%s' (always_on %d hw state %d use-count %d disable_power_well %d\n", - power_well->name, power_well->always_on, enabled, - power_well->count, i915.disable_power_well); -} - /** * intel_display_power_get - grab a power domain reference * @dev_priv: i915 device instance @@ -669,8 +646,6 @@ void intel_display_power_get(struct drm_i915_private *dev_priv, power_well->ops->enable(dev_priv, power_well); power_well->hw_enabled = true; } - - check_power_well_state(dev_priv, power_well); } power_domains->domain_use_count[domain]++; @@ -709,8 +684,6 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, power_well->hw_enabled = false; power_well->ops->disable(dev_priv, power_well); } - - check_power_well_state(dev_priv, power_well); } mutex_unlock(&power_domains->lock); diff --git a/drivers/gpu/drm/imx/Kconfig b/drivers/gpu/drm/imx/Kconfig index 82fb758a29bc..ab31848e92cf 100644 --- a/drivers/gpu/drm/imx/Kconfig +++ b/drivers/gpu/drm/imx/Kconfig @@ -6,6 +6,7 @@ config DRM_IMX select DRM_GEM_CMA_HELPER select DRM_KMS_CMA_HELPER depends on DRM && (ARCH_MXC || ARCH_MULTIPLATFORM) + depends on IMX_IPUV3_CORE help enable i.MX graphics support @@ -40,11 +41,11 @@ config DRM_IMX_LDB found on i.MX53 and i.MX6 processors. config DRM_IMX_IPUV3 - tristate "DRM Support for i.MX IPUv3" + tristate depends on DRM_IMX depends on IMX_IPUV3_CORE - help - Choose this if you have a i.MX5 or i.MX6 processor. + default y if DRM_IMX=y + default m if DRM_IMX=m config DRM_IMX_HDMI tristate "Freescale i.MX DRM HDMI" diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index e48b2211d2d6..b250130debc8 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c @@ -30,8 +30,6 @@ #define MAX_CRTC 4 -struct imx_drm_crtc; - struct imx_drm_component { struct device_node *of_node; struct list_head list; @@ -633,7 +631,8 @@ static int imx_drm_platform_probe(struct platform_device *pdev) continue; } - component_match_add(&pdev->dev, &match, compare_of, remote); + component_match_add(&pdev->dev, &match, compare_of, + remote); of_node_put(remote); } of_node_put(port); diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index 2638dc1671d0..c60460043e24 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c @@ -11,11 +11,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. */ #include <linux/module.h> diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c index 64b54d7f996c..a729f4f7074c 100644 --- a/drivers/gpu/drm/imx/imx-tve.c +++ b/drivers/gpu/drm/imx/imx-tve.c @@ -11,11 +11,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. */ #include <linux/clk.h> @@ -665,7 +660,8 @@ static int imx_tve_bind(struct device *dev, struct device *master, void *data) ret = regmap_read(tve->regmap, TVE_COM_CONF_REG, &val); if (ret < 0) { - dev_err(dev, "failed to read configuration register: %d\n", ret); + dev_err(dev, "failed to read configuration register: %d\n", + ret); return ret; } if (val != 0x00100000) { diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c index 11e84a251773..ebee59cb96d8 100644 --- a/drivers/gpu/drm/imx/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3-crtc.c @@ -11,11 +11,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. */ #include <linux/component.h> #include <linux/module.h> diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c index 944962b692bb..6987e16fe99b 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3-plane.c @@ -64,6 +64,7 @@ int ipu_plane_set_base(struct ipu_plane *ipu_plane, struct drm_framebuffer *fb, { struct drm_gem_cma_object *cma_obj; unsigned long eba; + int active; cma_obj = drm_fb_cma_get_gem_obj(fb, 0); if (!cma_obj) { @@ -74,12 +75,17 @@ int ipu_plane_set_base(struct ipu_plane *ipu_plane, struct drm_framebuffer *fb, dev_dbg(ipu_plane->base.dev->dev, "phys = %pad, x = %d, y = %d", &cma_obj->paddr, x, y); - ipu_cpmem_set_stride(ipu_plane->ipu_ch, fb->pitches[0]); - eba = cma_obj->paddr + fb->offsets[0] + fb->pitches[0] * y + (fb->bits_per_pixel >> 3) * x; - ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 0, eba); - ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 1, eba); + + if (ipu_plane->enabled) { + active = ipu_idmac_get_current_buffer(ipu_plane->ipu_ch); + ipu_cpmem_set_buffer(ipu_plane->ipu_ch, !active, eba); + ipu_idmac_select_buffer(ipu_plane->ipu_ch, !active); + } else { + ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 0, eba); + ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 1, eba); + } /* cache offsets for subsequent pageflips */ ipu_plane->x = x; @@ -137,6 +143,18 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc, if (crtc_h < 2) return -EINVAL; + /* + * since we cannot touch active IDMAC channels, we do not support + * resizing the enabled plane or changing its format + */ + if (ipu_plane->enabled) { + if (src_w != ipu_plane->w || src_h != ipu_plane->h || + fb->pixel_format != ipu_plane->base.fb->pixel_format) + return -EINVAL; + + return ipu_plane_set_base(ipu_plane, fb, src_x, src_y); + } + switch (ipu_plane->dp_flow) { case IPU_DP_FLOW_SYNC_BG: ret = ipu_dp_setup_channel(ipu_plane->dp, @@ -148,14 +166,22 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc, ret); return ret; } - ipu_dp_set_global_alpha(ipu_plane->dp, 1, 0, 1); + ipu_dp_set_global_alpha(ipu_plane->dp, true, 0, true); break; case IPU_DP_FLOW_SYNC_FG: ipu_dp_setup_channel(ipu_plane->dp, ipu_drm_fourcc_to_colorspace(fb->pixel_format), IPUV3_COLORSPACE_UNKNOWN); ipu_dp_set_window_pos(ipu_plane->dp, crtc_x, crtc_y); - break; + /* Enable local alpha on partial plane */ + switch (fb->pixel_format) { + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_ABGR8888: + ipu_dp_set_global_alpha(ipu_plane->dp, false, 0, false); + break; + default: + break; + } } ret = ipu_dmfc_init_channel(ipu_plane->dmfc, crtc_w); @@ -181,11 +207,16 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc, return ret; } ipu_cpmem_set_high_priority(ipu_plane->ipu_ch); + ipu_idmac_set_double_buffer(ipu_plane->ipu_ch, 1); + ipu_cpmem_set_stride(ipu_plane->ipu_ch, fb->pitches[0]); ret = ipu_plane_set_base(ipu_plane, fb, src_x, src_y); if (ret < 0) return ret; + ipu_plane->w = src_w; + ipu_plane->h = src_h; + return 0; } diff --git a/drivers/gpu/drm/imx/ipuv3-plane.h b/drivers/gpu/drm/imx/ipuv3-plane.h index c0aae5bcb5d4..af125fb40ef5 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.h +++ b/drivers/gpu/drm/imx/ipuv3-plane.h @@ -26,6 +26,8 @@ struct ipu_plane { int x; int y; + int w; + int h; bool enabled; }; diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c index 8a76a5c1c34b..796c3c1c170a 100644 --- a/drivers/gpu/drm/imx/parallel-display.c +++ b/drivers/gpu/drm/imx/parallel-display.c @@ -11,11 +11,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. */ #include <linux/component.h> @@ -128,6 +123,10 @@ static void imx_pd_encoder_prepare(struct drm_encoder *encoder) static void imx_pd_encoder_commit(struct drm_encoder *encoder) { + struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); + + drm_panel_prepare(imxpd->panel); + drm_panel_enable(imxpd->panel); } static void imx_pd_encoder_mode_set(struct drm_encoder *encoder, @@ -138,6 +137,10 @@ static void imx_pd_encoder_mode_set(struct drm_encoder *encoder, static void imx_pd_encoder_disable(struct drm_encoder *encoder) { + struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); + + drm_panel_disable(imxpd->panel); + drm_panel_unprepare(imxpd->panel); } static struct drm_connector_funcs imx_pd_connector_funcs = { diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index aa873048308b..94a5bee69fe7 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -386,9 +386,7 @@ void adreno_gpu_cleanup(struct adreno_gpu *gpu) msm_gem_put_iova(gpu->memptrs_bo, gpu->base.id); drm_gem_object_unreference(gpu->memptrs_bo); } - if (gpu->pm4) - release_firmware(gpu->pm4); - if (gpu->pfp) - release_firmware(gpu->pfp); + release_firmware(gpu->pm4); + release_firmware(gpu->pfp); msm_gpu_cleanup(&gpu->base); } diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c index fbebb0405d76..b4e70e0e3cfa 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c @@ -141,6 +141,15 @@ static int hpd_enable(struct hdmi_connector *hdmi_connector) uint32_t hpd_ctrl; int i, ret; + for (i = 0; i < config->hpd_reg_cnt; i++) { + ret = regulator_enable(hdmi->hpd_regs[i]); + if (ret) { + dev_err(dev->dev, "failed to enable hpd regulator: %s (%d)\n", + config->hpd_reg_names[i], ret); + goto fail; + } + } + ret = gpio_config(hdmi, true); if (ret) { dev_err(dev->dev, "failed to configure GPIOs: %d\n", ret); @@ -164,15 +173,6 @@ static int hpd_enable(struct hdmi_connector *hdmi_connector) } } - for (i = 0; i < config->hpd_reg_cnt; i++) { - ret = regulator_enable(hdmi->hpd_regs[i]); - if (ret) { - dev_err(dev->dev, "failed to enable hpd regulator: %s (%d)\n", - config->hpd_reg_names[i], ret); - goto fail; - } - } - hdmi_set_mode(hdmi, false); phy->funcs->reset(phy); hdmi_set_mode(hdmi, true); @@ -200,7 +200,7 @@ fail: return ret; } -static int hdp_disable(struct hdmi_connector *hdmi_connector) +static void hdp_disable(struct hdmi_connector *hdmi_connector) { struct hdmi *hdmi = hdmi_connector->hdmi; const struct hdmi_platform_config *config = hdmi->config; @@ -212,28 +212,19 @@ static int hdp_disable(struct hdmi_connector *hdmi_connector) hdmi_set_mode(hdmi, false); - for (i = 0; i < config->hpd_reg_cnt; i++) { - ret = regulator_disable(hdmi->hpd_regs[i]); - if (ret) { - dev_err(dev->dev, "failed to disable hpd regulator: %s (%d)\n", - config->hpd_reg_names[i], ret); - goto fail; - } - } - for (i = 0; i < config->hpd_clk_cnt; i++) clk_disable_unprepare(hdmi->hpd_clks[i]); ret = gpio_config(hdmi, false); - if (ret) { - dev_err(dev->dev, "failed to unconfigure GPIOs: %d\n", ret); - goto fail; - } - - return 0; + if (ret) + dev_warn(dev->dev, "failed to unconfigure GPIOs: %d\n", ret); -fail: - return ret; + for (i = 0; i < config->hpd_reg_cnt; i++) { + ret = regulator_disable(hdmi->hpd_regs[i]); + if (ret) + dev_warn(dev->dev, "failed to disable hpd regulator: %s (%d)\n", + config->hpd_reg_names[i], ret); + } } static void @@ -260,11 +251,11 @@ void hdmi_connector_irq(struct drm_connector *connector) (hpd_int_status & HDMI_HPD_INT_STATUS_INT)) { bool detected = !!(hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED); - DBG("status=%04x, ctrl=%04x", hpd_int_status, hpd_int_ctrl); - - /* ack the irq: */ + /* ack & disable (temporarily) HPD events: */ hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, - hpd_int_ctrl | HDMI_HPD_INT_CTRL_INT_ACK); + HDMI_HPD_INT_CTRL_INT_ACK); + + DBG("status=%04x, ctrl=%04x", hpd_int_status, hpd_int_ctrl); /* detect disconnect if we are connected or visa versa: */ hpd_int_ctrl = HDMI_HPD_INT_CTRL_INT_EN; diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index a7672e100d8b..3449213f1e76 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c @@ -331,17 +331,8 @@ static int mdp4_crtc_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); - struct drm_device *dev = crtc->dev; - DBG("%s: check", mdp4_crtc->name); - - if (mdp4_crtc->event) { - dev_err(dev->dev, "already pending flip!\n"); - return -EBUSY; - } - // TODO anything else to check? - return 0; } @@ -357,7 +348,7 @@ static void mdp4_crtc_atomic_flush(struct drm_crtc *crtc) struct drm_device *dev = crtc->dev; unsigned long flags; - DBG("%s: flush", mdp4_crtc->name); + DBG("%s: event: %p", mdp4_crtc->name, crtc->state->event); WARN_ON(mdp4_crtc->event); diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 0e9a2e3a82d7..f021f960a8a2 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -303,11 +303,6 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc, DBG("%s: check", mdp5_crtc->name); - if (mdp5_crtc->event) { - dev_err(dev->dev, "already pending flip!\n"); - return -EBUSY; - } - /* request a free CTL, if none is already allocated for this CRTC */ if (state->enable && !mdp5_crtc->ctl) { mdp5_crtc->ctl = mdp5_ctlm_request(mdp5_kms->ctlm, crtc); @@ -364,7 +359,7 @@ static void mdp5_crtc_atomic_flush(struct drm_crtc *crtc) struct drm_device *dev = crtc->dev; unsigned long flags; - DBG("%s: flush", mdp5_crtc->name); + DBG("%s: event: %p", mdp5_crtc->name, crtc->state->event); WARN_ON(mdp5_crtc->event); @@ -460,10 +455,7 @@ void mdp5_crtc_set_intf(struct drm_crtc *crtc, int intf, /* now that we know what irq's we want: */ mdp5_crtc->err.irqmask = intf2err(intf); mdp5_crtc->vblank.irqmask = intf2vblank(intf); - - /* when called from modeset_init(), skip the rest until later: */ - if (!mdp5_kms) - return; + mdp_irq_update(&mdp5_kms->base); spin_lock_irqsave(&mdp5_kms->resource_lock, flags); intf_sel = mdp5_read(mdp5_kms, REG_MDP5_DISP_INTF_SEL); diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index a11f1b80c488..9f01a4f21af2 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -216,17 +216,7 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) goto fail; } - /* NOTE: the vsync and error irq's are actually associated with - * the INTF/encoder.. the easiest way to deal with this (ie. what - * we do now) is assume a fixed relationship between crtc's and - * encoders. I'm not sure if there is ever a need to more freely - * assign crtcs to encoders, but if there is then we need to take - * care of error and vblank irq's that the crtc has registered, - * and also update user-requested vblank_mask. - */ - encoder->possible_crtcs = BIT(0); - mdp5_crtc_set_intf(priv->crtcs[0], 3, INTF_HDMI); - + encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;; priv->encoders[priv->num_encoders++] = encoder; /* Construct bridge/connector for HDMI: */ diff --git a/drivers/gpu/drm/msm/mdp/mdp_kms.c b/drivers/gpu/drm/msm/mdp/mdp_kms.c index 03455b64a245..2a731722d840 100644 --- a/drivers/gpu/drm/msm/mdp/mdp_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp_kms.c @@ -42,7 +42,10 @@ static void update_irq(struct mdp_kms *mdp_kms) mdp_kms->funcs->set_irqmask(mdp_kms, irqmask); } -static void update_irq_unlocked(struct mdp_kms *mdp_kms) +/* if an mdp_irq's irqmask has changed, such as when mdp5 crtc<->encoder + * link changes, this must be called to figure out the new global irqmask + */ +void mdp_irq_update(struct mdp_kms *mdp_kms) { unsigned long flags; spin_lock_irqsave(&list_lock, flags); @@ -122,7 +125,7 @@ void mdp_irq_register(struct mdp_kms *mdp_kms, struct mdp_irq *irq) spin_unlock_irqrestore(&list_lock, flags); if (needs_update) - update_irq_unlocked(mdp_kms); + mdp_irq_update(mdp_kms); } void mdp_irq_unregister(struct mdp_kms *mdp_kms, struct mdp_irq *irq) @@ -141,5 +144,5 @@ void mdp_irq_unregister(struct mdp_kms *mdp_kms, struct mdp_irq *irq) spin_unlock_irqrestore(&list_lock, flags); if (needs_update) - update_irq_unlocked(mdp_kms); + mdp_irq_update(mdp_kms); } diff --git a/drivers/gpu/drm/msm/mdp/mdp_kms.h b/drivers/gpu/drm/msm/mdp/mdp_kms.h index 99557b5ad4fd..b268ce95d394 100644 --- a/drivers/gpu/drm/msm/mdp/mdp_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp_kms.h @@ -75,7 +75,7 @@ void mdp_update_vblank_mask(struct mdp_kms *mdp_kms, uint32_t mask, bool enable) void mdp_irq_wait(struct mdp_kms *mdp_kms, uint32_t irqmask); void mdp_irq_register(struct mdp_kms *mdp_kms, struct mdp_irq *irq); void mdp_irq_unregister(struct mdp_kms *mdp_kms, struct mdp_irq *irq); - +void mdp_irq_update(struct mdp_kms *mdp_kms); /* * pixel format helpers: diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index f0de412e13dc..191968256c58 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -23,10 +23,41 @@ struct msm_commit { struct drm_atomic_state *state; uint32_t fence; struct msm_fence_cb fence_cb; + uint32_t crtc_mask; }; static void fence_cb(struct msm_fence_cb *cb); +/* block until specified crtcs are no longer pending update, and + * atomically mark them as pending update + */ +static int start_atomic(struct msm_drm_private *priv, uint32_t crtc_mask) +{ + int ret; + + spin_lock(&priv->pending_crtcs_event.lock); + ret = wait_event_interruptible_locked(priv->pending_crtcs_event, + !(priv->pending_crtcs & crtc_mask)); + if (ret == 0) { + DBG("start: %08x", crtc_mask); + priv->pending_crtcs |= crtc_mask; + } + spin_unlock(&priv->pending_crtcs_event.lock); + + return ret; +} + +/* clear specified crtcs (no longer pending update) + */ +static void end_atomic(struct msm_drm_private *priv, uint32_t crtc_mask) +{ + spin_lock(&priv->pending_crtcs_event.lock); + DBG("end: %08x", crtc_mask); + priv->pending_crtcs &= ~crtc_mask; + wake_up_all_locked(&priv->pending_crtcs_event); + spin_unlock(&priv->pending_crtcs_event.lock); +} + static struct msm_commit *new_commit(struct drm_atomic_state *state) { struct msm_commit *c = kzalloc(sizeof(*c), GFP_KERNEL); @@ -58,12 +89,27 @@ static void complete_commit(struct msm_commit *c) drm_atomic_helper_commit_post_planes(dev, state); + /* NOTE: _wait_for_vblanks() only waits for vblank on + * enabled CRTCs. So we end up faulting when disabling + * due to (potentially) unref'ing the outgoing fb's + * before the vblank when the disable has latched. + * + * But if it did wait on disabled (or newly disabled) + * CRTCs, that would be racy (ie. we could have missed + * the irq. We need some way to poll for pipe shut + * down. Or just live with occasionally hitting the + * timeout in the CRTC disable path (which really should + * not be critical path) + */ + drm_atomic_helper_wait_for_vblanks(dev, state); drm_atomic_helper_cleanup_planes(dev, state); drm_atomic_state_free(state); + end_atomic(dev->dev_private, c->crtc_mask); + kfree(c); } @@ -97,8 +143,9 @@ static void add_fb(struct msm_commit *c, struct drm_framebuffer *fb) int msm_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state, bool async) { - struct msm_commit *c; int nplanes = dev->mode_config.num_total_plane; + int ncrtcs = dev->mode_config.num_crtc; + struct msm_commit *c; int i, ret; ret = drm_atomic_helper_prepare_planes(dev, state); @@ -106,6 +153,18 @@ int msm_atomic_commit(struct drm_device *dev, return ret; c = new_commit(state); + if (!c) + return -ENOMEM; + + /* + * Figure out what crtcs we have: + */ + for (i = 0; i < ncrtcs; i++) { + struct drm_crtc *crtc = state->crtcs[i]; + if (!crtc) + continue; + c->crtc_mask |= (1 << drm_crtc_index(crtc)); + } /* * Figure out what fence to wait for: @@ -122,6 +181,14 @@ int msm_atomic_commit(struct drm_device *dev, } /* + * Wait for pending updates on any of the same crtc's and then + * mark our set of crtc's as busy: + */ + ret = start_atomic(dev->dev_private, c->crtc_mask); + if (ret) + return ret; + + /* * This is the point of no return - everything below never fails except * when the hw goes bonghits. Which means we can commit the new state on * the software side now. diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index c795217e1bfc..9a61546a0b05 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -193,6 +193,7 @@ static int msm_load(struct drm_device *dev, unsigned long flags) priv->wq = alloc_ordered_workqueue("msm", 0); init_waitqueue_head(&priv->fence_event); + init_waitqueue_head(&priv->pending_crtcs_event); INIT_LIST_HEAD(&priv->inactive_list); INIT_LIST_HEAD(&priv->fence_cbs); diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 136303818436..b69ef2d5a26c 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -96,6 +96,10 @@ struct msm_drm_private { /* callbacks deferred until bo is inactive: */ struct list_head fence_cbs; + /* crtcs pending async atomic updates: */ + uint32_t pending_crtcs; + wait_queue_head_t pending_crtcs_event; + /* registered MMUs: */ unsigned int num_mmus; struct msm_mmu *mmus[NUM_DOMAINS]; diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index 94d55e526b4e..1f3af13ccede 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -190,8 +190,7 @@ fail_unlock: fail: if (ret) { - if (fbi) - framebuffer_release(fbi); + framebuffer_release(fbi); if (fb) { drm_framebuffer_unregister_private(fb); drm_framebuffer_remove(fb); diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 4a6f0e49d5b5..49dea4fb55ac 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -535,8 +535,7 @@ void msm_gem_free_object(struct drm_gem_object *obj) drm_free_large(msm_obj->pages); } else { - if (msm_obj->vaddr) - vunmap(msm_obj->vaddr); + vunmap(msm_obj->vaddr); put_pages(obj); } diff --git a/drivers/gpu/drm/nouveau/core/core/event.c b/drivers/gpu/drm/nouveau/core/core/event.c index ff2b434b3db4..760947e380c9 100644 --- a/drivers/gpu/drm/nouveau/core/core/event.c +++ b/drivers/gpu/drm/nouveau/core/core/event.c @@ -26,7 +26,7 @@ void nvkm_event_put(struct nvkm_event *event, u32 types, int index) { - BUG_ON(!spin_is_locked(&event->refs_lock)); + assert_spin_locked(&event->refs_lock); while (types) { int type = __ffs(types); types &= ~(1 << type); if (--event->refs[index * event->types_nr + type] == 0) { @@ -39,7 +39,7 @@ nvkm_event_put(struct nvkm_event *event, u32 types, int index) void nvkm_event_get(struct nvkm_event *event, u32 types, int index) { - BUG_ON(!spin_is_locked(&event->refs_lock)); + assert_spin_locked(&event->refs_lock); while (types) { int type = __ffs(types); types &= ~(1 << type); if (++event->refs[index * event->types_nr + type] == 1) { diff --git a/drivers/gpu/drm/nouveau/core/core/notify.c b/drivers/gpu/drm/nouveau/core/core/notify.c index d1bcde55e9d7..839a32577680 100644 --- a/drivers/gpu/drm/nouveau/core/core/notify.c +++ b/drivers/gpu/drm/nouveau/core/core/notify.c @@ -98,7 +98,7 @@ nvkm_notify_send(struct nvkm_notify *notify, void *data, u32 size) struct nvkm_event *event = notify->event; unsigned long flags; - BUG_ON(!spin_is_locked(&event->list_lock)); + assert_spin_locked(&event->list_lock); BUG_ON(size != notify->size); spin_lock_irqsave(&event->refs_lock, flags); diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c index 674da1f095b2..732922690653 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c @@ -249,6 +249,39 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass; break; + case 0x106: + device->cname = "GK208B"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nve0_i2c_oclass; + device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass; + device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; + device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; + device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; + device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass; + device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; + device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; + device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = nv108_pwr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv108_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; + device->oclass[NVDEV_ENGINE_GR ] = nv108_graph_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nvf0_disp_oclass; + device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass; + device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass; + device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass; + device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; + device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; + device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; + break; case 0x108: device->cname = "GK208"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c b/drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c index 5e58bba0dd5c..a7a890fad1e5 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c @@ -44,8 +44,10 @@ static void pramin_fini(void *data) { struct priv *priv = data; - nv_wr32(priv->bios, 0x001700, priv->bar0); - kfree(priv); + if (priv) { + nv_wr32(priv->bios, 0x001700, priv->bar0); + kfree(priv); + } } static void * diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c index 00f2ca7e44a5..033a8e999497 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c @@ -24,34 +24,71 @@ #include "nv50.h" +struct nvaa_ram_priv { + struct nouveau_ram base; + u64 poller_base; +}; + static int nvaa_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 datasize, struct nouveau_object **pobject) { - const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */ - const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */ + u32 rsvd_head = ( 256 * 1024); /* vga memory */ + u32 rsvd_tail = (1024 * 1024); /* vbios etc */ struct nouveau_fb *pfb = nouveau_fb(parent); - struct nouveau_ram *ram; + struct nvaa_ram_priv *priv; int ret; - ret = nouveau_ram_create(parent, engine, oclass, &ram); - *pobject = nv_object(ram); + ret = nouveau_ram_create(parent, engine, oclass, &priv); + *pobject = nv_object(priv); if (ret) return ret; - ram->size = nv_rd32(pfb, 0x10020c); - ram->size = (ram->size & 0xffffff00) | ((ram->size & 0x000000ff) << 32); + priv->base.type = NV_MEM_TYPE_STOLEN; + priv->base.stolen = (u64)nv_rd32(pfb, 0x100e10) << 12; + priv->base.size = (u64)nv_rd32(pfb, 0x100e14) << 12; - ret = nouveau_mm_init(&pfb->vram, rsvd_head, (ram->size >> 12) - - (rsvd_head + rsvd_tail), 1); + rsvd_tail += 0x1000; + priv->poller_base = priv->base.size - rsvd_tail; + + ret = nouveau_mm_init(&pfb->vram, rsvd_head >> 12, + (priv->base.size - (rsvd_head + rsvd_tail)) >> 12, + 1); if (ret) return ret; - ram->type = NV_MEM_TYPE_STOLEN; - ram->stolen = (u64)nv_rd32(pfb, 0x100e10) << 12; - ram->get = nv50_ram_get; - ram->put = nv50_ram_put; + priv->base.get = nv50_ram_get; + priv->base.put = nv50_ram_put; + return 0; +} + +static int +nvaa_ram_init(struct nouveau_object *object) +{ + struct nouveau_fb *pfb = nouveau_fb(object); + struct nvaa_ram_priv *priv = (void *)object; + int ret; + u64 dniso, hostnb, flush; + + ret = nouveau_ram_init(&priv->base); + if (ret) + return ret; + + dniso = ((priv->base.size - (priv->poller_base + 0x00)) >> 5) - 1; + hostnb = ((priv->base.size - (priv->poller_base + 0x20)) >> 5) - 1; + flush = ((priv->base.size - (priv->poller_base + 0x40)) >> 5) - 1; + + /* Enable NISO poller for various clients and set their associated + * read address, only for MCP77/78 and MCP79/7A. (fd#25701) + */ + nv_wr32(pfb, 0x100c18, dniso); + nv_mask(pfb, 0x100c14, 0x00000000, 0x00000001); + nv_wr32(pfb, 0x100c1c, hostnb); + nv_mask(pfb, 0x100c14, 0x00000000, 0x00000002); + nv_wr32(pfb, 0x100c24, flush); + nv_mask(pfb, 0x100c14, 0x00000000, 0x00010000); + return 0; } @@ -60,7 +97,7 @@ nvaa_ram_oclass = { .ofuncs = &(struct nouveau_ofuncs) { .ctor = nvaa_ram_ctor, .dtor = _nouveau_ram_dtor, - .init = _nouveau_ram_init, + .init = nvaa_ram_init, .fini = _nouveau_ram_fini, }, }; diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c index a75c35ccf25c..165401c4045c 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c @@ -24,13 +24,6 @@ #include "nv04.h" -static void -nv4c_mc_msi_rearm(struct nouveau_mc *pmc) -{ - struct nv04_mc_priv *priv = (void *)pmc; - nv_wr08(priv, 0x088050, 0xff); -} - struct nouveau_oclass * nv4c_mc_oclass = &(struct nouveau_mc_oclass) { .base.handle = NV_SUBDEV(MC, 0x4c), @@ -41,5 +34,4 @@ nv4c_mc_oclass = &(struct nouveau_mc_oclass) { .fini = _nouveau_mc_fini, }, .intr = nv04_mc_intr, - .msi_rearm = nv4c_mc_msi_rearm, }.base; diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 21ec561edc99..bba2960d3dfb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1572,8 +1572,10 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm) * so use the DMA API for them. */ if (!nv_device_is_cpu_coherent(device) && - ttm->caching_state == tt_uncached) + ttm->caching_state == tt_uncached) { ttm_dma_unpopulate(ttm_dma, dev->dev); + return; + } #if __OS_HAS_AGP if (drm->agp.stat == ENABLED) { diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 5d93902a91ab..f8042433752b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -876,7 +876,6 @@ nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev, if (ret) return ret; - bo->gem.dumb = true; ret = drm_gem_handle_create(file_priv, &bo->gem, &args->handle); drm_gem_object_unreference_unlocked(&bo->gem); return ret; @@ -892,14 +891,6 @@ nouveau_display_dumb_map_offset(struct drm_file *file_priv, gem = drm_gem_object_lookup(dev, file_priv, handle); if (gem) { struct nouveau_bo *bo = nouveau_gem_object(gem); - - /* - * We don't allow dumb mmaps on objects created using another - * interface. - */ - WARN_ONCE(!(gem->dumb || gem->import_attach), - "Illegal dumb map of accelerated buffer.\n"); - *poffset = drm_vma_node_offset_addr(&bo->bo.vma_node); drm_gem_object_unreference_unlocked(gem); return 0; diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 28d51a22a4bf..bf0f9e21d714 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -36,7 +36,14 @@ void nouveau_gem_object_del(struct drm_gem_object *gem) { struct nouveau_bo *nvbo = nouveau_gem_object(gem); + struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); struct ttm_buffer_object *bo = &nvbo->bo; + struct device *dev = drm->dev->dev; + int ret; + + ret = pm_runtime_get_sync(dev); + if (WARN_ON(ret < 0 && ret != -EACCES)) + return; if (gem->import_attach) drm_prime_gem_destroy(gem, nvbo->bo.sg); @@ -46,6 +53,9 @@ nouveau_gem_object_del(struct drm_gem_object *gem) /* reset filp so nouveau_bo_del_ttm() can test for it */ gem->filp = NULL; ttm_bo_unref(&bo); + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); } int @@ -53,7 +63,9 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv) { struct nouveau_cli *cli = nouveau_cli(file_priv); struct nouveau_bo *nvbo = nouveau_gem_object(gem); + struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); struct nouveau_vma *vma; + struct device *dev = drm->dev->dev; int ret; if (!cli->vm) @@ -71,11 +83,16 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv) goto out; } + ret = pm_runtime_get_sync(dev); + if (ret < 0 && ret != -EACCES) + goto out; + ret = nouveau_bo_vma_add(nvbo, cli->vm, vma); - if (ret) { + if (ret) kfree(vma); - goto out; - } + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); } else { vma->refcount++; } @@ -129,6 +146,8 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv) { struct nouveau_cli *cli = nouveau_cli(file_priv); struct nouveau_bo *nvbo = nouveau_gem_object(gem); + struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); + struct device *dev = drm->dev->dev; struct nouveau_vma *vma; int ret; @@ -141,8 +160,14 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv) vma = nouveau_bo_vma_find(nvbo, cli->vm); if (vma) { - if (--vma->refcount == 0) - nouveau_gem_object_unmap(nvbo, vma); + if (--vma->refcount == 0) { + ret = pm_runtime_get_sync(dev); + if (!WARN_ON(ret < 0 && ret != -EACCES)) { + nouveau_gem_object_unmap(nvbo, vma); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + } + } } ttm_bo_unreserve(&nvbo->bo); } @@ -444,9 +469,6 @@ validate_list(struct nouveau_channel *chan, struct nouveau_cli *cli, list_for_each_entry(nvbo, list, entry) { struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; - WARN_ONCE(nvbo->gem.dumb, - "GPU use of dumb buffer is illegal.\n"); - ret = nouveau_gem_set_domain(&nvbo->gem, b->read_domains, b->write_domains, b->valid_domains); diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index 753a6def61e7..3d1cfcb96b6b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -28,6 +28,7 @@ #include "nouveau_ttm.h" #include "nouveau_gem.h" +#include "drm_legacy.h" static int nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long psize) { @@ -281,7 +282,7 @@ nouveau_ttm_mmap(struct file *filp, struct vm_area_struct *vma) struct nouveau_drm *drm = nouveau_drm(file_priv->minor->dev); if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) - return -EINVAL; + return drm_legacy_mmap(filp, vma); return ttm_bo_mmap(filp, vma, &drm->ttm.bdev); } diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index d59ec491dbb9..ed644a4f6f57 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1851,10 +1851,9 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) return pll; } /* otherwise, pick one of the plls */ - if ((rdev->family == CHIP_KAVERI) || - (rdev->family == CHIP_KABINI) || + if ((rdev->family == CHIP_KABINI) || (rdev->family == CHIP_MULLINS)) { - /* KB/KV/ML has PPLL1 and PPLL2 */ + /* KB/ML has PPLL1 and PPLL2 */ pll_in_use = radeon_get_pll_use_mask(crtc); if (!(pll_in_use & (1 << ATOM_PPLL2))) return ATOM_PPLL2; @@ -1863,7 +1862,7 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) DRM_ERROR("unable to allocate a PPLL\n"); return ATOM_PPLL_INVALID; } else { - /* CI has PPLL0, PPLL1, and PPLL2 */ + /* CI/KV has PPLL0, PPLL1, and PPLL2 */ pll_in_use = radeon_get_pll_use_mask(crtc); if (!(pll_in_use & (1 << ATOM_PPLL2))) return ATOM_PPLL2; @@ -2155,6 +2154,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) case ATOM_PPLL0: /* disable the ppll */ if ((rdev->family == CHIP_ARUBA) || + (rdev->family == CHIP_KAVERI) || (rdev->family == CHIP_BONAIRE) || (rdev->family == CHIP_HAWAII)) atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 11ba9d21b89b..db42a670f995 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -492,6 +492,10 @@ int radeon_dp_mode_valid_helper(struct drm_connector *connector, struct radeon_connector_atom_dig *dig_connector; int dp_clock; + if ((mode->clock > 340000) && + (!radeon_connector_is_dp12_capable(connector))) + return MODE_CLOCK_HIGH; + if (!radeon_connector->con_priv) return MODE_CLOCK_HIGH; dig_connector = radeon_connector->con_priv; diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 6dcde3798b45..64fdae558d36 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -6033,6 +6033,17 @@ void cik_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, radeon_ring_write(ring, 0); radeon_ring_write(ring, 1 << vm_id); + /* wait for the invalidate to complete */ + radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5)); + radeon_ring_write(ring, (WAIT_REG_MEM_OPERATION(0) | /* wait */ + WAIT_REG_MEM_FUNCTION(0) | /* always */ + WAIT_REG_MEM_ENGINE(0))); /* me */ + radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); /* ref */ + radeon_ring_write(ring, 0); /* mask */ + radeon_ring_write(ring, 0x20); /* poll interval */ + /* compute doesn't have PFP */ if (usepfp) { /* sync PFP to ME, otherwise we might get invalid PFP reads */ diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index dde5c7e29eb2..a0133c74f4cf 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c @@ -903,6 +903,9 @@ void cik_sdma_vm_pad_ib(struct radeon_ib *ib) void cik_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, unsigned vm_id, uint64_t pd_addr) { + u32 extra_bits = (SDMA_POLL_REG_MEM_EXTRA_OP(0) | + SDMA_POLL_REG_MEM_EXTRA_FUNC(0)); /* always */ + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); if (vm_id < 8) { radeon_ring_write(ring, (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2); @@ -943,5 +946,12 @@ void cik_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); radeon_ring_write(ring, 1 << vm_id); + + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_POLL_REG_MEM, 0, extra_bits)); + radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); /* reference */ + radeon_ring_write(ring, 0); /* mask */ + radeon_ring_write(ring, (0xfff << 16) | 10); /* retry count, poll interval */ } diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index ba85986febea..03003f8a6de6 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h @@ -2156,4 +2156,6 @@ #define ATC_VM_APERTURE1_HIGH_ADDR 0x330Cu #define ATC_VM_APERTURE1_LOW_ADDR 0x3304u +#define IH_VMID_0_LUT 0x3D40u + #endif diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index 2fe8cfc966d9..bafdf92a5732 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c @@ -103,7 +103,7 @@ static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder) } sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); - if (sad_count < 0) { + if (sad_count <= 0) { DRM_ERROR("Couldn't read SADs: %d\n", sad_count); return; } diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index 9b42001295ba..e3e9c10cfba9 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c @@ -2745,13 +2745,11 @@ int kv_dpm_init(struct radeon_device *rdev) pi->enable_auto_thermal_throttling = true; pi->disable_nb_ps3_in_battery = false; if (radeon_bapm == -1) { - /* There are stability issues reported on with - * bapm enabled on an asrock system. - */ - if (rdev->pdev->subsystem_vendor == 0x1849) - pi->bapm_enable = false; - else + /* only enable bapm on KB, ML by default */ + if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) pi->bapm_enable = true; + else + pi->bapm_enable = false; } else if (radeon_bapm == 0) { pi->bapm_enable = false; } else { diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 360de9f1f491..aea48c89b241 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -2516,6 +2516,16 @@ void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0)); radeon_ring_write(ring, 1 << vm_id); + /* wait for the invalidate to complete */ + radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5)); + radeon_ring_write(ring, (WAIT_REG_MEM_FUNCTION(0) | /* always */ + WAIT_REG_MEM_ENGINE(0))); /* me */ + radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); /* ref */ + radeon_ring_write(ring, 0); /* mask */ + radeon_ring_write(ring, 0x20); /* poll interval */ + /* sync PFP to ME, otherwise we might get invalid PFP reads */ radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); radeon_ring_write(ring, 0x0); diff --git a/drivers/gpu/drm/radeon/ni_dma.c b/drivers/gpu/drm/radeon/ni_dma.c index 50f88611ff60..4be2bb7cbef3 100644 --- a/drivers/gpu/drm/radeon/ni_dma.c +++ b/drivers/gpu/drm/radeon/ni_dma.c @@ -463,5 +463,11 @@ void cayman_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2)); radeon_ring_write(ring, 1 << vm_id); + + /* wait for invalidate to complete */ + radeon_ring_write(ring, DMA_SRBM_READ_PACKET); + radeon_ring_write(ring, (0xff << 20) | (VM_INVALIDATE_REQUEST >> 2)); + radeon_ring_write(ring, 0); /* mask */ + radeon_ring_write(ring, 0); /* value */ } diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h index 2e12e4d69253..ad7125486894 100644 --- a/drivers/gpu/drm/radeon/nid.h +++ b/drivers/gpu/drm/radeon/nid.h @@ -1133,6 +1133,23 @@ #define PACKET3_MEM_SEMAPHORE 0x39 #define PACKET3_MPEG_INDEX 0x3A #define PACKET3_WAIT_REG_MEM 0x3C +#define WAIT_REG_MEM_FUNCTION(x) ((x) << 0) + /* 0 - always + * 1 - < + * 2 - <= + * 3 - == + * 4 - != + * 5 - >= + * 6 - > + */ +#define WAIT_REG_MEM_MEM_SPACE(x) ((x) << 4) + /* 0 - reg + * 1 - mem + */ +#define WAIT_REG_MEM_ENGINE(x) ((x) << 8) + /* 0 - me + * 1 - pfp + */ #define PACKET3_MEM_WRITE 0x3D #define PACKET3_PFP_SYNC_ME 0x42 #define PACKET3_SURFACE_SYNC 0x43 @@ -1272,6 +1289,13 @@ (1 << 21) | \ (((n) & 0xFFFFF) << 0)) +#define DMA_SRBM_POLL_PACKET ((9 << 28) | \ + (1 << 27) | \ + (1 << 26)) + +#define DMA_SRBM_READ_PACKET ((9 << 28) | \ + (1 << 27)) + /* async DMA Packet types */ #define DMA_PACKET_WRITE 0x2 #define DMA_PACKET_COPY 0x3 diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 850de57069be..121aff6a3b41 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -333,6 +333,20 @@ static struct radeon_asic_ring r300_gfx_ring = { .set_wptr = &r100_gfx_set_wptr, }; +static struct radeon_asic_ring rv515_gfx_ring = { + .ib_execute = &r100_ring_ib_execute, + .emit_fence = &r300_fence_ring_emit, + .emit_semaphore = &r100_semaphore_ring_emit, + .cs_parse = &r300_cs_parse, + .ring_start = &rv515_ring_start, + .ring_test = &r100_ring_test, + .ib_test = &r100_ib_test, + .is_lockup = &r100_gpu_is_lockup, + .get_rptr = &r100_gfx_get_rptr, + .get_wptr = &r100_gfx_get_wptr, + .set_wptr = &r100_gfx_set_wptr, +}; + static struct radeon_asic r300_asic = { .init = &r300_init, .fini = &r300_fini, @@ -748,7 +762,7 @@ static struct radeon_asic rv515_asic = { .set_page = &rv370_pcie_gart_set_page, }, .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = &r300_gfx_ring + [RADEON_RING_TYPE_GFX_INDEX] = &rv515_gfx_ring }, .irq = { .set = &rs600_irq_set, @@ -814,7 +828,7 @@ static struct radeon_asic r520_asic = { .set_page = &rv370_pcie_gart_set_page, }, .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = &r300_gfx_ring + [RADEON_RING_TYPE_GFX_INDEX] = &rv515_gfx_ring }, .irq = { .set = &rs600_irq_set, diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index fe48f229043e..d0b4f7d1140d 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -394,10 +394,9 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, return r; } -static int radeon_mode_mmap(struct drm_file *filp, - struct drm_device *dev, - uint32_t handle, bool dumb, - uint64_t *offset_p) +int radeon_mode_dumb_mmap(struct drm_file *filp, + struct drm_device *dev, + uint32_t handle, uint64_t *offset_p) { struct drm_gem_object *gobj; struct radeon_bo *robj; @@ -406,14 +405,6 @@ static int radeon_mode_mmap(struct drm_file *filp, if (gobj == NULL) { return -ENOENT; } - - /* - * We don't allow dumb mmaps on objects created using another - * interface. - */ - WARN_ONCE(dumb && !(gobj->dumb || gobj->import_attach), - "Illegal dumb map of GPU buffer.\n"); - robj = gem_to_radeon_bo(gobj); if (radeon_ttm_tt_has_userptr(robj->tbo.ttm)) { drm_gem_object_unreference_unlocked(gobj); @@ -424,20 +415,12 @@ static int radeon_mode_mmap(struct drm_file *filp, return 0; } -int radeon_mode_dumb_mmap(struct drm_file *filp, - struct drm_device *dev, - uint32_t handle, uint64_t *offset_p) -{ - return radeon_mode_mmap(filp, dev, handle, true, offset_p); -} - int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { struct drm_radeon_gem_mmap *args = data; - return radeon_mode_mmap(filp, dev, args->handle, false, - &args->addr_ptr); + return radeon_mode_dumb_mmap(filp, dev, args->handle, &args->addr_ptr); } int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, @@ -593,7 +576,7 @@ error_unreserve: error_free: drm_free_large(vm_bos); - if (r) + if (r && r != -ERESTARTSYS) DRM_ERROR("Couldn't update BO_VA (%d)\n", r); } @@ -763,7 +746,6 @@ int radeon_mode_dumb_create(struct drm_file *file_priv, return -ENOMEM; r = drm_gem_handle_create(file_priv, gobj, &handle); - gobj->dumb = true; /* drop reference from allocate - handle holds it now */ drm_gem_object_unreference_unlocked(gobj); if (r) { diff --git a/drivers/gpu/drm/radeon/radeon_kfd.c b/drivers/gpu/drm/radeon/radeon_kfd.c index 065d02068ec3..8bf87f1203cc 100644 --- a/drivers/gpu/drm/radeon/radeon_kfd.c +++ b/drivers/gpu/drm/radeon/radeon_kfd.c @@ -28,6 +28,8 @@ #include "cikd.h" #include "cik_reg.h" #include "radeon_kfd.h" +#include "radeon_ucode.h" +#include <linux/firmware.h> #define CIK_PIPE_PER_MEC (4) @@ -49,6 +51,7 @@ static uint64_t get_vmem_size(struct kgd_dev *kgd); static uint64_t get_gpu_clock_counter(struct kgd_dev *kgd); static uint32_t get_max_engine_clock_in_mhz(struct kgd_dev *kgd); +static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type); /* * Register access functions @@ -69,7 +72,7 @@ static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id, static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, uint32_t queue_id, uint32_t __user *wptr); -static bool kgd_hqd_is_occupies(struct kgd_dev *kgd, uint64_t queue_address, +static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address, uint32_t pipe_id, uint32_t queue_id); static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type, @@ -89,14 +92,16 @@ static const struct kfd2kgd_calls kfd2kgd = { .init_memory = kgd_init_memory, .init_pipeline = kgd_init_pipeline, .hqd_load = kgd_hqd_load, - .hqd_is_occupies = kgd_hqd_is_occupies, + .hqd_is_occupied = kgd_hqd_is_occupied, .hqd_destroy = kgd_hqd_destroy, + .get_fw_version = get_fw_version }; static const struct kgd2kfd_calls *kgd2kfd; bool radeon_kfd_init(void) { +#if defined(CONFIG_HSA_AMD_MODULE) bool (*kgd2kfd_init_p)(unsigned, const struct kfd2kgd_calls*, const struct kgd2kfd_calls**); @@ -113,6 +118,17 @@ bool radeon_kfd_init(void) } return true; +#elif defined(CONFIG_HSA_AMD) + if (!kgd2kfd_init(KFD_INTERFACE_VERSION, &kfd2kgd, &kgd2kfd)) { + kgd2kfd = NULL; + + return false; + } + + return true; +#else + return false; +#endif } void radeon_kfd_fini(void) @@ -374,6 +390,10 @@ static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid, cpu_relax(); write_register(kgd, ATC_VMID_PASID_MAPPING_UPDATE_STATUS, 1U << vmid); + /* Mapping vmid to pasid also for IH block */ + write_register(kgd, IH_VMID_0_LUT + vmid * sizeof(uint32_t), + pasid_mapping); + return 0; } @@ -513,7 +533,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, return 0; } -static bool kgd_hqd_is_occupies(struct kgd_dev *kgd, uint64_t queue_address, +static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address, uint32_t pipe_id, uint32_t queue_id) { uint32_t act; @@ -552,6 +572,7 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type, if (timeout == 0) { pr_err("kfd: cp queue preemption time out (%dms)\n", temp); + release_queue(kgd); return -ETIME; } msleep(20); @@ -561,3 +582,52 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type, release_queue(kgd); return 0; } + +static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type) +{ + struct radeon_device *rdev = (struct radeon_device *) kgd; + const union radeon_firmware_header *hdr; + + BUG_ON(kgd == NULL || rdev->mec_fw == NULL); + + switch (type) { + case KGD_ENGINE_PFP: + hdr = (const union radeon_firmware_header *) rdev->pfp_fw->data; + break; + + case KGD_ENGINE_ME: + hdr = (const union radeon_firmware_header *) rdev->me_fw->data; + break; + + case KGD_ENGINE_CE: + hdr = (const union radeon_firmware_header *) rdev->ce_fw->data; + break; + + case KGD_ENGINE_MEC1: + hdr = (const union radeon_firmware_header *) rdev->mec_fw->data; + break; + + case KGD_ENGINE_MEC2: + hdr = (const union radeon_firmware_header *) + rdev->mec2_fw->data; + break; + + case KGD_ENGINE_RLC: + hdr = (const union radeon_firmware_header *) rdev->rlc_fw->data; + break; + + case KGD_ENGINE_SDMA: + hdr = (const union radeon_firmware_header *) + rdev->sdma_fw->data; + break; + + default: + return 0; + } + + if (hdr == NULL) + return 0; + + /* Only 12 bit in use*/ + return hdr->common.ucode_version; +} diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 7d68223eb469..86fc56434b28 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -529,9 +529,6 @@ int radeon_bo_list_validate(struct radeon_device *rdev, u32 current_domain = radeon_mem_type_to_domain(bo->tbo.mem.mem_type); - WARN_ONCE(bo->gem_base.dumb, - "GPU use of dumb buffer is illegal.\n"); - /* Check if this buffer will be moved and don't move it * if we have moved too many buffers for this IB already. * diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 32522cc940a1..f7da8fe96a66 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -1287,8 +1287,39 @@ dpm_failed: return ret; } +struct radeon_dpm_quirk { + u32 chip_vendor; + u32 chip_device; + u32 subsys_vendor; + u32 subsys_device; +}; + +/* cards with dpm stability problems */ +static struct radeon_dpm_quirk radeon_dpm_quirk_list[] = { + /* TURKS - https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1386534 */ + { PCI_VENDOR_ID_ATI, 0x6759, 0x1682, 0x3195 }, + /* TURKS - https://bugzilla.kernel.org/show_bug.cgi?id=83731 */ + { PCI_VENDOR_ID_ATI, 0x6840, 0x1179, 0xfb81 }, + { 0, 0, 0, 0 }, +}; + int radeon_pm_init(struct radeon_device *rdev) { + struct radeon_dpm_quirk *p = radeon_dpm_quirk_list; + bool disable_dpm = false; + + /* Apply dpm quirks */ + while (p && p->chip_device != 0) { + if (rdev->pdev->vendor == p->chip_vendor && + rdev->pdev->device == p->chip_device && + rdev->pdev->subsystem_vendor == p->subsys_vendor && + rdev->pdev->subsystem_device == p->subsys_device) { + disable_dpm = true; + break; + } + ++p; + } + /* enable dpm on rv6xx+ */ switch (rdev->family) { case CHIP_RV610: @@ -1344,6 +1375,8 @@ int radeon_pm_init(struct radeon_device *rdev) (!(rdev->flags & RADEON_IS_IGP)) && (!rdev->smc_fw)) rdev->pm.pm_method = PM_METHOD_PROFILE; + else if (disable_dpm && (radeon_dpm == -1)) + rdev->pm.pm_method = PM_METHOD_PROFILE; else if (radeon_dpm == 0) rdev->pm.pm_method = PM_METHOD_PROFILE; else diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index 535403e0c8a2..15aee723db77 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c @@ -1703,7 +1703,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev, u32 format; u32 *buffer; const u8 __user *data; - int size, dwords, tex_width, blit_width, spitch; + unsigned int size, dwords, tex_width, blit_width, spitch; u32 height; int i; u32 texpitch, microtile; diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 60df444bd075..5d89b874a1a2 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -5057,6 +5057,16 @@ void si_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, radeon_ring_write(ring, 0); radeon_ring_write(ring, 1 << vm_id); + /* wait for the invalidate to complete */ + radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5)); + radeon_ring_write(ring, (WAIT_REG_MEM_FUNCTION(0) | /* always */ + WAIT_REG_MEM_ENGINE(0))); /* me */ + radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); /* ref */ + radeon_ring_write(ring, 0); /* mask */ + radeon_ring_write(ring, 0x20); /* poll interval */ + /* sync PFP to ME, otherwise we might get invalid PFP reads */ radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); radeon_ring_write(ring, 0x0); diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c index f5cc777e1c5f..aa7b872b2c43 100644 --- a/drivers/gpu/drm/radeon/si_dma.c +++ b/drivers/gpu/drm/radeon/si_dma.c @@ -206,6 +206,14 @@ void si_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0)); radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2)); radeon_ring_write(ring, 1 << vm_id); + + /* wait for invalidate to complete */ + radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_POLL_REG_MEM, 0, 0, 0, 0)); + radeon_ring_write(ring, VM_INVALIDATE_REQUEST); + radeon_ring_write(ring, 0xff << 16); /* retry */ + radeon_ring_write(ring, 1 << vm_id); /* mask */ + radeon_ring_write(ring, 0); /* value */ + radeon_ring_write(ring, (0 << 28) | 0x20); /* func(always) | poll interval */ } /** diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 32e354b8b0ab..eff8a6444956 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -2908,6 +2908,22 @@ static int si_init_smc_spll_table(struct radeon_device *rdev) return ret; } +struct si_dpm_quirk { + u32 chip_vendor; + u32 chip_device; + u32 subsys_vendor; + u32 subsys_device; + u32 max_sclk; + u32 max_mclk; +}; + +/* cards with dpm stability problems */ +static struct si_dpm_quirk si_dpm_quirk_list[] = { + /* PITCAIRN - https://bugs.freedesktop.org/show_bug.cgi?id=76490 */ + { PCI_VENDOR_ID_ATI, 0x6810, 0x1462, 0x3036, 0, 120000 }, + { 0, 0, 0, 0 }, +}; + static void si_apply_state_adjust_rules(struct radeon_device *rdev, struct radeon_ps *rps) { @@ -2918,7 +2934,22 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, u32 mclk, sclk; u16 vddc, vddci; u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc; + u32 max_sclk = 0, max_mclk = 0; int i; + struct si_dpm_quirk *p = si_dpm_quirk_list; + + /* Apply dpm quirks */ + while (p && p->chip_device != 0) { + if (rdev->pdev->vendor == p->chip_vendor && + rdev->pdev->device == p->chip_device && + rdev->pdev->subsystem_vendor == p->subsys_vendor && + rdev->pdev->subsystem_device == p->subsys_device) { + max_sclk = p->max_sclk; + max_mclk = p->max_mclk; + break; + } + ++p; + } if ((rdev->pm.dpm.new_active_crtc_count > 1) || ni_dpm_vblank_too_short(rdev)) @@ -2972,6 +3003,14 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, if (ps->performance_levels[i].mclk > max_mclk_vddc) ps->performance_levels[i].mclk = max_mclk_vddc; } + if (max_mclk) { + if (ps->performance_levels[i].mclk > max_mclk) + ps->performance_levels[i].mclk = max_mclk; + } + if (max_sclk) { + if (ps->performance_levels[i].sclk > max_sclk) + ps->performance_levels[i].sclk = max_sclk; + } } /* XXX validate the min clocks required for display */ diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 4069be89e585..84999242c747 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h @@ -1632,6 +1632,23 @@ #define PACKET3_MPEG_INDEX 0x3A #define PACKET3_COPY_DW 0x3B #define PACKET3_WAIT_REG_MEM 0x3C +#define WAIT_REG_MEM_FUNCTION(x) ((x) << 0) + /* 0 - always + * 1 - < + * 2 - <= + * 3 - == + * 4 - != + * 5 - >= + * 6 - > + */ +#define WAIT_REG_MEM_MEM_SPACE(x) ((x) << 4) + /* 0 - reg + * 1 - mem + */ +#define WAIT_REG_MEM_ENGINE(x) ((x) << 8) + /* 0 - me + * 1 - pfp + */ #define PACKET3_MEM_WRITE 0x3D #define PACKET3_COPY_DATA 0x40 #define PACKET3_CP_DMA 0x41 @@ -1835,6 +1852,7 @@ #define DMA_PACKET_TRAP 0x7 #define DMA_PACKET_SRBM_WRITE 0x9 #define DMA_PACKET_CONSTANT_FILL 0xd +#define DMA_PACKET_POLL_REG_MEM 0xe #define DMA_PACKET_NOP 0xf #define VCE_STATUS 0x20004 diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 3367960286a6..978993fa3a36 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -168,7 +168,7 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index, const struct tegra_dc_window *window) { unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp; - unsigned long value; + unsigned long value, flags; bool yuv, planar; /* @@ -181,6 +181,8 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index, else bpp = planar ? 1 : 2; + spin_lock_irqsave(&dc->lock, flags); + value = WINDOW_A_SELECT << index; tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER); @@ -273,6 +275,7 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index, case TEGRA_BO_TILING_MODE_BLOCK: DRM_ERROR("hardware doesn't support block linear mode\n"); + spin_unlock_irqrestore(&dc->lock, flags); return -EINVAL; } @@ -331,6 +334,8 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index, tegra_dc_window_commit(dc, index); + spin_unlock_irqrestore(&dc->lock, flags); + return 0; } @@ -338,11 +343,14 @@ static int tegra_window_plane_disable(struct drm_plane *plane) { struct tegra_dc *dc = to_tegra_dc(plane->crtc); struct tegra_plane *p = to_tegra_plane(plane); + unsigned long flags; u32 value; if (!plane->crtc) return 0; + spin_lock_irqsave(&dc->lock, flags); + value = WINDOW_A_SELECT << p->index; tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER); @@ -352,6 +360,8 @@ static int tegra_window_plane_disable(struct drm_plane *plane) tegra_dc_window_commit(dc, p->index); + spin_unlock_irqrestore(&dc->lock, flags); + return 0; } @@ -699,14 +709,16 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y, struct tegra_bo *bo = tegra_fb_get_plane(fb, 0); unsigned int h_offset = 0, v_offset = 0; struct tegra_bo_tiling tiling; + unsigned long value, flags; unsigned int format, swap; - unsigned long value; int err; err = tegra_fb_get_tiling(fb, &tiling); if (err < 0) return err; + spin_lock_irqsave(&dc->lock, flags); + tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER); value = fb->offsets[0] + y * fb->pitches[0] + @@ -752,6 +764,7 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y, case TEGRA_BO_TILING_MODE_BLOCK: DRM_ERROR("hardware doesn't support block linear mode\n"); + spin_unlock_irqrestore(&dc->lock, flags); return -EINVAL; } @@ -778,6 +791,8 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y, tegra_dc_writel(dc, value << 8, DC_CMD_STATE_CONTROL); tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); + spin_unlock_irqrestore(&dc->lock, flags); + return 0; } @@ -814,23 +829,32 @@ static void tegra_dc_finish_page_flip(struct tegra_dc *dc) unsigned long flags, base; struct tegra_bo *bo; - if (!dc->event) + spin_lock_irqsave(&drm->event_lock, flags); + + if (!dc->event) { + spin_unlock_irqrestore(&drm->event_lock, flags); return; + } bo = tegra_fb_get_plane(crtc->primary->fb, 0); + spin_lock_irqsave(&dc->lock, flags); + /* check if new start address has been latched */ + tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER); tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS); base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR); tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS); + spin_unlock_irqrestore(&dc->lock, flags); + if (base == bo->paddr + crtc->primary->fb->offsets[0]) { - spin_lock_irqsave(&drm->event_lock, flags); - drm_send_vblank_event(drm, dc->pipe, dc->event); - drm_vblank_put(drm, dc->pipe); + drm_crtc_send_vblank_event(crtc, dc->event); + drm_crtc_vblank_put(crtc); dc->event = NULL; - spin_unlock_irqrestore(&drm->event_lock, flags); } + + spin_unlock_irqrestore(&drm->event_lock, flags); } void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file) @@ -843,7 +867,7 @@ void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file) if (dc->event && dc->event->base.file_priv == file) { dc->event->base.destroy(&dc->event->base); - drm_vblank_put(drm, dc->pipe); + drm_crtc_vblank_put(crtc); dc->event = NULL; } @@ -853,16 +877,16 @@ void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file) static int tegra_dc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, uint32_t page_flip_flags) { + unsigned int pipe = drm_crtc_index(crtc); struct tegra_dc *dc = to_tegra_dc(crtc); - struct drm_device *drm = crtc->dev; if (dc->event) return -EBUSY; if (event) { - event->pipe = dc->pipe; + event->pipe = pipe; dc->event = event; - drm_vblank_get(drm, dc->pipe); + drm_crtc_vblank_get(crtc); } tegra_dc_set_base(dc, 0, 0, fb); @@ -1127,7 +1151,7 @@ static irqreturn_t tegra_dc_irq(int irq, void *data) /* dev_dbg(dc->dev, "%s(): vertical blank\n", __func__); */ - drm_handle_vblank(dc->base.dev, dc->pipe); + drm_crtc_handle_vblank(&dc->base); tegra_dc_finish_page_flip(dc); } diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index e549afeece1f..d4f827593dfa 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -694,24 +694,28 @@ static const struct file_operations tegra_drm_fops = { .llseek = noop_llseek, }; -static struct drm_crtc *tegra_crtc_from_pipe(struct drm_device *drm, int pipe) +static struct drm_crtc *tegra_crtc_from_pipe(struct drm_device *drm, + unsigned int pipe) { struct drm_crtc *crtc; list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) { - struct tegra_dc *dc = to_tegra_dc(crtc); - - if (dc->pipe == pipe) + if (pipe == drm_crtc_index(crtc)) return crtc; } return NULL; } -static u32 tegra_drm_get_vblank_counter(struct drm_device *dev, int crtc) +static u32 tegra_drm_get_vblank_counter(struct drm_device *drm, int pipe) { + struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe); + + if (!crtc) + return 0; + /* TODO: implement real hardware counter using syncpoints */ - return drm_vblank_count(dev, crtc); + return drm_crtc_vblank_count(crtc); } static int tegra_drm_enable_vblank(struct drm_device *drm, int pipe) diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index da32086cbeaf..8777b7f75791 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -216,32 +216,58 @@ static void tegra_bo_free(struct drm_device *drm, struct tegra_bo *bo) } } -static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo, - size_t size) +static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo) { + struct scatterlist *s; + struct sg_table *sgt; + unsigned int i; + bo->pages = drm_gem_get_pages(&bo->gem); if (IS_ERR(bo->pages)) return PTR_ERR(bo->pages); - bo->num_pages = size >> PAGE_SHIFT; - - bo->sgt = drm_prime_pages_to_sg(bo->pages, bo->num_pages); - if (IS_ERR(bo->sgt)) { - drm_gem_put_pages(&bo->gem, bo->pages, false, false); - return PTR_ERR(bo->sgt); + bo->num_pages = bo->gem.size >> PAGE_SHIFT; + + sgt = drm_prime_pages_to_sg(bo->pages, bo->num_pages); + if (IS_ERR(sgt)) + goto put_pages; + + /* + * Fake up the SG table so that dma_map_sg() can be used to flush the + * pages associated with it. Note that this relies on the fact that + * the DMA API doesn't hook into IOMMU on Tegra, therefore mapping is + * only cache maintenance. + * + * TODO: Replace this by drm_clflash_sg() once it can be implemented + * without relying on symbols that are not exported. + */ + for_each_sg(sgt->sgl, s, sgt->nents, i) + sg_dma_address(s) = sg_phys(s); + + if (dma_map_sg(drm->dev, sgt->sgl, sgt->nents, DMA_TO_DEVICE) == 0) { + sgt = ERR_PTR(-ENOMEM); + goto release_sgt; } + bo->sgt = sgt; + return 0; + +release_sgt: + sg_free_table(sgt); + kfree(sgt); +put_pages: + drm_gem_put_pages(&bo->gem, bo->pages, false, false); + return PTR_ERR(sgt); } -static int tegra_bo_alloc(struct drm_device *drm, struct tegra_bo *bo, - size_t size) +static int tegra_bo_alloc(struct drm_device *drm, struct tegra_bo *bo) { struct tegra_drm *tegra = drm->dev_private; int err; if (tegra->domain) { - err = tegra_bo_get_pages(drm, bo, size); + err = tegra_bo_get_pages(drm, bo); if (err < 0) return err; @@ -251,6 +277,8 @@ static int tegra_bo_alloc(struct drm_device *drm, struct tegra_bo *bo, return err; } } else { + size_t size = bo->gem.size; + bo->vaddr = dma_alloc_writecombine(drm->dev, size, &bo->paddr, GFP_KERNEL | __GFP_NOWARN); if (!bo->vaddr) { @@ -274,7 +302,7 @@ struct tegra_bo *tegra_bo_create(struct drm_device *drm, size_t size, if (IS_ERR(bo)) return bo; - err = tegra_bo_alloc(drm, bo, size); + err = tegra_bo_alloc(drm, bo); if (err < 0) goto release; diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 230b6f887cd8..dfdc26970022 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -27,7 +27,8 @@ if HID config HID_BATTERY_STRENGTH bool "Battery level reporting for HID devices" - depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY + depends on HID + select POWER_SUPPLY default n ---help--- This option adds support of reporting battery strength (for HID devices diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index c3d0ac1a0988..8b638792cb43 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1805,6 +1805,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X) }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) }, + { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) }, { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 7460f3402298..9243359c1821 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -526,6 +526,7 @@ #define USB_DEVICE_ID_KYE_GPEN_560 0x5003 #define USB_DEVICE_ID_KYE_EASYPEN_I405X 0x5010 #define USB_DEVICE_ID_KYE_MOUSEPEN_I608X 0x5011 +#define USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2 0x501a #define USB_DEVICE_ID_KYE_EASYPEN_M610X 0x5013 #define USB_VENDOR_ID_LABTEC 0x1020 diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index e0a0f06ac5ef..9505605b6e22 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -312,6 +312,9 @@ static const struct hid_device_id hid_battery_quirks[] = { USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, + USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO), + HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI), HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, {} diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c index b92bf01a1ae8..158fcf577fae 100644 --- a/drivers/hid/hid-kye.c +++ b/drivers/hid/hid-kye.c @@ -323,6 +323,7 @@ static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc, } break; case USB_DEVICE_ID_KYE_MOUSEPEN_I608X: + case USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2: if (*rsize == MOUSEPEN_I608X_RDESC_ORIG_SIZE) { rdesc = mousepen_i608x_rdesc_fixed; *rsize = sizeof(mousepen_i608x_rdesc_fixed); @@ -415,6 +416,7 @@ static int kye_probe(struct hid_device *hdev, const struct hid_device_id *id) switch (id->product) { case USB_DEVICE_ID_KYE_EASYPEN_I405X: case USB_DEVICE_ID_KYE_MOUSEPEN_I608X: + case USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2: case USB_DEVICE_ID_KYE_EASYPEN_M610X: ret = kye_tablet_enable(hdev); if (ret) { @@ -446,6 +448,8 @@ static const struct hid_device_id kye_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, + USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE) }, diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index c917ab61aafa..5bc6d80d5be7 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -962,10 +962,24 @@ static int logi_dj_raw_event(struct hid_device *hdev, switch (data[0]) { case REPORT_ID_DJ_SHORT: + if (size != DJREPORT_SHORT_LENGTH) { + dev_err(&hdev->dev, "DJ report of bad size (%d)", size); + return false; + } return logi_dj_dj_event(hdev, report, data, size); case REPORT_ID_HIDPP_SHORT: - /* intentional fallthrough */ + if (size != HIDPP_REPORT_SHORT_LENGTH) { + dev_err(&hdev->dev, + "Short HID++ report of bad size (%d)", size); + return false; + } + return logi_dj_hidpp_event(hdev, report, data, size); case REPORT_ID_HIDPP_LONG: + if (size != HIDPP_REPORT_LONG_LENGTH) { + dev_err(&hdev->dev, + "Long HID++ report of bad size (%d)", size); + return false; + } return logi_dj_hidpp_event(hdev, report, data, size); } diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 2f420c0b6609..a93cefe0e522 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -282,6 +282,33 @@ static inline bool hidpp_report_is_connect_event(struct hidpp_report *report) (report->rap.sub_id == 0x41); } +/** + * hidpp_prefix_name() prefixes the current given name with "Logitech ". + */ +static void hidpp_prefix_name(char **name, int name_length) +{ +#define PREFIX_LENGTH 9 /* "Logitech " */ + + int new_length; + char *new_name; + + if (name_length > PREFIX_LENGTH && + strncmp(*name, "Logitech ", PREFIX_LENGTH) == 0) + /* The prefix has is already in the name */ + return; + + new_length = PREFIX_LENGTH + name_length; + new_name = kzalloc(new_length, GFP_KERNEL); + if (!new_name) + return; + + snprintf(new_name, new_length, "Logitech %s", *name); + + kfree(*name); + + *name = new_name; +} + /* -------------------------------------------------------------------------- */ /* HIDP++ 1.0 commands */ /* -------------------------------------------------------------------------- */ @@ -321,6 +348,10 @@ static char *hidpp_get_unifying_name(struct hidpp_device *hidpp_dev) return NULL; memcpy(name, &response.rap.params[2], len); + + /* include the terminating '\0' */ + hidpp_prefix_name(&name, len + 1); + return name; } @@ -498,6 +529,9 @@ static char *hidpp_get_device_name(struct hidpp_device *hidpp) index += ret; } + /* include the terminating '\0' */ + hidpp_prefix_name(&name, __name_length + 1); + return name; } @@ -794,18 +828,25 @@ static int wtp_raw_event(struct hid_device *hdev, u8 *data, int size) switch (data[0]) { case 0x02: + if (size < 2) { + hid_err(hdev, "Received HID report of bad size (%d)", + size); + return 1; + } if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) { input_event(wd->input, EV_KEY, BTN_LEFT, !!(data[1] & 0x01)); input_event(wd->input, EV_KEY, BTN_RIGHT, !!(data[1] & 0x02)); input_sync(wd->input); + return 0; } else { if (size < 21) return 1; return wtp_mouse_raw_xy_event(hidpp, &data[7]); } case REPORT_ID_HIDPP_LONG: + /* size is already checked in hidpp_raw_event. */ if ((report->fap.feature_index != wd->mt_feature_index) || (report->fap.funcindex_clientid != EVENT_TOUCHPAD_RAW_XY)) return 1; diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c index 1a07e07d99a0..47d7e74231e5 100644 --- a/drivers/hid/hid-roccat-pyra.c +++ b/drivers/hid/hid-roccat-pyra.c @@ -35,6 +35,8 @@ static struct class *pyra_class; static void profile_activated(struct pyra_device *pyra, unsigned int new_profile) { + if (new_profile >= ARRAY_SIZE(pyra->profile_settings)) + return; pyra->actual_profile = new_profile; pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi; } @@ -257,9 +259,11 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp, if (off != 0 || count != PYRA_SIZE_SETTINGS) return -EINVAL; - mutex_lock(&pyra->pyra_lock); - settings = (struct pyra_settings const *)buf; + if (settings->startup_profile >= ARRAY_SIZE(pyra->profile_settings)) + return -EINVAL; + + mutex_lock(&pyra->pyra_lock); retval = pyra_set_settings(usb_dev, settings); if (retval) { diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index d32037cbf9db..d43e967e7533 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -706,12 +706,7 @@ static int i2c_hid_start(struct hid_device *hid) static void i2c_hid_stop(struct hid_device *hid) { - struct i2c_client *client = hid->driver_data; - struct i2c_hid *ihid = i2c_get_clientdata(client); - hid->claimed = 0; - - i2c_hid_free_buffers(ihid); } static int i2c_hid_open(struct hid_device *hid) diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index dc89be90b35e..b27b3d33ebab 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -124,6 +124,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD, HID_QUIRK_NO_INIT_REPORTS }, diff --git a/drivers/hsi/clients/nokia-modem.c b/drivers/hsi/clients/nokia-modem.c index 363b780dacea..f0c21458962c 100644 --- a/drivers/hsi/clients/nokia-modem.c +++ b/drivers/hsi/clients/nokia-modem.c @@ -29,7 +29,7 @@ #include <linux/of_gpio.h> #include <linux/hsi/ssi_protocol.h> -static unsigned int pm; +static unsigned int pm = 1; module_param(pm, int, 0400); MODULE_PARM_DESC(pm, "Enable power management (0=disabled, 1=userland based [default])"); @@ -164,9 +164,9 @@ static int nokia_modem_probe(struct device *dev) dev_set_drvdata(dev, modem); irq = irq_of_parse_and_map(np, 0); - if (irq < 0) { + if (!irq) { dev_err(dev, "Invalid rst_ind interrupt (%d)\n", irq); - return irq; + return -EINVAL; } modem->nokia_modem_rst_ind_irq = irq; pflags = irq_get_trigger_type(irq); @@ -174,7 +174,7 @@ static int nokia_modem_probe(struct device *dev) tasklet_init(&modem->nokia_modem_rst_ind_tasklet, do_nokia_modem_rst_ind_tasklet, (unsigned long)modem); err = devm_request_irq(dev, irq, nokia_modem_rst_ind_isr, - IRQF_DISABLED | pflags, "modem_rst_ind", modem); + pflags, "modem_rst_ind", modem); if (err < 0) { dev_err(dev, "Request rst_ind irq(%d) failed (flags %d)\n", irq, pflags); diff --git a/drivers/hsi/controllers/omap_ssi_port.c b/drivers/hsi/controllers/omap_ssi_port.c index 1314ab80164b..1f8652b3de06 100644 --- a/drivers/hsi/controllers/omap_ssi_port.c +++ b/drivers/hsi/controllers/omap_ssi_port.c @@ -1118,8 +1118,7 @@ static int __init ssi_port_probe(struct platform_device *pd) dev_dbg(&pd->dev, "init ssi port...\n"); if (!try_module_get(ssi->owner)) { - dev_err(&pd->dev, "could not increment parent module refcount (err=%d)\n", - err); + dev_err(&pd->dev, "could not increment parent module refcount\n"); return -ENODEV; } diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 6529c09c46f0..a7de26d1ac80 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -574,6 +574,16 @@ config SENSORS_IIO_HWMON for those channels specified in the map. This map can be provided either via platform data or the device tree bindings. +config SENSORS_I5500 + tristate "Intel 5500/5520/X58 temperature sensor" + depends on X86 && PCI + help + If you say yes here you get support for the temperature + sensor inside the Intel 5500, 5520 and X58 chipsets. + + This driver can also be built as a module. If so, the module + will be called i5500_temp. + config SENSORS_CORETEMP tristate "Intel Core/Core2/Atom temperature sensor" depends on X86 diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 67280643bcf0..6c941472e707 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -68,6 +68,7 @@ obj-$(CONFIG_SENSORS_GPIO_FAN) += gpio-fan.o obj-$(CONFIG_SENSORS_HIH6130) += hih6130.o obj-$(CONFIG_SENSORS_HTU21) += htu21.o obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o +obj-$(CONFIG_SENSORS_I5500) += i5500_temp.o obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o diff --git a/drivers/hwmon/i5500_temp.c b/drivers/hwmon/i5500_temp.c new file mode 100644 index 000000000000..3e3ccbf18b4e --- /dev/null +++ b/drivers/hwmon/i5500_temp.c @@ -0,0 +1,149 @@ +/* + * i5500_temp - Driver for Intel 5500/5520/X58 chipset thermal sensor + * + * Copyright (C) 2012, 2014 Jean Delvare <jdelvare@suse.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/jiffies.h> +#include <linux/device.h> +#include <linux/pci.h> +#include <linux/hwmon.h> +#include <linux/hwmon-sysfs.h> +#include <linux/err.h> +#include <linux/mutex.h> + +/* Register definitions from datasheet */ +#define REG_TSTHRCATA 0xE2 +#define REG_TSCTRL 0xE8 +#define REG_TSTHRRPEX 0xEB +#define REG_TSTHRLO 0xEC +#define REG_TSTHRHI 0xEE +#define REG_CTHINT 0xF0 +#define REG_TSFSC 0xF3 +#define REG_CTSTS 0xF4 +#define REG_TSTHRRQPI 0xF5 +#define REG_CTCTRL 0xF7 +#define REG_TSTIMER 0xF8 + +/* + * Sysfs stuff + */ + +/* Sensor resolution : 0.5 degree C */ +static ssize_t show_temp(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct pci_dev *pdev = to_pci_dev(dev->parent); + long temp; + u16 tsthrhi; + s8 tsfsc; + + pci_read_config_word(pdev, REG_TSTHRHI, &tsthrhi); + pci_read_config_byte(pdev, REG_TSFSC, &tsfsc); + temp = ((long)tsthrhi - tsfsc) * 500; + + return sprintf(buf, "%ld\n", temp); +} + +static ssize_t show_thresh(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct pci_dev *pdev = to_pci_dev(dev->parent); + int reg = to_sensor_dev_attr(devattr)->index; + long temp; + u16 tsthr; + + pci_read_config_word(pdev, reg, &tsthr); + temp = tsthr * 500; + + return sprintf(buf, "%ld\n", temp); +} + +static ssize_t show_alarm(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct pci_dev *pdev = to_pci_dev(dev->parent); + int nr = to_sensor_dev_attr(devattr)->index; + u8 ctsts; + + pci_read_config_byte(pdev, REG_CTSTS, &ctsts); + return sprintf(buf, "%u\n", (unsigned int)ctsts & (1 << nr)); +} + +static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL); +static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_thresh, NULL, 0xE2); +static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_thresh, NULL, 0xEC); +static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_thresh, NULL, 0xEE); +static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); +static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1); + +static struct attribute *i5500_temp_attrs[] = { + &dev_attr_temp1_input.attr, + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, + NULL +}; + +ATTRIBUTE_GROUPS(i5500_temp); + +static const struct pci_device_id i5500_temp_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3438) }, + { 0 }, +}; + +MODULE_DEVICE_TABLE(pci, i5500_temp_ids); + +static int i5500_temp_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + int err; + struct device *hwmon_dev; + u32 tstimer; + s8 tsfsc; + + err = pci_enable_device(pdev); + if (err) { + dev_err(&pdev->dev, "Failed to enable device\n"); + return err; + } + + pci_read_config_byte(pdev, REG_TSFSC, &tsfsc); + pci_read_config_dword(pdev, REG_TSTIMER, &tstimer); + if (tsfsc == 0x7F && tstimer == 0x07D30D40) { + dev_notice(&pdev->dev, "Sensor seems to be disabled\n"); + return -ENODEV; + } + + hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, + "intel5500", NULL, + i5500_temp_groups); + return PTR_ERR_OR_ZERO(hwmon_dev); +} + +static struct pci_driver i5500_temp_driver = { + .name = "i5500_temp", + .id_table = i5500_temp_ids, + .probe = i5500_temp_probe, +}; + +module_pci_driver(i5500_temp_driver); + +MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>"); +MODULE_DESCRIPTION("Intel 5500/5520/X58 chipset thermal sensor driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index 6753fd940c76..fe41d5ae7cb2 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -177,6 +177,10 @@ static struct attribute *lm75_attrs[] = { }; ATTRIBUTE_GROUPS(lm75); +static const struct thermal_zone_of_device_ops lm75_of_thermal_ops = { + .get_temp = lm75_read_temp, +}; + /*-----------------------------------------------------------------------*/ /* device probe and removal */ @@ -296,10 +300,9 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) if (IS_ERR(data->hwmon_dev)) return PTR_ERR(data->hwmon_dev); - data->tz = thermal_zone_of_sensor_register(data->hwmon_dev, - 0, + data->tz = thermal_zone_of_sensor_register(data->hwmon_dev, 0, data->hwmon_dev, - lm75_read_temp, NULL); + &lm75_of_thermal_ops); if (IS_ERR(data->tz)) data->tz = NULL; diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c index fd9a945fe8db..112e4d45e4a0 100644 --- a/drivers/hwmon/ntc_thermistor.c +++ b/drivers/hwmon/ntc_thermistor.c @@ -486,6 +486,10 @@ static const struct attribute_group ntc_attr_group = { .attrs = ntc_attributes, }; +static const struct thermal_zone_of_device_ops ntc_of_thermal_ops = { + .get_temp = ntc_read_temp, +}; + static int ntc_thermistor_probe(struct platform_device *pdev) { const struct of_device_id *of_id = @@ -579,7 +583,7 @@ static int ntc_thermistor_probe(struct platform_device *pdev) pdev_id->name); data->tz = thermal_zone_of_sensor_register(data->dev, 0, data->dev, - ntc_read_temp, NULL); + &ntc_of_thermal_ops); if (IS_ERR(data->tz)) { dev_dbg(&pdev->dev, "Failed to register to thermal fw.\n"); data->tz = NULL; diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c index 51719956cc03..ba9f478f64ee 100644 --- a/drivers/hwmon/tmp102.c +++ b/drivers/hwmon/tmp102.c @@ -158,6 +158,10 @@ ATTRIBUTE_GROUPS(tmp102); #define TMP102_CONFIG (TMP102_CONF_TM | TMP102_CONF_EM | TMP102_CONF_CR1) #define TMP102_CONFIG_RD_ONLY (TMP102_CONF_R0 | TMP102_CONF_R1 | TMP102_CONF_AL) +static const struct thermal_zone_of_device_ops tmp102_of_thermal_ops = { + .get_temp = tmp102_read_temp, +}; + static int tmp102_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -215,7 +219,7 @@ static int tmp102_probe(struct i2c_client *client, } tmp102->hwmon_dev = hwmon_dev; tmp102->tz = thermal_zone_of_sensor_register(hwmon_dev, 0, hwmon_dev, - tmp102_read_temp, NULL); + &tmp102_of_thermal_ops); if (IS_ERR(tmp102->tz)) tmp102->tz = NULL; diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index c1351d9fb35b..31e8308ba899 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -753,6 +753,7 @@ config I2C_SH7760 config I2C_SH_MOBILE tristate "SuperH Mobile I2C Controller" + depends on HAS_DMA depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST help If you say yes to this option, support will be included for the @@ -1072,4 +1073,15 @@ config SCx200_ACB This support is also available as a module. If so, the module will be called scx200_acb. +config I2C_OPAL + tristate "IBM OPAL I2C driver" + depends on PPC_POWERNV + default y + help + This exposes the PowerNV platform i2c busses to the linux i2c layer, + the driver is based on the OPAL interfaces. + + This driver can also be built as a module. If so, the module will be + called as i2c-opal. + endmenu diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 5e6c8223719e..56388f658d2f 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -102,6 +102,7 @@ obj-$(CONFIG_I2C_ACORN) += i2c-acorn.o obj-$(CONFIG_I2C_BCM_KONA) += i2c-bcm-kona.o obj-$(CONFIG_I2C_CROS_EC_TUNNEL) += i2c-cros-ec-tunnel.o obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o +obj-$(CONFIG_I2C_OPAL) += i2c-opal.o obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o obj-$(CONFIG_SCx200_ACB) += scx200_acb.o diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index 373f6d4e4080..30059c1df2a3 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -30,12 +30,12 @@ #define MV64XXX_I2C_BAUD_DIV_N(val) (val & 0x7) #define MV64XXX_I2C_BAUD_DIV_M(val) ((val & 0xf) << 3) -#define MV64XXX_I2C_REG_CONTROL_ACK 0x00000004 -#define MV64XXX_I2C_REG_CONTROL_IFLG 0x00000008 -#define MV64XXX_I2C_REG_CONTROL_STOP 0x00000010 -#define MV64XXX_I2C_REG_CONTROL_START 0x00000020 -#define MV64XXX_I2C_REG_CONTROL_TWSIEN 0x00000040 -#define MV64XXX_I2C_REG_CONTROL_INTEN 0x00000080 +#define MV64XXX_I2C_REG_CONTROL_ACK BIT(2) +#define MV64XXX_I2C_REG_CONTROL_IFLG BIT(3) +#define MV64XXX_I2C_REG_CONTROL_STOP BIT(4) +#define MV64XXX_I2C_REG_CONTROL_START BIT(5) +#define MV64XXX_I2C_REG_CONTROL_TWSIEN BIT(6) +#define MV64XXX_I2C_REG_CONTROL_INTEN BIT(7) /* Ctlr status values */ #define MV64XXX_I2C_STATUS_BUS_ERR 0x00 @@ -68,19 +68,17 @@ #define MV64XXX_I2C_REG_BRIDGE_TIMING 0xe0 /* Bridge Control values */ -#define MV64XXX_I2C_BRIDGE_CONTROL_WR 0x00000001 -#define MV64XXX_I2C_BRIDGE_CONTROL_RD 0x00000002 +#define MV64XXX_I2C_BRIDGE_CONTROL_WR BIT(0) +#define MV64XXX_I2C_BRIDGE_CONTROL_RD BIT(1) #define MV64XXX_I2C_BRIDGE_CONTROL_ADDR_SHIFT 2 -#define MV64XXX_I2C_BRIDGE_CONTROL_ADDR_EXT 0x00001000 +#define MV64XXX_I2C_BRIDGE_CONTROL_ADDR_EXT BIT(12) #define MV64XXX_I2C_BRIDGE_CONTROL_TX_SIZE_SHIFT 13 #define MV64XXX_I2C_BRIDGE_CONTROL_RX_SIZE_SHIFT 16 -#define MV64XXX_I2C_BRIDGE_CONTROL_ENABLE 0x00080000 +#define MV64XXX_I2C_BRIDGE_CONTROL_ENABLE BIT(19) +#define MV64XXX_I2C_BRIDGE_CONTROL_REPEATED_START BIT(20) /* Bridge Status values */ -#define MV64XXX_I2C_BRIDGE_STATUS_ERROR 0x00000001 -#define MV64XXX_I2C_STATUS_OFFLOAD_ERROR 0xf0000001 -#define MV64XXX_I2C_STATUS_OFFLOAD_OK 0xf0000000 - +#define MV64XXX_I2C_BRIDGE_STATUS_ERROR BIT(0) /* Driver states */ enum { @@ -99,14 +97,12 @@ enum { MV64XXX_I2C_ACTION_INVALID, MV64XXX_I2C_ACTION_CONTINUE, MV64XXX_I2C_ACTION_SEND_RESTART, - MV64XXX_I2C_ACTION_OFFLOAD_RESTART, MV64XXX_I2C_ACTION_SEND_ADDR_1, MV64XXX_I2C_ACTION_SEND_ADDR_2, MV64XXX_I2C_ACTION_SEND_DATA, MV64XXX_I2C_ACTION_RCV_DATA, MV64XXX_I2C_ACTION_RCV_DATA_STOP, MV64XXX_I2C_ACTION_SEND_STOP, - MV64XXX_I2C_ACTION_OFFLOAD_SEND_STOP, }; struct mv64xxx_i2c_regs { @@ -193,75 +189,6 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data, } } -static int mv64xxx_i2c_offload_msg(struct mv64xxx_i2c_data *drv_data) -{ - unsigned long data_reg_hi = 0; - unsigned long data_reg_lo = 0; - unsigned long ctrl_reg; - struct i2c_msg *msg = drv_data->msgs; - - if (!drv_data->offload_enabled) - return -EOPNOTSUPP; - - /* Only regular transactions can be offloaded */ - if ((msg->flags & ~(I2C_M_TEN | I2C_M_RD)) != 0) - return -EINVAL; - - /* Only 1-8 byte transfers can be offloaded */ - if (msg->len < 1 || msg->len > 8) - return -EINVAL; - - /* Build transaction */ - ctrl_reg = MV64XXX_I2C_BRIDGE_CONTROL_ENABLE | - (msg->addr << MV64XXX_I2C_BRIDGE_CONTROL_ADDR_SHIFT); - - if ((msg->flags & I2C_M_TEN) != 0) - ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_ADDR_EXT; - - if ((msg->flags & I2C_M_RD) == 0) { - u8 local_buf[8] = { 0 }; - - memcpy(local_buf, msg->buf, msg->len); - data_reg_lo = cpu_to_le32(*((u32 *)local_buf)); - data_reg_hi = cpu_to_le32(*((u32 *)(local_buf+4))); - - ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_WR | - (msg->len - 1) << MV64XXX_I2C_BRIDGE_CONTROL_TX_SIZE_SHIFT; - - writel(data_reg_lo, - drv_data->reg_base + MV64XXX_I2C_REG_TX_DATA_LO); - writel(data_reg_hi, - drv_data->reg_base + MV64XXX_I2C_REG_TX_DATA_HI); - - } else { - ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_RD | - (msg->len - 1) << MV64XXX_I2C_BRIDGE_CONTROL_RX_SIZE_SHIFT; - } - - /* Execute transaction */ - writel(ctrl_reg, drv_data->reg_base + MV64XXX_I2C_REG_BRIDGE_CONTROL); - - return 0; -} - -static void -mv64xxx_i2c_update_offload_data(struct mv64xxx_i2c_data *drv_data) -{ - struct i2c_msg *msg = drv_data->msg; - - if (msg->flags & I2C_M_RD) { - u32 data_reg_lo = readl(drv_data->reg_base + - MV64XXX_I2C_REG_RX_DATA_LO); - u32 data_reg_hi = readl(drv_data->reg_base + - MV64XXX_I2C_REG_RX_DATA_HI); - u8 local_buf[8] = { 0 }; - - *((u32 *)local_buf) = le32_to_cpu(data_reg_lo); - *((u32 *)(local_buf+4)) = le32_to_cpu(data_reg_hi); - memcpy(msg->buf, local_buf, msg->len); - } - -} /* ***************************************************************************** * @@ -389,16 +316,6 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status) drv_data->rc = -ENXIO; break; - case MV64XXX_I2C_STATUS_OFFLOAD_OK: - if (drv_data->send_stop || drv_data->aborting) { - drv_data->action = MV64XXX_I2C_ACTION_OFFLOAD_SEND_STOP; - drv_data->state = MV64XXX_I2C_STATE_IDLE; - } else { - drv_data->action = MV64XXX_I2C_ACTION_OFFLOAD_RESTART; - drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_RESTART; - } - break; - default: dev_err(&drv_data->adapter.dev, "mv64xxx_i2c_fsm: Ctlr Error -- state: 0x%x, " @@ -419,25 +336,15 @@ static void mv64xxx_i2c_send_start(struct mv64xxx_i2c_data *drv_data) drv_data->aborting = 0; drv_data->rc = 0; - /* Can we offload this msg ? */ - if (mv64xxx_i2c_offload_msg(drv_data) < 0) { - /* No, switch to standard path */ - mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs); - writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START, - drv_data->reg_base + drv_data->reg_offsets.control); - } + mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs); + writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START, + drv_data->reg_base + drv_data->reg_offsets.control); } static void mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) { switch(drv_data->action) { - case MV64XXX_I2C_ACTION_OFFLOAD_RESTART: - mv64xxx_i2c_update_offload_data(drv_data); - writel(0, drv_data->reg_base + MV64XXX_I2C_REG_BRIDGE_CONTROL); - writel(0, drv_data->reg_base + - MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE); - /* FALLTHRU */ case MV64XXX_I2C_ACTION_SEND_RESTART: /* We should only get here if we have further messages */ BUG_ON(drv_data->num_msgs == 0); @@ -518,16 +425,71 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) drv_data->block = 0; wake_up(&drv_data->waitq); break; + } +} - case MV64XXX_I2C_ACTION_OFFLOAD_SEND_STOP: - mv64xxx_i2c_update_offload_data(drv_data); - writel(0, drv_data->reg_base + MV64XXX_I2C_REG_BRIDGE_CONTROL); - writel(0, drv_data->reg_base + - MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE); - drv_data->block = 0; - wake_up(&drv_data->waitq); - break; +static void +mv64xxx_i2c_read_offload_rx_data(struct mv64xxx_i2c_data *drv_data, + struct i2c_msg *msg) +{ + u32 buf[2]; + + buf[0] = readl(drv_data->reg_base + MV64XXX_I2C_REG_RX_DATA_LO); + buf[1] = readl(drv_data->reg_base + MV64XXX_I2C_REG_RX_DATA_HI); + + memcpy(msg->buf, buf, msg->len); +} + +static int +mv64xxx_i2c_intr_offload(struct mv64xxx_i2c_data *drv_data) +{ + u32 cause, status; + + cause = readl(drv_data->reg_base + + MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE); + if (!cause) + return IRQ_NONE; + + status = readl(drv_data->reg_base + + MV64XXX_I2C_REG_BRIDGE_STATUS); + + if (status & MV64XXX_I2C_BRIDGE_STATUS_ERROR) { + drv_data->rc = -EIO; + goto out; + } + + drv_data->rc = 0; + + /* + * Transaction is a one message read transaction, read data + * for this message. + */ + if (drv_data->num_msgs == 1 && drv_data->msgs[0].flags & I2C_M_RD) { + mv64xxx_i2c_read_offload_rx_data(drv_data, drv_data->msgs); + drv_data->msgs++; + drv_data->num_msgs--; + } + /* + * Transaction is a two messages write/read transaction, read + * data for the second (read) message. + */ + else if (drv_data->num_msgs == 2 && + !(drv_data->msgs[0].flags & I2C_M_RD) && + drv_data->msgs[1].flags & I2C_M_RD) { + mv64xxx_i2c_read_offload_rx_data(drv_data, drv_data->msgs + 1); + drv_data->msgs += 2; + drv_data->num_msgs -= 2; } + +out: + writel(0, drv_data->reg_base + MV64XXX_I2C_REG_BRIDGE_CONTROL); + writel(0, drv_data->reg_base + + MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE); + drv_data->block = 0; + + wake_up(&drv_data->waitq); + + return IRQ_HANDLED; } static irqreturn_t @@ -540,20 +502,9 @@ mv64xxx_i2c_intr(int irq, void *dev_id) spin_lock_irqsave(&drv_data->lock, flags); - if (drv_data->offload_enabled) { - while (readl(drv_data->reg_base + - MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE)) { - int reg_status = readl(drv_data->reg_base + - MV64XXX_I2C_REG_BRIDGE_STATUS); - if (reg_status & MV64XXX_I2C_BRIDGE_STATUS_ERROR) - status = MV64XXX_I2C_STATUS_OFFLOAD_ERROR; - else - status = MV64XXX_I2C_STATUS_OFFLOAD_OK; - mv64xxx_i2c_fsm(drv_data, status); - mv64xxx_i2c_do_action(drv_data); - rc = IRQ_HANDLED; - } - } + if (drv_data->offload_enabled) + rc = mv64xxx_i2c_intr_offload(drv_data); + while (readl(drv_data->reg_base + drv_data->reg_offsets.control) & MV64XXX_I2C_REG_CONTROL_IFLG) { status = readl(drv_data->reg_base + drv_data->reg_offsets.status); @@ -635,6 +586,117 @@ mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg, return drv_data->rc; } +static void +mv64xxx_i2c_prepare_tx(struct mv64xxx_i2c_data *drv_data) +{ + struct i2c_msg *msg = drv_data->msgs; + u32 buf[2]; + + memcpy(buf, msg->buf, msg->len); + + writel(buf[0], drv_data->reg_base + MV64XXX_I2C_REG_TX_DATA_LO); + writel(buf[1], drv_data->reg_base + MV64XXX_I2C_REG_TX_DATA_HI); +} + +static int +mv64xxx_i2c_offload_xfer(struct mv64xxx_i2c_data *drv_data) +{ + struct i2c_msg *msgs = drv_data->msgs; + int num = drv_data->num_msgs; + unsigned long ctrl_reg; + unsigned long flags; + + spin_lock_irqsave(&drv_data->lock, flags); + + /* Build transaction */ + ctrl_reg = MV64XXX_I2C_BRIDGE_CONTROL_ENABLE | + (msgs[0].addr << MV64XXX_I2C_BRIDGE_CONTROL_ADDR_SHIFT); + + if (msgs[0].flags & I2C_M_TEN) + ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_ADDR_EXT; + + /* Single write message transaction */ + if (num == 1 && !(msgs[0].flags & I2C_M_RD)) { + size_t len = msgs[0].len - 1; + + ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_WR | + (len << MV64XXX_I2C_BRIDGE_CONTROL_TX_SIZE_SHIFT); + mv64xxx_i2c_prepare_tx(drv_data); + } + /* Single read message transaction */ + else if (num == 1 && msgs[0].flags & I2C_M_RD) { + size_t len = msgs[0].len - 1; + + ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_RD | + (len << MV64XXX_I2C_BRIDGE_CONTROL_RX_SIZE_SHIFT); + } + /* + * Transaction with one write and one read message. This is + * guaranteed by the mv64xx_i2c_can_offload() checks. + */ + else if (num == 2) { + size_t lentx = msgs[0].len - 1; + size_t lenrx = msgs[1].len - 1; + + ctrl_reg |= + MV64XXX_I2C_BRIDGE_CONTROL_RD | + MV64XXX_I2C_BRIDGE_CONTROL_WR | + (lentx << MV64XXX_I2C_BRIDGE_CONTROL_TX_SIZE_SHIFT) | + (lenrx << MV64XXX_I2C_BRIDGE_CONTROL_RX_SIZE_SHIFT) | + MV64XXX_I2C_BRIDGE_CONTROL_REPEATED_START; + mv64xxx_i2c_prepare_tx(drv_data); + } + + /* Execute transaction */ + drv_data->block = 1; + writel(ctrl_reg, drv_data->reg_base + MV64XXX_I2C_REG_BRIDGE_CONTROL); + spin_unlock_irqrestore(&drv_data->lock, flags); + + mv64xxx_i2c_wait_for_completion(drv_data); + + return drv_data->rc; +} + +static bool +mv64xxx_i2c_valid_offload_sz(struct i2c_msg *msg) +{ + return msg->len <= 8 && msg->len >= 1; +} + +static bool +mv64xxx_i2c_can_offload(struct mv64xxx_i2c_data *drv_data) +{ + struct i2c_msg *msgs = drv_data->msgs; + int num = drv_data->num_msgs; + + return false; + + if (!drv_data->offload_enabled) + return false; + + /* + * We can offload a transaction consisting of a single + * message, as long as the message has a length between 1 and + * 8 bytes. + */ + if (num == 1 && mv64xxx_i2c_valid_offload_sz(msgs)) + return true; + + /* + * We can offload a transaction consisting of two messages, if + * the first is a write and a second is a read, and both have + * a length between 1 and 8 bytes. + */ + if (num == 2 && + mv64xxx_i2c_valid_offload_sz(msgs) && + mv64xxx_i2c_valid_offload_sz(msgs + 1) && + !(msgs[0].flags & I2C_M_RD) && + msgs[1].flags & I2C_M_RD) + return true; + + return false; +} + /* ***************************************************************************** * @@ -658,7 +720,11 @@ mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) drv_data->msgs = msgs; drv_data->num_msgs = num; - rc = mv64xxx_i2c_execute_msg(drv_data, &msgs[0], num == 1); + if (mv64xxx_i2c_can_offload(drv_data)) + rc = mv64xxx_i2c_offload_xfer(drv_data); + else + rc = mv64xxx_i2c_execute_msg(drv_data, &msgs[0], num == 1); + if (rc < 0) ret = rc; diff --git a/drivers/i2c/busses/i2c-opal.c b/drivers/i2c/busses/i2c-opal.c new file mode 100644 index 000000000000..16f90b1a7508 --- /dev/null +++ b/drivers/i2c/busses/i2c-opal.c @@ -0,0 +1,294 @@ +/* + * IBM OPAL I2C driver + * Copyright (C) 2014 IBM + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. + */ + +#include <linux/device.h> +#include <linux/i2c.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/slab.h> + +#include <asm/firmware.h> +#include <asm/opal.h> + +static int i2c_opal_translate_error(int rc) +{ + switch (rc) { + case OPAL_NO_MEM: + return -ENOMEM; + case OPAL_PARAMETER: + return -EINVAL; + case OPAL_I2C_ARBT_LOST: + return -EAGAIN; + case OPAL_I2C_TIMEOUT: + return -ETIMEDOUT; + case OPAL_I2C_NACK_RCVD: + return -ENXIO; + case OPAL_I2C_STOP_ERR: + return -EBUSY; + default: + return -EIO; + } +} + +static int i2c_opal_send_request(u32 bus_id, struct opal_i2c_request *req) +{ + struct opal_msg msg; + int token, rc; + + token = opal_async_get_token_interruptible(); + if (token < 0) { + if (token != -ERESTARTSYS) + pr_err("Failed to get the async token\n"); + + return token; + } + + rc = opal_i2c_request(token, bus_id, req); + if (rc != OPAL_ASYNC_COMPLETION) { + rc = i2c_opal_translate_error(rc); + goto exit; + } + + rc = opal_async_wait_response(token, &msg); + if (rc) + goto exit; + + rc = be64_to_cpu(msg.params[1]); + if (rc != OPAL_SUCCESS) { + rc = i2c_opal_translate_error(rc); + goto exit; + } + +exit: + opal_async_release_token(token); + return rc; +} + +static int i2c_opal_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, + int num) +{ + unsigned long opal_id = (unsigned long)adap->algo_data; + struct opal_i2c_request req; + int rc, i; + + /* We only support fairly simple combinations here of one + * or two messages + */ + memset(&req, 0, sizeof(req)); + switch(num) { + case 0: + return 0; + case 1: + req.type = (msgs[0].flags & I2C_M_RD) ? + OPAL_I2C_RAW_READ : OPAL_I2C_RAW_WRITE; + req.addr = cpu_to_be16(msgs[0].addr); + req.size = cpu_to_be32(msgs[0].len); + req.buffer_ra = cpu_to_be64(__pa(msgs[0].buf)); + break; + case 2: + /* For two messages, we basically support only simple + * smbus transactions of a write plus a read. We might + * want to allow also two writes but we'd have to bounce + * the data into a single buffer. + */ + if ((msgs[0].flags & I2C_M_RD) || !(msgs[1].flags & I2C_M_RD)) + return -EOPNOTSUPP; + if (msgs[0].len > 4) + return -EOPNOTSUPP; + if (msgs[0].addr != msgs[1].addr) + return -EOPNOTSUPP; + req.type = OPAL_I2C_SM_READ; + req.addr = cpu_to_be16(msgs[0].addr); + req.subaddr_sz = msgs[0].len; + for (i = 0; i < msgs[0].len; i++) + req.subaddr = (req.subaddr << 8) | msgs[0].buf[i]; + req.subaddr = cpu_to_be32(req.subaddr); + req.size = cpu_to_be32(msgs[1].len); + req.buffer_ra = cpu_to_be64(__pa(msgs[1].buf)); + break; + default: + return -EOPNOTSUPP; + } + + rc = i2c_opal_send_request(opal_id, &req); + if (rc) + return rc; + + return num; +} + +static int i2c_opal_smbus_xfer(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, union i2c_smbus_data *data) +{ + unsigned long opal_id = (unsigned long)adap->algo_data; + struct opal_i2c_request req; + u8 local[2]; + int rc; + + memset(&req, 0, sizeof(req)); + + req.addr = cpu_to_be16(addr); + switch (size) { + case I2C_SMBUS_BYTE: + req.buffer_ra = cpu_to_be64(__pa(&data->byte)); + req.size = cpu_to_be32(1); + /* Fall through */ + case I2C_SMBUS_QUICK: + req.type = (read_write == I2C_SMBUS_READ) ? + OPAL_I2C_RAW_READ : OPAL_I2C_RAW_WRITE; + break; + case I2C_SMBUS_BYTE_DATA: + req.buffer_ra = cpu_to_be64(__pa(&data->byte)); + req.size = cpu_to_be32(1); + req.subaddr = cpu_to_be32(command); + req.subaddr_sz = 1; + req.type = (read_write == I2C_SMBUS_READ) ? + OPAL_I2C_SM_READ : OPAL_I2C_SM_WRITE; + break; + case I2C_SMBUS_WORD_DATA: + if (!read_write) { + local[0] = data->word & 0xff; + local[1] = (data->word >> 8) & 0xff; + } + req.buffer_ra = cpu_to_be64(__pa(local)); + req.size = cpu_to_be32(2); + req.subaddr = cpu_to_be32(command); + req.subaddr_sz = 1; + req.type = (read_write == I2C_SMBUS_READ) ? + OPAL_I2C_SM_READ : OPAL_I2C_SM_WRITE; + break; + case I2C_SMBUS_I2C_BLOCK_DATA: + req.buffer_ra = cpu_to_be64(__pa(&data->block[1])); + req.size = cpu_to_be32(data->block[0]); + req.subaddr = cpu_to_be32(command); + req.subaddr_sz = 1; + req.type = (read_write == I2C_SMBUS_READ) ? + OPAL_I2C_SM_READ : OPAL_I2C_SM_WRITE; + break; + default: + return -EINVAL; + } + + rc = i2c_opal_send_request(opal_id, &req); + if (!rc && read_write && size == I2C_SMBUS_WORD_DATA) { + data->word = ((u16)local[1]) << 8; + data->word |= local[0]; + } + + return rc; +} + +static u32 i2c_opal_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK; +} + +static const struct i2c_algorithm i2c_opal_algo = { + .master_xfer = i2c_opal_master_xfer, + .smbus_xfer = i2c_opal_smbus_xfer, + .functionality = i2c_opal_func, +}; + +static int i2c_opal_probe(struct platform_device *pdev) +{ + struct i2c_adapter *adapter; + const char *pname; + u32 opal_id; + int rc; + + if (!pdev->dev.of_node) + return -ENODEV; + + rc = of_property_read_u32(pdev->dev.of_node, "ibm,opal-id", &opal_id); + if (rc) { + dev_err(&pdev->dev, "Missing ibm,opal-id property !\n"); + return -EIO; + } + + adapter = devm_kzalloc(&pdev->dev, sizeof(*adapter), GFP_KERNEL); + if (!adapter) + return -ENOMEM; + + adapter->algo = &i2c_opal_algo; + adapter->algo_data = (void *)(unsigned long)opal_id; + adapter->dev.parent = &pdev->dev; + adapter->dev.of_node = of_node_get(pdev->dev.of_node); + pname = of_get_property(pdev->dev.of_node, "ibm,port-name", NULL); + if (pname) + strlcpy(adapter->name, pname, sizeof(adapter->name)); + else + strlcpy(adapter->name, "opal", sizeof(adapter->name)); + + platform_set_drvdata(pdev, adapter); + rc = i2c_add_adapter(adapter); + if (rc) + dev_err(&pdev->dev, "Failed to register the i2c adapter\n"); + + return rc; +} + +static int i2c_opal_remove(struct platform_device *pdev) +{ + struct i2c_adapter *adapter = platform_get_drvdata(pdev); + + i2c_del_adapter(adapter); + + return 0; +} + +static const struct of_device_id i2c_opal_of_match[] = { + { + .compatible = "ibm,opal-i2c", + }, + { } +}; +MODULE_DEVICE_TABLE(of, i2c_opal_of_match); + +static struct platform_driver i2c_opal_driver = { + .probe = i2c_opal_probe, + .remove = i2c_opal_remove, + .driver = { + .name = "i2c-opal", + .of_match_table = i2c_opal_of_match, + }, +}; + +static int __init i2c_opal_init(void) +{ + if (!firmware_has_feature(FW_FEATURE_OPAL)) + return -ENODEV; + + return platform_driver_register(&i2c_opal_driver); +} +module_init(i2c_opal_init); + +static void __exit i2c_opal_exit(void) +{ + return platform_driver_unregister(&i2c_opal_driver); +} +module_exit(i2c_opal_exit); + +MODULE_AUTHOR("Neelesh Gupta <neelegup@linux.vnet.ibm.com>"); +MODULE_DESCRIPTION("IBM OPAL I2C driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index d7efaf44868b..440d5dbc8b5f 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c @@ -140,6 +140,7 @@ struct sh_mobile_i2c_data { int sr; bool send_stop; + struct resource *res; struct dma_chan *dma_tx; struct dma_chan *dma_rx; struct scatterlist sg; @@ -539,6 +540,42 @@ static void sh_mobile_i2c_dma_callback(void *data) iic_set_clr(pd, ICIC, 0, ICIC_TDMAE | ICIC_RDMAE); } +static struct dma_chan *sh_mobile_i2c_request_dma_chan(struct device *dev, + enum dma_transfer_direction dir, dma_addr_t port_addr) +{ + struct dma_chan *chan; + struct dma_slave_config cfg; + char *chan_name = dir == DMA_MEM_TO_DEV ? "tx" : "rx"; + int ret; + + chan = dma_request_slave_channel_reason(dev, chan_name); + if (IS_ERR(chan)) { + ret = PTR_ERR(chan); + dev_dbg(dev, "request_channel failed for %s (%d)\n", chan_name, ret); + return chan; + } + + memset(&cfg, 0, sizeof(cfg)); + cfg.direction = dir; + if (dir == DMA_MEM_TO_DEV) { + cfg.dst_addr = port_addr; + cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + } else { + cfg.src_addr = port_addr; + cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + } + + ret = dmaengine_slave_config(chan, &cfg); + if (ret) { + dev_dbg(dev, "slave_config failed for %s (%d)\n", chan_name, ret); + dma_release_channel(chan); + return ERR_PTR(ret); + } + + dev_dbg(dev, "got DMA channel for %s\n", chan_name); + return chan; +} + static void sh_mobile_i2c_xfer_dma(struct sh_mobile_i2c_data *pd) { bool read = pd->msg->flags & I2C_M_RD; @@ -548,7 +585,16 @@ static void sh_mobile_i2c_xfer_dma(struct sh_mobile_i2c_data *pd) dma_addr_t dma_addr; dma_cookie_t cookie; - if (!chan) + if (PTR_ERR(chan) == -EPROBE_DEFER) { + if (read) + chan = pd->dma_rx = sh_mobile_i2c_request_dma_chan(pd->dev, DMA_DEV_TO_MEM, + pd->res->start + ICDR); + else + chan = pd->dma_tx = sh_mobile_i2c_request_dma_chan(pd->dev, DMA_MEM_TO_DEV, + pd->res->start + ICDR); + } + + if (IS_ERR(chan)) return; dma_addr = dma_map_single(chan->device->dev, pd->msg->buf, pd->msg->len, dir); @@ -747,56 +793,16 @@ static const struct of_device_id sh_mobile_i2c_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, sh_mobile_i2c_dt_ids); -static int sh_mobile_i2c_request_dma_chan(struct device *dev, enum dma_transfer_direction dir, - dma_addr_t port_addr, struct dma_chan **chan_ptr) -{ - struct dma_chan *chan; - struct dma_slave_config cfg; - char *chan_name = dir == DMA_MEM_TO_DEV ? "tx" : "rx"; - int ret; - - *chan_ptr = NULL; - - chan = dma_request_slave_channel_reason(dev, chan_name); - if (IS_ERR(chan)) { - ret = PTR_ERR(chan); - dev_dbg(dev, "request_channel failed for %s (%d)\n", chan_name, ret); - return ret; - } - - memset(&cfg, 0, sizeof(cfg)); - cfg.direction = dir; - if (dir == DMA_MEM_TO_DEV) { - cfg.dst_addr = port_addr; - cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; - } else { - cfg.src_addr = port_addr; - cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; - } - - ret = dmaengine_slave_config(chan, &cfg); - if (ret) { - dev_dbg(dev, "slave_config failed for %s (%d)\n", chan_name, ret); - dma_release_channel(chan); - return ret; - } - - *chan_ptr = chan; - - dev_dbg(dev, "got DMA channel for %s\n", chan_name); - return 0; -} - static void sh_mobile_i2c_release_dma(struct sh_mobile_i2c_data *pd) { - if (pd->dma_tx) { + if (!IS_ERR(pd->dma_tx)) { dma_release_channel(pd->dma_tx); - pd->dma_tx = NULL; + pd->dma_tx = ERR_PTR(-EPROBE_DEFER); } - if (pd->dma_rx) { + if (!IS_ERR(pd->dma_rx)) { dma_release_channel(pd->dma_rx); - pd->dma_rx = NULL; + pd->dma_rx = ERR_PTR(-EPROBE_DEFER); } } @@ -849,6 +855,7 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) res = platform_get_resource(dev, IORESOURCE_MEM, 0); + pd->res = res; pd->reg = devm_ioremap_resource(&dev->dev, res); if (IS_ERR(pd->reg)) return PTR_ERR(pd->reg); @@ -889,17 +896,7 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) /* Init DMA */ sg_init_table(&pd->sg, 1); pd->dma_direction = DMA_NONE; - ret = sh_mobile_i2c_request_dma_chan(pd->dev, DMA_DEV_TO_MEM, - res->start + ICDR, &pd->dma_rx); - if (ret == -EPROBE_DEFER) - return ret; - - ret = sh_mobile_i2c_request_dma_chan(pd->dev, DMA_MEM_TO_DEV, - res->start + ICDR, &pd->dma_tx); - if (ret == -EPROBE_DEFER) { - sh_mobile_i2c_release_dma(pd); - return ret; - } + pd->dma_rx = pd->dma_tx = ERR_PTR(-EPROBE_DEFER); /* Enable Runtime PM for this device. * @@ -937,8 +934,7 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) return ret; } - dev_info(&dev->dev, "I2C adapter %d, bus speed %lu Hz, DMA=%c\n", - adap->nr, pd->bus_speed, (pd->dma_rx || pd->dma_tx) ? 'y' : 'n'); + dev_info(&dev->dev, "I2C adapter %d, bus speed %lu Hz\n", adap->nr, pd->bus_speed); return 0; } diff --git a/drivers/iio/accel/st_accel.h b/drivers/iio/accel/st_accel.h index c3877630b2e4..fa9646034305 100644 --- a/drivers/iio/accel/st_accel.h +++ b/drivers/iio/accel/st_accel.h @@ -33,8 +33,7 @@ static const struct st_sensors_platform_data default_accel_pdata = { .drdy_int_pin = 1, }; -int st_accel_common_probe(struct iio_dev *indio_dev, - struct st_sensors_platform_data *pdata); +int st_accel_common_probe(struct iio_dev *indio_dev); void st_accel_common_remove(struct iio_dev *indio_dev); #ifdef CONFIG_IIO_BUFFER diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index 087864854c61..53f32629283a 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c @@ -161,7 +161,7 @@ static const struct iio_chan_spec st_accel_16bit_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(3) }; -static const struct st_sensors st_accel_sensors[] = { +static const struct st_sensor_settings st_accel_sensors_settings[] = { { .wai = ST_ACCEL_1_WAI_EXP, .sensors_supported = { @@ -457,8 +457,7 @@ static const struct iio_trigger_ops st_accel_trigger_ops = { #define ST_ACCEL_TRIGGER_OPS NULL #endif -int st_accel_common_probe(struct iio_dev *indio_dev, - struct st_sensors_platform_data *plat_data) +int st_accel_common_probe(struct iio_dev *indio_dev) { struct st_sensor_data *adata = iio_priv(indio_dev); int irq = adata->get_irq_data_ready(indio_dev); @@ -470,24 +469,25 @@ int st_accel_common_probe(struct iio_dev *indio_dev, st_sensors_power_enable(indio_dev); err = st_sensors_check_device_support(indio_dev, - ARRAY_SIZE(st_accel_sensors), st_accel_sensors); + ARRAY_SIZE(st_accel_sensors_settings), + st_accel_sensors_settings); if (err < 0) return err; adata->num_data_channels = ST_ACCEL_NUMBER_DATA_CHANNELS; - adata->multiread_bit = adata->sensor->multi_read_bit; - indio_dev->channels = adata->sensor->ch; + adata->multiread_bit = adata->sensor_settings->multi_read_bit; + indio_dev->channels = adata->sensor_settings->ch; indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS; adata->current_fullscale = (struct st_sensor_fullscale_avl *) - &adata->sensor->fs.fs_avl[0]; - adata->odr = adata->sensor->odr.odr_avl[0].hz; + &adata->sensor_settings->fs.fs_avl[0]; + adata->odr = adata->sensor_settings->odr.odr_avl[0].hz; - if (!plat_data) - plat_data = + if (!adata->dev->platform_data) + adata->dev->platform_data = (struct st_sensors_platform_data *)&default_accel_pdata; - err = st_sensors_init_sensor(indio_dev, plat_data); + err = st_sensors_init_sensor(indio_dev, adata->dev->platform_data); if (err < 0) return err; diff --git a/drivers/iio/accel/st_accel_i2c.c b/drivers/iio/accel/st_accel_i2c.c index 7164aeff3ab1..c7246bdd30b9 100644 --- a/drivers/iio/accel/st_accel_i2c.c +++ b/drivers/iio/accel/st_accel_i2c.c @@ -79,12 +79,11 @@ static int st_accel_i2c_probe(struct i2c_client *client, return -ENOMEM; adata = iio_priv(indio_dev); - adata->dev = &client->dev; st_sensors_of_i2c_probe(client, st_accel_of_match); st_sensors_i2c_configure(indio_dev, client, adata); - err = st_accel_common_probe(indio_dev, client->dev.platform_data); + err = st_accel_common_probe(indio_dev); if (err < 0) return err; diff --git a/drivers/iio/accel/st_accel_spi.c b/drivers/iio/accel/st_accel_spi.c index 195639646e34..12ec29389e4b 100644 --- a/drivers/iio/accel/st_accel_spi.c +++ b/drivers/iio/accel/st_accel_spi.c @@ -29,11 +29,10 @@ static int st_accel_spi_probe(struct spi_device *spi) return -ENOMEM; adata = iio_priv(indio_dev); - adata->dev = &spi->dev; st_sensors_spi_configure(indio_dev, spi, adata); - err = st_accel_common_probe(indio_dev, spi->dev.platform_data); + err = st_accel_common_probe(indio_dev); if (err < 0) return err; diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index bc4e787096e8..0f79e4725763 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -214,6 +214,20 @@ config NAU7802 To compile this driver as a module, choose M here: the module will be called nau7802. +config QCOM_SPMI_IADC + tristate "Qualcomm SPMI PMIC current ADC" + depends on SPMI + select REGMAP_SPMI + help + This is the IIO Current ADC driver for Qualcomm QPNP IADC Chip. + + The driver supports single mode operation to read from one of two + channels (external or internal). Hardware have additional + channels internally used for gain and offset calibration. + + To compile this driver as a module, choose M here: the module will + be called qcom-spmi-iadc. + config ROCKCHIP_SARADC tristate "Rockchip SARADC driver" depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST) diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index f30093f5b67a..701fdb7c96aa 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_MCP320X) += mcp320x.o obj-$(CONFIG_MCP3422) += mcp3422.o obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o obj-$(CONFIG_NAU7802) += nau7802.o +obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o diff --git a/drivers/iio/adc/ad799x.c b/drivers/iio/adc/ad799x.c index e37412da15f5..b99de00e57b8 100644 --- a/drivers/iio/adc/ad799x.c +++ b/drivers/iio/adc/ad799x.c @@ -143,9 +143,15 @@ static int ad799x_write_config(struct ad799x_state *st, u16 val) case ad7998: return i2c_smbus_write_word_swapped(st->client, AD7998_CONF_REG, val); - default: + case ad7992: + case ad7993: + case ad7994: return i2c_smbus_write_byte_data(st->client, AD7998_CONF_REG, val); + default: + /* Will be written when doing a conversion */ + st->config = val; + return 0; } } @@ -155,8 +161,13 @@ static int ad799x_read_config(struct ad799x_state *st) case ad7997: case ad7998: return i2c_smbus_read_word_swapped(st->client, AD7998_CONF_REG); - default: + case ad7992: + case ad7993: + case ad7994: return i2c_smbus_read_byte_data(st->client, AD7998_CONF_REG); + default: + /* No readback support */ + return st->config; } } diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c index 43620fd4c66a..3a2dbb3b4926 100644 --- a/drivers/iio/adc/exynos_adc.c +++ b/drivers/iio/adc/exynos_adc.c @@ -39,6 +39,8 @@ #include <linux/iio/iio.h> #include <linux/iio/machine.h> #include <linux/iio/driver.h> +#include <linux/mfd/syscon.h> +#include <linux/regmap.h> /* S3C/EXYNOS4412/5250 ADC_V1 registers definitions */ #define ADC_V1_CON(x) ((x) + 0x00) @@ -90,11 +92,14 @@ #define EXYNOS_ADC_TIMEOUT (msecs_to_jiffies(100)) +#define EXYNOS_ADCV1_PHY_OFFSET 0x0718 +#define EXYNOS_ADCV2_PHY_OFFSET 0x0720 + struct exynos_adc { struct exynos_adc_data *data; struct device *dev; void __iomem *regs; - void __iomem *enable_reg; + struct regmap *pmu_map; struct clk *clk; struct clk *sclk; unsigned int irq; @@ -110,6 +115,7 @@ struct exynos_adc_data { int num_channels; bool needs_sclk; bool needs_adc_phy; + int phy_offset; u32 mask; void (*init_hw)(struct exynos_adc *info); @@ -183,7 +189,7 @@ static void exynos_adc_v1_init_hw(struct exynos_adc *info) u32 con1; if (info->data->needs_adc_phy) - writel(1, info->enable_reg); + regmap_write(info->pmu_map, info->data->phy_offset, 1); /* set default prescaler values and Enable prescaler */ con1 = ADC_V1_CON_PRSCLV(49) | ADC_V1_CON_PRSCEN; @@ -198,7 +204,7 @@ static void exynos_adc_v1_exit_hw(struct exynos_adc *info) u32 con; if (info->data->needs_adc_phy) - writel(0, info->enable_reg); + regmap_write(info->pmu_map, info->data->phy_offset, 0); con = readl(ADC_V1_CON(info->regs)); con |= ADC_V1_CON_STANDBY; @@ -225,6 +231,7 @@ static const struct exynos_adc_data exynos_adc_v1_data = { .num_channels = MAX_ADC_V1_CHANNELS, .mask = ADC_DATX_MASK, /* 12 bit ADC resolution */ .needs_adc_phy = true, + .phy_offset = EXYNOS_ADCV1_PHY_OFFSET, .init_hw = exynos_adc_v1_init_hw, .exit_hw = exynos_adc_v1_exit_hw, @@ -314,7 +321,7 @@ static void exynos_adc_v2_init_hw(struct exynos_adc *info) u32 con1, con2; if (info->data->needs_adc_phy) - writel(1, info->enable_reg); + regmap_write(info->pmu_map, info->data->phy_offset, 1); con1 = ADC_V2_CON1_SOFT_RESET; writel(con1, ADC_V2_CON1(info->regs)); @@ -332,7 +339,7 @@ static void exynos_adc_v2_exit_hw(struct exynos_adc *info) u32 con; if (info->data->needs_adc_phy) - writel(0, info->enable_reg); + regmap_write(info->pmu_map, info->data->phy_offset, 0); con = readl(ADC_V2_CON1(info->regs)); con &= ~ADC_CON_EN_START; @@ -362,6 +369,7 @@ static const struct exynos_adc_data exynos_adc_v2_data = { .num_channels = MAX_ADC_V2_CHANNELS, .mask = ADC_DATX_MASK, /* 12 bit ADC resolution */ .needs_adc_phy = true, + .phy_offset = EXYNOS_ADCV2_PHY_OFFSET, .init_hw = exynos_adc_v2_init_hw, .exit_hw = exynos_adc_v2_exit_hw, @@ -374,6 +382,7 @@ static const struct exynos_adc_data exynos3250_adc_data = { .mask = ADC_DATX_MASK, /* 12 bit ADC resolution */ .needs_sclk = true, .needs_adc_phy = true, + .phy_offset = EXYNOS_ADCV1_PHY_OFFSET, .init_hw = exynos_adc_v2_init_hw, .exit_hw = exynos_adc_v2_exit_hw, @@ -381,6 +390,35 @@ static const struct exynos_adc_data exynos3250_adc_data = { .start_conv = exynos_adc_v2_start_conv, }; +static void exynos_adc_exynos7_init_hw(struct exynos_adc *info) +{ + u32 con1, con2; + + if (info->data->needs_adc_phy) + regmap_write(info->pmu_map, info->data->phy_offset, 1); + + con1 = ADC_V2_CON1_SOFT_RESET; + writel(con1, ADC_V2_CON1(info->regs)); + + con2 = readl(ADC_V2_CON2(info->regs)); + con2 &= ~ADC_V2_CON2_C_TIME(7); + con2 |= ADC_V2_CON2_C_TIME(0); + writel(con2, ADC_V2_CON2(info->regs)); + + /* Enable interrupts */ + writel(1, ADC_V2_INT_EN(info->regs)); +} + +static const struct exynos_adc_data exynos7_adc_data = { + .num_channels = MAX_ADC_V1_CHANNELS, + .mask = ADC_DATX_MASK, /* 12 bit ADC resolution */ + + .init_hw = exynos_adc_exynos7_init_hw, + .exit_hw = exynos_adc_v2_exit_hw, + .clear_irq = exynos_adc_v2_clear_irq, + .start_conv = exynos_adc_v2_start_conv, +}; + static const struct of_device_id exynos_adc_match[] = { { .compatible = "samsung,s3c2410-adc", @@ -406,6 +444,9 @@ static const struct of_device_id exynos_adc_match[] = { }, { .compatible = "samsung,exynos3250-adc", .data = &exynos3250_adc_data, + }, { + .compatible = "samsung,exynos7-adc", + .data = &exynos7_adc_data, }, {}, }; @@ -558,10 +599,13 @@ static int exynos_adc_probe(struct platform_device *pdev) if (info->data->needs_adc_phy) { - mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); - info->enable_reg = devm_ioremap_resource(&pdev->dev, mem); - if (IS_ERR(info->enable_reg)) - return PTR_ERR(info->enable_reg); + info->pmu_map = syscon_regmap_lookup_by_phandle( + pdev->dev.of_node, + "samsung,syscon-phandle"); + if (IS_ERR(info->pmu_map)) { + dev_err(&pdev->dev, "syscon regmap lookup failed.\n"); + return PTR_ERR(info->pmu_map); + } } irq = platform_get_irq(pdev, 0); diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c index 28a086e48776..efbfd12a4bfd 100644 --- a/drivers/iio/adc/mcp320x.c +++ b/drivers/iio/adc/mcp320x.c @@ -1,9 +1,30 @@ /* * Copyright (C) 2013 Oskar Andero <oskar.andero@gmail.com> + * Copyright (C) 2014 Rose Technology + * Allan Bendorff Jensen <abj@rosetechnology.dk> + * Soren Andersen <san@rosetechnology.dk> + * + * Driver for following ADC chips from Microchip Technology's: + * 10 Bit converter + * MCP3001 + * MCP3002 + * MCP3004 + * MCP3008 + * ------------ + * 12 bit converter + * MCP3201 + * MCP3202 + * MCP3204 + * MCP3208 + * ------------ * - * Driver for Microchip Technology's MCP3204 and MCP3208 ADC chips. * Datasheet can be found here: - * http://ww1.microchip.com/downloads/en/devicedoc/21298c.pdf + * http://ww1.microchip.com/downloads/en/DeviceDoc/21293C.pdf mcp3001 + * http://ww1.microchip.com/downloads/en/DeviceDoc/21294E.pdf mcp3002 + * http://ww1.microchip.com/downloads/en/DeviceDoc/21295d.pdf mcp3004/08 + * http://ww1.microchip.com/downloads/en/DeviceDoc/21290D.pdf mcp3201 + * http://ww1.microchip.com/downloads/en/DeviceDoc/21034D.pdf mcp3202 + * http://ww1.microchip.com/downloads/en/DeviceDoc/21298c.pdf mcp3204/08 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -11,19 +32,29 @@ */ #include <linux/err.h> +#include <linux/delay.h> #include <linux/spi/spi.h> #include <linux/module.h> #include <linux/iio/iio.h> #include <linux/regulator/consumer.h> -#define MCP_SINGLE_ENDED (1 << 3) -#define MCP_START_BIT (1 << 4) - enum { + mcp3001, + mcp3002, + mcp3004, + mcp3008, + mcp3201, + mcp3202, mcp3204, mcp3208, }; +struct mcp320x_chip_info { + const struct iio_chan_spec *channels; + unsigned int num_channels; + unsigned int resolution; +}; + struct mcp320x { struct spi_device *spi; struct spi_message msg; @@ -34,19 +65,69 @@ struct mcp320x { struct regulator *reg; struct mutex lock; + const struct mcp320x_chip_info *chip_info; }; -static int mcp320x_adc_conversion(struct mcp320x *adc, u8 msg) +static int mcp320x_channel_to_tx_data(int device_index, + const unsigned int channel, bool differential) +{ + int start_bit = 1; + + switch (device_index) { + case mcp3001: + case mcp3201: + return 0; + case mcp3002: + case mcp3202: + return ((start_bit << 4) | (!differential << 3) | + (channel << 2)); + case mcp3004: + case mcp3204: + case mcp3008: + case mcp3208: + return ((start_bit << 6) | (!differential << 5) | + (channel << 2)); + default: + return -EINVAL; + } +} + +static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel, + bool differential, int device_index) { int ret; - adc->tx_buf = msg; - ret = spi_sync(adc->spi, &adc->msg); - if (ret < 0) - return ret; + adc->rx_buf[0] = 0; + adc->rx_buf[1] = 0; + adc->tx_buf = mcp320x_channel_to_tx_data(device_index, + channel, differential); + + if (device_index != mcp3001 && device_index != mcp3201) { + ret = spi_sync(adc->spi, &adc->msg); + if (ret < 0) + return ret; + } else { + ret = spi_read(adc->spi, &adc->rx_buf, sizeof(adc->rx_buf)); + if (ret < 0) + return ret; + } - return ((adc->rx_buf[0] & 0x3f) << 6) | - (adc->rx_buf[1] >> 2); + switch (device_index) { + case mcp3001: + return (adc->rx_buf[0] << 5 | adc->rx_buf[1] >> 3); + case mcp3002: + case mcp3004: + case mcp3008: + return (adc->rx_buf[0] << 2 | adc->rx_buf[1] >> 6); + case mcp3201: + return (adc->rx_buf[0] << 7 | adc->rx_buf[1] >> 1); + case mcp3202: + case mcp3204: + case mcp3208: + return (adc->rx_buf[0] << 4 | adc->rx_buf[1] >> 4); + default: + return -EINVAL; + } } static int mcp320x_read_raw(struct iio_dev *indio_dev, @@ -55,18 +136,17 @@ static int mcp320x_read_raw(struct iio_dev *indio_dev, { struct mcp320x *adc = iio_priv(indio_dev); int ret = -EINVAL; + int device_index = 0; mutex_lock(&adc->lock); + device_index = spi_get_device_id(adc->spi)->driver_data; + switch (mask) { case IIO_CHAN_INFO_RAW: - if (channel->differential) - ret = mcp320x_adc_conversion(adc, - MCP_START_BIT | channel->address); - else - ret = mcp320x_adc_conversion(adc, - MCP_START_BIT | MCP_SINGLE_ENDED | - channel->address); + ret = mcp320x_adc_conversion(adc, channel->address, + channel->differential, device_index); + if (ret < 0) goto out; @@ -75,18 +155,15 @@ static int mcp320x_read_raw(struct iio_dev *indio_dev, break; case IIO_CHAN_INFO_SCALE: - /* Digital output code = (4096 * Vin) / Vref */ ret = regulator_get_voltage(adc->reg); if (ret < 0) goto out; + /* convert regulator output voltage to mV */ *val = ret / 1000; - *val2 = 12; + *val2 = adc->chip_info->resolution; ret = IIO_VAL_FRACTIONAL_LOG2; break; - - default: - break; } out: @@ -117,6 +194,16 @@ out: .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \ } +static const struct iio_chan_spec mcp3201_channels[] = { + MCP320X_VOLTAGE_CHANNEL_DIFF(0), +}; + +static const struct iio_chan_spec mcp3202_channels[] = { + MCP320X_VOLTAGE_CHANNEL(0), + MCP320X_VOLTAGE_CHANNEL(1), + MCP320X_VOLTAGE_CHANNEL_DIFF(0), +}; + static const struct iio_chan_spec mcp3204_channels[] = { MCP320X_VOLTAGE_CHANNEL(0), MCP320X_VOLTAGE_CHANNEL(1), @@ -146,19 +233,46 @@ static const struct iio_info mcp320x_info = { .driver_module = THIS_MODULE, }; -struct mcp3208_chip_info { - const struct iio_chan_spec *channels; - unsigned int num_channels; -}; - -static const struct mcp3208_chip_info mcp3208_chip_infos[] = { +static const struct mcp320x_chip_info mcp320x_chip_infos[] = { + [mcp3001] = { + .channels = mcp3201_channels, + .num_channels = ARRAY_SIZE(mcp3201_channels), + .resolution = 10 + }, + [mcp3002] = { + .channels = mcp3202_channels, + .num_channels = ARRAY_SIZE(mcp3202_channels), + .resolution = 10 + }, + [mcp3004] = { + .channels = mcp3204_channels, + .num_channels = ARRAY_SIZE(mcp3204_channels), + .resolution = 10 + }, + [mcp3008] = { + .channels = mcp3208_channels, + .num_channels = ARRAY_SIZE(mcp3208_channels), + .resolution = 10 + }, + [mcp3201] = { + .channels = mcp3201_channels, + .num_channels = ARRAY_SIZE(mcp3201_channels), + .resolution = 12 + }, + [mcp3202] = { + .channels = mcp3202_channels, + .num_channels = ARRAY_SIZE(mcp3202_channels), + .resolution = 12 + }, [mcp3204] = { .channels = mcp3204_channels, - .num_channels = ARRAY_SIZE(mcp3204_channels) + .num_channels = ARRAY_SIZE(mcp3204_channels), + .resolution = 12 }, [mcp3208] = { .channels = mcp3208_channels, - .num_channels = ARRAY_SIZE(mcp3208_channels) + .num_channels = ARRAY_SIZE(mcp3208_channels), + .resolution = 12 }, }; @@ -166,7 +280,7 @@ static int mcp320x_probe(struct spi_device *spi) { struct iio_dev *indio_dev; struct mcp320x *adc; - const struct mcp3208_chip_info *chip_info; + const struct mcp320x_chip_info *chip_info; int ret; indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc)); @@ -181,7 +295,7 @@ static int mcp320x_probe(struct spi_device *spi) indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &mcp320x_info; - chip_info = &mcp3208_chip_infos[spi_get_device_id(spi)->driver_data]; + chip_info = &mcp320x_chip_infos[spi_get_device_id(spi)->driver_data]; indio_dev->channels = chip_info->channels; indio_dev->num_channels = chip_info->num_channels; @@ -226,7 +340,45 @@ static int mcp320x_remove(struct spi_device *spi) return 0; } +#if defined(CONFIG_OF) +static const struct of_device_id mcp320x_dt_ids[] = { + { + .compatible = "mcp3001", + .data = &mcp320x_chip_infos[mcp3001], + }, { + .compatible = "mcp3002", + .data = &mcp320x_chip_infos[mcp3002], + }, { + .compatible = "mcp3004", + .data = &mcp320x_chip_infos[mcp3004], + }, { + .compatible = "mcp3008", + .data = &mcp320x_chip_infos[mcp3008], + }, { + .compatible = "mcp3201", + .data = &mcp320x_chip_infos[mcp3201], + }, { + .compatible = "mcp3202", + .data = &mcp320x_chip_infos[mcp3202], + }, { + .compatible = "mcp3204", + .data = &mcp320x_chip_infos[mcp3204], + }, { + .compatible = "mcp3208", + .data = &mcp320x_chip_infos[mcp3208], + }, { + } +}; +MODULE_DEVICE_TABLE(of, mcp320x_dt_ids); +#endif + static const struct spi_device_id mcp320x_id[] = { + { "mcp3001", mcp3001 }, + { "mcp3002", mcp3002 }, + { "mcp3004", mcp3004 }, + { "mcp3008", mcp3008 }, + { "mcp3201", mcp3201 }, + { "mcp3202", mcp3202 }, { "mcp3204", mcp3204 }, { "mcp3208", mcp3208 }, { } @@ -245,5 +397,5 @@ static struct spi_driver mcp320x_driver = { module_spi_driver(mcp320x_driver); MODULE_AUTHOR("Oskar Andero <oskar.andero@gmail.com>"); -MODULE_DESCRIPTION("Microchip Technology MCP3204/08"); +MODULE_DESCRIPTION("Microchip Technology MCP3x01/02/04/08"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/adc/qcom-spmi-iadc.c b/drivers/iio/adc/qcom-spmi-iadc.c new file mode 100644 index 000000000000..b9666f2f5e51 --- /dev/null +++ b/drivers/iio/adc/qcom-spmi-iadc.c @@ -0,0 +1,595 @@ +/* + * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/bitops.h> +#include <linux/completion.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/iio/iio.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/mutex.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/slab.h> + +/* IADC register and bit definition */ +#define IADC_REVISION2 0x1 +#define IADC_REVISION2_SUPPORTED_IADC 1 + +#define IADC_PERPH_TYPE 0x4 +#define IADC_PERPH_TYPE_ADC 8 + +#define IADC_PERPH_SUBTYPE 0x5 +#define IADC_PERPH_SUBTYPE_IADC 3 + +#define IADC_STATUS1 0x8 +#define IADC_STATUS1_OP_MODE 4 +#define IADC_STATUS1_REQ_STS BIT(1) +#define IADC_STATUS1_EOC BIT(0) +#define IADC_STATUS1_REQ_STS_EOC_MASK 0x3 + +#define IADC_MODE_CTL 0x40 +#define IADC_OP_MODE_SHIFT 3 +#define IADC_OP_MODE_NORMAL 0 +#define IADC_TRIM_EN BIT(0) + +#define IADC_EN_CTL1 0x46 +#define IADC_EN_CTL1_SET BIT(7) + +#define IADC_CH_SEL_CTL 0x48 + +#define IADC_DIG_PARAM 0x50 +#define IADC_DIG_DEC_RATIO_SEL_SHIFT 2 + +#define IADC_HW_SETTLE_DELAY 0x51 + +#define IADC_CONV_REQ 0x52 +#define IADC_CONV_REQ_SET BIT(7) + +#define IADC_FAST_AVG_CTL 0x5a +#define IADC_FAST_AVG_EN 0x5b +#define IADC_FAST_AVG_EN_SET BIT(7) + +#define IADC_PERH_RESET_CTL3 0xda +#define IADC_FOLLOW_WARM_RB BIT(2) + +#define IADC_DATA 0x60 /* 16 bits */ + +#define IADC_SEC_ACCESS 0xd0 +#define IADC_SEC_ACCESS_DATA 0xa5 + +#define IADC_NOMINAL_RSENSE 0xf4 +#define IADC_NOMINAL_RSENSE_SIGN_MASK BIT(7) + +#define IADC_REF_GAIN_MICRO_VOLTS 17857 + +#define IADC_INT_RSENSE_DEVIATION 15625 /* nano Ohms per bit */ + +#define IADC_INT_RSENSE_IDEAL_VALUE 10000 /* micro Ohms */ +#define IADC_INT_RSENSE_DEFAULT_VALUE 7800 /* micro Ohms */ +#define IADC_INT_RSENSE_DEFAULT_GF 9000 /* micro Ohms */ +#define IADC_INT_RSENSE_DEFAULT_SMIC 9700 /* micro Ohms */ + +#define IADC_CONV_TIME_MIN_US 2000 +#define IADC_CONV_TIME_MAX_US 2100 + +#define IADC_DEF_PRESCALING 0 /* 1:1 */ +#define IADC_DEF_DECIMATION 0 /* 512 */ +#define IADC_DEF_HW_SETTLE_TIME 0 /* 0 us */ +#define IADC_DEF_AVG_SAMPLES 0 /* 1 sample */ + +/* IADC channel list */ +#define IADC_INT_RSENSE 0 +#define IADC_EXT_RSENSE 1 +#define IADC_GAIN_17P857MV 3 +#define IADC_EXT_OFFSET_CSP_CSN 5 +#define IADC_INT_OFFSET_CSP2_CSN2 6 + +/** + * struct iadc_chip - IADC Current ADC device structure. + * @regmap: regmap for register read/write. + * @dev: This device pointer. + * @base: base offset for the ADC peripheral. + * @rsense: Values of the internal and external sense resister in micro Ohms. + * @poll_eoc: Poll for end of conversion instead of waiting for IRQ. + * @offset: Raw offset values for the internal and external channels. + * @gain: Raw gain of the channels. + * @lock: ADC lock for access to the peripheral. + * @complete: ADC notification after end of conversion interrupt is received. + */ +struct iadc_chip { + struct regmap *regmap; + struct device *dev; + u16 base; + bool poll_eoc; + u32 rsense[2]; + u16 offset[2]; + u16 gain; + struct mutex lock; + struct completion complete; +}; + +static int iadc_read(struct iadc_chip *iadc, u16 offset, u8 *data) +{ + unsigned int val; + int ret; + + ret = regmap_read(iadc->regmap, iadc->base + offset, &val); + if (ret < 0) + return ret; + + *data = val; + return 0; +} + +static int iadc_write(struct iadc_chip *iadc, u16 offset, u8 data) +{ + return regmap_write(iadc->regmap, iadc->base + offset, data); +} + +static int iadc_reset(struct iadc_chip *iadc) +{ + u8 data; + int ret; + + ret = iadc_write(iadc, IADC_SEC_ACCESS, IADC_SEC_ACCESS_DATA); + if (ret < 0) + return ret; + + ret = iadc_read(iadc, IADC_PERH_RESET_CTL3, &data); + if (ret < 0) + return ret; + + ret = iadc_write(iadc, IADC_SEC_ACCESS, IADC_SEC_ACCESS_DATA); + if (ret < 0) + return ret; + + data |= IADC_FOLLOW_WARM_RB; + + return iadc_write(iadc, IADC_PERH_RESET_CTL3, data); +} + +static int iadc_set_state(struct iadc_chip *iadc, bool state) +{ + return iadc_write(iadc, IADC_EN_CTL1, state ? IADC_EN_CTL1_SET : 0); +} + +static void iadc_status_show(struct iadc_chip *iadc) +{ + u8 mode, sta1, chan, dig, en, req; + int ret; + + ret = iadc_read(iadc, IADC_MODE_CTL, &mode); + if (ret < 0) + return; + + ret = iadc_read(iadc, IADC_DIG_PARAM, &dig); + if (ret < 0) + return; + + ret = iadc_read(iadc, IADC_CH_SEL_CTL, &chan); + if (ret < 0) + return; + + ret = iadc_read(iadc, IADC_CONV_REQ, &req); + if (ret < 0) + return; + + ret = iadc_read(iadc, IADC_STATUS1, &sta1); + if (ret < 0) + return; + + ret = iadc_read(iadc, IADC_EN_CTL1, &en); + if (ret < 0) + return; + + dev_err(iadc->dev, + "mode:%02x en:%02x chan:%02x dig:%02x req:%02x sta1:%02x\n", + mode, en, chan, dig, req, sta1); +} + +static int iadc_configure(struct iadc_chip *iadc, int channel) +{ + u8 decim, mode; + int ret; + + /* Mode selection */ + mode = (IADC_OP_MODE_NORMAL << IADC_OP_MODE_SHIFT) | IADC_TRIM_EN; + ret = iadc_write(iadc, IADC_MODE_CTL, mode); + if (ret < 0) + return ret; + + /* Channel selection */ + ret = iadc_write(iadc, IADC_CH_SEL_CTL, channel); + if (ret < 0) + return ret; + + /* Digital parameter setup */ + decim = IADC_DEF_DECIMATION << IADC_DIG_DEC_RATIO_SEL_SHIFT; + ret = iadc_write(iadc, IADC_DIG_PARAM, decim); + if (ret < 0) + return ret; + + /* HW settle time delay */ + ret = iadc_write(iadc, IADC_HW_SETTLE_DELAY, IADC_DEF_HW_SETTLE_TIME); + if (ret < 0) + return ret; + + ret = iadc_write(iadc, IADC_FAST_AVG_CTL, IADC_DEF_AVG_SAMPLES); + if (ret < 0) + return ret; + + if (IADC_DEF_AVG_SAMPLES) + ret = iadc_write(iadc, IADC_FAST_AVG_EN, IADC_FAST_AVG_EN_SET); + else + ret = iadc_write(iadc, IADC_FAST_AVG_EN, 0); + + if (ret < 0) + return ret; + + if (!iadc->poll_eoc) + reinit_completion(&iadc->complete); + + ret = iadc_set_state(iadc, true); + if (ret < 0) + return ret; + + /* Request conversion */ + return iadc_write(iadc, IADC_CONV_REQ, IADC_CONV_REQ_SET); +} + +static int iadc_poll_wait_eoc(struct iadc_chip *iadc, unsigned int interval_us) +{ + unsigned int count, retry; + int ret; + u8 sta1; + + retry = interval_us / IADC_CONV_TIME_MIN_US; + + for (count = 0; count < retry; count++) { + ret = iadc_read(iadc, IADC_STATUS1, &sta1); + if (ret < 0) + return ret; + + sta1 &= IADC_STATUS1_REQ_STS_EOC_MASK; + if (sta1 == IADC_STATUS1_EOC) + return 0; + + usleep_range(IADC_CONV_TIME_MIN_US, IADC_CONV_TIME_MAX_US); + } + + iadc_status_show(iadc); + + return -ETIMEDOUT; +} + +static int iadc_read_result(struct iadc_chip *iadc, u16 *data) +{ + return regmap_bulk_read(iadc->regmap, iadc->base + IADC_DATA, data, 2); +} + +static int iadc_do_conversion(struct iadc_chip *iadc, int chan, u16 *data) +{ + unsigned int wait; + int ret; + + ret = iadc_configure(iadc, chan); + if (ret < 0) + goto exit; + + wait = BIT(IADC_DEF_AVG_SAMPLES) * IADC_CONV_TIME_MIN_US * 2; + + if (iadc->poll_eoc) { + ret = iadc_poll_wait_eoc(iadc, wait); + } else { + ret = wait_for_completion_timeout(&iadc->complete, wait); + if (!ret) + ret = -ETIMEDOUT; + else + /* double check conversion status */ + ret = iadc_poll_wait_eoc(iadc, IADC_CONV_TIME_MIN_US); + } + + if (!ret) + ret = iadc_read_result(iadc, data); +exit: + iadc_set_state(iadc, false); + if (ret < 0) + dev_err(iadc->dev, "conversion failed\n"); + + return ret; +} + +static int iadc_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct iadc_chip *iadc = iio_priv(indio_dev); + s32 isense_ua, vsense_uv; + u16 adc_raw, vsense_raw; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + mutex_lock(&iadc->lock); + ret = iadc_do_conversion(iadc, chan->channel, &adc_raw); + mutex_unlock(&iadc->lock); + if (ret < 0) + return ret; + + vsense_raw = adc_raw - iadc->offset[chan->channel]; + + vsense_uv = vsense_raw * IADC_REF_GAIN_MICRO_VOLTS; + vsense_uv /= (s32)iadc->gain - iadc->offset[chan->channel]; + + isense_ua = vsense_uv / iadc->rsense[chan->channel]; + + dev_dbg(iadc->dev, "off %d gain %d adc %d %duV I %duA\n", + iadc->offset[chan->channel], iadc->gain, + adc_raw, vsense_uv, isense_ua); + + *val = isense_ua; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + *val = 0; + *val2 = 1000; + return IIO_VAL_INT_PLUS_MICRO; + } + + return -EINVAL; +} + +static const struct iio_info iadc_info = { + .read_raw = iadc_read_raw, + .driver_module = THIS_MODULE, +}; + +static irqreturn_t iadc_isr(int irq, void *dev_id) +{ + struct iadc_chip *iadc = dev_id; + + complete(&iadc->complete); + + return IRQ_HANDLED; +} + +static int iadc_update_offset(struct iadc_chip *iadc) +{ + int ret; + + ret = iadc_do_conversion(iadc, IADC_GAIN_17P857MV, &iadc->gain); + if (ret < 0) + return ret; + + ret = iadc_do_conversion(iadc, IADC_INT_OFFSET_CSP2_CSN2, + &iadc->offset[IADC_INT_RSENSE]); + if (ret < 0) + return ret; + + if (iadc->gain == iadc->offset[IADC_INT_RSENSE]) { + dev_err(iadc->dev, "error: internal offset == gain %d\n", + iadc->gain); + return -EINVAL; + } + + ret = iadc_do_conversion(iadc, IADC_EXT_OFFSET_CSP_CSN, + &iadc->offset[IADC_EXT_RSENSE]); + if (ret < 0) + return ret; + + if (iadc->gain == iadc->offset[IADC_EXT_RSENSE]) { + dev_err(iadc->dev, "error: external offset == gain %d\n", + iadc->gain); + return -EINVAL; + } + + return 0; +} + +static int iadc_version_check(struct iadc_chip *iadc) +{ + u8 val; + int ret; + + ret = iadc_read(iadc, IADC_PERPH_TYPE, &val); + if (ret < 0) + return ret; + + if (val < IADC_PERPH_TYPE_ADC) { + dev_err(iadc->dev, "%d is not ADC\n", val); + return -EINVAL; + } + + ret = iadc_read(iadc, IADC_PERPH_SUBTYPE, &val); + if (ret < 0) + return ret; + + if (val < IADC_PERPH_SUBTYPE_IADC) { + dev_err(iadc->dev, "%d is not IADC\n", val); + return -EINVAL; + } + + ret = iadc_read(iadc, IADC_REVISION2, &val); + if (ret < 0) + return ret; + + if (val < IADC_REVISION2_SUPPORTED_IADC) { + dev_err(iadc->dev, "revision %d not supported\n", val); + return -EINVAL; + } + + return 0; +} + +static int iadc_rsense_read(struct iadc_chip *iadc, struct device_node *node) +{ + int ret, sign, int_sense; + u8 deviation; + + ret = of_property_read_u32(node, "qcom,external-resistor-micro-ohms", + &iadc->rsense[IADC_EXT_RSENSE]); + if (ret < 0) + iadc->rsense[IADC_EXT_RSENSE] = IADC_INT_RSENSE_IDEAL_VALUE; + + if (!iadc->rsense[IADC_EXT_RSENSE]) { + dev_err(iadc->dev, "external resistor can't be zero Ohms"); + return -EINVAL; + } + + ret = iadc_read(iadc, IADC_NOMINAL_RSENSE, &deviation); + if (ret < 0) + return ret; + + /* + * Deviation value stored is an offset from 10 mili Ohms, bit 7 is + * the sign, the remaining bits have an LSB of 15625 nano Ohms. + */ + sign = (deviation & IADC_NOMINAL_RSENSE_SIGN_MASK) ? -1 : 1; + + deviation &= ~IADC_NOMINAL_RSENSE_SIGN_MASK; + + /* Scale it to nono Ohms */ + int_sense = IADC_INT_RSENSE_IDEAL_VALUE * 1000; + int_sense += sign * deviation * IADC_INT_RSENSE_DEVIATION; + int_sense /= 1000; /* micro Ohms */ + + iadc->rsense[IADC_INT_RSENSE] = int_sense; + return 0; +} + +static const struct iio_chan_spec iadc_channels[] = { + { + .type = IIO_CURRENT, + .datasheet_name = "INTERNAL_RSENSE", + .channel = 0, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + .indexed = 1, + }, + { + .type = IIO_CURRENT, + .datasheet_name = "EXTERNAL_RSENSE", + .channel = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + .indexed = 1, + }, +}; + +static int iadc_probe(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct iio_dev *indio_dev; + struct iadc_chip *iadc; + int ret, irq_eoc; + u32 res; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*iadc)); + if (!indio_dev) + return -ENOMEM; + + iadc = iio_priv(indio_dev); + iadc->dev = dev; + + iadc->regmap = dev_get_regmap(dev->parent, NULL); + if (!iadc->regmap) + return -ENODEV; + + init_completion(&iadc->complete); + mutex_init(&iadc->lock); + + ret = of_property_read_u32(node, "reg", &res); + if (ret < 0) + return -ENODEV; + + iadc->base = res; + + ret = iadc_version_check(iadc); + if (ret < 0) + return -ENODEV; + + ret = iadc_rsense_read(iadc, node); + if (ret < 0) + return -ENODEV; + + dev_dbg(iadc->dev, "sense resistors %d and %d micro Ohm\n", + iadc->rsense[IADC_INT_RSENSE], + iadc->rsense[IADC_EXT_RSENSE]); + + irq_eoc = platform_get_irq(pdev, 0); + if (irq_eoc == -EPROBE_DEFER) + return irq_eoc; + + if (irq_eoc < 0) + iadc->poll_eoc = true; + + ret = iadc_reset(iadc); + if (ret < 0) { + dev_err(dev, "reset failed\n"); + return ret; + } + + if (!iadc->poll_eoc) { + ret = devm_request_irq(dev, irq_eoc, iadc_isr, 0, + "spmi-iadc", iadc); + if (!ret) + enable_irq_wake(irq_eoc); + else + return ret; + } else { + device_init_wakeup(iadc->dev, 1); + } + + ret = iadc_update_offset(iadc); + if (ret < 0) { + dev_err(dev, "failed offset calibration\n"); + return ret; + } + + indio_dev->dev.parent = dev; + indio_dev->dev.of_node = node; + indio_dev->name = pdev->name; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &iadc_info; + indio_dev->channels = iadc_channels; + indio_dev->num_channels = ARRAY_SIZE(iadc_channels); + + return devm_iio_device_register(dev, indio_dev); +} + +static const struct of_device_id iadc_match_table[] = { + { .compatible = "qcom,spmi-iadc" }, + { } +}; + +MODULE_DEVICE_TABLE(of, iadc_match_table); + +static struct platform_driver iadc_driver = { + .driver = { + .name = "qcom-spmi-iadc", + .of_match_table = iadc_match_table, + }, + .probe = iadc_probe, +}; + +module_platform_driver(iadc_driver); + +MODULE_ALIAS("platform:qcom-spmi-iadc"); +MODULE_DESCRIPTION("Qualcomm SPMI PMIC current ADC driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>"); diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c index 63a9797775cb..8d4e019ea4ca 100644 --- a/drivers/iio/adc/rockchip_saradc.c +++ b/drivers/iio/adc/rockchip_saradc.c @@ -18,13 +18,13 @@ #include <linux/interrupt.h> #include <linux/io.h> #include <linux/of.h> +#include <linux/of_device.h> #include <linux/clk.h> #include <linux/completion.h> #include <linux/regulator/consumer.h> #include <linux/iio/iio.h> #define SARADC_DATA 0x00 -#define SARADC_DATA_MASK 0x3ff #define SARADC_STAS 0x04 #define SARADC_STAS_BUSY BIT(0) @@ -38,15 +38,22 @@ #define SARADC_DLY_PU_SOC 0x0c #define SARADC_DLY_PU_SOC_MASK 0x3f -#define SARADC_BITS 10 #define SARADC_TIMEOUT msecs_to_jiffies(100) +struct rockchip_saradc_data { + int num_bits; + const struct iio_chan_spec *channels; + int num_channels; + unsigned long clk_rate; +}; + struct rockchip_saradc { void __iomem *regs; struct clk *pclk; struct clk *clk; struct completion completion; struct regulator *vref; + const struct rockchip_saradc_data *data; u16 last_val; }; @@ -90,7 +97,7 @@ static int rockchip_saradc_read_raw(struct iio_dev *indio_dev, } *val = ret / 1000; - *val2 = SARADC_BITS; + *val2 = info->data->num_bits; return IIO_VAL_FRACTIONAL_LOG2; default: return -EINVAL; @@ -103,7 +110,7 @@ static irqreturn_t rockchip_saradc_isr(int irq, void *dev_id) /* Read value */ info->last_val = readl_relaxed(info->regs + SARADC_DATA); - info->last_val &= SARADC_DATA_MASK; + info->last_val &= GENMASK(info->data->num_bits - 1, 0); /* Clear irq & power down adc */ writel_relaxed(0, info->regs + SARADC_CTRL); @@ -133,12 +140,44 @@ static const struct iio_chan_spec rockchip_saradc_iio_channels[] = { ADC_CHANNEL(2, "adc2"), }; +static const struct rockchip_saradc_data saradc_data = { + .num_bits = 10, + .channels = rockchip_saradc_iio_channels, + .num_channels = ARRAY_SIZE(rockchip_saradc_iio_channels), + .clk_rate = 1000000, +}; + +static const struct iio_chan_spec rockchip_rk3066_tsadc_iio_channels[] = { + ADC_CHANNEL(0, "adc0"), + ADC_CHANNEL(1, "adc1"), +}; + +static const struct rockchip_saradc_data rk3066_tsadc_data = { + .num_bits = 12, + .channels = rockchip_rk3066_tsadc_iio_channels, + .num_channels = ARRAY_SIZE(rockchip_rk3066_tsadc_iio_channels), + .clk_rate = 50000, +}; + +static const struct of_device_id rockchip_saradc_match[] = { + { + .compatible = "rockchip,saradc", + .data = &saradc_data, + }, { + .compatible = "rockchip,rk3066-tsadc", + .data = &rk3066_tsadc_data, + }, + {}, +}; +MODULE_DEVICE_TABLE(of, rockchip_saradc_match); + static int rockchip_saradc_probe(struct platform_device *pdev) { struct rockchip_saradc *info = NULL; struct device_node *np = pdev->dev.of_node; struct iio_dev *indio_dev = NULL; struct resource *mem; + const struct of_device_id *match; int ret; int irq; @@ -152,6 +191,9 @@ static int rockchip_saradc_probe(struct platform_device *pdev) } info = iio_priv(indio_dev); + match = of_match_device(rockchip_saradc_match, &pdev->dev); + info->data = match->data; + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); info->regs = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(info->regs)) @@ -192,10 +234,10 @@ static int rockchip_saradc_probe(struct platform_device *pdev) } /* - * Use a default of 1MHz for the converter clock. + * Use a default value for the converter clock. * This may become user-configurable in the future. */ - ret = clk_set_rate(info->clk, 1000000); + ret = clk_set_rate(info->clk, info->data->clk_rate); if (ret < 0) { dev_err(&pdev->dev, "failed to set adc clk rate, %d\n", ret); return ret; @@ -227,8 +269,8 @@ static int rockchip_saradc_probe(struct platform_device *pdev) indio_dev->info = &rockchip_saradc_iio_info; indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->channels = rockchip_saradc_iio_channels; - indio_dev->num_channels = ARRAY_SIZE(rockchip_saradc_iio_channels); + indio_dev->channels = info->data->channels; + indio_dev->num_channels = info->data->num_channels; ret = iio_device_register(indio_dev); if (ret) @@ -296,12 +338,6 @@ static int rockchip_saradc_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(rockchip_saradc_pm_ops, rockchip_saradc_suspend, rockchip_saradc_resume); -static const struct of_device_id rockchip_saradc_match[] = { - { .compatible = "rockchip,saradc" }, - {}, -}; -MODULE_DEVICE_TABLE(of, rockchip_saradc_match); - static struct platform_driver rockchip_saradc_driver = { .probe = rockchip_saradc_probe, .remove = rockchip_saradc_remove, diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index 4a10ae97dbf2..8ec353c01d98 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -91,7 +91,7 @@ #define VF610_ADC_CAL 0x80 /* Other field define */ -#define VF610_ADC_ADCHC(x) ((x) & 0xF) +#define VF610_ADC_ADCHC(x) ((x) & 0x1F) #define VF610_ADC_AIEN (0x1 << 7) #define VF610_ADC_CONV_DISABLE 0x1F #define VF610_ADC_HS_COCO0 0x1 @@ -153,6 +153,12 @@ struct vf610_adc { BIT(IIO_CHAN_INFO_SAMP_FREQ), \ } +#define VF610_ADC_TEMPERATURE_CHAN(_idx, _chan_type) { \ + .type = (_chan_type), \ + .channel = (_idx), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \ +} + static const struct iio_chan_spec vf610_adc_iio_channels[] = { VF610_ADC_CHAN(0, IIO_VOLTAGE), VF610_ADC_CHAN(1, IIO_VOLTAGE), @@ -170,6 +176,7 @@ static const struct iio_chan_spec vf610_adc_iio_channels[] = { VF610_ADC_CHAN(13, IIO_VOLTAGE), VF610_ADC_CHAN(14, IIO_VOLTAGE), VF610_ADC_CHAN(15, IIO_VOLTAGE), + VF610_ADC_TEMPERATURE_CHAN(26, IIO_TEMP), /* sentinel */ }; @@ -451,6 +458,7 @@ static int vf610_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: + case IIO_CHAN_INFO_PROCESSED: mutex_lock(&indio_dev->mlock); reinit_completion(&info->completion); @@ -468,7 +476,23 @@ static int vf610_read_raw(struct iio_dev *indio_dev, return ret; } - *val = info->value; + switch (chan->type) { + case IIO_VOLTAGE: + *val = info->value; + break; + case IIO_TEMP: + /* + * Calculate in degree Celsius times 1000 + * Using sensor slope of 1.84 mV/°C and + * V at 25°C of 696 mV + */ + *val = 25000 - ((int)info->value - 864) * 1000000 / 1840; + break; + default: + mutex_unlock(&indio_dev->mlock); + return -EINVAL; + } + mutex_unlock(&indio_dev->mlock); return IIO_VAL_INT; @@ -569,9 +593,9 @@ static int vf610_adc_probe(struct platform_device *pdev) return PTR_ERR(info->regs); irq = platform_get_irq(pdev, 0); - if (irq <= 0) { + if (irq < 0) { dev_err(&pdev->dev, "no irq resource?\n"); - return -EINVAL; + return irq; } ret = devm_request_irq(info->dev, irq, @@ -586,8 +610,7 @@ static int vf610_adc_probe(struct platform_device *pdev) if (IS_ERR(info->clk)) { dev_err(&pdev->dev, "failed getting clock, err = %ld\n", PTR_ERR(info->clk)); - ret = PTR_ERR(info->clk); - return ret; + return PTR_ERR(info->clk); } info->vref = devm_regulator_get(&pdev->dev, "vref"); @@ -681,17 +704,19 @@ static int vf610_adc_resume(struct device *dev) ret = clk_prepare_enable(info->clk); if (ret) - return ret; + goto disable_reg; vf610_adc_hw_init(info); return 0; + +disable_reg: + regulator_disable(info->vref); + return ret; } #endif -static SIMPLE_DEV_PM_OPS(vf610_adc_pm_ops, - vf610_adc_suspend, - vf610_adc_resume); +static SIMPLE_DEV_PM_OPS(vf610_adc_pm_ops, vf610_adc_suspend, vf610_adc_resume); static struct platform_driver vf610_adc_driver = { .probe = vf610_adc_probe, diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c index 24cfe4e044f9..edd13d2b4121 100644 --- a/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/drivers/iio/common/st_sensors/st_sensors_core.c @@ -44,18 +44,18 @@ st_sensors_write_data_with_mask_error: return err; } -static int st_sensors_match_odr(struct st_sensors *sensor, +static int st_sensors_match_odr(struct st_sensor_settings *sensor_settings, unsigned int odr, struct st_sensor_odr_avl *odr_out) { int i, ret = -EINVAL; for (i = 0; i < ST_SENSORS_ODR_LIST_MAX; i++) { - if (sensor->odr.odr_avl[i].hz == 0) + if (sensor_settings->odr.odr_avl[i].hz == 0) goto st_sensors_match_odr_error; - if (sensor->odr.odr_avl[i].hz == odr) { - odr_out->hz = sensor->odr.odr_avl[i].hz; - odr_out->value = sensor->odr.odr_avl[i].value; + if (sensor_settings->odr.odr_avl[i].hz == odr) { + odr_out->hz = sensor_settings->odr.odr_avl[i].hz; + odr_out->value = sensor_settings->odr.odr_avl[i].value; ret = 0; break; } @@ -71,23 +71,26 @@ int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr) struct st_sensor_odr_avl odr_out = {0, 0}; struct st_sensor_data *sdata = iio_priv(indio_dev); - err = st_sensors_match_odr(sdata->sensor, odr, &odr_out); + err = st_sensors_match_odr(sdata->sensor_settings, odr, &odr_out); if (err < 0) goto st_sensors_match_odr_error; - if ((sdata->sensor->odr.addr == sdata->sensor->pw.addr) && - (sdata->sensor->odr.mask == sdata->sensor->pw.mask)) { + if ((sdata->sensor_settings->odr.addr == + sdata->sensor_settings->pw.addr) && + (sdata->sensor_settings->odr.mask == + sdata->sensor_settings->pw.mask)) { if (sdata->enabled == true) { err = st_sensors_write_data_with_mask(indio_dev, - sdata->sensor->odr.addr, - sdata->sensor->odr.mask, + sdata->sensor_settings->odr.addr, + sdata->sensor_settings->odr.mask, odr_out.value); } else { err = 0; } } else { err = st_sensors_write_data_with_mask(indio_dev, - sdata->sensor->odr.addr, sdata->sensor->odr.mask, + sdata->sensor_settings->odr.addr, + sdata->sensor_settings->odr.mask, odr_out.value); } if (err >= 0) @@ -98,16 +101,16 @@ st_sensors_match_odr_error: } EXPORT_SYMBOL(st_sensors_set_odr); -static int st_sensors_match_fs(struct st_sensors *sensor, +static int st_sensors_match_fs(struct st_sensor_settings *sensor_settings, unsigned int fs, int *index_fs_avl) { int i, ret = -EINVAL; for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) { - if (sensor->fs.fs_avl[i].num == 0) + if (sensor_settings->fs.fs_avl[i].num == 0) goto st_sensors_match_odr_error; - if (sensor->fs.fs_avl[i].num == fs) { + if (sensor_settings->fs.fs_avl[i].num == fs) { *index_fs_avl = i; ret = 0; break; @@ -118,25 +121,24 @@ st_sensors_match_odr_error: return ret; } -static int st_sensors_set_fullscale(struct iio_dev *indio_dev, - unsigned int fs) +static int st_sensors_set_fullscale(struct iio_dev *indio_dev, unsigned int fs) { int err, i = 0; struct st_sensor_data *sdata = iio_priv(indio_dev); - err = st_sensors_match_fs(sdata->sensor, fs, &i); + err = st_sensors_match_fs(sdata->sensor_settings, fs, &i); if (err < 0) goto st_accel_set_fullscale_error; err = st_sensors_write_data_with_mask(indio_dev, - sdata->sensor->fs.addr, - sdata->sensor->fs.mask, - sdata->sensor->fs.fs_avl[i].value); + sdata->sensor_settings->fs.addr, + sdata->sensor_settings->fs.mask, + sdata->sensor_settings->fs.fs_avl[i].value); if (err < 0) goto st_accel_set_fullscale_error; sdata->current_fullscale = (struct st_sensor_fullscale_avl *) - &sdata->sensor->fs.fs_avl[i]; + &sdata->sensor_settings->fs.fs_avl[i]; return err; st_accel_set_fullscale_error: @@ -153,10 +155,12 @@ int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable) struct st_sensor_data *sdata = iio_priv(indio_dev); if (enable) { - tmp_value = sdata->sensor->pw.value_on; - if ((sdata->sensor->odr.addr == sdata->sensor->pw.addr) && - (sdata->sensor->odr.mask == sdata->sensor->pw.mask)) { - err = st_sensors_match_odr(sdata->sensor, + tmp_value = sdata->sensor_settings->pw.value_on; + if ((sdata->sensor_settings->odr.addr == + sdata->sensor_settings->pw.addr) && + (sdata->sensor_settings->odr.mask == + sdata->sensor_settings->pw.mask)) { + err = st_sensors_match_odr(sdata->sensor_settings, sdata->odr, &odr_out); if (err < 0) goto set_enable_error; @@ -164,8 +168,8 @@ int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable) found = true; } err = st_sensors_write_data_with_mask(indio_dev, - sdata->sensor->pw.addr, - sdata->sensor->pw.mask, tmp_value); + sdata->sensor_settings->pw.addr, + sdata->sensor_settings->pw.mask, tmp_value); if (err < 0) goto set_enable_error; @@ -175,9 +179,9 @@ int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable) sdata->odr = odr_out.hz; } else { err = st_sensors_write_data_with_mask(indio_dev, - sdata->sensor->pw.addr, - sdata->sensor->pw.mask, - sdata->sensor->pw.value_off); + sdata->sensor_settings->pw.addr, + sdata->sensor_settings->pw.mask, + sdata->sensor_settings->pw.value_off); if (err < 0) goto set_enable_error; @@ -194,8 +198,9 @@ int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable) struct st_sensor_data *sdata = iio_priv(indio_dev); return st_sensors_write_data_with_mask(indio_dev, - sdata->sensor->enable_axis.addr, - sdata->sensor->enable_axis.mask, axis_enable); + sdata->sensor_settings->enable_axis.addr, + sdata->sensor_settings->enable_axis.mask, + axis_enable); } EXPORT_SYMBOL(st_sensors_set_axis_enable); @@ -236,13 +241,13 @@ void st_sensors_power_disable(struct iio_dev *indio_dev) EXPORT_SYMBOL(st_sensors_power_disable); static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev, - struct st_sensors_platform_data *pdata) + struct st_sensors_platform_data *pdata) { struct st_sensor_data *sdata = iio_priv(indio_dev); switch (pdata->drdy_int_pin) { case 1: - if (sdata->sensor->drdy_irq.mask_int1 == 0) { + if (sdata->sensor_settings->drdy_irq.mask_int1 == 0) { dev_err(&indio_dev->dev, "DRDY on INT1 not available.\n"); return -EINVAL; @@ -250,7 +255,7 @@ static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev, sdata->drdy_int_pin = 1; break; case 2: - if (sdata->sensor->drdy_irq.mask_int2 == 0) { + if (sdata->sensor_settings->drdy_irq.mask_int2 == 0) { dev_err(&indio_dev->dev, "DRDY on INT2 not available.\n"); return -EINVAL; @@ -318,7 +323,7 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev, if (sdata->current_fullscale) { err = st_sensors_set_fullscale(indio_dev, - sdata->current_fullscale->num); + sdata->current_fullscale->num); if (err < 0) return err; } else @@ -330,7 +335,8 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev, /* set BDU */ err = st_sensors_write_data_with_mask(indio_dev, - sdata->sensor->bdu.addr, sdata->sensor->bdu.mask, true); + sdata->sensor_settings->bdu.addr, + sdata->sensor_settings->bdu.mask, true); if (err < 0) return err; @@ -346,26 +352,28 @@ int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable) u8 drdy_mask; struct st_sensor_data *sdata = iio_priv(indio_dev); - if (!sdata->sensor->drdy_irq.addr) + if (!sdata->sensor_settings->drdy_irq.addr) return 0; /* Enable/Disable the interrupt generator 1. */ - if (sdata->sensor->drdy_irq.ig1.en_addr > 0) { + if (sdata->sensor_settings->drdy_irq.ig1.en_addr > 0) { err = st_sensors_write_data_with_mask(indio_dev, - sdata->sensor->drdy_irq.ig1.en_addr, - sdata->sensor->drdy_irq.ig1.en_mask, (int)enable); + sdata->sensor_settings->drdy_irq.ig1.en_addr, + sdata->sensor_settings->drdy_irq.ig1.en_mask, + (int)enable); if (err < 0) goto st_accel_set_dataready_irq_error; } if (sdata->drdy_int_pin == 1) - drdy_mask = sdata->sensor->drdy_irq.mask_int1; + drdy_mask = sdata->sensor_settings->drdy_irq.mask_int1; else - drdy_mask = sdata->sensor->drdy_irq.mask_int2; + drdy_mask = sdata->sensor_settings->drdy_irq.mask_int2; /* Enable/Disable the interrupt generator for data ready. */ err = st_sensors_write_data_with_mask(indio_dev, - sdata->sensor->drdy_irq.addr, drdy_mask, (int)enable); + sdata->sensor_settings->drdy_irq.addr, + drdy_mask, (int)enable); st_accel_set_dataready_irq_error: return err; @@ -378,8 +386,8 @@ int st_sensors_set_fullscale_by_gain(struct iio_dev *indio_dev, int scale) struct st_sensor_data *sdata = iio_priv(indio_dev); for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) { - if ((sdata->sensor->fs.fs_avl[i].gain == scale) && - (sdata->sensor->fs.fs_avl[i].gain != 0)) { + if ((sdata->sensor_settings->fs.fs_avl[i].gain == scale) && + (sdata->sensor_settings->fs.fs_avl[i].gain != 0)) { err = 0; break; } @@ -388,7 +396,7 @@ int st_sensors_set_fullscale_by_gain(struct iio_dev *indio_dev, int scale) goto st_sensors_match_scale_error; err = st_sensors_set_fullscale(indio_dev, - sdata->sensor->fs.fs_avl[i].num); + sdata->sensor_settings->fs.fs_avl[i].num); st_sensors_match_scale_error: return err; @@ -439,7 +447,7 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev, if (err < 0) goto out; - msleep((sdata->sensor->bootime * 1000) / sdata->odr); + msleep((sdata->sensor_settings->bootime * 1000) / sdata->odr); err = st_sensors_read_axis_data(indio_dev, ch, val); if (err < 0) goto out; @@ -456,7 +464,8 @@ out: EXPORT_SYMBOL(st_sensors_read_info_raw); int st_sensors_check_device_support(struct iio_dev *indio_dev, - int num_sensors_list, const struct st_sensors *sensors) + int num_sensors_list, + const struct st_sensor_settings *sensor_settings) { u8 wai; int i, n, err; @@ -470,23 +479,24 @@ int st_sensors_check_device_support(struct iio_dev *indio_dev, } for (i = 0; i < num_sensors_list; i++) { - if (sensors[i].wai == wai) + if (sensor_settings[i].wai == wai) break; } if (i == num_sensors_list) goto device_not_supported; - for (n = 0; n < ARRAY_SIZE(sensors[i].sensors_supported); n++) { + for (n = 0; n < ARRAY_SIZE(sensor_settings[i].sensors_supported); n++) { if (strcmp(indio_dev->name, - &sensors[i].sensors_supported[n][0]) == 0) + &sensor_settings[i].sensors_supported[n][0]) == 0) break; } - if (n == ARRAY_SIZE(sensors[i].sensors_supported)) { + if (n == ARRAY_SIZE(sensor_settings[i].sensors_supported)) { dev_err(&indio_dev->dev, "device name and WhoAmI mismatch.\n"); goto sensor_name_mismatch; } - sdata->sensor = (struct st_sensors *)&sensors[i]; + sdata->sensor_settings = + (struct st_sensor_settings *)&sensor_settings[i]; return i; @@ -508,11 +518,11 @@ ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev, mutex_lock(&indio_dev->mlock); for (i = 0; i < ST_SENSORS_ODR_LIST_MAX; i++) { - if (sdata->sensor->odr.odr_avl[i].hz == 0) + if (sdata->sensor_settings->odr.odr_avl[i].hz == 0) break; len += scnprintf(buf + len, PAGE_SIZE - len, "%d ", - sdata->sensor->odr.odr_avl[i].hz); + sdata->sensor_settings->odr.odr_avl[i].hz); } mutex_unlock(&indio_dev->mlock); buf[len - 1] = '\n'; @@ -530,11 +540,11 @@ ssize_t st_sensors_sysfs_scale_avail(struct device *dev, mutex_lock(&indio_dev->mlock); for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) { - if (sdata->sensor->fs.fs_avl[i].num == 0) + if (sdata->sensor_settings->fs.fs_avl[i].num == 0) break; len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ", - sdata->sensor->fs.fs_avl[i].gain); + sdata->sensor_settings->fs.fs_avl[i].gain); } mutex_unlock(&indio_dev->mlock); buf[len - 1] = '\n'; diff --git a/drivers/iio/common/st_sensors/st_sensors_i2c.c b/drivers/iio/common/st_sensors/st_sensors_i2c.c index bb6f3085f57b..98cfee296d46 100644 --- a/drivers/iio/common/st_sensors/st_sensors_i2c.c +++ b/drivers/iio/common/st_sensors/st_sensors_i2c.c @@ -72,6 +72,7 @@ void st_sensors_i2c_configure(struct iio_dev *indio_dev, indio_dev->dev.parent = &client->dev; indio_dev->name = client->name; + sdata->dev = &client->dev; sdata->tf = &st_sensors_tf_i2c; sdata->get_irq_data_ready = st_sensors_i2c_get_irq; } diff --git a/drivers/iio/common/st_sensors/st_sensors_spi.c b/drivers/iio/common/st_sensors/st_sensors_spi.c index 251baf6abc25..78a6a1ab3ece 100644 --- a/drivers/iio/common/st_sensors/st_sensors_spi.c +++ b/drivers/iio/common/st_sensors/st_sensors_spi.c @@ -111,6 +111,7 @@ void st_sensors_spi_configure(struct iio_dev *indio_dev, indio_dev->dev.parent = &spi->dev; indio_dev->name = spi->modalias; + sdata->dev = &spi->dev; sdata->tf = &st_sensors_tf_spi; sdata->get_irq_data_ready = st_sensors_spi_get_irq; } diff --git a/drivers/iio/gyro/st_gyro.h b/drivers/iio/gyro/st_gyro.h index c197360c450b..5353d6328c54 100644 --- a/drivers/iio/gyro/st_gyro.h +++ b/drivers/iio/gyro/st_gyro.h @@ -30,8 +30,7 @@ static const struct st_sensors_platform_data gyro_pdata = { .drdy_int_pin = 2, }; -int st_gyro_common_probe(struct iio_dev *indio_dev, - struct st_sensors_platform_data *pdata); +int st_gyro_common_probe(struct iio_dev *indio_dev); void st_gyro_common_remove(struct iio_dev *indio_dev); #ifdef CONFIG_IIO_BUFFER diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c index f156fc6c5c6c..f07a2336f7dc 100644 --- a/drivers/iio/gyro/st_gyro_core.c +++ b/drivers/iio/gyro/st_gyro_core.c @@ -103,7 +103,7 @@ static const struct iio_chan_spec st_gyro_16bit_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(3) }; -static const struct st_sensors st_gyro_sensors[] = { +static const struct st_sensor_settings st_gyro_sensors_settings[] = { { .wai = ST_GYRO_1_WAI_EXP, .sensors_supported = { @@ -309,8 +309,7 @@ static const struct iio_trigger_ops st_gyro_trigger_ops = { #define ST_GYRO_TRIGGER_OPS NULL #endif -int st_gyro_common_probe(struct iio_dev *indio_dev, - struct st_sensors_platform_data *pdata) +int st_gyro_common_probe(struct iio_dev *indio_dev) { struct st_sensor_data *gdata = iio_priv(indio_dev); int irq = gdata->get_irq_data_ready(indio_dev); @@ -322,20 +321,22 @@ int st_gyro_common_probe(struct iio_dev *indio_dev, st_sensors_power_enable(indio_dev); err = st_sensors_check_device_support(indio_dev, - ARRAY_SIZE(st_gyro_sensors), st_gyro_sensors); + ARRAY_SIZE(st_gyro_sensors_settings), + st_gyro_sensors_settings); if (err < 0) return err; gdata->num_data_channels = ST_GYRO_NUMBER_DATA_CHANNELS; - gdata->multiread_bit = gdata->sensor->multi_read_bit; - indio_dev->channels = gdata->sensor->ch; + gdata->multiread_bit = gdata->sensor_settings->multi_read_bit; + indio_dev->channels = gdata->sensor_settings->ch; indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS; gdata->current_fullscale = (struct st_sensor_fullscale_avl *) - &gdata->sensor->fs.fs_avl[0]; - gdata->odr = gdata->sensor->odr.odr_avl[0].hz; + &gdata->sensor_settings->fs.fs_avl[0]; + gdata->odr = gdata->sensor_settings->odr.odr_avl[0].hz; - err = st_sensors_init_sensor(indio_dev, pdata); + err = st_sensors_init_sensor(indio_dev, + (struct st_sensors_platform_data *)&gyro_pdata); if (err < 0) return err; diff --git a/drivers/iio/gyro/st_gyro_i2c.c b/drivers/iio/gyro/st_gyro_i2c.c index 8fa0ad2ef4ef..64480b16c689 100644 --- a/drivers/iio/gyro/st_gyro_i2c.c +++ b/drivers/iio/gyro/st_gyro_i2c.c @@ -67,13 +67,11 @@ static int st_gyro_i2c_probe(struct i2c_client *client, return -ENOMEM; gdata = iio_priv(indio_dev); - gdata->dev = &client->dev; st_sensors_of_i2c_probe(client, st_gyro_of_match); st_sensors_i2c_configure(indio_dev, client, gdata); - err = st_gyro_common_probe(indio_dev, - (struct st_sensors_platform_data *)&gyro_pdata); + err = st_gyro_common_probe(indio_dev); if (err < 0) return err; diff --git a/drivers/iio/gyro/st_gyro_spi.c b/drivers/iio/gyro/st_gyro_spi.c index b4ad3be26687..e59bead6bc3c 100644 --- a/drivers/iio/gyro/st_gyro_spi.c +++ b/drivers/iio/gyro/st_gyro_spi.c @@ -29,12 +29,10 @@ static int st_gyro_spi_probe(struct spi_device *spi) return -ENOMEM; gdata = iio_priv(indio_dev); - gdata->dev = &spi->dev; st_sensors_spi_configure(indio_dev, spi, gdata); - err = st_gyro_common_probe(indio_dev, - (struct st_sensors_platform_data *)&gyro_pdata); + err = st_gyro_common_probe(indio_dev); if (err < 0) return err; diff --git a/drivers/iio/humidity/Kconfig b/drivers/iio/humidity/Kconfig index e116bd8dd0e4..4813b793b9f7 100644 --- a/drivers/iio/humidity/Kconfig +++ b/drivers/iio/humidity/Kconfig @@ -22,4 +22,14 @@ config SI7005 To compile this driver as a module, choose M here: the module will be called si7005. +config SI7020 + tristate "Si7013/20/21 Relative Humidity and Temperature Sensors" + depends on I2C + help + Say yes here to build support for the Silicon Labs Si7013/20/21 + Relative Humidity and Temperature Sensors. + + To compile this driver as a module, choose M here: the module + will be called si7020. + endmenu diff --git a/drivers/iio/humidity/Makefile b/drivers/iio/humidity/Makefile index e3f3d942e646..86e2d26e9f4d 100644 --- a/drivers/iio/humidity/Makefile +++ b/drivers/iio/humidity/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_DHT11) += dht11.o obj-$(CONFIG_SI7005) += si7005.o +obj-$(CONFIG_SI7020) += si7020.o diff --git a/drivers/iio/humidity/si7020.c b/drivers/iio/humidity/si7020.c new file mode 100644 index 000000000000..b54164677b89 --- /dev/null +++ b/drivers/iio/humidity/si7020.c @@ -0,0 +1,161 @@ +/* + * si7020.c - Silicon Labs Si7013/20/21 Relative Humidity and Temp Sensors + * Copyright (c) 2013,2014 Uplogix, Inc. + * David Barksdale <dbarksdale@uplogix.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * The Silicon Labs Si7013/20/21 Relative Humidity and Temperature Sensors + * are i2c devices which have an identical programming interface for + * measuring relative humidity and temperature. The Si7013 has an additional + * temperature input which this driver does not support. + * + * Data Sheets: + * Si7013: http://www.silabs.com/Support%20Documents/TechnicalDocs/Si7013.pdf + * Si7020: http://www.silabs.com/Support%20Documents/TechnicalDocs/Si7020.pdf + * Si7021: http://www.silabs.com/Support%20Documents/TechnicalDocs/Si7021.pdf + */ + +#include <linux/delay.h> +#include <linux/i2c.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/sysfs.h> + +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> + +/* Measure Relative Humidity, Hold Master Mode */ +#define SI7020CMD_RH_HOLD 0xE5 +/* Measure Temperature, Hold Master Mode */ +#define SI7020CMD_TEMP_HOLD 0xE3 +/* Software Reset */ +#define SI7020CMD_RESET 0xFE + +static int si7020_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long mask) +{ + struct i2c_client *client = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = i2c_smbus_read_word_data(client, + chan->type == IIO_TEMP ? + SI7020CMD_TEMP_HOLD : + SI7020CMD_RH_HOLD); + if (ret < 0) + return ret; + *val = ret >> 2; + if (chan->type == IIO_HUMIDITYRELATIVE) + *val &= GENMASK(11, 0); + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + if (chan->type == IIO_TEMP) + *val = 175720; /* = 175.72 * 1000 */ + else + *val = 125 * 1000; + *val2 = 65536 >> 2; + return IIO_VAL_FRACTIONAL; + case IIO_CHAN_INFO_OFFSET: + /* + * Since iio_convert_raw_to_processed_unlocked assumes offset + * is an integer we have to round these values and lose + * accuracy. + * Relative humidity will be 0.0032959% too high and + * temperature will be 0.00277344 degrees too high. + * This is no big deal because it's within the accuracy of the + * sensor. + */ + if (chan->type == IIO_TEMP) + *val = -4368; /* = -46.85 * (65536 >> 2) / 175.72 */ + else + *val = -786; /* = -6 * (65536 >> 2) / 125 */ + return IIO_VAL_INT; + default: + break; + } + + return -EINVAL; +} + +static const struct iio_chan_spec si7020_channels[] = { + { + .type = IIO_HUMIDITYRELATIVE, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET), + }, + { + .type = IIO_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET), + } +}; + +static const struct iio_info si7020_info = { + .read_raw = si7020_read_raw, + .driver_module = THIS_MODULE, +}; + +static int si7020_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct iio_dev *indio_dev; + struct i2c_client **data; + int ret; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_BYTE | + I2C_FUNC_SMBUS_READ_WORD_DATA)) + return -ENODEV; + + /* Reset device, loads default settings. */ + ret = i2c_smbus_write_byte(client, SI7020CMD_RESET); + if (ret < 0) + return ret; + /* Wait the maximum power-up time after software reset. */ + msleep(15); + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*client)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + *data = client; + + indio_dev->dev.parent = &client->dev; + indio_dev->name = dev_name(&client->dev); + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &si7020_info; + indio_dev->channels = si7020_channels; + indio_dev->num_channels = ARRAY_SIZE(si7020_channels); + + return devm_iio_device_register(&client->dev, indio_dev); +} + +static const struct i2c_device_id si7020_id[] = { + { "si7020", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, si7020_id); + +static struct i2c_driver si7020_driver = { + .driver.name = "si7020", + .probe = si7020_probe, + .id_table = si7020_id, +}; + +module_i2c_driver(si7020_driver); +MODULE_DESCRIPTION("Silicon Labs Si7013/20/21 Relative Humidity and Temperature Sensors"); +MODULE_AUTHOR("David Barksdale <dbarksdale@uplogix.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index f0846108d006..90c8cb727cc7 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -100,6 +100,28 @@ static int iio_dev_node_match(struct device *dev, void *data) return dev->of_node == data && dev->type == &iio_device_type; } +/** + * __of_iio_simple_xlate - translate iiospec to the IIO channel index + * @indio_dev: pointer to the iio_dev structure + * @iiospec: IIO specifier as found in the device tree + * + * This is simple translation function, suitable for the most 1:1 mapped + * channels in IIO chips. This function performs only one sanity check: + * whether IIO index is less than num_channels (that is specified in the + * iio_dev). + */ +static int __of_iio_simple_xlate(struct iio_dev *indio_dev, + const struct of_phandle_args *iiospec) +{ + if (!iiospec->args_count) + return 0; + + if (iiospec->args[0] >= indio_dev->num_channels) + return -EINVAL; + + return iiospec->args[0]; +} + static int __of_iio_channel_get(struct iio_channel *channel, struct device_node *np, int index) { @@ -122,18 +144,19 @@ static int __of_iio_channel_get(struct iio_channel *channel, indio_dev = dev_to_iio_dev(idev); channel->indio_dev = indio_dev; - index = iiospec.args_count ? iiospec.args[0] : 0; - if (index >= indio_dev->num_channels) { - err = -EINVAL; + if (indio_dev->info->of_xlate) + index = indio_dev->info->of_xlate(indio_dev, &iiospec); + else + index = __of_iio_simple_xlate(indio_dev, &iiospec); + if (index < 0) goto err_put; - } channel->channel = &indio_dev->channels[index]; return 0; err_put: iio_device_put(indio_dev); - return err; + return index; } static struct iio_channel *of_iio_channel_get(struct device_node *np, int index) @@ -426,6 +449,9 @@ static int iio_channel_read(struct iio_channel *chan, int *val, int *val2, if (val2 == NULL) val2 = &unused; + if(!iio_channel_has_info(chan->channel, info)) + return -EINVAL; + if (chan->indio_dev->info->read_raw_multi) { ret = chan->indio_dev->info->read_raw_multi(chan->indio_dev, chan->channel, INDIO_MAX_RAW_ELEMENTS, diff --git a/drivers/iio/magnetometer/st_magn.h b/drivers/iio/magnetometer/st_magn.h index 694e33e0fb72..7e81d00ef0c3 100644 --- a/drivers/iio/magnetometer/st_magn.h +++ b/drivers/iio/magnetometer/st_magn.h @@ -18,8 +18,7 @@ #define LSM303DLM_MAGN_DEV_NAME "lsm303dlm_magn" #define LIS3MDL_MAGN_DEV_NAME "lis3mdl" -int st_magn_common_probe(struct iio_dev *indio_dev, - struct st_sensors_platform_data *pdata); +int st_magn_common_probe(struct iio_dev *indio_dev); void st_magn_common_remove(struct iio_dev *indio_dev); #ifdef CONFIG_IIO_BUFFER diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c index 68cae86dbd29..8ade473f99fe 100644 --- a/drivers/iio/magnetometer/st_magn_core.c +++ b/drivers/iio/magnetometer/st_magn_core.c @@ -149,7 +149,7 @@ static const struct iio_chan_spec st_magn_2_16bit_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(3) }; -static const struct st_sensors st_magn_sensors[] = { +static const struct st_sensor_settings st_magn_sensors_settings[] = { { .wai = ST_MAGN_1_WAI_EXP, .sensors_supported = { @@ -361,8 +361,7 @@ static const struct iio_info magn_info = { .write_raw = &st_magn_write_raw, }; -int st_magn_common_probe(struct iio_dev *indio_dev, - struct st_sensors_platform_data *pdata) +int st_magn_common_probe(struct iio_dev *indio_dev) { struct st_sensor_data *mdata = iio_priv(indio_dev); int irq = mdata->get_irq_data_ready(indio_dev); @@ -374,20 +373,21 @@ int st_magn_common_probe(struct iio_dev *indio_dev, st_sensors_power_enable(indio_dev); err = st_sensors_check_device_support(indio_dev, - ARRAY_SIZE(st_magn_sensors), st_magn_sensors); + ARRAY_SIZE(st_magn_sensors_settings), + st_magn_sensors_settings); if (err < 0) return err; mdata->num_data_channels = ST_MAGN_NUMBER_DATA_CHANNELS; - mdata->multiread_bit = mdata->sensor->multi_read_bit; - indio_dev->channels = mdata->sensor->ch; + mdata->multiread_bit = mdata->sensor_settings->multi_read_bit; + indio_dev->channels = mdata->sensor_settings->ch; indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS; mdata->current_fullscale = (struct st_sensor_fullscale_avl *) - &mdata->sensor->fs.fs_avl[0]; - mdata->odr = mdata->sensor->odr.odr_avl[0].hz; + &mdata->sensor_settings->fs.fs_avl[0]; + mdata->odr = mdata->sensor_settings->odr.odr_avl[0].hz; - err = st_sensors_init_sensor(indio_dev, pdata); + err = st_sensors_init_sensor(indio_dev, NULL); if (err < 0) return err; diff --git a/drivers/iio/magnetometer/st_magn_i2c.c b/drivers/iio/magnetometer/st_magn_i2c.c index 689250058442..92e5c15452a3 100644 --- a/drivers/iio/magnetometer/st_magn_i2c.c +++ b/drivers/iio/magnetometer/st_magn_i2c.c @@ -51,12 +51,11 @@ static int st_magn_i2c_probe(struct i2c_client *client, return -ENOMEM; mdata = iio_priv(indio_dev); - mdata->dev = &client->dev; st_sensors_of_i2c_probe(client, st_magn_of_match); st_sensors_i2c_configure(indio_dev, client, mdata); - err = st_magn_common_probe(indio_dev, NULL); + err = st_magn_common_probe(indio_dev); if (err < 0) return err; diff --git a/drivers/iio/magnetometer/st_magn_spi.c b/drivers/iio/magnetometer/st_magn_spi.c index a6143ea51dfc..7adacf160146 100644 --- a/drivers/iio/magnetometer/st_magn_spi.c +++ b/drivers/iio/magnetometer/st_magn_spi.c @@ -29,11 +29,10 @@ static int st_magn_spi_probe(struct spi_device *spi) return -ENOMEM; mdata = iio_priv(indio_dev); - mdata->dev = &spi->dev; st_sensors_spi_configure(indio_dev, spi, mdata); - err = st_magn_common_probe(indio_dev, NULL); + err = st_magn_common_probe(indio_dev); if (err < 0) return err; diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig index 15afbc919521..a3be53792072 100644 --- a/drivers/iio/pressure/Kconfig +++ b/drivers/iio/pressure/Kconfig @@ -5,6 +5,17 @@ menu "Pressure sensors" +config BMP280 + tristate "Bosch Sensortec BMP280 pressure sensor driver" + depends on I2C + select REGMAP_I2C + help + Say yes here to build support for Bosch Sensortec BMP280 + pressure and temperature sensor. + + To compile this driver as a module, choose M here: the module + will be called bmp280. + config HID_SENSOR_PRESS depends on HID_SENSOR_HUB select IIO_BUFFER diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile index 90a37e85cf21..88011f2ae00e 100644 --- a/drivers/iio/pressure/Makefile +++ b/drivers/iio/pressure/Makefile @@ -3,6 +3,7 @@ # # When adding new entries keep the list in alphabetical order +obj-$(CONFIG_BMP280) += bmp280.o obj-$(CONFIG_HID_SENSOR_PRESS) += hid-sensor-press.o obj-$(CONFIG_MPL115) += mpl115.o obj-$(CONFIG_MPL3115) += mpl3115.o diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c new file mode 100644 index 000000000000..75038dacfff1 --- /dev/null +++ b/drivers/iio/pressure/bmp280.c @@ -0,0 +1,455 @@ +/* + * Copyright (c) 2014 Intel Corporation + * + * Driver for Bosch Sensortec BMP280 digital pressure sensor. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#define pr_fmt(fmt) "bmp280: " fmt + +#include <linux/module.h> +#include <linux/i2c.h> +#include <linux/acpi.h> +#include <linux/regmap.h> +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> + +#define BMP280_REG_TEMP_XLSB 0xFC +#define BMP280_REG_TEMP_LSB 0xFB +#define BMP280_REG_TEMP_MSB 0xFA +#define BMP280_REG_PRESS_XLSB 0xF9 +#define BMP280_REG_PRESS_LSB 0xF8 +#define BMP280_REG_PRESS_MSB 0xF7 + +#define BMP280_REG_CONFIG 0xF5 +#define BMP280_REG_CTRL_MEAS 0xF4 +#define BMP280_REG_STATUS 0xF3 +#define BMP280_REG_RESET 0xE0 +#define BMP280_REG_ID 0xD0 + +#define BMP280_REG_COMP_TEMP_START 0x88 +#define BMP280_COMP_TEMP_REG_COUNT 6 + +#define BMP280_REG_COMP_PRESS_START 0x8E +#define BMP280_COMP_PRESS_REG_COUNT 18 + +#define BMP280_FILTER_MASK (BIT(4) | BIT(3) | BIT(2)) +#define BMP280_FILTER_OFF 0 +#define BMP280_FILTER_2X BIT(2) +#define BMP280_FILTER_4X BIT(3) +#define BMP280_FILTER_8X (BIT(3) | BIT(2)) +#define BMP280_FILTER_16X BIT(4) + +#define BMP280_OSRS_TEMP_MASK (BIT(7) | BIT(6) | BIT(5)) +#define BMP280_OSRS_TEMP_SKIP 0 +#define BMP280_OSRS_TEMP_1X BIT(5) +#define BMP280_OSRS_TEMP_2X BIT(6) +#define BMP280_OSRS_TEMP_4X (BIT(6) | BIT(5)) +#define BMP280_OSRS_TEMP_8X BIT(7) +#define BMP280_OSRS_TEMP_16X (BIT(7) | BIT(5)) + +#define BMP280_OSRS_PRESS_MASK (BIT(4) | BIT(3) | BIT(2)) +#define BMP280_OSRS_PRESS_SKIP 0 +#define BMP280_OSRS_PRESS_1X BIT(2) +#define BMP280_OSRS_PRESS_2X BIT(3) +#define BMP280_OSRS_PRESS_4X (BIT(3) | BIT(2)) +#define BMP280_OSRS_PRESS_8X BIT(4) +#define BMP280_OSRS_PRESS_16X (BIT(4) | BIT(2)) + +#define BMP280_MODE_MASK (BIT(1) | BIT(0)) +#define BMP280_MODE_SLEEP 0 +#define BMP280_MODE_FORCED BIT(0) +#define BMP280_MODE_NORMAL (BIT(1) | BIT(0)) + +#define BMP280_CHIP_ID 0x58 +#define BMP280_SOFT_RESET_VAL 0xB6 + +struct bmp280_data { + struct i2c_client *client; + struct mutex lock; + struct regmap *regmap; + + /* + * Carryover value from temperature conversion, used in pressure + * calculation. + */ + s32 t_fine; +}; + +/* Compensation parameters. */ +struct bmp280_comp_temp { + u16 dig_t1; + s16 dig_t2, dig_t3; +}; + +struct bmp280_comp_press { + u16 dig_p1; + s16 dig_p2, dig_p3, dig_p4, dig_p5, dig_p6, dig_p7, dig_p8, dig_p9; +}; + +static const struct iio_chan_spec bmp280_channels[] = { + { + .type = IIO_PRESSURE, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + }, + { + .type = IIO_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + }, +}; + +static bool bmp280_is_writeable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case BMP280_REG_CONFIG: + case BMP280_REG_CTRL_MEAS: + case BMP280_REG_RESET: + return true; + default: + return false; + }; +} + +static bool bmp280_is_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case BMP280_REG_TEMP_XLSB: + case BMP280_REG_TEMP_LSB: + case BMP280_REG_TEMP_MSB: + case BMP280_REG_PRESS_XLSB: + case BMP280_REG_PRESS_LSB: + case BMP280_REG_PRESS_MSB: + case BMP280_REG_STATUS: + return true; + default: + return false; + } +} + +static const struct regmap_config bmp280_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = BMP280_REG_TEMP_XLSB, + .cache_type = REGCACHE_RBTREE, + + .writeable_reg = bmp280_is_writeable_reg, + .volatile_reg = bmp280_is_volatile_reg, +}; + +static int bmp280_read_compensation_temp(struct bmp280_data *data, + struct bmp280_comp_temp *comp) +{ + int ret; + __le16 buf[BMP280_COMP_TEMP_REG_COUNT / 2]; + + ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_TEMP_START, + buf, BMP280_COMP_TEMP_REG_COUNT); + if (ret < 0) { + dev_err(&data->client->dev, + "failed to read temperature calibration parameters\n"); + return ret; + } + + comp->dig_t1 = (u16) le16_to_cpu(buf[0]); + comp->dig_t2 = (s16) le16_to_cpu(buf[1]); + comp->dig_t3 = (s16) le16_to_cpu(buf[2]); + + return 0; +} + +static int bmp280_read_compensation_press(struct bmp280_data *data, + struct bmp280_comp_press *comp) +{ + int ret; + __le16 buf[BMP280_COMP_PRESS_REG_COUNT / 2]; + + ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_PRESS_START, + buf, BMP280_COMP_PRESS_REG_COUNT); + if (ret < 0) { + dev_err(&data->client->dev, + "failed to read pressure calibration parameters\n"); + return ret; + } + + comp->dig_p1 = (u16) le16_to_cpu(buf[0]); + comp->dig_p2 = (s16) le16_to_cpu(buf[1]); + comp->dig_p3 = (s16) le16_to_cpu(buf[2]); + comp->dig_p4 = (s16) le16_to_cpu(buf[3]); + comp->dig_p5 = (s16) le16_to_cpu(buf[4]); + comp->dig_p6 = (s16) le16_to_cpu(buf[5]); + comp->dig_p7 = (s16) le16_to_cpu(buf[6]); + comp->dig_p8 = (s16) le16_to_cpu(buf[7]); + comp->dig_p9 = (s16) le16_to_cpu(buf[8]); + + return 0; +} + +/* + * Returns temperature in DegC, resolution is 0.01 DegC. Output value of + * "5123" equals 51.23 DegC. t_fine carries fine temperature as global + * value. + * + * Taken from datasheet, Section 3.11.3, "Compensation formula". + */ +static s32 bmp280_compensate_temp(struct bmp280_data *data, + struct bmp280_comp_temp *comp, + s32 adc_temp) +{ + s32 var1, var2, t; + + var1 = (((adc_temp >> 3) - ((s32) comp->dig_t1 << 1)) * + ((s32) comp->dig_t2)) >> 11; + var2 = (((((adc_temp >> 4) - ((s32) comp->dig_t1)) * + ((adc_temp >> 4) - ((s32) comp->dig_t1))) >> 12) * + ((s32) comp->dig_t3)) >> 14; + + data->t_fine = var1 + var2; + t = (data->t_fine * 5 + 128) >> 8; + + return t; +} + +/* + * Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24 + * integer bits and 8 fractional bits). Output value of "24674867" + * represents 24674867/256 = 96386.2 Pa = 963.862 hPa + * + * Taken from datasheet, Section 3.11.3, "Compensation formula". + */ +static u32 bmp280_compensate_press(struct bmp280_data *data, + struct bmp280_comp_press *comp, + s32 adc_press) +{ + s64 var1, var2, p; + + var1 = ((s64) data->t_fine) - 128000; + var2 = var1 * var1 * (s64) comp->dig_p6; + var2 = var2 + ((var1 * (s64) comp->dig_p5) << 17); + var2 = var2 + (((s64) comp->dig_p4) << 35); + var1 = ((var1 * var1 * (s64) comp->dig_p3) >> 8) + + ((var1 * (s64) comp->dig_p2) << 12); + var1 = (((((s64) 1) << 47) + var1)) * ((s64) comp->dig_p1) >> 33; + + if (var1 == 0) + return 0; + + p = ((((s64) 1048576 - adc_press) << 31) - var2) * 3125; + p = div64_s64(p, var1); + var1 = (((s64) comp->dig_p9) * (p >> 13) * (p >> 13)) >> 25; + var2 = (((s64) comp->dig_p8) * p) >> 19; + p = ((p + var1 + var2) >> 8) + (((s64) comp->dig_p7) << 4); + + return (u32) p; +} + +static int bmp280_read_temp(struct bmp280_data *data, + int *val) +{ + int ret; + __be32 tmp = 0; + s32 adc_temp, comp_temp; + struct bmp280_comp_temp comp; + + ret = bmp280_read_compensation_temp(data, &comp); + if (ret < 0) + return ret; + + ret = regmap_bulk_read(data->regmap, BMP280_REG_TEMP_MSB, + (u8 *) &tmp, 3); + if (ret < 0) { + dev_err(&data->client->dev, "failed to read temperature\n"); + return ret; + } + + adc_temp = be32_to_cpu(tmp) >> 12; + comp_temp = bmp280_compensate_temp(data, &comp, adc_temp); + + /* + * val might be NULL if we're called by the read_press routine, + * who only cares about the carry over t_fine value. + */ + if (val) { + *val = comp_temp * 10; + return IIO_VAL_INT; + } + + return 0; +} + +static int bmp280_read_press(struct bmp280_data *data, + int *val, int *val2) +{ + int ret; + __be32 tmp = 0; + s32 adc_press; + u32 comp_press; + struct bmp280_comp_press comp; + + ret = bmp280_read_compensation_press(data, &comp); + if (ret < 0) + return ret; + + /* Read and compensate temperature so we get a reading of t_fine. */ + ret = bmp280_read_temp(data, NULL); + if (ret < 0) + return ret; + + ret = regmap_bulk_read(data->regmap, BMP280_REG_PRESS_MSB, + (u8 *) &tmp, 3); + if (ret < 0) { + dev_err(&data->client->dev, "failed to read pressure\n"); + return ret; + } + + adc_press = be32_to_cpu(tmp) >> 12; + comp_press = bmp280_compensate_press(data, &comp, adc_press); + + *val = comp_press; + *val2 = 256000; + + return IIO_VAL_FRACTIONAL; +} + +static int bmp280_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + int ret; + struct bmp280_data *data = iio_priv(indio_dev); + + mutex_lock(&data->lock); + + switch (mask) { + case IIO_CHAN_INFO_PROCESSED: + switch (chan->type) { + case IIO_PRESSURE: + ret = bmp280_read_press(data, val, val2); + break; + case IIO_TEMP: + ret = bmp280_read_temp(data, val); + break; + default: + ret = -EINVAL; + break; + } + break; + default: + ret = -EINVAL; + break; + } + + mutex_unlock(&data->lock); + + return ret; +} + +static const struct iio_info bmp280_info = { + .driver_module = THIS_MODULE, + .read_raw = &bmp280_read_raw, +}; + +static int bmp280_chip_init(struct bmp280_data *data) +{ + int ret; + + ret = regmap_update_bits(data->regmap, BMP280_REG_CTRL_MEAS, + BMP280_OSRS_TEMP_MASK | + BMP280_OSRS_PRESS_MASK | + BMP280_MODE_MASK, + BMP280_OSRS_TEMP_2X | + BMP280_OSRS_PRESS_16X | + BMP280_MODE_NORMAL); + if (ret < 0) { + dev_err(&data->client->dev, + "failed to write config register\n"); + return ret; + } + + ret = regmap_update_bits(data->regmap, BMP280_REG_CONFIG, + BMP280_FILTER_MASK, + BMP280_FILTER_4X); + if (ret < 0) { + dev_err(&data->client->dev, + "failed to write config register\n"); + return ret; + } + + return ret; +} + +static int bmp280_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret; + struct iio_dev *indio_dev; + struct bmp280_data *data; + unsigned int chip_id; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + i2c_set_clientdata(client, indio_dev); + data = iio_priv(indio_dev); + mutex_init(&data->lock); + data->client = client; + + indio_dev->dev.parent = &client->dev; + indio_dev->name = id->name; + indio_dev->channels = bmp280_channels; + indio_dev->num_channels = ARRAY_SIZE(bmp280_channels); + indio_dev->info = &bmp280_info; + indio_dev->modes = INDIO_DIRECT_MODE; + + data->regmap = devm_regmap_init_i2c(client, &bmp280_regmap_config); + if (IS_ERR(data->regmap)) { + dev_err(&client->dev, "failed to allocate register map\n"); + return PTR_ERR(data->regmap); + } + + ret = regmap_read(data->regmap, BMP280_REG_ID, &chip_id); + if (ret < 0) + return ret; + if (chip_id != BMP280_CHIP_ID) { + dev_err(&client->dev, "bad chip id. expected %x got %x\n", + BMP280_CHIP_ID, chip_id); + return -EINVAL; + } + + ret = bmp280_chip_init(data); + if (ret < 0) + return ret; + + return devm_iio_device_register(&client->dev, indio_dev); +} + +static const struct acpi_device_id bmp280_acpi_match[] = { + {"BMP0280", 0}, + { }, +}; +MODULE_DEVICE_TABLE(acpi, bmp280_acpi_match); + +static const struct i2c_device_id bmp280_id[] = { + {"bmp280", 0}, + { }, +}; +MODULE_DEVICE_TABLE(i2c, bmp280_id); + +static struct i2c_driver bmp280_driver = { + .driver = { + .name = "bmp280", + .acpi_match_table = ACPI_PTR(bmp280_acpi_match), + }, + .probe = bmp280_probe, + .id_table = bmp280_id, +}; +module_i2c_driver(bmp280_driver); + +MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>"); +MODULE_DESCRIPTION("Driver for Bosch Sensortec BMP280 pressure and temperature sensor"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/pressure/st_pressure.h b/drivers/iio/pressure/st_pressure.h index 242943c0c4e4..f5f41490060b 100644 --- a/drivers/iio/pressure/st_pressure.h +++ b/drivers/iio/pressure/st_pressure.h @@ -26,8 +26,7 @@ static const struct st_sensors_platform_data default_press_pdata = { .drdy_int_pin = 1, }; -int st_press_common_probe(struct iio_dev *indio_dev, - struct st_sensors_platform_data *pdata); +int st_press_common_probe(struct iio_dev *indio_dev); void st_press_common_remove(struct iio_dev *indio_dev); #ifdef CONFIG_IIO_BUFFER diff --git a/drivers/iio/pressure/st_pressure_buffer.c b/drivers/iio/pressure/st_pressure_buffer.c index b37b1c9ac932..2ff53f222352 100644 --- a/drivers/iio/pressure/st_pressure_buffer.c +++ b/drivers/iio/pressure/st_pressure_buffer.c @@ -38,10 +38,10 @@ static int st_press_buffer_preenable(struct iio_dev *indio_dev) static int st_press_buffer_postenable(struct iio_dev *indio_dev) { int err; - struct st_sensor_data *pdata = iio_priv(indio_dev); + struct st_sensor_data *press_data = iio_priv(indio_dev); - pdata->buffer_data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); - if (pdata->buffer_data == NULL) { + press_data->buffer_data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); + if (press_data->buffer_data == NULL) { err = -ENOMEM; goto allocate_memory_error; } @@ -53,7 +53,7 @@ static int st_press_buffer_postenable(struct iio_dev *indio_dev) return err; st_press_buffer_postenable_error: - kfree(pdata->buffer_data); + kfree(press_data->buffer_data); allocate_memory_error: return err; } @@ -61,7 +61,7 @@ allocate_memory_error: static int st_press_buffer_predisable(struct iio_dev *indio_dev) { int err; - struct st_sensor_data *pdata = iio_priv(indio_dev); + struct st_sensor_data *press_data = iio_priv(indio_dev); err = iio_triggered_buffer_predisable(indio_dev); if (err < 0) @@ -70,7 +70,7 @@ static int st_press_buffer_predisable(struct iio_dev *indio_dev) err = st_sensors_set_enable(indio_dev, false); st_press_buffer_predisable_error: - kfree(pdata->buffer_data); + kfree(press_data->buffer_data); return err; } diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c index 473d914ef470..97baf40d424b 100644 --- a/drivers/iio/pressure/st_pressure_core.c +++ b/drivers/iio/pressure/st_pressure_core.c @@ -175,7 +175,7 @@ static const struct iio_chan_spec st_press_lps001wp_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(1) }; -static const struct st_sensors st_press_sensors[] = { +static const struct st_sensor_settings st_press_sensors_settings[] = { { .wai = ST_PRESS_LPS331AP_WAI_EXP, .sensors_supported = { @@ -333,7 +333,7 @@ static int st_press_read_raw(struct iio_dev *indio_dev, int *val2, long mask) { int err; - struct st_sensor_data *pdata = iio_priv(indio_dev); + struct st_sensor_data *press_data = iio_priv(indio_dev); switch (mask) { case IIO_CHAN_INFO_RAW: @@ -347,10 +347,10 @@ static int st_press_read_raw(struct iio_dev *indio_dev, switch (ch->type) { case IIO_PRESSURE: - *val2 = pdata->current_fullscale->gain; + *val2 = press_data->current_fullscale->gain; break; case IIO_TEMP: - *val2 = pdata->current_fullscale->gain2; + *val2 = press_data->current_fullscale->gain2; break; default: err = -EINVAL; @@ -371,7 +371,7 @@ static int st_press_read_raw(struct iio_dev *indio_dev, return IIO_VAL_FRACTIONAL; case IIO_CHAN_INFO_SAMP_FREQ: - *val = pdata->odr; + *val = press_data->odr; return IIO_VAL_INT; default: return -EINVAL; @@ -409,11 +409,10 @@ static const struct iio_trigger_ops st_press_trigger_ops = { #define ST_PRESS_TRIGGER_OPS NULL #endif -int st_press_common_probe(struct iio_dev *indio_dev, - struct st_sensors_platform_data *plat_data) +int st_press_common_probe(struct iio_dev *indio_dev) { - struct st_sensor_data *pdata = iio_priv(indio_dev); - int irq = pdata->get_irq_data_ready(indio_dev); + struct st_sensor_data *press_data = iio_priv(indio_dev); + int irq = press_data->get_irq_data_ready(indio_dev); int err; indio_dev->modes = INDIO_DIRECT_MODE; @@ -422,28 +421,30 @@ int st_press_common_probe(struct iio_dev *indio_dev, st_sensors_power_enable(indio_dev); err = st_sensors_check_device_support(indio_dev, - ARRAY_SIZE(st_press_sensors), - st_press_sensors); + ARRAY_SIZE(st_press_sensors_settings), + st_press_sensors_settings); if (err < 0) return err; - pdata->num_data_channels = ST_PRESS_NUMBER_DATA_CHANNELS; - pdata->multiread_bit = pdata->sensor->multi_read_bit; - indio_dev->channels = pdata->sensor->ch; - indio_dev->num_channels = pdata->sensor->num_ch; + press_data->num_data_channels = ST_PRESS_NUMBER_DATA_CHANNELS; + press_data->multiread_bit = press_data->sensor_settings->multi_read_bit; + indio_dev->channels = press_data->sensor_settings->ch; + indio_dev->num_channels = press_data->sensor_settings->num_ch; - if (pdata->sensor->fs.addr != 0) - pdata->current_fullscale = (struct st_sensor_fullscale_avl *) - &pdata->sensor->fs.fs_avl[0]; + if (press_data->sensor_settings->fs.addr != 0) + press_data->current_fullscale = + (struct st_sensor_fullscale_avl *) + &press_data->sensor_settings->fs.fs_avl[0]; - pdata->odr = pdata->sensor->odr.odr_avl[0].hz; + press_data->odr = press_data->sensor_settings->odr.odr_avl[0].hz; /* Some devices don't support a data ready pin. */ - if (!plat_data && pdata->sensor->drdy_irq.addr) - plat_data = + if (!press_data->dev->platform_data && + press_data->sensor_settings->drdy_irq.addr) + press_data->dev->platform_data = (struct st_sensors_platform_data *)&default_press_pdata; - err = st_sensors_init_sensor(indio_dev, plat_data); + err = st_sensors_init_sensor(indio_dev, press_data->dev->platform_data); if (err < 0) return err; @@ -479,12 +480,12 @@ EXPORT_SYMBOL(st_press_common_probe); void st_press_common_remove(struct iio_dev *indio_dev) { - struct st_sensor_data *pdata = iio_priv(indio_dev); + struct st_sensor_data *press_data = iio_priv(indio_dev); st_sensors_power_disable(indio_dev); iio_device_unregister(indio_dev); - if (pdata->get_irq_data_ready(indio_dev) > 0) + if (press_data->get_irq_data_ready(indio_dev) > 0) st_sensors_deallocate_trigger(indio_dev); st_press_deallocate_ring(indio_dev); diff --git a/drivers/iio/pressure/st_pressure_i2c.c b/drivers/iio/pressure/st_pressure_i2c.c index acaf165260bb..137788bba4a3 100644 --- a/drivers/iio/pressure/st_pressure_i2c.c +++ b/drivers/iio/pressure/st_pressure_i2c.c @@ -43,20 +43,19 @@ static int st_press_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct iio_dev *indio_dev; - struct st_sensor_data *pdata; + struct st_sensor_data *press_data; int err; - indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*pdata)); + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*press_data)); if (!indio_dev) return -ENOMEM; - pdata = iio_priv(indio_dev); - pdata->dev = &client->dev; + press_data = iio_priv(indio_dev); st_sensors_of_i2c_probe(client, st_press_of_match); - st_sensors_i2c_configure(indio_dev, client, pdata); + st_sensors_i2c_configure(indio_dev, client, press_data); - err = st_press_common_probe(indio_dev, client->dev.platform_data); + err = st_press_common_probe(indio_dev); if (err < 0) return err; diff --git a/drivers/iio/pressure/st_pressure_spi.c b/drivers/iio/pressure/st_pressure_spi.c index f45d430ec529..1ffa6d4d349c 100644 --- a/drivers/iio/pressure/st_pressure_spi.c +++ b/drivers/iio/pressure/st_pressure_spi.c @@ -21,19 +21,18 @@ static int st_press_spi_probe(struct spi_device *spi) { struct iio_dev *indio_dev; - struct st_sensor_data *pdata; + struct st_sensor_data *press_data; int err; - indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*pdata)); + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*press_data)); if (indio_dev == NULL) return -ENOMEM; - pdata = iio_priv(indio_dev); - pdata->dev = &spi->dev; + press_data = iio_priv(indio_dev); - st_sensors_spi_configure(indio_dev, spi, pdata); + st_sensors_spi_configure(indio_dev, spi, press_data); - err = st_press_common_probe(indio_dev, spi->dev.platform_data); + err = st_press_common_probe(indio_dev); if (err < 0) return err; diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c index 8349cc0fdf66..466aa4314667 100644 --- a/drivers/iio/proximity/as3935.c +++ b/drivers/iio/proximity/as3935.c @@ -95,7 +95,7 @@ static int as3935_read(struct as3935_state *st, unsigned int reg, int *val) *val = ret; return 0; -}; +} static int as3935_write(struct as3935_state *st, unsigned int reg, @@ -107,7 +107,7 @@ static int as3935_write(struct as3935_state *st, buf[1] = val; return spi_write(st->spi, buf, 2); -}; +} static ssize_t as3935_sensor_sensitivity_show(struct device *dev, struct device_attribute *attr, @@ -122,7 +122,7 @@ static ssize_t as3935_sensor_sensitivity_show(struct device *dev, val = (val & AS3935_AFE_MASK) >> 1; return sprintf(buf, "%d\n", val); -}; +} static ssize_t as3935_sensor_sensitivity_store(struct device *dev, struct device_attribute *attr, @@ -142,7 +142,7 @@ static ssize_t as3935_sensor_sensitivity_store(struct device *dev, as3935_write(st, AS3935_AFE_GAIN, val << 1); return len; -}; +} static IIO_DEVICE_ATTR(sensor_sensitivity, S_IRUGO | S_IWUSR, as3935_sensor_sensitivity_show, as3935_sensor_sensitivity_store, 0); @@ -214,7 +214,7 @@ err_read: iio_trigger_notify_done(indio_dev->trig); return IRQ_HANDLED; -}; +} static const struct iio_trigger_ops iio_interrupt_trigger_ops = { .owner = THIS_MODULE, @@ -238,7 +238,7 @@ static void as3935_event_work(struct work_struct *work) dev_warn(&st->spi->dev, "noise level is too high"); break; } -}; +} static irqreturn_t as3935_interrupt_handler(int irq, void *private) { @@ -417,7 +417,7 @@ unregister_trigger: iio_trigger_unregister(st->trig); return ret; -}; +} static int as3935_remove(struct spi_device *spi) { @@ -429,7 +429,7 @@ static int as3935_remove(struct spi_device *spi) iio_trigger_unregister(st->trig); return 0; -}; +} static const struct spi_device_id as3935_id[] = { {"as3935", 0}, diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig index 77089399359b..b899531498eb 100644 --- a/drivers/infiniband/Kconfig +++ b/drivers/infiniband/Kconfig @@ -38,6 +38,17 @@ config INFINIBAND_USER_MEM depends on INFINIBAND_USER_ACCESS != n default y +config INFINIBAND_ON_DEMAND_PAGING + bool "InfiniBand on-demand paging support" + depends on INFINIBAND_USER_MEM + select MMU_NOTIFIER + default y + ---help--- + On demand paging support for the InfiniBand subsystem. + Together with driver support this allows registration of + memory regions without pinning their pages, fetching the + pages on demand instead. + config INFINIBAND_ADDR_TRANS bool depends on INFINIBAND diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile index ffd0af6734af..acf736764445 100644 --- a/drivers/infiniband/core/Makefile +++ b/drivers/infiniband/core/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o ib_ucm.o \ ib_core-y := packer.o ud_header.o verbs.o sysfs.o \ device.o fmr_pool.o cache.o netlink.o ib_core-$(CONFIG_INFINIBAND_USER_MEM) += umem.o +ib_core-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += umem_odp.o umem_rbtree.o ib_mad-y := mad.o smi.o agent.o mad_rmpp.o diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 8172d37f9add..f80da50d84a5 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -176,8 +176,8 @@ static void set_timeout(unsigned long time) unsigned long delay; delay = time - jiffies; - if ((long)delay <= 0) - delay = 1; + if ((long)delay < 0) + delay = 0; mod_delayed_work(addr_wq, &work, delay); } diff --git a/drivers/infiniband/core/multicast.c b/drivers/infiniband/core/multicast.c index d2360a8ef0b2..fa17b552ff78 100644 --- a/drivers/infiniband/core/multicast.c +++ b/drivers/infiniband/core/multicast.c @@ -525,17 +525,22 @@ static void join_handler(int status, struct ib_sa_mcmember_rec *rec, if (status) process_join_error(group, status); else { + int mgids_changed, is_mgid0; ib_find_pkey(group->port->dev->device, group->port->port_num, be16_to_cpu(rec->pkey), &pkey_index); spin_lock_irq(&group->port->lock); - group->rec = *rec; if (group->state == MCAST_BUSY && group->pkey_index == MCAST_INVALID_PKEY_INDEX) group->pkey_index = pkey_index; - if (!memcmp(&mgid0, &group->rec.mgid, sizeof mgid0)) { + mgids_changed = memcmp(&rec->mgid, &group->rec.mgid, + sizeof(group->rec.mgid)); + group->rec = *rec; + if (mgids_changed) { rb_erase(&group->node, &group->port->table); - mcast_insert(group->port, group, 1); + is_mgid0 = !memcmp(&mgid0, &group->rec.mgid, + sizeof(mgid0)); + mcast_insert(group->port, group, is_mgid0); } spin_unlock_irq(&group->port->lock); } diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index df0c4f605a21..aec7a6aa2951 100644 --- a/drivers/infiniband/core/umem.c +++ b/drivers/infiniband/core/umem.c @@ -39,6 +39,7 @@ #include <linux/hugetlb.h> #include <linux/dma-attrs.h> #include <linux/slab.h> +#include <rdma/ib_umem_odp.h> #include "uverbs.h" @@ -69,6 +70,10 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d /** * ib_umem_get - Pin and DMA map userspace memory. + * + * If access flags indicate ODP memory, avoid pinning. Instead, stores + * the mm for future page fault handling in conjunction with MMU notifiers. + * * @context: userspace context to pin memory for * @addr: userspace virtual address to start at * @size: length of region to pin @@ -103,17 +108,30 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, umem->context = context; umem->length = size; - umem->offset = addr & ~PAGE_MASK; + umem->address = addr; umem->page_size = PAGE_SIZE; umem->pid = get_task_pid(current, PIDTYPE_PID); /* - * We ask for writable memory if any access flags other than - * "remote read" are set. "Local write" and "remote write" + * We ask for writable memory if any of the following + * access flags are set. "Local write" and "remote write" * obviously require write access. "Remote atomic" can do * things like fetch and add, which will modify memory, and * "MW bind" can change permissions by binding a window. */ - umem->writable = !!(access & ~IB_ACCESS_REMOTE_READ); + umem->writable = !!(access & + (IB_ACCESS_LOCAL_WRITE | IB_ACCESS_REMOTE_WRITE | + IB_ACCESS_REMOTE_ATOMIC | IB_ACCESS_MW_BIND)); + + if (access & IB_ACCESS_ON_DEMAND) { + ret = ib_umem_odp_get(context, umem); + if (ret) { + kfree(umem); + return ERR_PTR(ret); + } + return umem; + } + + umem->odp_data = NULL; /* We assume the memory is from hugetlb until proved otherwise */ umem->hugetlb = 1; @@ -132,7 +150,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, if (!vma_list) umem->hugetlb = 0; - npages = PAGE_ALIGN(size + umem->offset) >> PAGE_SHIFT; + npages = ib_umem_num_pages(umem); down_write(¤t->mm->mmap_sem); @@ -235,6 +253,11 @@ void ib_umem_release(struct ib_umem *umem) struct task_struct *task; unsigned long diff; + if (umem->odp_data) { + ib_umem_odp_release(umem); + return; + } + __ib_umem_release(umem->context->device, umem, 1); task = get_pid_task(umem->pid, PIDTYPE_PID); @@ -246,7 +269,7 @@ void ib_umem_release(struct ib_umem *umem) if (!mm) goto out; - diff = PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT; + diff = ib_umem_num_pages(umem); /* * We may be called with the mm's mmap_sem already held. This @@ -283,6 +306,9 @@ int ib_umem_page_count(struct ib_umem *umem) int n; struct scatterlist *sg; + if (umem->odp_data) + return ib_umem_num_pages(umem); + shift = ilog2(umem->page_size); n = 0; @@ -292,3 +318,37 @@ int ib_umem_page_count(struct ib_umem *umem) return n; } EXPORT_SYMBOL(ib_umem_page_count); + +/* + * Copy from the given ib_umem's pages to the given buffer. + * + * umem - the umem to copy from + * offset - offset to start copying from + * dst - destination buffer + * length - buffer length + * + * Returns 0 on success, or an error code. + */ +int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offset, + size_t length) +{ + size_t end = offset + length; + int ret; + + if (offset > umem->length || length > umem->length - offset) { + pr_err("ib_umem_copy_from not in range. offset: %zd umem length: %zd end: %zd\n", + offset, umem->length, end); + return -EINVAL; + } + + ret = sg_pcopy_to_buffer(umem->sg_head.sgl, umem->nmap, dst, length, + offset + ib_umem_offset(umem)); + + if (ret < 0) + return ret; + else if (ret != length) + return -EINVAL; + else + return 0; +} +EXPORT_SYMBOL(ib_umem_copy_from); diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c new file mode 100644 index 000000000000..6095872549e7 --- /dev/null +++ b/drivers/infiniband/core/umem_odp.c @@ -0,0 +1,668 @@ +/* + * Copyright (c) 2014 Mellanox Technologies. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <linux/types.h> +#include <linux/sched.h> +#include <linux/pid.h> +#include <linux/slab.h> +#include <linux/export.h> +#include <linux/vmalloc.h> + +#include <rdma/ib_verbs.h> +#include <rdma/ib_umem.h> +#include <rdma/ib_umem_odp.h> + +static void ib_umem_notifier_start_account(struct ib_umem *item) +{ + mutex_lock(&item->odp_data->umem_mutex); + + /* Only update private counters for this umem if it has them. + * Otherwise skip it. All page faults will be delayed for this umem. */ + if (item->odp_data->mn_counters_active) { + int notifiers_count = item->odp_data->notifiers_count++; + + if (notifiers_count == 0) + /* Initialize the completion object for waiting on + * notifiers. Since notifier_count is zero, no one + * should be waiting right now. */ + reinit_completion(&item->odp_data->notifier_completion); + } + mutex_unlock(&item->odp_data->umem_mutex); +} + +static void ib_umem_notifier_end_account(struct ib_umem *item) +{ + mutex_lock(&item->odp_data->umem_mutex); + + /* Only update private counters for this umem if it has them. + * Otherwise skip it. All page faults will be delayed for this umem. */ + if (item->odp_data->mn_counters_active) { + /* + * This sequence increase will notify the QP page fault that + * the page that is going to be mapped in the spte could have + * been freed. + */ + ++item->odp_data->notifiers_seq; + if (--item->odp_data->notifiers_count == 0) + complete_all(&item->odp_data->notifier_completion); + } + mutex_unlock(&item->odp_data->umem_mutex); +} + +/* Account for a new mmu notifier in an ib_ucontext. */ +static void ib_ucontext_notifier_start_account(struct ib_ucontext *context) +{ + atomic_inc(&context->notifier_count); +} + +/* Account for a terminating mmu notifier in an ib_ucontext. + * + * Must be called with the ib_ucontext->umem_rwsem semaphore unlocked, since + * the function takes the semaphore itself. */ +static void ib_ucontext_notifier_end_account(struct ib_ucontext *context) +{ + int zero_notifiers = atomic_dec_and_test(&context->notifier_count); + + if (zero_notifiers && + !list_empty(&context->no_private_counters)) { + /* No currently running mmu notifiers. Now is the chance to + * add private accounting to all previously added umems. */ + struct ib_umem_odp *odp_data, *next; + + /* Prevent concurrent mmu notifiers from working on the + * no_private_counters list. */ + down_write(&context->umem_rwsem); + + /* Read the notifier_count again, with the umem_rwsem + * semaphore taken for write. */ + if (!atomic_read(&context->notifier_count)) { + list_for_each_entry_safe(odp_data, next, + &context->no_private_counters, + no_private_counters) { + mutex_lock(&odp_data->umem_mutex); + odp_data->mn_counters_active = true; + list_del(&odp_data->no_private_counters); + complete_all(&odp_data->notifier_completion); + mutex_unlock(&odp_data->umem_mutex); + } + } + + up_write(&context->umem_rwsem); + } +} + +static int ib_umem_notifier_release_trampoline(struct ib_umem *item, u64 start, + u64 end, void *cookie) { + /* + * Increase the number of notifiers running, to + * prevent any further fault handling on this MR. + */ + ib_umem_notifier_start_account(item); + item->odp_data->dying = 1; + /* Make sure that the fact the umem is dying is out before we release + * all pending page faults. */ + smp_wmb(); + complete_all(&item->odp_data->notifier_completion); + item->context->invalidate_range(item, ib_umem_start(item), + ib_umem_end(item)); + return 0; +} + +static void ib_umem_notifier_release(struct mmu_notifier *mn, + struct mm_struct *mm) +{ + struct ib_ucontext *context = container_of(mn, struct ib_ucontext, mn); + + if (!context->invalidate_range) + return; + + ib_ucontext_notifier_start_account(context); + down_read(&context->umem_rwsem); + rbt_ib_umem_for_each_in_range(&context->umem_tree, 0, + ULLONG_MAX, + ib_umem_notifier_release_trampoline, + NULL); + up_read(&context->umem_rwsem); +} + +static int invalidate_page_trampoline(struct ib_umem *item, u64 start, + u64 end, void *cookie) +{ + ib_umem_notifier_start_account(item); + item->context->invalidate_range(item, start, start + PAGE_SIZE); + ib_umem_notifier_end_account(item); + return 0; +} + +static void ib_umem_notifier_invalidate_page(struct mmu_notifier *mn, + struct mm_struct *mm, + unsigned long address) +{ + struct ib_ucontext *context = container_of(mn, struct ib_ucontext, mn); + + if (!context->invalidate_range) + return; + + ib_ucontext_notifier_start_account(context); + down_read(&context->umem_rwsem); + rbt_ib_umem_for_each_in_range(&context->umem_tree, address, + address + PAGE_SIZE, + invalidate_page_trampoline, NULL); + up_read(&context->umem_rwsem); + ib_ucontext_notifier_end_account(context); +} + +static int invalidate_range_start_trampoline(struct ib_umem *item, u64 start, + u64 end, void *cookie) +{ + ib_umem_notifier_start_account(item); + item->context->invalidate_range(item, start, end); + return 0; +} + +static void ib_umem_notifier_invalidate_range_start(struct mmu_notifier *mn, + struct mm_struct *mm, + unsigned long start, + unsigned long end) +{ + struct ib_ucontext *context = container_of(mn, struct ib_ucontext, mn); + + if (!context->invalidate_range) + return; + + ib_ucontext_notifier_start_account(context); + down_read(&context->umem_rwsem); + rbt_ib_umem_for_each_in_range(&context->umem_tree, start, + end, + invalidate_range_start_trampoline, NULL); + up_read(&context->umem_rwsem); +} + +static int invalidate_range_end_trampoline(struct ib_umem *item, u64 start, + u64 end, void *cookie) +{ + ib_umem_notifier_end_account(item); + return 0; +} + +static void ib_umem_notifier_invalidate_range_end(struct mmu_notifier *mn, + struct mm_struct *mm, + unsigned long start, + unsigned long end) +{ + struct ib_ucontext *context = container_of(mn, struct ib_ucontext, mn); + + if (!context->invalidate_range) + return; + + down_read(&context->umem_rwsem); + rbt_ib_umem_for_each_in_range(&context->umem_tree, start, + end, + invalidate_range_end_trampoline, NULL); + up_read(&context->umem_rwsem); + ib_ucontext_notifier_end_account(context); +} + +static struct mmu_notifier_ops ib_umem_notifiers = { + .release = ib_umem_notifier_release, + .invalidate_page = ib_umem_notifier_invalidate_page, + .invalidate_range_start = ib_umem_notifier_invalidate_range_start, + .invalidate_range_end = ib_umem_notifier_invalidate_range_end, +}; + +int ib_umem_odp_get(struct ib_ucontext *context, struct ib_umem *umem) +{ + int ret_val; + struct pid *our_pid; + struct mm_struct *mm = get_task_mm(current); + + if (!mm) + return -EINVAL; + + /* Prevent creating ODP MRs in child processes */ + rcu_read_lock(); + our_pid = get_task_pid(current->group_leader, PIDTYPE_PID); + rcu_read_unlock(); + put_pid(our_pid); + if (context->tgid != our_pid) { + ret_val = -EINVAL; + goto out_mm; + } + + umem->hugetlb = 0; + umem->odp_data = kzalloc(sizeof(*umem->odp_data), GFP_KERNEL); + if (!umem->odp_data) { + ret_val = -ENOMEM; + goto out_mm; + } + umem->odp_data->umem = umem; + + mutex_init(&umem->odp_data->umem_mutex); + + init_completion(&umem->odp_data->notifier_completion); + + umem->odp_data->page_list = vzalloc(ib_umem_num_pages(umem) * + sizeof(*umem->odp_data->page_list)); + if (!umem->odp_data->page_list) { + ret_val = -ENOMEM; + goto out_odp_data; + } + + umem->odp_data->dma_list = vzalloc(ib_umem_num_pages(umem) * + sizeof(*umem->odp_data->dma_list)); + if (!umem->odp_data->dma_list) { + ret_val = -ENOMEM; + goto out_page_list; + } + + /* + * When using MMU notifiers, we will get a + * notification before the "current" task (and MM) is + * destroyed. We use the umem_rwsem semaphore to synchronize. + */ + down_write(&context->umem_rwsem); + context->odp_mrs_count++; + if (likely(ib_umem_start(umem) != ib_umem_end(umem))) + rbt_ib_umem_insert(&umem->odp_data->interval_tree, + &context->umem_tree); + if (likely(!atomic_read(&context->notifier_count))) + umem->odp_data->mn_counters_active = true; + else + list_add(&umem->odp_data->no_private_counters, + &context->no_private_counters); + downgrade_write(&context->umem_rwsem); + + if (context->odp_mrs_count == 1) { + /* + * Note that at this point, no MMU notifier is running + * for this context! + */ + atomic_set(&context->notifier_count, 0); + INIT_HLIST_NODE(&context->mn.hlist); + context->mn.ops = &ib_umem_notifiers; + /* + * Lock-dep detects a false positive for mmap_sem vs. + * umem_rwsem, due to not grasping downgrade_write correctly. + */ + lockdep_off(); + ret_val = mmu_notifier_register(&context->mn, mm); + lockdep_on(); + if (ret_val) { + pr_err("Failed to register mmu_notifier %d\n", ret_val); + ret_val = -EBUSY; + goto out_mutex; + } + } + + up_read(&context->umem_rwsem); + + /* + * Note that doing an mmput can cause a notifier for the relevant mm. + * If the notifier is called while we hold the umem_rwsem, this will + * cause a deadlock. Therefore, we release the reference only after we + * released the semaphore. + */ + mmput(mm); + return 0; + +out_mutex: + up_read(&context->umem_rwsem); + vfree(umem->odp_data->dma_list); +out_page_list: + vfree(umem->odp_data->page_list); +out_odp_data: + kfree(umem->odp_data); +out_mm: + mmput(mm); + return ret_val; +} + +void ib_umem_odp_release(struct ib_umem *umem) +{ + struct ib_ucontext *context = umem->context; + + /* + * Ensure that no more pages are mapped in the umem. + * + * It is the driver's responsibility to ensure, before calling us, + * that the hardware will not attempt to access the MR any more. + */ + ib_umem_odp_unmap_dma_pages(umem, ib_umem_start(umem), + ib_umem_end(umem)); + + down_write(&context->umem_rwsem); + if (likely(ib_umem_start(umem) != ib_umem_end(umem))) + rbt_ib_umem_remove(&umem->odp_data->interval_tree, + &context->umem_tree); + context->odp_mrs_count--; + if (!umem->odp_data->mn_counters_active) { + list_del(&umem->odp_data->no_private_counters); + complete_all(&umem->odp_data->notifier_completion); + } + + /* + * Downgrade the lock to a read lock. This ensures that the notifiers + * (who lock the mutex for reading) will be able to finish, and we + * will be able to enventually obtain the mmu notifiers SRCU. Note + * that since we are doing it atomically, no other user could register + * and unregister while we do the check. + */ + downgrade_write(&context->umem_rwsem); + if (!context->odp_mrs_count) { + struct task_struct *owning_process = NULL; + struct mm_struct *owning_mm = NULL; + + owning_process = get_pid_task(context->tgid, + PIDTYPE_PID); + if (owning_process == NULL) + /* + * The process is already dead, notifier were removed + * already. + */ + goto out; + + owning_mm = get_task_mm(owning_process); + if (owning_mm == NULL) + /* + * The process' mm is already dead, notifier were + * removed already. + */ + goto out_put_task; + mmu_notifier_unregister(&context->mn, owning_mm); + + mmput(owning_mm); + +out_put_task: + put_task_struct(owning_process); + } +out: + up_read(&context->umem_rwsem); + + vfree(umem->odp_data->dma_list); + vfree(umem->odp_data->page_list); + kfree(umem->odp_data); + kfree(umem); +} + +/* + * Map for DMA and insert a single page into the on-demand paging page tables. + * + * @umem: the umem to insert the page to. + * @page_index: index in the umem to add the page to. + * @page: the page struct to map and add. + * @access_mask: access permissions needed for this page. + * @current_seq: sequence number for synchronization with invalidations. + * the sequence number is taken from + * umem->odp_data->notifiers_seq. + * + * The function returns -EFAULT if the DMA mapping operation fails. It returns + * -EAGAIN if a concurrent invalidation prevents us from updating the page. + * + * The page is released via put_page even if the operation failed. For + * on-demand pinning, the page is released whenever it isn't stored in the + * umem. + */ +static int ib_umem_odp_map_dma_single_page( + struct ib_umem *umem, + int page_index, + u64 base_virt_addr, + struct page *page, + u64 access_mask, + unsigned long current_seq) +{ + struct ib_device *dev = umem->context->device; + dma_addr_t dma_addr; + int stored_page = 0; + int remove_existing_mapping = 0; + int ret = 0; + + mutex_lock(&umem->odp_data->umem_mutex); + /* + * Note: we avoid writing if seq is different from the initial seq, to + * handle case of a racing notifier. This check also allows us to bail + * early if we have a notifier running in parallel with us. + */ + if (ib_umem_mmu_notifier_retry(umem, current_seq)) { + ret = -EAGAIN; + goto out; + } + if (!(umem->odp_data->dma_list[page_index])) { + dma_addr = ib_dma_map_page(dev, + page, + 0, PAGE_SIZE, + DMA_BIDIRECTIONAL); + if (ib_dma_mapping_error(dev, dma_addr)) { + ret = -EFAULT; + goto out; + } + umem->odp_data->dma_list[page_index] = dma_addr | access_mask; + umem->odp_data->page_list[page_index] = page; + stored_page = 1; + } else if (umem->odp_data->page_list[page_index] == page) { + umem->odp_data->dma_list[page_index] |= access_mask; + } else { + pr_err("error: got different pages in IB device and from get_user_pages. IB device page: %p, gup page: %p\n", + umem->odp_data->page_list[page_index], page); + /* Better remove the mapping now, to prevent any further + * damage. */ + remove_existing_mapping = 1; + } + +out: + mutex_unlock(&umem->odp_data->umem_mutex); + + /* On Demand Paging - avoid pinning the page */ + if (umem->context->invalidate_range || !stored_page) + put_page(page); + + if (remove_existing_mapping && umem->context->invalidate_range) { + invalidate_page_trampoline( + umem, + base_virt_addr + (page_index * PAGE_SIZE), + base_virt_addr + ((page_index+1)*PAGE_SIZE), + NULL); + ret = -EAGAIN; + } + + return ret; +} + +/** + * ib_umem_odp_map_dma_pages - Pin and DMA map userspace memory in an ODP MR. + * + * Pins the range of pages passed in the argument, and maps them to + * DMA addresses. The DMA addresses of the mapped pages is updated in + * umem->odp_data->dma_list. + * + * Returns the number of pages mapped in success, negative error code + * for failure. + * An -EAGAIN error code is returned when a concurrent mmu notifier prevents + * the function from completing its task. + * + * @umem: the umem to map and pin + * @user_virt: the address from which we need to map. + * @bcnt: the minimal number of bytes to pin and map. The mapping might be + * bigger due to alignment, and may also be smaller in case of an error + * pinning or mapping a page. The actual pages mapped is returned in + * the return value. + * @access_mask: bit mask of the requested access permissions for the given + * range. + * @current_seq: the MMU notifiers sequance value for synchronization with + * invalidations. the sequance number is read from + * umem->odp_data->notifiers_seq before calling this function + */ +int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt, + u64 access_mask, unsigned long current_seq) +{ + struct task_struct *owning_process = NULL; + struct mm_struct *owning_mm = NULL; + struct page **local_page_list = NULL; + u64 off; + int j, k, ret = 0, start_idx, npages = 0; + u64 base_virt_addr; + + if (access_mask == 0) + return -EINVAL; + + if (user_virt < ib_umem_start(umem) || + user_virt + bcnt > ib_umem_end(umem)) + return -EFAULT; + + local_page_list = (struct page **)__get_free_page(GFP_KERNEL); + if (!local_page_list) + return -ENOMEM; + + off = user_virt & (~PAGE_MASK); + user_virt = user_virt & PAGE_MASK; + base_virt_addr = user_virt; + bcnt += off; /* Charge for the first page offset as well. */ + + owning_process = get_pid_task(umem->context->tgid, PIDTYPE_PID); + if (owning_process == NULL) { + ret = -EINVAL; + goto out_no_task; + } + + owning_mm = get_task_mm(owning_process); + if (owning_mm == NULL) { + ret = -EINVAL; + goto out_put_task; + } + + start_idx = (user_virt - ib_umem_start(umem)) >> PAGE_SHIFT; + k = start_idx; + + while (bcnt > 0) { + const size_t gup_num_pages = + min_t(size_t, ALIGN(bcnt, PAGE_SIZE) / PAGE_SIZE, + PAGE_SIZE / sizeof(struct page *)); + + down_read(&owning_mm->mmap_sem); + /* + * Note: this might result in redundent page getting. We can + * avoid this by checking dma_list to be 0 before calling + * get_user_pages. However, this make the code much more + * complex (and doesn't gain us much performance in most use + * cases). + */ + npages = get_user_pages(owning_process, owning_mm, user_virt, + gup_num_pages, + access_mask & ODP_WRITE_ALLOWED_BIT, 0, + local_page_list, NULL); + up_read(&owning_mm->mmap_sem); + + if (npages < 0) + break; + + bcnt -= min_t(size_t, npages << PAGE_SHIFT, bcnt); + user_virt += npages << PAGE_SHIFT; + for (j = 0; j < npages; ++j) { + ret = ib_umem_odp_map_dma_single_page( + umem, k, base_virt_addr, local_page_list[j], + access_mask, current_seq); + if (ret < 0) + break; + k++; + } + + if (ret < 0) { + /* Release left over pages when handling errors. */ + for (++j; j < npages; ++j) + put_page(local_page_list[j]); + break; + } + } + + if (ret >= 0) { + if (npages < 0 && k == start_idx) + ret = npages; + else + ret = k - start_idx; + } + + mmput(owning_mm); +out_put_task: + put_task_struct(owning_process); +out_no_task: + free_page((unsigned long)local_page_list); + return ret; +} +EXPORT_SYMBOL(ib_umem_odp_map_dma_pages); + +void ib_umem_odp_unmap_dma_pages(struct ib_umem *umem, u64 virt, + u64 bound) +{ + int idx; + u64 addr; + struct ib_device *dev = umem->context->device; + + virt = max_t(u64, virt, ib_umem_start(umem)); + bound = min_t(u64, bound, ib_umem_end(umem)); + /* Note that during the run of this function, the + * notifiers_count of the MR is > 0, preventing any racing + * faults from completion. We might be racing with other + * invalidations, so we must make sure we free each page only + * once. */ + for (addr = virt; addr < bound; addr += (u64)umem->page_size) { + idx = (addr - ib_umem_start(umem)) / PAGE_SIZE; + mutex_lock(&umem->odp_data->umem_mutex); + if (umem->odp_data->page_list[idx]) { + struct page *page = umem->odp_data->page_list[idx]; + struct page *head_page = compound_head(page); + dma_addr_t dma = umem->odp_data->dma_list[idx]; + dma_addr_t dma_addr = dma & ODP_DMA_ADDR_MASK; + + WARN_ON(!dma_addr); + + ib_dma_unmap_page(dev, dma_addr, PAGE_SIZE, + DMA_BIDIRECTIONAL); + if (dma & ODP_WRITE_ALLOWED_BIT) + /* + * set_page_dirty prefers being called with + * the page lock. However, MMU notifiers are + * called sometimes with and sometimes without + * the lock. We rely on the umem_mutex instead + * to prevent other mmu notifiers from + * continuing and allowing the page mapping to + * be removed. + */ + set_page_dirty(head_page); + /* on demand pinning support */ + if (!umem->context->invalidate_range) + put_page(page); + umem->odp_data->page_list[idx] = NULL; + umem->odp_data->dma_list[idx] = 0; + } + mutex_unlock(&umem->odp_data->umem_mutex); + } +} +EXPORT_SYMBOL(ib_umem_odp_unmap_dma_pages); diff --git a/drivers/infiniband/core/umem_rbtree.c b/drivers/infiniband/core/umem_rbtree.c new file mode 100644 index 000000000000..727d788448f5 --- /dev/null +++ b/drivers/infiniband/core/umem_rbtree.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2014 Mellanox Technologies. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/interval_tree_generic.h> +#include <linux/sched.h> +#include <linux/gfp.h> +#include <rdma/ib_umem_odp.h> + +/* + * The ib_umem list keeps track of memory regions for which the HW + * device request to receive notification when the related memory + * mapping is changed. + * + * ib_umem_lock protects the list. + */ + +static inline u64 node_start(struct umem_odp_node *n) +{ + struct ib_umem_odp *umem_odp = + container_of(n, struct ib_umem_odp, interval_tree); + + return ib_umem_start(umem_odp->umem); +} + +/* Note that the representation of the intervals in the interval tree + * considers the ending point as contained in the interval, while the + * function ib_umem_end returns the first address which is not contained + * in the umem. + */ +static inline u64 node_last(struct umem_odp_node *n) +{ + struct ib_umem_odp *umem_odp = + container_of(n, struct ib_umem_odp, interval_tree); + + return ib_umem_end(umem_odp->umem) - 1; +} + +INTERVAL_TREE_DEFINE(struct umem_odp_node, rb, u64, __subtree_last, + node_start, node_last, , rbt_ib_umem) + +/* @last is not a part of the interval. See comment for function + * node_last. + */ +int rbt_ib_umem_for_each_in_range(struct rb_root *root, + u64 start, u64 last, + umem_call_back cb, + void *cookie) +{ + int ret_val = 0; + struct umem_odp_node *node; + struct ib_umem_odp *umem; + + if (unlikely(start == last)) + return ret_val; + + for (node = rbt_ib_umem_iter_first(root, start, last - 1); node; + node = rbt_ib_umem_iter_next(node, start, last - 1)) { + umem = container_of(node, struct ib_umem_odp, interval_tree); + ret_val = cb(umem->umem, start, last, cookie) || ret_val; + } + + return ret_val; +} diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index 643c08a025a5..b716b0815644 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h @@ -258,5 +258,6 @@ IB_UVERBS_DECLARE_CMD(close_xrcd); IB_UVERBS_DECLARE_EX_CMD(create_flow); IB_UVERBS_DECLARE_EX_CMD(destroy_flow); +IB_UVERBS_DECLARE_EX_CMD(query_device); #endif /* UVERBS_H */ diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 5ba2a86aab6a..532d8eba8b02 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -36,6 +36,7 @@ #include <linux/file.h> #include <linux/fs.h> #include <linux/slab.h> +#include <linux/sched.h> #include <asm/uaccess.h> @@ -288,6 +289,9 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, struct ib_uverbs_get_context_resp resp; struct ib_udata udata; struct ib_device *ibdev = file->device->ib_dev; +#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING + struct ib_device_attr dev_attr; +#endif struct ib_ucontext *ucontext; struct file *filp; int ret; @@ -325,8 +329,25 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, INIT_LIST_HEAD(&ucontext->ah_list); INIT_LIST_HEAD(&ucontext->xrcd_list); INIT_LIST_HEAD(&ucontext->rule_list); + rcu_read_lock(); + ucontext->tgid = get_task_pid(current->group_leader, PIDTYPE_PID); + rcu_read_unlock(); ucontext->closing = 0; +#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING + ucontext->umem_tree = RB_ROOT; + init_rwsem(&ucontext->umem_rwsem); + ucontext->odp_mrs_count = 0; + INIT_LIST_HEAD(&ucontext->no_private_counters); + + ret = ib_query_device(ibdev, &dev_attr); + if (ret) + goto err_free; + if (!(dev_attr.device_cap_flags & IB_DEVICE_ON_DEMAND_PAGING)) + ucontext->invalidate_range = NULL; + +#endif + resp.num_comp_vectors = file->device->num_comp_vectors; ret = get_unused_fd_flags(O_CLOEXEC); @@ -371,6 +392,7 @@ err_fd: put_unused_fd(resp.async_fd); err_free: + put_pid(ucontext->tgid); ibdev->dealloc_ucontext(ucontext); err: @@ -378,6 +400,52 @@ err: return ret; } +static void copy_query_dev_fields(struct ib_uverbs_file *file, + struct ib_uverbs_query_device_resp *resp, + struct ib_device_attr *attr) +{ + resp->fw_ver = attr->fw_ver; + resp->node_guid = file->device->ib_dev->node_guid; + resp->sys_image_guid = attr->sys_image_guid; + resp->max_mr_size = attr->max_mr_size; + resp->page_size_cap = attr->page_size_cap; + resp->vendor_id = attr->vendor_id; + resp->vendor_part_id = attr->vendor_part_id; + resp->hw_ver = attr->hw_ver; + resp->max_qp = attr->max_qp; + resp->max_qp_wr = attr->max_qp_wr; + resp->device_cap_flags = attr->device_cap_flags; + resp->max_sge = attr->max_sge; + resp->max_sge_rd = attr->max_sge_rd; + resp->max_cq = attr->max_cq; + resp->max_cqe = attr->max_cqe; + resp->max_mr = attr->max_mr; + resp->max_pd = attr->max_pd; + resp->max_qp_rd_atom = attr->max_qp_rd_atom; + resp->max_ee_rd_atom = attr->max_ee_rd_atom; + resp->max_res_rd_atom = attr->max_res_rd_atom; + resp->max_qp_init_rd_atom = attr->max_qp_init_rd_atom; + resp->max_ee_init_rd_atom = attr->max_ee_init_rd_atom; + resp->atomic_cap = attr->atomic_cap; + resp->max_ee = attr->max_ee; + resp->max_rdd = attr->max_rdd; + resp->max_mw = attr->max_mw; + resp->max_raw_ipv6_qp = attr->max_raw_ipv6_qp; + resp->max_raw_ethy_qp = attr->max_raw_ethy_qp; + resp->max_mcast_grp = attr->max_mcast_grp; + resp->max_mcast_qp_attach = attr->max_mcast_qp_attach; + resp->max_total_mcast_qp_attach = attr->max_total_mcast_qp_attach; + resp->max_ah = attr->max_ah; + resp->max_fmr = attr->max_fmr; + resp->max_map_per_fmr = attr->max_map_per_fmr; + resp->max_srq = attr->max_srq; + resp->max_srq_wr = attr->max_srq_wr; + resp->max_srq_sge = attr->max_srq_sge; + resp->max_pkeys = attr->max_pkeys; + resp->local_ca_ack_delay = attr->local_ca_ack_delay; + resp->phys_port_cnt = file->device->ib_dev->phys_port_cnt; +} + ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file, const char __user *buf, int in_len, int out_len) @@ -398,47 +466,7 @@ ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file, return ret; memset(&resp, 0, sizeof resp); - - resp.fw_ver = attr.fw_ver; - resp.node_guid = file->device->ib_dev->node_guid; - resp.sys_image_guid = attr.sys_image_guid; - resp.max_mr_size = attr.max_mr_size; - resp.page_size_cap = attr.page_size_cap; - resp.vendor_id = attr.vendor_id; - resp.vendor_part_id = attr.vendor_part_id; - resp.hw_ver = attr.hw_ver; - resp.max_qp = attr.max_qp; - resp.max_qp_wr = attr.max_qp_wr; - resp.device_cap_flags = attr.device_cap_flags; - resp.max_sge = attr.max_sge; - resp.max_sge_rd = attr.max_sge_rd; - resp.max_cq = attr.max_cq; - resp.max_cqe = attr.max_cqe; - resp.max_mr = attr.max_mr; - resp.max_pd = attr.max_pd; - resp.max_qp_rd_atom = attr.max_qp_rd_atom; - resp.max_ee_rd_atom = attr.max_ee_rd_atom; - resp.max_res_rd_atom = attr.max_res_rd_atom; - resp.max_qp_init_rd_atom = attr.max_qp_init_rd_atom; - resp.max_ee_init_rd_atom = attr.max_ee_init_rd_atom; - resp.atomic_cap = attr.atomic_cap; - resp.max_ee = attr.max_ee; - resp.max_rdd = attr.max_rdd; - resp.max_mw = attr.max_mw; - resp.max_raw_ipv6_qp = attr.max_raw_ipv6_qp; - resp.max_raw_ethy_qp = attr.max_raw_ethy_qp; - resp.max_mcast_grp = attr.max_mcast_grp; - resp.max_mcast_qp_attach = attr.max_mcast_qp_attach; - resp.max_total_mcast_qp_attach = attr.max_total_mcast_qp_attach; - resp.max_ah = attr.max_ah; - resp.max_fmr = attr.max_fmr; - resp.max_map_per_fmr = attr.max_map_per_fmr; - resp.max_srq = attr.max_srq; - resp.max_srq_wr = attr.max_srq_wr; - resp.max_srq_sge = attr.max_srq_sge; - resp.max_pkeys = attr.max_pkeys; - resp.local_ca_ack_delay = attr.local_ca_ack_delay; - resp.phys_port_cnt = file->device->ib_dev->phys_port_cnt; + copy_query_dev_fields(file, &resp, &attr); if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp)) @@ -947,6 +975,18 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file, goto err_free; } + if (cmd.access_flags & IB_ACCESS_ON_DEMAND) { + struct ib_device_attr attr; + + ret = ib_query_device(pd->device, &attr); + if (ret || !(attr.device_cap_flags & + IB_DEVICE_ON_DEMAND_PAGING)) { + pr_debug("ODP support not available\n"); + ret = -EINVAL; + goto err_put; + } + } + mr = pd->device->reg_user_mr(pd, cmd.start, cmd.length, cmd.hca_va, cmd.access_flags, &udata); if (IS_ERR(mr)) { @@ -3253,3 +3293,52 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, return ret ? ret : in_len; } + +int ib_uverbs_ex_query_device(struct ib_uverbs_file *file, + struct ib_udata *ucore, + struct ib_udata *uhw) +{ + struct ib_uverbs_ex_query_device_resp resp; + struct ib_uverbs_ex_query_device cmd; + struct ib_device_attr attr; + struct ib_device *device; + int err; + + device = file->device->ib_dev; + if (ucore->inlen < sizeof(cmd)) + return -EINVAL; + + err = ib_copy_from_udata(&cmd, ucore, sizeof(cmd)); + if (err) + return err; + + if (cmd.reserved) + return -EINVAL; + + err = device->query_device(device, &attr); + if (err) + return err; + + memset(&resp, 0, sizeof(resp)); + copy_query_dev_fields(file, &resp.base, &attr); + resp.comp_mask = 0; + +#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING + if (cmd.comp_mask & IB_USER_VERBS_EX_QUERY_DEVICE_ODP) { + resp.odp_caps.general_caps = attr.odp_caps.general_caps; + resp.odp_caps.per_transport_caps.rc_odp_caps = + attr.odp_caps.per_transport_caps.rc_odp_caps; + resp.odp_caps.per_transport_caps.uc_odp_caps = + attr.odp_caps.per_transport_caps.uc_odp_caps; + resp.odp_caps.per_transport_caps.ud_odp_caps = + attr.odp_caps.per_transport_caps.ud_odp_caps; + resp.comp_mask |= IB_USER_VERBS_EX_QUERY_DEVICE_ODP; + } +#endif + + err = ib_copy_to_udata(ucore, &resp, sizeof(resp)); + if (err) + return err; + + return 0; +} diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 71ab83fde472..e6c23b9eab33 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -122,7 +122,8 @@ static int (*uverbs_ex_cmd_table[])(struct ib_uverbs_file *file, struct ib_udata *ucore, struct ib_udata *uhw) = { [IB_USER_VERBS_EX_CMD_CREATE_FLOW] = ib_uverbs_ex_create_flow, - [IB_USER_VERBS_EX_CMD_DESTROY_FLOW] = ib_uverbs_ex_destroy_flow + [IB_USER_VERBS_EX_CMD_DESTROY_FLOW] = ib_uverbs_ex_destroy_flow, + [IB_USER_VERBS_EX_CMD_QUERY_DEVICE] = ib_uverbs_ex_query_device }; static void ib_uverbs_add_one(struct ib_device *device); @@ -296,6 +297,8 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, kfree(uobj); } + put_pid(context->tgid); + return context->device->dealloc_ucontext(context); } diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index c2b89cc5dbca..f93eb8da7b5a 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -879,7 +879,8 @@ int ib_resolve_eth_l2_attrs(struct ib_qp *qp, if (rdma_link_local_addr((struct in6_addr *)qp_attr->ah_attr.grh.dgid.raw)) { rdma_get_ll_mac((struct in6_addr *)qp_attr->ah_attr.grh.dgid.raw, qp_attr->ah_attr.dmac); rdma_get_ll_mac((struct in6_addr *)sgid.raw, qp_attr->smac); - qp_attr->vlan_id = rdma_get_vlan_id(&sgid); + if (!(*qp_attr_mask & IB_QP_VID)) + qp_attr->vlan_id = rdma_get_vlan_id(&sgid); } else { ret = rdma_addr_find_dmac_by_grh(&sgid, &qp_attr->ah_attr.grh.dgid, qp_attr->ah_attr.dmac, &qp_attr->vlan_id); diff --git a/drivers/infiniband/hw/amso1100/c2_provider.c b/drivers/infiniband/hw/amso1100/c2_provider.c index 2d5cbf4363e4..bdf3507810cb 100644 --- a/drivers/infiniband/hw/amso1100/c2_provider.c +++ b/drivers/infiniband/hw/amso1100/c2_provider.c @@ -476,7 +476,7 @@ static struct ib_mr *c2_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, c2mr->umem->page_size, i, length, - c2mr->umem->offset, + ib_umem_offset(c2mr->umem), &kva, c2_convert_access(acc), c2mr); diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 4b8c6116c058..9edc200b311d 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -1640,7 +1640,8 @@ static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb) __state_set(&ep->com, MPA_REQ_RCVD); /* drive upcall */ - mutex_lock(&ep->parent_ep->com.mutex); + mutex_lock_nested(&ep->parent_ep->com.mutex, + SINGLE_DEPTH_NESTING); if (ep->parent_ep->com.state != DEAD) { if (connect_request_upcall(ep)) abort_connection(ep, skb, GFP_KERNEL); @@ -3126,6 +3127,8 @@ static int create_server6(struct c4iw_dev *dev, struct c4iw_listen_ep *ep) err = c4iw_wait_for_reply(&ep->com.dev->rdev, &ep->com.wr_wait, 0, 0, __func__); + else if (err > 0) + err = net_xmit_errno(err); if (err) pr_err("cxgb4_create_server6/filter failed err %d stid %d laddr %pI6 lport %d\n", err, ep->stid, @@ -3159,6 +3162,8 @@ static int create_server4(struct c4iw_dev *dev, struct c4iw_listen_ep *ep) err = c4iw_wait_for_reply(&ep->com.dev->rdev, &ep->com.wr_wait, 0, 0, __func__); + else if (err > 0) + err = net_xmit_errno(err); } if (err) pr_err("cxgb4_create_server/filter failed err %d stid %d laddr %pI4 lport %d\n" diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index 72f1f052e88c..eb5df4e62703 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c @@ -670,7 +670,7 @@ static int ep_open(struct inode *inode, struct file *file) idr_for_each(&epd->devp->stid_idr, count_idrs, &count); spin_unlock_irq(&epd->devp->lock); - epd->bufsize = count * 160; + epd->bufsize = count * 240; epd->buf = vmalloc(epd->bufsize); if (!epd->buf) { ret = -ENOMEM; diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c index 0744455cd88b..cb43c2299ac0 100644 --- a/drivers/infiniband/hw/cxgb4/mem.c +++ b/drivers/infiniband/hw/cxgb4/mem.c @@ -50,6 +50,13 @@ static int inline_threshold = C4IW_INLINE_THRESHOLD; module_param(inline_threshold, int, 0644); MODULE_PARM_DESC(inline_threshold, "inline vs dsgl threshold (default=128)"); +static int mr_exceeds_hw_limits(struct c4iw_dev *dev, u64 length) +{ + return (is_t4(dev->rdev.lldi.adapter_type) || + is_t5(dev->rdev.lldi.adapter_type)) && + length >= 8*1024*1024*1024ULL; +} + static int _c4iw_write_mem_dma_aligned(struct c4iw_rdev *rdev, u32 addr, u32 len, dma_addr_t data, int wait) { @@ -369,9 +376,11 @@ static int register_mem(struct c4iw_dev *rhp, struct c4iw_pd *php, int ret; ret = write_tpt_entry(&rhp->rdev, 0, &stag, 1, mhp->attr.pdid, - FW_RI_STAG_NSMR, mhp->attr.perms, + FW_RI_STAG_NSMR, mhp->attr.len ? + mhp->attr.perms : 0, mhp->attr.mw_bind_enable, mhp->attr.zbva, - mhp->attr.va_fbo, mhp->attr.len, shift - 12, + mhp->attr.va_fbo, mhp->attr.len ? + mhp->attr.len : -1, shift - 12, mhp->attr.pbl_size, mhp->attr.pbl_addr); if (ret) return ret; @@ -536,6 +545,11 @@ int c4iw_reregister_phys_mem(struct ib_mr *mr, int mr_rereg_mask, return ret; } + if (mr_exceeds_hw_limits(rhp, total_size)) { + kfree(page_list); + return -EINVAL; + } + ret = reregister_mem(rhp, php, &mh, shift, npages); kfree(page_list); if (ret) @@ -596,6 +610,12 @@ struct ib_mr *c4iw_register_phys_mem(struct ib_pd *pd, if (ret) goto err; + if (mr_exceeds_hw_limits(rhp, total_size)) { + kfree(page_list); + ret = -EINVAL; + goto err; + } + ret = alloc_pbl(mhp, npages); if (ret) { kfree(page_list); @@ -699,6 +719,10 @@ struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, php = to_c4iw_pd(pd); rhp = php->rhp; + + if (mr_exceeds_hw_limits(rhp, length)) + return ERR_PTR(-EINVAL); + mhp = kzalloc(sizeof(*mhp), GFP_KERNEL); if (!mhp) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 2ed3ece2b2ee..bb85d479e66e 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -1538,9 +1538,9 @@ err: set_state(qhp, C4IW_QP_STATE_ERROR); free = 1; abort = 1; - wake_up(&qhp->wait); BUG_ON(!ep); flush_qp(qhp); + wake_up(&qhp->wait); out: mutex_unlock(&qhp->mutex); diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c index 3488e8c9fcb4..f914b30999f8 100644 --- a/drivers/infiniband/hw/ehca/ehca_mrmw.c +++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c @@ -399,7 +399,7 @@ reg_user_mr_fallback: pginfo.num_kpages = num_kpages; pginfo.num_hwpages = num_hwpages; pginfo.u.usr.region = e_mr->umem; - pginfo.next_hwpage = e_mr->umem->offset / hwpage_size; + pginfo.next_hwpage = ib_umem_offset(e_mr->umem) / hwpage_size; pginfo.u.usr.next_sg = pginfo.u.usr.region->sg_head.sgl; ret = ehca_reg_mr(shca, e_mr, (u64 *)virt, length, mr_access_flags, e_pd, &pginfo, &e_mr->ib.ib_mr.lkey, diff --git a/drivers/infiniband/hw/ipath/ipath_mr.c b/drivers/infiniband/hw/ipath/ipath_mr.c index 5e61e9bff697..c7278f6a8217 100644 --- a/drivers/infiniband/hw/ipath/ipath_mr.c +++ b/drivers/infiniband/hw/ipath/ipath_mr.c @@ -214,7 +214,7 @@ struct ib_mr *ipath_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, mr->mr.user_base = start; mr->mr.iova = virt_addr; mr->mr.length = length; - mr->mr.offset = umem->offset; + mr->mr.offset = ib_umem_offset(umem); mr->mr.access_flags = mr_access_flags; mr->mr.max_segs = n; mr->umem = umem; diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 57ecc5b204f3..9117b7a2d5f8 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -1114,7 +1114,8 @@ static int mlx4_ib_tunnel_steer_add(struct ib_qp *qp, struct ib_flow_attr *flow_ struct mlx4_dev *dev = to_mdev(qp->device)->dev; int err = 0; - if (dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) + if (dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN || + dev->caps.dmfs_high_steer_mode == MLX4_STEERING_DMFS_A0_STATIC) return 0; /* do nothing */ ib_flow = flow_attr + 1; diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c index 8f9325cfc85d..c36ccbd9a644 100644 --- a/drivers/infiniband/hw/mlx4/mr.c +++ b/drivers/infiniband/hw/mlx4/mr.c @@ -223,7 +223,6 @@ int mlx4_ib_rereg_user_mr(struct ib_mr *mr, int flags, if (flags & IB_MR_REREG_TRANS) { int shift; - int err; int n; mlx4_mr_rereg_mem_cleanup(dev->dev, &mmr->mmr); diff --git a/drivers/infiniband/hw/mlx5/Makefile b/drivers/infiniband/hw/mlx5/Makefile index 4ea0135af484..27a70159e2ea 100644 --- a/drivers/infiniband/hw/mlx5/Makefile +++ b/drivers/infiniband/hw/mlx5/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_MLX5_INFINIBAND) += mlx5_ib.o mlx5_ib-y := main.o cq.o doorbell.o qp.o mem.o srq.o mr.o ah.o mad.o +mlx5_ib-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += odp.o diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 1ba6c42e4df8..8a87404e9c76 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -244,6 +244,12 @@ static int mlx5_ib_query_device(struct ib_device *ibdev, props->max_mcast_grp; props->max_map_per_fmr = INT_MAX; /* no limit in ConnectIB */ +#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING + if (dev->mdev->caps.gen.flags & MLX5_DEV_CAP_FLAG_ON_DMND_PG) + props->device_cap_flags |= IB_DEVICE_ON_DEMAND_PAGING; + props->odp_caps = dev->odp_caps; +#endif + out: kfree(in_mad); kfree(out_mad); @@ -568,6 +574,10 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev, goto out_count; } +#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING + context->ibucontext.invalidate_range = &mlx5_ib_invalidate_range; +#endif + INIT_LIST_HEAD(&context->db_page_list); mutex_init(&context->db_page_mutex); @@ -858,7 +868,7 @@ static ssize_t show_reg_pages(struct device *device, struct mlx5_ib_dev *dev = container_of(device, struct mlx5_ib_dev, ib_dev.dev); - return sprintf(buf, "%d\n", dev->mdev->priv.reg_pages); + return sprintf(buf, "%d\n", atomic_read(&dev->mdev->priv.reg_pages)); } static ssize_t show_hca(struct device *device, struct device_attribute *attr, @@ -1321,6 +1331,8 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev) (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ) | (1ull << IB_USER_VERBS_CMD_CREATE_XSRQ) | (1ull << IB_USER_VERBS_CMD_OPEN_QP); + dev->ib_dev.uverbs_ex_cmd_mask = + (1ull << IB_USER_VERBS_EX_CMD_QUERY_DEVICE); dev->ib_dev.query_device = mlx5_ib_query_device; dev->ib_dev.query_port = mlx5_ib_query_port; @@ -1366,6 +1378,8 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev) dev->ib_dev.free_fast_reg_page_list = mlx5_ib_free_fast_reg_page_list; dev->ib_dev.check_mr_status = mlx5_ib_check_mr_status; + mlx5_ib_internal_query_odp_caps(dev); + if (mdev->caps.gen.flags & MLX5_DEV_CAP_FLAG_XRC) { dev->ib_dev.alloc_xrcd = mlx5_ib_alloc_xrcd; dev->ib_dev.dealloc_xrcd = mlx5_ib_dealloc_xrcd; @@ -1379,16 +1393,19 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev) goto err_eqs; mutex_init(&dev->cap_mask_mutex); - spin_lock_init(&dev->mr_lock); err = create_dev_resources(&dev->devr); if (err) goto err_eqs; - err = ib_register_device(&dev->ib_dev, NULL); + err = mlx5_ib_odp_init_one(dev); if (err) goto err_rsrc; + err = ib_register_device(&dev->ib_dev, NULL); + if (err) + goto err_odp; + err = create_umr_res(dev); if (err) goto err_dev; @@ -1410,6 +1427,9 @@ err_umrc: err_dev: ib_unregister_device(&dev->ib_dev); +err_odp: + mlx5_ib_odp_remove_one(dev); + err_rsrc: destroy_dev_resources(&dev->devr); @@ -1425,8 +1445,10 @@ err_dealloc: static void mlx5_ib_remove(struct mlx5_core_dev *mdev, void *context) { struct mlx5_ib_dev *dev = context; + ib_unregister_device(&dev->ib_dev); destroy_umrc_res(dev); + mlx5_ib_odp_remove_one(dev); destroy_dev_resources(&dev->devr); free_comp_eqs(dev); ib_dealloc_device(&dev->ib_dev); @@ -1440,15 +1462,30 @@ static struct mlx5_interface mlx5_ib_interface = { static int __init mlx5_ib_init(void) { + int err; + if (deprecated_prof_sel != 2) pr_warn("prof_sel is deprecated for mlx5_ib, set it for mlx5_core\n"); - return mlx5_register_interface(&mlx5_ib_interface); + err = mlx5_ib_odp_init(); + if (err) + return err; + + err = mlx5_register_interface(&mlx5_ib_interface); + if (err) + goto clean_odp; + + return err; + +clean_odp: + mlx5_ib_odp_cleanup(); + return err; } static void __exit mlx5_ib_cleanup(void) { mlx5_unregister_interface(&mlx5_ib_interface); + mlx5_ib_odp_cleanup(); } module_init(mlx5_ib_init); diff --git a/drivers/infiniband/hw/mlx5/mem.c b/drivers/infiniband/hw/mlx5/mem.c index dae07eae9507..b56e4c5593ee 100644 --- a/drivers/infiniband/hw/mlx5/mem.c +++ b/drivers/infiniband/hw/mlx5/mem.c @@ -32,6 +32,7 @@ #include <linux/module.h> #include <rdma/ib_umem.h> +#include <rdma/ib_umem_odp.h> #include "mlx5_ib.h" /* @umem: umem object to scan @@ -57,6 +58,17 @@ void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr, int *count, int *shift, int entry; unsigned long page_shift = ilog2(umem->page_size); + /* With ODP we must always match OS page size. */ + if (umem->odp_data) { + *count = ib_umem_page_count(umem); + *shift = PAGE_SHIFT; + *ncont = *count; + if (order) + *order = ilog2(roundup_pow_of_two(*count)); + + return; + } + addr = addr >> page_shift; tmp = (unsigned long)addr; m = find_first_bit(&tmp, sizeof(tmp)); @@ -108,8 +120,36 @@ void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr, int *count, int *shift, *count = i; } -void mlx5_ib_populate_pas(struct mlx5_ib_dev *dev, struct ib_umem *umem, - int page_shift, __be64 *pas, int umr) +#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING +static u64 umem_dma_to_mtt(dma_addr_t umem_dma) +{ + u64 mtt_entry = umem_dma & ODP_DMA_ADDR_MASK; + + if (umem_dma & ODP_READ_ALLOWED_BIT) + mtt_entry |= MLX5_IB_MTT_READ; + if (umem_dma & ODP_WRITE_ALLOWED_BIT) + mtt_entry |= MLX5_IB_MTT_WRITE; + + return mtt_entry; +} +#endif + +/* + * Populate the given array with bus addresses from the umem. + * + * dev - mlx5_ib device + * umem - umem to use to fill the pages + * page_shift - determines the page size used in the resulting array + * offset - offset into the umem to start from, + * only implemented for ODP umems + * num_pages - total number of pages to fill + * pas - bus addresses array to fill + * access_flags - access flags to set on all present pages. + use enum mlx5_ib_mtt_access_flags for this. + */ +void __mlx5_ib_populate_pas(struct mlx5_ib_dev *dev, struct ib_umem *umem, + int page_shift, size_t offset, size_t num_pages, + __be64 *pas, int access_flags) { unsigned long umem_page_shift = ilog2(umem->page_size); int shift = page_shift - umem_page_shift; @@ -120,6 +160,21 @@ void mlx5_ib_populate_pas(struct mlx5_ib_dev *dev, struct ib_umem *umem, int len; struct scatterlist *sg; int entry; +#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING + const bool odp = umem->odp_data != NULL; + + if (odp) { + WARN_ON(shift != 0); + WARN_ON(access_flags != (MLX5_IB_MTT_READ | MLX5_IB_MTT_WRITE)); + + for (i = 0; i < num_pages; ++i) { + dma_addr_t pa = umem->odp_data->dma_list[offset + i]; + + pas[i] = cpu_to_be64(umem_dma_to_mtt(pa)); + } + return; + } +#endif i = 0; for_each_sg(umem->sg_head.sgl, sg, umem->nmap, entry) { @@ -128,8 +183,7 @@ void mlx5_ib_populate_pas(struct mlx5_ib_dev *dev, struct ib_umem *umem, for (k = 0; k < len; k++) { if (!(i & mask)) { cur = base + (k << umem_page_shift); - if (umr) - cur |= 3; + cur |= access_flags; pas[i >> shift] = cpu_to_be64(cur); mlx5_ib_dbg(dev, "pas[%d] 0x%llx\n", @@ -142,6 +196,13 @@ void mlx5_ib_populate_pas(struct mlx5_ib_dev *dev, struct ib_umem *umem, } } +void mlx5_ib_populate_pas(struct mlx5_ib_dev *dev, struct ib_umem *umem, + int page_shift, __be64 *pas, int access_flags) +{ + return __mlx5_ib_populate_pas(dev, umem, page_shift, 0, + ib_umem_num_pages(umem), pas, + access_flags); +} int mlx5_ib_get_buf_offset(u64 addr, int page_shift, u32 *offset) { u64 page_size; diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h index 386780f0d1e1..83f22fe297c8 100644 --- a/drivers/infiniband/hw/mlx5/mlx5_ib.h +++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h @@ -111,6 +111,8 @@ struct mlx5_ib_pd { */ #define MLX5_IB_SEND_UMR_UNREG IB_SEND_RESERVED_START +#define MLX5_IB_SEND_UMR_FAIL_IF_FREE (IB_SEND_RESERVED_START << 1) +#define MLX5_IB_SEND_UMR_UPDATE_MTT (IB_SEND_RESERVED_START << 2) #define MLX5_IB_QPT_REG_UMR IB_QPT_RESERVED1 #define MLX5_IB_WR_UMR IB_WR_RESERVED1 @@ -147,6 +149,29 @@ enum { MLX5_QP_EMPTY }; +/* + * Connect-IB can trigger up to four concurrent pagefaults + * per-QP. + */ +enum mlx5_ib_pagefault_context { + MLX5_IB_PAGEFAULT_RESPONDER_READ, + MLX5_IB_PAGEFAULT_REQUESTOR_READ, + MLX5_IB_PAGEFAULT_RESPONDER_WRITE, + MLX5_IB_PAGEFAULT_REQUESTOR_WRITE, + MLX5_IB_PAGEFAULT_CONTEXTS +}; + +static inline enum mlx5_ib_pagefault_context + mlx5_ib_get_pagefault_context(struct mlx5_pagefault *pagefault) +{ + return pagefault->flags & (MLX5_PFAULT_REQUESTOR | MLX5_PFAULT_WRITE); +} + +struct mlx5_ib_pfault { + struct work_struct work; + struct mlx5_pagefault mpfault; +}; + struct mlx5_ib_qp { struct ib_qp ibqp; struct mlx5_core_qp mqp; @@ -192,6 +217,21 @@ struct mlx5_ib_qp { /* Store signature errors */ bool signature_en; + +#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING + /* + * A flag that is true for QP's that are in a state that doesn't + * allow page faults, and shouldn't schedule any more faults. + */ + int disable_page_faults; + /* + * The disable_page_faults_lock protects a QP's disable_page_faults + * field, allowing for a thread to atomically check whether the QP + * allows page faults, and if so schedule a page fault. + */ + spinlock_t disable_page_faults_lock; + struct mlx5_ib_pfault pagefaults[MLX5_IB_PAGEFAULT_CONTEXTS]; +#endif }; struct mlx5_ib_cq_buf { @@ -206,6 +246,19 @@ enum mlx5_ib_qp_flags { MLX5_IB_QP_SIGNATURE_HANDLING = 1 << 1, }; +struct mlx5_umr_wr { + union { + u64 virt_addr; + u64 offset; + } target; + struct ib_pd *pd; + unsigned int page_shift; + unsigned int npages; + u32 length; + int access_flags; + u32 mkey; +}; + struct mlx5_shared_mr_info { int mr_id; struct ib_umem *umem; @@ -253,6 +306,13 @@ struct mlx5_ib_xrcd { u32 xrcdn; }; +enum mlx5_ib_mtt_access_flags { + MLX5_IB_MTT_READ = (1 << 0), + MLX5_IB_MTT_WRITE = (1 << 1), +}; + +#define MLX5_IB_MTT_PRESENT (MLX5_IB_MTT_READ | MLX5_IB_MTT_WRITE) + struct mlx5_ib_mr { struct ib_mr ibmr; struct mlx5_core_mr mmr; @@ -261,12 +321,11 @@ struct mlx5_ib_mr { struct list_head list; int order; int umred; - __be64 *pas; - dma_addr_t dma; int npages; struct mlx5_ib_dev *dev; struct mlx5_create_mkey_mbox_out out; struct mlx5_core_sig_ctx *sig; + int live; }; struct mlx5_ib_fast_reg_page_list { @@ -372,11 +431,18 @@ struct mlx5_ib_dev { struct umr_common umrc; /* sync used page count stats */ - spinlock_t mr_lock; struct mlx5_ib_resources devr; struct mlx5_mr_cache cache; struct timer_list delay_timer; int fill_delay; +#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING + struct ib_odp_caps odp_caps; + /* + * Sleepable RCU that prevents destruction of MRs while they are still + * being used by a page fault handler. + */ + struct srcu_struct mr_srcu; +#endif }; static inline struct mlx5_ib_cq *to_mibcq(struct mlx5_core_cq *mcq) @@ -490,6 +556,8 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, int mlx5_ib_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr, struct ib_recv_wr **bad_wr); void *mlx5_get_send_wqe(struct mlx5_ib_qp *qp, int n); +int mlx5_ib_read_user_wqe(struct mlx5_ib_qp *qp, int send, int wqe_index, + void *buffer, u32 length); struct ib_cq *mlx5_ib_create_cq(struct ib_device *ibdev, int entries, int vector, struct ib_ucontext *context, struct ib_udata *udata); @@ -502,6 +570,8 @@ struct ib_mr *mlx5_ib_get_dma_mr(struct ib_pd *pd, int acc); struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, u64 virt_addr, int access_flags, struct ib_udata *udata); +int mlx5_ib_update_mtt(struct mlx5_ib_mr *mr, u64 start_page_index, + int npages, int zap); int mlx5_ib_dereg_mr(struct ib_mr *ibmr); int mlx5_ib_destroy_mr(struct ib_mr *ibmr); struct ib_mr *mlx5_ib_create_mr(struct ib_pd *pd, @@ -533,8 +603,11 @@ int mlx5_ib_init_fmr(struct mlx5_ib_dev *dev); void mlx5_ib_cleanup_fmr(struct mlx5_ib_dev *dev); void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr, int *count, int *shift, int *ncont, int *order); +void __mlx5_ib_populate_pas(struct mlx5_ib_dev *dev, struct ib_umem *umem, + int page_shift, size_t offset, size_t num_pages, + __be64 *pas, int access_flags); void mlx5_ib_populate_pas(struct mlx5_ib_dev *dev, struct ib_umem *umem, - int page_shift, __be64 *pas, int umr); + int page_shift, __be64 *pas, int access_flags); void mlx5_ib_copy_pas(u64 *old, u64 *new, int step, int num); int mlx5_ib_get_cqe_size(struct mlx5_ib_dev *dev, struct ib_cq *ibcq); int mlx5_mr_cache_init(struct mlx5_ib_dev *dev); @@ -544,6 +617,38 @@ void mlx5_umr_cq_handler(struct ib_cq *cq, void *cq_context); int mlx5_ib_check_mr_status(struct ib_mr *ibmr, u32 check_mask, struct ib_mr_status *mr_status); +#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING +extern struct workqueue_struct *mlx5_ib_page_fault_wq; + +int mlx5_ib_internal_query_odp_caps(struct mlx5_ib_dev *dev); +void mlx5_ib_mr_pfault_handler(struct mlx5_ib_qp *qp, + struct mlx5_ib_pfault *pfault); +void mlx5_ib_odp_create_qp(struct mlx5_ib_qp *qp); +int mlx5_ib_odp_init_one(struct mlx5_ib_dev *ibdev); +void mlx5_ib_odp_remove_one(struct mlx5_ib_dev *ibdev); +int __init mlx5_ib_odp_init(void); +void mlx5_ib_odp_cleanup(void); +void mlx5_ib_qp_disable_pagefaults(struct mlx5_ib_qp *qp); +void mlx5_ib_qp_enable_pagefaults(struct mlx5_ib_qp *qp); +void mlx5_ib_invalidate_range(struct ib_umem *umem, unsigned long start, + unsigned long end); + +#else /* CONFIG_INFINIBAND_ON_DEMAND_PAGING */ +static inline int mlx5_ib_internal_query_odp_caps(struct mlx5_ib_dev *dev) +{ + return 0; +} + +static inline void mlx5_ib_odp_create_qp(struct mlx5_ib_qp *qp) {} +static inline int mlx5_ib_odp_init_one(struct mlx5_ib_dev *ibdev) { return 0; } +static inline void mlx5_ib_odp_remove_one(struct mlx5_ib_dev *ibdev) {} +static inline int mlx5_ib_odp_init(void) { return 0; } +static inline void mlx5_ib_odp_cleanup(void) {} +static inline void mlx5_ib_qp_disable_pagefaults(struct mlx5_ib_qp *qp) {} +static inline void mlx5_ib_qp_enable_pagefaults(struct mlx5_ib_qp *qp) {} + +#endif /* CONFIG_INFINIBAND_ON_DEMAND_PAGING */ + static inline void init_query_mad(struct ib_smp *mad) { mad->base_version = 1; @@ -561,4 +666,7 @@ static inline u8 convert_access(int acc) MLX5_PERM_LOCAL_READ; } +#define MLX5_MAX_UMR_SHIFT 16 +#define MLX5_MAX_UMR_PAGES (1 << MLX5_MAX_UMR_SHIFT) + #endif /* MLX5_IB_H */ diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index 5a80dd993761..32a28bd50b20 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c @@ -37,21 +37,34 @@ #include <linux/export.h> #include <linux/delay.h> #include <rdma/ib_umem.h> +#include <rdma/ib_umem_odp.h> +#include <rdma/ib_verbs.h> #include "mlx5_ib.h" enum { MAX_PENDING_REG_MR = 8, }; -enum { - MLX5_UMR_ALIGN = 2048 -}; +#define MLX5_UMR_ALIGN 2048 +#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING +static __be64 mlx5_ib_update_mtt_emergency_buffer[ + MLX5_UMR_MTT_MIN_CHUNK_SIZE/sizeof(__be64)] + __aligned(MLX5_UMR_ALIGN); +static DEFINE_MUTEX(mlx5_ib_update_mtt_emergency_buffer_mutex); +#endif + +static int clean_mr(struct mlx5_ib_mr *mr); -static __be64 *mr_align(__be64 *ptr, int align) +static int destroy_mkey(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr) { - unsigned long mask = align - 1; + int err = mlx5_core_destroy_mkey(dev->mdev, &mr->mmr); - return (__be64 *)(((unsigned long)ptr + mask) & ~mask); +#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING + /* Wait until all page fault handlers using the mr complete. */ + synchronize_srcu(&dev->mr_srcu); +#endif + + return err; } static int order2idx(struct mlx5_ib_dev *dev, int order) @@ -146,7 +159,7 @@ static int add_keys(struct mlx5_ib_dev *dev, int c, int num) mr->order = ent->order; mr->umred = 1; mr->dev = dev; - in->seg.status = 1 << 6; + in->seg.status = MLX5_MKEY_STATUS_FREE; in->seg.xlt_oct_size = cpu_to_be32((npages + 1) / 2); in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8); in->seg.flags = MLX5_ACCESS_MODE_MTT | MLX5_PERM_UMR_EN; @@ -191,7 +204,7 @@ static void remove_keys(struct mlx5_ib_dev *dev, int c, int num) ent->cur--; ent->size--; spin_unlock_irq(&ent->lock); - err = mlx5_core_destroy_mkey(dev->mdev, &mr->mmr); + err = destroy_mkey(dev, mr); if (err) mlx5_ib_warn(dev, "failed destroy mkey\n"); else @@ -482,7 +495,7 @@ static void clean_keys(struct mlx5_ib_dev *dev, int c) ent->cur--; ent->size--; spin_unlock_irq(&ent->lock); - err = mlx5_core_destroy_mkey(dev->mdev, &mr->mmr); + err = destroy_mkey(dev, mr); if (err) mlx5_ib_warn(dev, "failed destroy mkey\n"); else @@ -668,7 +681,7 @@ static int get_octo_len(u64 addr, u64 len, int page_size) static int use_umr(int order) { - return order <= 17; + return order <= MLX5_MAX_UMR_SHIFT; } static void prep_umr_reg_wqe(struct ib_pd *pd, struct ib_send_wr *wr, @@ -678,6 +691,7 @@ static void prep_umr_reg_wqe(struct ib_pd *pd, struct ib_send_wr *wr, { struct mlx5_ib_dev *dev = to_mdev(pd->device); struct ib_mr *mr = dev->umrc.mr; + struct mlx5_umr_wr *umrwr = (struct mlx5_umr_wr *)&wr->wr.fast_reg; sg->addr = dma; sg->length = ALIGN(sizeof(u64) * n, 64); @@ -692,21 +706,24 @@ static void prep_umr_reg_wqe(struct ib_pd *pd, struct ib_send_wr *wr, wr->num_sge = 0; wr->opcode = MLX5_IB_WR_UMR; - wr->wr.fast_reg.page_list_len = n; - wr->wr.fast_reg.page_shift = page_shift; - wr->wr.fast_reg.rkey = key; - wr->wr.fast_reg.iova_start = virt_addr; - wr->wr.fast_reg.length = len; - wr->wr.fast_reg.access_flags = access_flags; - wr->wr.fast_reg.page_list = (struct ib_fast_reg_page_list *)pd; + + umrwr->npages = n; + umrwr->page_shift = page_shift; + umrwr->mkey = key; + umrwr->target.virt_addr = virt_addr; + umrwr->length = len; + umrwr->access_flags = access_flags; + umrwr->pd = pd; } static void prep_umr_unreg_wqe(struct mlx5_ib_dev *dev, struct ib_send_wr *wr, u32 key) { - wr->send_flags = MLX5_IB_SEND_UMR_UNREG; + struct mlx5_umr_wr *umrwr = (struct mlx5_umr_wr *)&wr->wr.fast_reg; + + wr->send_flags = MLX5_IB_SEND_UMR_UNREG | MLX5_IB_SEND_UMR_FAIL_IF_FREE; wr->opcode = MLX5_IB_WR_UMR; - wr->wr.fast_reg.rkey = key; + umrwr->mkey = key; } void mlx5_umr_cq_handler(struct ib_cq *cq, void *cq_context) @@ -742,7 +759,10 @@ static struct mlx5_ib_mr *reg_umr(struct ib_pd *pd, struct ib_umem *umem, struct ib_send_wr wr, *bad; struct mlx5_ib_mr *mr; struct ib_sge sg; - int size = sizeof(u64) * npages; + int size; + __be64 *mr_pas; + __be64 *pas; + dma_addr_t dma; int err = 0; int i; @@ -761,25 +781,31 @@ static struct mlx5_ib_mr *reg_umr(struct ib_pd *pd, struct ib_umem *umem, if (!mr) return ERR_PTR(-EAGAIN); - mr->pas = kmalloc(size + MLX5_UMR_ALIGN - 1, GFP_KERNEL); - if (!mr->pas) { + /* UMR copies MTTs in units of MLX5_UMR_MTT_ALIGNMENT bytes. + * To avoid copying garbage after the pas array, we allocate + * a little more. */ + size = ALIGN(sizeof(u64) * npages, MLX5_UMR_MTT_ALIGNMENT); + mr_pas = kmalloc(size + MLX5_UMR_ALIGN - 1, GFP_KERNEL); + if (!mr_pas) { err = -ENOMEM; goto free_mr; } - mlx5_ib_populate_pas(dev, umem, page_shift, - mr_align(mr->pas, MLX5_UMR_ALIGN), 1); + pas = PTR_ALIGN(mr_pas, MLX5_UMR_ALIGN); + mlx5_ib_populate_pas(dev, umem, page_shift, pas, MLX5_IB_MTT_PRESENT); + /* Clear padding after the actual pages. */ + memset(pas + npages, 0, size - npages * sizeof(u64)); - mr->dma = dma_map_single(ddev, mr_align(mr->pas, MLX5_UMR_ALIGN), size, - DMA_TO_DEVICE); - if (dma_mapping_error(ddev, mr->dma)) { + dma = dma_map_single(ddev, pas, size, DMA_TO_DEVICE); + if (dma_mapping_error(ddev, dma)) { err = -ENOMEM; goto free_pas; } memset(&wr, 0, sizeof(wr)); wr.wr_id = (u64)(unsigned long)&umr_context; - prep_umr_reg_wqe(pd, &wr, &sg, mr->dma, npages, mr->mmr.key, page_shift, virt_addr, len, access_flags); + prep_umr_reg_wqe(pd, &wr, &sg, dma, npages, mr->mmr.key, page_shift, + virt_addr, len, access_flags); mlx5_ib_init_umr_context(&umr_context); down(&umrc->sem); @@ -799,12 +825,14 @@ static struct mlx5_ib_mr *reg_umr(struct ib_pd *pd, struct ib_umem *umem, mr->mmr.size = len; mr->mmr.pd = to_mpd(pd)->pdn; + mr->live = 1; + unmap_dma: up(&umrc->sem); - dma_unmap_single(ddev, mr->dma, size, DMA_TO_DEVICE); + dma_unmap_single(ddev, dma, size, DMA_TO_DEVICE); free_pas: - kfree(mr->pas); + kfree(mr_pas); free_mr: if (err) { @@ -815,6 +843,128 @@ free_mr: return mr; } +#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING +int mlx5_ib_update_mtt(struct mlx5_ib_mr *mr, u64 start_page_index, int npages, + int zap) +{ + struct mlx5_ib_dev *dev = mr->dev; + struct device *ddev = dev->ib_dev.dma_device; + struct umr_common *umrc = &dev->umrc; + struct mlx5_ib_umr_context umr_context; + struct ib_umem *umem = mr->umem; + int size; + __be64 *pas; + dma_addr_t dma; + struct ib_send_wr wr, *bad; + struct mlx5_umr_wr *umrwr = (struct mlx5_umr_wr *)&wr.wr.fast_reg; + struct ib_sge sg; + int err = 0; + const int page_index_alignment = MLX5_UMR_MTT_ALIGNMENT / sizeof(u64); + const int page_index_mask = page_index_alignment - 1; + size_t pages_mapped = 0; + size_t pages_to_map = 0; + size_t pages_iter = 0; + int use_emergency_buf = 0; + + /* UMR copies MTTs in units of MLX5_UMR_MTT_ALIGNMENT bytes, + * so we need to align the offset and length accordingly */ + if (start_page_index & page_index_mask) { + npages += start_page_index & page_index_mask; + start_page_index &= ~page_index_mask; + } + + pages_to_map = ALIGN(npages, page_index_alignment); + + if (start_page_index + pages_to_map > MLX5_MAX_UMR_PAGES) + return -EINVAL; + + size = sizeof(u64) * pages_to_map; + size = min_t(int, PAGE_SIZE, size); + /* We allocate with GFP_ATOMIC to avoid recursion into page-reclaim + * code, when we are called from an invalidation. The pas buffer must + * be 2k-aligned for Connect-IB. */ + pas = (__be64 *)get_zeroed_page(GFP_ATOMIC); + if (!pas) { + mlx5_ib_warn(dev, "unable to allocate memory during MTT update, falling back to slower chunked mechanism.\n"); + pas = mlx5_ib_update_mtt_emergency_buffer; + size = MLX5_UMR_MTT_MIN_CHUNK_SIZE; + use_emergency_buf = 1; + mutex_lock(&mlx5_ib_update_mtt_emergency_buffer_mutex); + memset(pas, 0, size); + } + pages_iter = size / sizeof(u64); + dma = dma_map_single(ddev, pas, size, DMA_TO_DEVICE); + if (dma_mapping_error(ddev, dma)) { + mlx5_ib_err(dev, "unable to map DMA during MTT update.\n"); + err = -ENOMEM; + goto free_pas; + } + + for (pages_mapped = 0; + pages_mapped < pages_to_map && !err; + pages_mapped += pages_iter, start_page_index += pages_iter) { + dma_sync_single_for_cpu(ddev, dma, size, DMA_TO_DEVICE); + + npages = min_t(size_t, + pages_iter, + ib_umem_num_pages(umem) - start_page_index); + + if (!zap) { + __mlx5_ib_populate_pas(dev, umem, PAGE_SHIFT, + start_page_index, npages, pas, + MLX5_IB_MTT_PRESENT); + /* Clear padding after the pages brought from the + * umem. */ + memset(pas + npages, 0, size - npages * sizeof(u64)); + } + + dma_sync_single_for_device(ddev, dma, size, DMA_TO_DEVICE); + + memset(&wr, 0, sizeof(wr)); + wr.wr_id = (u64)(unsigned long)&umr_context; + + sg.addr = dma; + sg.length = ALIGN(npages * sizeof(u64), + MLX5_UMR_MTT_ALIGNMENT); + sg.lkey = dev->umrc.mr->lkey; + + wr.send_flags = MLX5_IB_SEND_UMR_FAIL_IF_FREE | + MLX5_IB_SEND_UMR_UPDATE_MTT; + wr.sg_list = &sg; + wr.num_sge = 1; + wr.opcode = MLX5_IB_WR_UMR; + umrwr->npages = sg.length / sizeof(u64); + umrwr->page_shift = PAGE_SHIFT; + umrwr->mkey = mr->mmr.key; + umrwr->target.offset = start_page_index; + + mlx5_ib_init_umr_context(&umr_context); + down(&umrc->sem); + err = ib_post_send(umrc->qp, &wr, &bad); + if (err) { + mlx5_ib_err(dev, "UMR post send failed, err %d\n", err); + } else { + wait_for_completion(&umr_context.done); + if (umr_context.status != IB_WC_SUCCESS) { + mlx5_ib_err(dev, "UMR completion failed, code %d\n", + umr_context.status); + err = -EFAULT; + } + } + up(&umrc->sem); + } + dma_unmap_single(ddev, dma, size, DMA_TO_DEVICE); + +free_pas: + if (!use_emergency_buf) + free_page((unsigned long)pas); + else + mutex_unlock(&mlx5_ib_update_mtt_emergency_buffer_mutex); + + return err; +} +#endif + static struct mlx5_ib_mr *reg_create(struct ib_pd *pd, u64 virt_addr, u64 length, struct ib_umem *umem, int npages, int page_shift, @@ -825,6 +975,8 @@ static struct mlx5_ib_mr *reg_create(struct ib_pd *pd, u64 virt_addr, struct mlx5_ib_mr *mr; int inlen; int err; + bool pg_cap = !!(dev->mdev->caps.gen.flags & + MLX5_DEV_CAP_FLAG_ON_DMND_PG); mr = kzalloc(sizeof(*mr), GFP_KERNEL); if (!mr) @@ -836,8 +988,12 @@ static struct mlx5_ib_mr *reg_create(struct ib_pd *pd, u64 virt_addr, err = -ENOMEM; goto err_1; } - mlx5_ib_populate_pas(dev, umem, page_shift, in->pas, 0); + mlx5_ib_populate_pas(dev, umem, page_shift, in->pas, + pg_cap ? MLX5_IB_MTT_PRESENT : 0); + /* The MLX5_MKEY_INBOX_PG_ACCESS bit allows setting the access flags + * in the page list submitted with the command. */ + in->flags = pg_cap ? cpu_to_be32(MLX5_MKEY_INBOX_PG_ACCESS) : 0; in->seg.flags = convert_access(access_flags) | MLX5_ACCESS_MODE_MTT; in->seg.flags_pd = cpu_to_be32(to_mpd(pd)->pdn); @@ -856,6 +1012,7 @@ static struct mlx5_ib_mr *reg_create(struct ib_pd *pd, u64 virt_addr, goto err_2; } mr->umem = umem; + mr->live = 1; kvfree(in); mlx5_ib_dbg(dev, "mkey = 0x%x\n", mr->mmr.key); @@ -910,6 +1067,10 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, mlx5_ib_dbg(dev, "cache empty for order %d", order); mr = NULL; } + } else if (access_flags & IB_ACCESS_ON_DEMAND) { + err = -EINVAL; + pr_err("Got MR registration for ODP MR > 512MB, not supported for Connect-IB"); + goto error; } if (!mr) @@ -925,16 +1086,51 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, mr->umem = umem; mr->npages = npages; - spin_lock(&dev->mr_lock); - dev->mdev->priv.reg_pages += npages; - spin_unlock(&dev->mr_lock); + atomic_add(npages, &dev->mdev->priv.reg_pages); mr->ibmr.lkey = mr->mmr.key; mr->ibmr.rkey = mr->mmr.key; +#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING + if (umem->odp_data) { + /* + * This barrier prevents the compiler from moving the + * setting of umem->odp_data->private to point to our + * MR, before reg_umr finished, to ensure that the MR + * initialization have finished before starting to + * handle invalidations. + */ + smp_wmb(); + mr->umem->odp_data->private = mr; + /* + * Make sure we will see the new + * umem->odp_data->private value in the invalidation + * routines, before we can get page faults on the + * MR. Page faults can happen once we put the MR in + * the tree, below this line. Without the barrier, + * there can be a fault handling and an invalidation + * before umem->odp_data->private == mr is visible to + * the invalidation handler. + */ + smp_wmb(); + } +#endif + return &mr->ibmr; error: + /* + * Destroy the umem *before* destroying the MR, to ensure we + * will not have any in-flight notifiers when destroying the + * MR. + * + * As the MR is completely invalid to begin with, and this + * error path is only taken if we can't push the mr entry into + * the pagefault tree, this is safe. + */ + ib_umem_release(umem); + /* Kill the MR, and return an error code. */ + clean_mr(mr); return ERR_PTR(err); } @@ -971,17 +1167,14 @@ error: return err; } -int mlx5_ib_dereg_mr(struct ib_mr *ibmr) +static int clean_mr(struct mlx5_ib_mr *mr) { - struct mlx5_ib_dev *dev = to_mdev(ibmr->device); - struct mlx5_ib_mr *mr = to_mmr(ibmr); - struct ib_umem *umem = mr->umem; - int npages = mr->npages; + struct mlx5_ib_dev *dev = to_mdev(mr->ibmr.device); int umred = mr->umred; int err; if (!umred) { - err = mlx5_core_destroy_mkey(dev->mdev, &mr->mmr); + err = destroy_mkey(dev, mr); if (err) { mlx5_ib_warn(dev, "failed to destroy mkey 0x%x (%d)\n", mr->mmr.key, err); @@ -996,15 +1189,47 @@ int mlx5_ib_dereg_mr(struct ib_mr *ibmr) free_cached_mr(dev, mr); } - if (umem) { + if (!umred) + kfree(mr); + + return 0; +} + +int mlx5_ib_dereg_mr(struct ib_mr *ibmr) +{ + struct mlx5_ib_dev *dev = to_mdev(ibmr->device); + struct mlx5_ib_mr *mr = to_mmr(ibmr); + int npages = mr->npages; + struct ib_umem *umem = mr->umem; + +#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING + if (umem && umem->odp_data) { + /* Prevent new page faults from succeeding */ + mr->live = 0; + /* Wait for all running page-fault handlers to finish. */ + synchronize_srcu(&dev->mr_srcu); + /* Destroy all page mappings */ + mlx5_ib_invalidate_range(umem, ib_umem_start(umem), + ib_umem_end(umem)); + /* + * We kill the umem before the MR for ODP, + * so that there will not be any invalidations in + * flight, looking at the *mr struct. + */ ib_umem_release(umem); - spin_lock(&dev->mr_lock); - dev->mdev->priv.reg_pages -= npages; - spin_unlock(&dev->mr_lock); + atomic_sub(npages, &dev->mdev->priv.reg_pages); + + /* Avoid double-freeing the umem. */ + umem = NULL; } +#endif - if (!umred) - kfree(mr); + clean_mr(mr); + + if (umem) { + ib_umem_release(umem); + atomic_sub(npages, &dev->mdev->priv.reg_pages); + } return 0; } @@ -1028,7 +1253,7 @@ struct ib_mr *mlx5_ib_create_mr(struct ib_pd *pd, goto err_free; } - in->seg.status = 1 << 6; /* free */ + in->seg.status = MLX5_MKEY_STATUS_FREE; in->seg.xlt_oct_size = cpu_to_be32(ndescs); in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8); in->seg.flags_pd = cpu_to_be32(to_mpd(pd)->pdn); @@ -1113,7 +1338,7 @@ int mlx5_ib_destroy_mr(struct ib_mr *ibmr) kfree(mr->sig); } - err = mlx5_core_destroy_mkey(dev->mdev, &mr->mmr); + err = destroy_mkey(dev, mr); if (err) { mlx5_ib_warn(dev, "failed to destroy mkey 0x%x (%d)\n", mr->mmr.key, err); @@ -1143,7 +1368,7 @@ struct ib_mr *mlx5_ib_alloc_fast_reg_mr(struct ib_pd *pd, goto err_free; } - in->seg.status = 1 << 6; /* free */ + in->seg.status = MLX5_MKEY_STATUS_FREE; in->seg.xlt_oct_size = cpu_to_be32((max_page_list_len + 1) / 2); in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8); in->seg.flags = MLX5_PERM_UMR_EN | MLX5_ACCESS_MODE_MTT; diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c new file mode 100644 index 000000000000..a2c541c4809a --- /dev/null +++ b/drivers/infiniband/hw/mlx5/odp.c @@ -0,0 +1,798 @@ +/* + * Copyright (c) 2014 Mellanox Technologies. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <rdma/ib_umem.h> +#include <rdma/ib_umem_odp.h> + +#include "mlx5_ib.h" + +#define MAX_PREFETCH_LEN (4*1024*1024U) + +/* Timeout in ms to wait for an active mmu notifier to complete when handling + * a pagefault. */ +#define MMU_NOTIFIER_TIMEOUT 1000 + +struct workqueue_struct *mlx5_ib_page_fault_wq; + +void mlx5_ib_invalidate_range(struct ib_umem *umem, unsigned long start, + unsigned long end) +{ + struct mlx5_ib_mr *mr; + const u64 umr_block_mask = (MLX5_UMR_MTT_ALIGNMENT / sizeof(u64)) - 1; + u64 idx = 0, blk_start_idx = 0; + int in_block = 0; + u64 addr; + + if (!umem || !umem->odp_data) { + pr_err("invalidation called on NULL umem or non-ODP umem\n"); + return; + } + + mr = umem->odp_data->private; + + if (!mr || !mr->ibmr.pd) + return; + + start = max_t(u64, ib_umem_start(umem), start); + end = min_t(u64, ib_umem_end(umem), end); + + /* + * Iteration one - zap the HW's MTTs. The notifiers_count ensures that + * while we are doing the invalidation, no page fault will attempt to + * overwrite the same MTTs. Concurent invalidations might race us, + * but they will write 0s as well, so no difference in the end result. + */ + + for (addr = start; addr < end; addr += (u64)umem->page_size) { + idx = (addr - ib_umem_start(umem)) / PAGE_SIZE; + /* + * Strive to write the MTTs in chunks, but avoid overwriting + * non-existing MTTs. The huristic here can be improved to + * estimate the cost of another UMR vs. the cost of bigger + * UMR. + */ + if (umem->odp_data->dma_list[idx] & + (ODP_READ_ALLOWED_BIT | ODP_WRITE_ALLOWED_BIT)) { + if (!in_block) { + blk_start_idx = idx; + in_block = 1; + } + } else { + u64 umr_offset = idx & umr_block_mask; + + if (in_block && umr_offset == 0) { + mlx5_ib_update_mtt(mr, blk_start_idx, + idx - blk_start_idx, 1); + in_block = 0; + } + } + } + if (in_block) + mlx5_ib_update_mtt(mr, blk_start_idx, idx - blk_start_idx + 1, + 1); + + /* + * We are now sure that the device will not access the + * memory. We can safely unmap it, and mark it as dirty if + * needed. + */ + + ib_umem_odp_unmap_dma_pages(umem, start, end); +} + +#define COPY_ODP_BIT_MLX_TO_IB(reg, ib_caps, field_name, bit_name) do { \ + if (be32_to_cpu(reg.field_name) & MLX5_ODP_SUPPORT_##bit_name) \ + ib_caps->field_name |= IB_ODP_SUPPORT_##bit_name; \ +} while (0) + +int mlx5_ib_internal_query_odp_caps(struct mlx5_ib_dev *dev) +{ + int err; + struct mlx5_odp_caps hw_caps; + struct ib_odp_caps *caps = &dev->odp_caps; + + memset(caps, 0, sizeof(*caps)); + + if (!(dev->mdev->caps.gen.flags & MLX5_DEV_CAP_FLAG_ON_DMND_PG)) + return 0; + + err = mlx5_query_odp_caps(dev->mdev, &hw_caps); + if (err) + goto out; + + caps->general_caps = IB_ODP_SUPPORT; + COPY_ODP_BIT_MLX_TO_IB(hw_caps, caps, per_transport_caps.ud_odp_caps, + SEND); + COPY_ODP_BIT_MLX_TO_IB(hw_caps, caps, per_transport_caps.rc_odp_caps, + SEND); + COPY_ODP_BIT_MLX_TO_IB(hw_caps, caps, per_transport_caps.rc_odp_caps, + RECV); + COPY_ODP_BIT_MLX_TO_IB(hw_caps, caps, per_transport_caps.rc_odp_caps, + WRITE); + COPY_ODP_BIT_MLX_TO_IB(hw_caps, caps, per_transport_caps.rc_odp_caps, + READ); + +out: + return err; +} + +static struct mlx5_ib_mr *mlx5_ib_odp_find_mr_lkey(struct mlx5_ib_dev *dev, + u32 key) +{ + u32 base_key = mlx5_base_mkey(key); + struct mlx5_core_mr *mmr = __mlx5_mr_lookup(dev->mdev, base_key); + struct mlx5_ib_mr *mr = container_of(mmr, struct mlx5_ib_mr, mmr); + + if (!mmr || mmr->key != key || !mr->live) + return NULL; + + return container_of(mmr, struct mlx5_ib_mr, mmr); +} + +static void mlx5_ib_page_fault_resume(struct mlx5_ib_qp *qp, + struct mlx5_ib_pfault *pfault, + int error) { + struct mlx5_ib_dev *dev = to_mdev(qp->ibqp.pd->device); + int ret = mlx5_core_page_fault_resume(dev->mdev, qp->mqp.qpn, + pfault->mpfault.flags, + error); + if (ret) + pr_err("Failed to resolve the page fault on QP 0x%x\n", + qp->mqp.qpn); +} + +/* + * Handle a single data segment in a page-fault WQE. + * + * Returns number of pages retrieved on success. The caller will continue to + * the next data segment. + * Can return the following error codes: + * -EAGAIN to designate a temporary error. The caller will abort handling the + * page fault and resolve it. + * -EFAULT when there's an error mapping the requested pages. The caller will + * abort the page fault handling and possibly move the QP to an error state. + * On other errors the QP should also be closed with an error. + */ +static int pagefault_single_data_segment(struct mlx5_ib_qp *qp, + struct mlx5_ib_pfault *pfault, + u32 key, u64 io_virt, size_t bcnt, + u32 *bytes_mapped) +{ + struct mlx5_ib_dev *mib_dev = to_mdev(qp->ibqp.pd->device); + int srcu_key; + unsigned int current_seq; + u64 start_idx; + int npages = 0, ret = 0; + struct mlx5_ib_mr *mr; + u64 access_mask = ODP_READ_ALLOWED_BIT; + + srcu_key = srcu_read_lock(&mib_dev->mr_srcu); + mr = mlx5_ib_odp_find_mr_lkey(mib_dev, key); + /* + * If we didn't find the MR, it means the MR was closed while we were + * handling the ODP event. In this case we return -EFAULT so that the + * QP will be closed. + */ + if (!mr || !mr->ibmr.pd) { + pr_err("Failed to find relevant mr for lkey=0x%06x, probably the MR was destroyed\n", + key); + ret = -EFAULT; + goto srcu_unlock; + } + if (!mr->umem->odp_data) { + pr_debug("skipping non ODP MR (lkey=0x%06x) in page fault handler.\n", + key); + if (bytes_mapped) + *bytes_mapped += + (bcnt - pfault->mpfault.bytes_committed); + goto srcu_unlock; + } + if (mr->ibmr.pd != qp->ibqp.pd) { + pr_err("Page-fault with different PDs for QP and MR.\n"); + ret = -EFAULT; + goto srcu_unlock; + } + + current_seq = ACCESS_ONCE(mr->umem->odp_data->notifiers_seq); + /* + * Ensure the sequence number is valid for some time before we call + * gup. + */ + smp_rmb(); + + /* + * Avoid branches - this code will perform correctly + * in all iterations (in iteration 2 and above, + * bytes_committed == 0). + */ + io_virt += pfault->mpfault.bytes_committed; + bcnt -= pfault->mpfault.bytes_committed; + + start_idx = (io_virt - (mr->mmr.iova & PAGE_MASK)) >> PAGE_SHIFT; + + if (mr->umem->writable) + access_mask |= ODP_WRITE_ALLOWED_BIT; + npages = ib_umem_odp_map_dma_pages(mr->umem, io_virt, bcnt, + access_mask, current_seq); + if (npages < 0) { + ret = npages; + goto srcu_unlock; + } + + if (npages > 0) { + mutex_lock(&mr->umem->odp_data->umem_mutex); + if (!ib_umem_mmu_notifier_retry(mr->umem, current_seq)) { + /* + * No need to check whether the MTTs really belong to + * this MR, since ib_umem_odp_map_dma_pages already + * checks this. + */ + ret = mlx5_ib_update_mtt(mr, start_idx, npages, 0); + } else { + ret = -EAGAIN; + } + mutex_unlock(&mr->umem->odp_data->umem_mutex); + if (ret < 0) { + if (ret != -EAGAIN) + pr_err("Failed to update mkey page tables\n"); + goto srcu_unlock; + } + + if (bytes_mapped) { + u32 new_mappings = npages * PAGE_SIZE - + (io_virt - round_down(io_virt, PAGE_SIZE)); + *bytes_mapped += min_t(u32, new_mappings, bcnt); + } + } + +srcu_unlock: + if (ret == -EAGAIN) { + if (!mr->umem->odp_data->dying) { + struct ib_umem_odp *odp_data = mr->umem->odp_data; + unsigned long timeout = + msecs_to_jiffies(MMU_NOTIFIER_TIMEOUT); + + if (!wait_for_completion_timeout( + &odp_data->notifier_completion, + timeout)) { + pr_warn("timeout waiting for mmu notifier completion\n"); + } + } else { + /* The MR is being killed, kill the QP as well. */ + ret = -EFAULT; + } + } + srcu_read_unlock(&mib_dev->mr_srcu, srcu_key); + pfault->mpfault.bytes_committed = 0; + return ret ? ret : npages; +} + +/** + * Parse a series of data segments for page fault handling. + * + * @qp the QP on which the fault occurred. + * @pfault contains page fault information. + * @wqe points at the first data segment in the WQE. + * @wqe_end points after the end of the WQE. + * @bytes_mapped receives the number of bytes that the function was able to + * map. This allows the caller to decide intelligently whether + * enough memory was mapped to resolve the page fault + * successfully (e.g. enough for the next MTU, or the entire + * WQE). + * @total_wqe_bytes receives the total data size of this WQE in bytes (minus + * the committed bytes). + * + * Returns the number of pages loaded if positive, zero for an empty WQE, or a + * negative error code. + */ +static int pagefault_data_segments(struct mlx5_ib_qp *qp, + struct mlx5_ib_pfault *pfault, void *wqe, + void *wqe_end, u32 *bytes_mapped, + u32 *total_wqe_bytes, int receive_queue) +{ + int ret = 0, npages = 0; + u64 io_virt; + u32 key; + u32 byte_count; + size_t bcnt; + int inline_segment; + + /* Skip SRQ next-WQE segment. */ + if (receive_queue && qp->ibqp.srq) + wqe += sizeof(struct mlx5_wqe_srq_next_seg); + + if (bytes_mapped) + *bytes_mapped = 0; + if (total_wqe_bytes) + *total_wqe_bytes = 0; + + while (wqe < wqe_end) { + struct mlx5_wqe_data_seg *dseg = wqe; + + io_virt = be64_to_cpu(dseg->addr); + key = be32_to_cpu(dseg->lkey); + byte_count = be32_to_cpu(dseg->byte_count); + inline_segment = !!(byte_count & MLX5_INLINE_SEG); + bcnt = byte_count & ~MLX5_INLINE_SEG; + + if (inline_segment) { + bcnt = bcnt & MLX5_WQE_INLINE_SEG_BYTE_COUNT_MASK; + wqe += ALIGN(sizeof(struct mlx5_wqe_inline_seg) + bcnt, + 16); + } else { + wqe += sizeof(*dseg); + } + + /* receive WQE end of sg list. */ + if (receive_queue && bcnt == 0 && key == MLX5_INVALID_LKEY && + io_virt == 0) + break; + + if (!inline_segment && total_wqe_bytes) { + *total_wqe_bytes += bcnt - min_t(size_t, bcnt, + pfault->mpfault.bytes_committed); + } + + /* A zero length data segment designates a length of 2GB. */ + if (bcnt == 0) + bcnt = 1U << 31; + + if (inline_segment || bcnt <= pfault->mpfault.bytes_committed) { + pfault->mpfault.bytes_committed -= + min_t(size_t, bcnt, + pfault->mpfault.bytes_committed); + continue; + } + + ret = pagefault_single_data_segment(qp, pfault, key, io_virt, + bcnt, bytes_mapped); + if (ret < 0) + break; + npages += ret; + } + + return ret < 0 ? ret : npages; +} + +/* + * Parse initiator WQE. Advances the wqe pointer to point at the + * scatter-gather list, and set wqe_end to the end of the WQE. + */ +static int mlx5_ib_mr_initiator_pfault_handler( + struct mlx5_ib_qp *qp, struct mlx5_ib_pfault *pfault, + void **wqe, void **wqe_end, int wqe_length) +{ + struct mlx5_ib_dev *dev = to_mdev(qp->ibqp.pd->device); + struct mlx5_wqe_ctrl_seg *ctrl = *wqe; + u16 wqe_index = pfault->mpfault.wqe.wqe_index; + unsigned ds, opcode; +#if defined(DEBUG) + u32 ctrl_wqe_index, ctrl_qpn; +#endif + + ds = be32_to_cpu(ctrl->qpn_ds) & MLX5_WQE_CTRL_DS_MASK; + if (ds * MLX5_WQE_DS_UNITS > wqe_length) { + mlx5_ib_err(dev, "Unable to read the complete WQE. ds = 0x%x, ret = 0x%x\n", + ds, wqe_length); + return -EFAULT; + } + + if (ds == 0) { + mlx5_ib_err(dev, "Got WQE with zero DS. wqe_index=%x, qpn=%x\n", + wqe_index, qp->mqp.qpn); + return -EFAULT; + } + +#if defined(DEBUG) + ctrl_wqe_index = (be32_to_cpu(ctrl->opmod_idx_opcode) & + MLX5_WQE_CTRL_WQE_INDEX_MASK) >> + MLX5_WQE_CTRL_WQE_INDEX_SHIFT; + if (wqe_index != ctrl_wqe_index) { + mlx5_ib_err(dev, "Got WQE with invalid wqe_index. wqe_index=0x%x, qpn=0x%x ctrl->wqe_index=0x%x\n", + wqe_index, qp->mqp.qpn, + ctrl_wqe_index); + return -EFAULT; + } + + ctrl_qpn = (be32_to_cpu(ctrl->qpn_ds) & MLX5_WQE_CTRL_QPN_MASK) >> + MLX5_WQE_CTRL_QPN_SHIFT; + if (qp->mqp.qpn != ctrl_qpn) { + mlx5_ib_err(dev, "Got WQE with incorrect QP number. wqe_index=0x%x, qpn=0x%x ctrl->qpn=0x%x\n", + wqe_index, qp->mqp.qpn, + ctrl_qpn); + return -EFAULT; + } +#endif /* DEBUG */ + + *wqe_end = *wqe + ds * MLX5_WQE_DS_UNITS; + *wqe += sizeof(*ctrl); + + opcode = be32_to_cpu(ctrl->opmod_idx_opcode) & + MLX5_WQE_CTRL_OPCODE_MASK; + switch (qp->ibqp.qp_type) { + case IB_QPT_RC: + switch (opcode) { + case MLX5_OPCODE_SEND: + case MLX5_OPCODE_SEND_IMM: + case MLX5_OPCODE_SEND_INVAL: + if (!(dev->odp_caps.per_transport_caps.rc_odp_caps & + IB_ODP_SUPPORT_SEND)) + goto invalid_transport_or_opcode; + break; + case MLX5_OPCODE_RDMA_WRITE: + case MLX5_OPCODE_RDMA_WRITE_IMM: + if (!(dev->odp_caps.per_transport_caps.rc_odp_caps & + IB_ODP_SUPPORT_WRITE)) + goto invalid_transport_or_opcode; + *wqe += sizeof(struct mlx5_wqe_raddr_seg); + break; + case MLX5_OPCODE_RDMA_READ: + if (!(dev->odp_caps.per_transport_caps.rc_odp_caps & + IB_ODP_SUPPORT_READ)) + goto invalid_transport_or_opcode; + *wqe += sizeof(struct mlx5_wqe_raddr_seg); + break; + default: + goto invalid_transport_or_opcode; + } + break; + case IB_QPT_UD: + switch (opcode) { + case MLX5_OPCODE_SEND: + case MLX5_OPCODE_SEND_IMM: + if (!(dev->odp_caps.per_transport_caps.ud_odp_caps & + IB_ODP_SUPPORT_SEND)) + goto invalid_transport_or_opcode; + *wqe += sizeof(struct mlx5_wqe_datagram_seg); + break; + default: + goto invalid_transport_or_opcode; + } + break; + default: +invalid_transport_or_opcode: + mlx5_ib_err(dev, "ODP fault on QP of an unsupported opcode or transport. transport: 0x%x opcode: 0x%x.\n", + qp->ibqp.qp_type, opcode); + return -EFAULT; + } + + return 0; +} + +/* + * Parse responder WQE. Advances the wqe pointer to point at the + * scatter-gather list, and set wqe_end to the end of the WQE. + */ +static int mlx5_ib_mr_responder_pfault_handler( + struct mlx5_ib_qp *qp, struct mlx5_ib_pfault *pfault, + void **wqe, void **wqe_end, int wqe_length) +{ + struct mlx5_ib_dev *dev = to_mdev(qp->ibqp.pd->device); + struct mlx5_ib_wq *wq = &qp->rq; + int wqe_size = 1 << wq->wqe_shift; + + if (qp->ibqp.srq) { + mlx5_ib_err(dev, "ODP fault on SRQ is not supported\n"); + return -EFAULT; + } + + if (qp->wq_sig) { + mlx5_ib_err(dev, "ODP fault with WQE signatures is not supported\n"); + return -EFAULT; + } + + if (wqe_size > wqe_length) { + mlx5_ib_err(dev, "Couldn't read all of the receive WQE's content\n"); + return -EFAULT; + } + + switch (qp->ibqp.qp_type) { + case IB_QPT_RC: + if (!(dev->odp_caps.per_transport_caps.rc_odp_caps & + IB_ODP_SUPPORT_RECV)) + goto invalid_transport_or_opcode; + break; + default: +invalid_transport_or_opcode: + mlx5_ib_err(dev, "ODP fault on QP of an unsupported transport. transport: 0x%x\n", + qp->ibqp.qp_type); + return -EFAULT; + } + + *wqe_end = *wqe + wqe_size; + + return 0; +} + +static void mlx5_ib_mr_wqe_pfault_handler(struct mlx5_ib_qp *qp, + struct mlx5_ib_pfault *pfault) +{ + struct mlx5_ib_dev *dev = to_mdev(qp->ibqp.pd->device); + int ret; + void *wqe, *wqe_end; + u32 bytes_mapped, total_wqe_bytes; + char *buffer = NULL; + int resume_with_error = 0; + u16 wqe_index = pfault->mpfault.wqe.wqe_index; + int requestor = pfault->mpfault.flags & MLX5_PFAULT_REQUESTOR; + + buffer = (char *)__get_free_page(GFP_KERNEL); + if (!buffer) { + mlx5_ib_err(dev, "Error allocating memory for IO page fault handling.\n"); + resume_with_error = 1; + goto resolve_page_fault; + } + + ret = mlx5_ib_read_user_wqe(qp, requestor, wqe_index, buffer, + PAGE_SIZE); + if (ret < 0) { + mlx5_ib_err(dev, "Failed reading a WQE following page fault, error=%x, wqe_index=%x, qpn=%x\n", + -ret, wqe_index, qp->mqp.qpn); + resume_with_error = 1; + goto resolve_page_fault; + } + + wqe = buffer; + if (requestor) + ret = mlx5_ib_mr_initiator_pfault_handler(qp, pfault, &wqe, + &wqe_end, ret); + else + ret = mlx5_ib_mr_responder_pfault_handler(qp, pfault, &wqe, + &wqe_end, ret); + if (ret < 0) { + resume_with_error = 1; + goto resolve_page_fault; + } + + if (wqe >= wqe_end) { + mlx5_ib_err(dev, "ODP fault on invalid WQE.\n"); + resume_with_error = 1; + goto resolve_page_fault; + } + + ret = pagefault_data_segments(qp, pfault, wqe, wqe_end, &bytes_mapped, + &total_wqe_bytes, !requestor); + if (ret == -EAGAIN) { + goto resolve_page_fault; + } else if (ret < 0 || total_wqe_bytes > bytes_mapped) { + mlx5_ib_err(dev, "Error getting user pages for page fault. Error: 0x%x\n", + -ret); + resume_with_error = 1; + goto resolve_page_fault; + } + +resolve_page_fault: + mlx5_ib_page_fault_resume(qp, pfault, resume_with_error); + mlx5_ib_dbg(dev, "PAGE FAULT completed. QP 0x%x resume_with_error=%d, flags: 0x%x\n", + qp->mqp.qpn, resume_with_error, pfault->mpfault.flags); + + free_page((unsigned long)buffer); +} + +static int pages_in_range(u64 address, u32 length) +{ + return (ALIGN(address + length, PAGE_SIZE) - + (address & PAGE_MASK)) >> PAGE_SHIFT; +} + +static void mlx5_ib_mr_rdma_pfault_handler(struct mlx5_ib_qp *qp, + struct mlx5_ib_pfault *pfault) +{ + struct mlx5_pagefault *mpfault = &pfault->mpfault; + u64 address; + u32 length; + u32 prefetch_len = mpfault->bytes_committed; + int prefetch_activated = 0; + u32 rkey = mpfault->rdma.r_key; + int ret; + + /* The RDMA responder handler handles the page fault in two parts. + * First it brings the necessary pages for the current packet + * (and uses the pfault context), and then (after resuming the QP) + * prefetches more pages. The second operation cannot use the pfault + * context and therefore uses the dummy_pfault context allocated on + * the stack */ + struct mlx5_ib_pfault dummy_pfault = {}; + + dummy_pfault.mpfault.bytes_committed = 0; + + mpfault->rdma.rdma_va += mpfault->bytes_committed; + mpfault->rdma.rdma_op_len -= min(mpfault->bytes_committed, + mpfault->rdma.rdma_op_len); + mpfault->bytes_committed = 0; + + address = mpfault->rdma.rdma_va; + length = mpfault->rdma.rdma_op_len; + + /* For some operations, the hardware cannot tell the exact message + * length, and in those cases it reports zero. Use prefetch + * logic. */ + if (length == 0) { + prefetch_activated = 1; + length = mpfault->rdma.packet_size; + prefetch_len = min(MAX_PREFETCH_LEN, prefetch_len); + } + + ret = pagefault_single_data_segment(qp, pfault, rkey, address, length, + NULL); + if (ret == -EAGAIN) { + /* We're racing with an invalidation, don't prefetch */ + prefetch_activated = 0; + } else if (ret < 0 || pages_in_range(address, length) > ret) { + mlx5_ib_page_fault_resume(qp, pfault, 1); + return; + } + + mlx5_ib_page_fault_resume(qp, pfault, 0); + + /* At this point, there might be a new pagefault already arriving in + * the eq, switch to the dummy pagefault for the rest of the + * processing. We're still OK with the objects being alive as the + * work-queue is being fenced. */ + + if (prefetch_activated) { + ret = pagefault_single_data_segment(qp, &dummy_pfault, rkey, + address, + prefetch_len, + NULL); + if (ret < 0) { + pr_warn("Prefetch failed (ret = %d, prefetch_activated = %d) for QPN %d, address: 0x%.16llx, length = 0x%.16x\n", + ret, prefetch_activated, + qp->ibqp.qp_num, address, prefetch_len); + } + } +} + +void mlx5_ib_mr_pfault_handler(struct mlx5_ib_qp *qp, + struct mlx5_ib_pfault *pfault) +{ + u8 event_subtype = pfault->mpfault.event_subtype; + + switch (event_subtype) { + case MLX5_PFAULT_SUBTYPE_WQE: + mlx5_ib_mr_wqe_pfault_handler(qp, pfault); + break; + case MLX5_PFAULT_SUBTYPE_RDMA: + mlx5_ib_mr_rdma_pfault_handler(qp, pfault); + break; + default: + pr_warn("Invalid page fault event subtype: 0x%x\n", + event_subtype); + mlx5_ib_page_fault_resume(qp, pfault, 1); + break; + } +} + +static void mlx5_ib_qp_pfault_action(struct work_struct *work) +{ + struct mlx5_ib_pfault *pfault = container_of(work, + struct mlx5_ib_pfault, + work); + enum mlx5_ib_pagefault_context context = + mlx5_ib_get_pagefault_context(&pfault->mpfault); + struct mlx5_ib_qp *qp = container_of(pfault, struct mlx5_ib_qp, + pagefaults[context]); + mlx5_ib_mr_pfault_handler(qp, pfault); +} + +void mlx5_ib_qp_disable_pagefaults(struct mlx5_ib_qp *qp) +{ + unsigned long flags; + + spin_lock_irqsave(&qp->disable_page_faults_lock, flags); + qp->disable_page_faults = 1; + spin_unlock_irqrestore(&qp->disable_page_faults_lock, flags); + + /* + * Note that at this point, we are guarenteed that no more + * work queue elements will be posted to the work queue with + * the QP we are closing. + */ + flush_workqueue(mlx5_ib_page_fault_wq); +} + +void mlx5_ib_qp_enable_pagefaults(struct mlx5_ib_qp *qp) +{ + unsigned long flags; + + spin_lock_irqsave(&qp->disable_page_faults_lock, flags); + qp->disable_page_faults = 0; + spin_unlock_irqrestore(&qp->disable_page_faults_lock, flags); +} + +static void mlx5_ib_pfault_handler(struct mlx5_core_qp *qp, + struct mlx5_pagefault *pfault) +{ + /* + * Note that we will only get one fault event per QP per context + * (responder/initiator, read/write), until we resolve the page fault + * with the mlx5_ib_page_fault_resume command. Since this function is + * called from within the work element, there is no risk of missing + * events. + */ + struct mlx5_ib_qp *mibqp = to_mibqp(qp); + enum mlx5_ib_pagefault_context context = + mlx5_ib_get_pagefault_context(pfault); + struct mlx5_ib_pfault *qp_pfault = &mibqp->pagefaults[context]; + + qp_pfault->mpfault = *pfault; + + /* No need to stop interrupts here since we are in an interrupt */ + spin_lock(&mibqp->disable_page_faults_lock); + if (!mibqp->disable_page_faults) + queue_work(mlx5_ib_page_fault_wq, &qp_pfault->work); + spin_unlock(&mibqp->disable_page_faults_lock); +} + +void mlx5_ib_odp_create_qp(struct mlx5_ib_qp *qp) +{ + int i; + + qp->disable_page_faults = 1; + spin_lock_init(&qp->disable_page_faults_lock); + + qp->mqp.pfault_handler = mlx5_ib_pfault_handler; + + for (i = 0; i < MLX5_IB_PAGEFAULT_CONTEXTS; ++i) + INIT_WORK(&qp->pagefaults[i].work, mlx5_ib_qp_pfault_action); +} + +int mlx5_ib_odp_init_one(struct mlx5_ib_dev *ibdev) +{ + int ret; + + ret = init_srcu_struct(&ibdev->mr_srcu); + if (ret) + return ret; + + return 0; +} + +void mlx5_ib_odp_remove_one(struct mlx5_ib_dev *ibdev) +{ + cleanup_srcu_struct(&ibdev->mr_srcu); +} + +int __init mlx5_ib_odp_init(void) +{ + mlx5_ib_page_fault_wq = + create_singlethread_workqueue("mlx5_ib_page_faults"); + if (!mlx5_ib_page_fault_wq) + return -ENOMEM; + + return 0; +} + +void mlx5_ib_odp_cleanup(void) +{ + destroy_workqueue(mlx5_ib_page_fault_wq); +} diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 1cae1c7132b4..be0cd358b080 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -70,15 +70,6 @@ static const u32 mlx5_ib_opcode[] = { [MLX5_IB_WR_UMR] = MLX5_OPCODE_UMR, }; -struct umr_wr { - u64 virt_addr; - struct ib_pd *pd; - unsigned int page_shift; - unsigned int npages; - u32 length; - int access_flags; - u32 mkey; -}; static int is_qp0(enum ib_qp_type qp_type) { @@ -110,6 +101,77 @@ void *mlx5_get_send_wqe(struct mlx5_ib_qp *qp, int n) return get_wqe(qp, qp->sq.offset + (n << MLX5_IB_SQ_STRIDE)); } +/** + * mlx5_ib_read_user_wqe() - Copy a user-space WQE to kernel space. + * + * @qp: QP to copy from. + * @send: copy from the send queue when non-zero, use the receive queue + * otherwise. + * @wqe_index: index to start copying from. For send work queues, the + * wqe_index is in units of MLX5_SEND_WQE_BB. + * For receive work queue, it is the number of work queue + * element in the queue. + * @buffer: destination buffer. + * @length: maximum number of bytes to copy. + * + * Copies at least a single WQE, but may copy more data. + * + * Return: the number of bytes copied, or an error code. + */ +int mlx5_ib_read_user_wqe(struct mlx5_ib_qp *qp, int send, int wqe_index, + void *buffer, u32 length) +{ + struct ib_device *ibdev = qp->ibqp.device; + struct mlx5_ib_dev *dev = to_mdev(ibdev); + struct mlx5_ib_wq *wq = send ? &qp->sq : &qp->rq; + size_t offset; + size_t wq_end; + struct ib_umem *umem = qp->umem; + u32 first_copy_length; + int wqe_length; + int ret; + + if (wq->wqe_cnt == 0) { + mlx5_ib_dbg(dev, "mlx5_ib_read_user_wqe for a QP with wqe_cnt == 0. qp_type: 0x%x\n", + qp->ibqp.qp_type); + return -EINVAL; + } + + offset = wq->offset + ((wqe_index % wq->wqe_cnt) << wq->wqe_shift); + wq_end = wq->offset + (wq->wqe_cnt << wq->wqe_shift); + + if (send && length < sizeof(struct mlx5_wqe_ctrl_seg)) + return -EINVAL; + + if (offset > umem->length || + (send && offset + sizeof(struct mlx5_wqe_ctrl_seg) > umem->length)) + return -EINVAL; + + first_copy_length = min_t(u32, offset + length, wq_end) - offset; + ret = ib_umem_copy_from(buffer, umem, offset, first_copy_length); + if (ret) + return ret; + + if (send) { + struct mlx5_wqe_ctrl_seg *ctrl = buffer; + int ds = be32_to_cpu(ctrl->qpn_ds) & MLX5_WQE_CTRL_DS_MASK; + + wqe_length = ds * MLX5_WQE_DS_UNITS; + } else { + wqe_length = 1 << wq->wqe_shift; + } + + if (wqe_length <= first_copy_length) + return first_copy_length; + + ret = ib_umem_copy_from(buffer + first_copy_length, umem, wq->offset, + wqe_length - first_copy_length); + if (ret) + return ret; + + return wqe_length; +} + static void mlx5_ib_qp_event(struct mlx5_core_qp *qp, int type) { struct ib_qp *ibqp = &to_mibqp(qp)->ibqp; @@ -814,6 +876,8 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd, int inlen = sizeof(*in); int err; + mlx5_ib_odp_create_qp(qp); + gen = &dev->mdev->caps.gen; mutex_init(&qp->mutex); spin_lock_init(&qp->sq.lock); @@ -1098,11 +1162,13 @@ static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp) in = kzalloc(sizeof(*in), GFP_KERNEL); if (!in) return; - if (qp->state != IB_QPS_RESET) + if (qp->state != IB_QPS_RESET) { + mlx5_ib_qp_disable_pagefaults(qp); if (mlx5_core_qp_modify(dev->mdev, to_mlx5_state(qp->state), MLX5_QP_STATE_RST, in, sizeof(*in), &qp->mqp)) mlx5_ib_warn(dev, "mlx5_ib: modify QP %06x to RESET failed\n", qp->mqp.qpn); + } get_cqs(qp, &send_cq, &recv_cq); @@ -1650,6 +1716,15 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp, if (mlx5_st < 0) goto out; + /* If moving to a reset or error state, we must disable page faults on + * this QP and flush all current page faults. Otherwise a stale page + * fault may attempt to work on this QP after it is reset and moved + * again to RTS, and may cause the driver and the device to get out of + * sync. */ + if (cur_state != IB_QPS_RESET && cur_state != IB_QPS_ERR && + (new_state == IB_QPS_RESET || new_state == IB_QPS_ERR)) + mlx5_ib_qp_disable_pagefaults(qp); + optpar = ib_mask_to_mlx5_opt(attr_mask); optpar &= opt_mask[mlx5_cur][mlx5_new][mlx5_st]; in->optparam = cpu_to_be32(optpar); @@ -1659,6 +1734,9 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp, if (err) goto out; + if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) + mlx5_ib_qp_enable_pagefaults(qp); + qp->state = new_state; if (attr_mask & IB_QP_ACCESS_FLAGS) @@ -1848,37 +1926,70 @@ static void set_frwr_umr_segment(struct mlx5_wqe_umr_ctrl_seg *umr, umr->mkey_mask = frwr_mkey_mask(); } +static __be64 get_umr_reg_mr_mask(void) +{ + u64 result; + + result = MLX5_MKEY_MASK_LEN | + MLX5_MKEY_MASK_PAGE_SIZE | + MLX5_MKEY_MASK_START_ADDR | + MLX5_MKEY_MASK_PD | + MLX5_MKEY_MASK_LR | + MLX5_MKEY_MASK_LW | + MLX5_MKEY_MASK_KEY | + MLX5_MKEY_MASK_RR | + MLX5_MKEY_MASK_RW | + MLX5_MKEY_MASK_A | + MLX5_MKEY_MASK_FREE; + + return cpu_to_be64(result); +} + +static __be64 get_umr_unreg_mr_mask(void) +{ + u64 result; + + result = MLX5_MKEY_MASK_FREE; + + return cpu_to_be64(result); +} + +static __be64 get_umr_update_mtt_mask(void) +{ + u64 result; + + result = MLX5_MKEY_MASK_FREE; + + return cpu_to_be64(result); +} + static void set_reg_umr_segment(struct mlx5_wqe_umr_ctrl_seg *umr, struct ib_send_wr *wr) { - struct umr_wr *umrwr = (struct umr_wr *)&wr->wr.fast_reg; - u64 mask; + struct mlx5_umr_wr *umrwr = (struct mlx5_umr_wr *)&wr->wr.fast_reg; memset(umr, 0, sizeof(*umr)); + if (wr->send_flags & MLX5_IB_SEND_UMR_FAIL_IF_FREE) + umr->flags = MLX5_UMR_CHECK_FREE; /* fail if free */ + else + umr->flags = MLX5_UMR_CHECK_NOT_FREE; /* fail if not free */ + if (!(wr->send_flags & MLX5_IB_SEND_UMR_UNREG)) { - umr->flags = 1 << 5; /* fail if not free */ umr->klm_octowords = get_klm_octo(umrwr->npages); - mask = MLX5_MKEY_MASK_LEN | - MLX5_MKEY_MASK_PAGE_SIZE | - MLX5_MKEY_MASK_START_ADDR | - MLX5_MKEY_MASK_PD | - MLX5_MKEY_MASK_LR | - MLX5_MKEY_MASK_LW | - MLX5_MKEY_MASK_KEY | - MLX5_MKEY_MASK_RR | - MLX5_MKEY_MASK_RW | - MLX5_MKEY_MASK_A | - MLX5_MKEY_MASK_FREE; - umr->mkey_mask = cpu_to_be64(mask); + if (wr->send_flags & MLX5_IB_SEND_UMR_UPDATE_MTT) { + umr->mkey_mask = get_umr_update_mtt_mask(); + umr->bsf_octowords = get_klm_octo(umrwr->target.offset); + umr->flags |= MLX5_UMR_TRANSLATION_OFFSET_EN; + } else { + umr->mkey_mask = get_umr_reg_mr_mask(); + } } else { - umr->flags = 2 << 5; /* fail if free */ - mask = MLX5_MKEY_MASK_FREE; - umr->mkey_mask = cpu_to_be64(mask); + umr->mkey_mask = get_umr_unreg_mr_mask(); } if (!wr->num_sge) - umr->flags |= (1 << 7); /* inline */ + umr->flags |= MLX5_UMR_INLINE; } static u8 get_umr_flags(int acc) @@ -1895,7 +2006,7 @@ static void set_mkey_segment(struct mlx5_mkey_seg *seg, struct ib_send_wr *wr, { memset(seg, 0, sizeof(*seg)); if (li) { - seg->status = 1 << 6; + seg->status = MLX5_MKEY_STATUS_FREE; return; } @@ -1912,19 +2023,23 @@ static void set_mkey_segment(struct mlx5_mkey_seg *seg, struct ib_send_wr *wr, static void set_reg_mkey_segment(struct mlx5_mkey_seg *seg, struct ib_send_wr *wr) { + struct mlx5_umr_wr *umrwr = (struct mlx5_umr_wr *)&wr->wr.fast_reg; + memset(seg, 0, sizeof(*seg)); if (wr->send_flags & MLX5_IB_SEND_UMR_UNREG) { - seg->status = 1 << 6; + seg->status = MLX5_MKEY_STATUS_FREE; return; } - seg->flags = convert_access(wr->wr.fast_reg.access_flags); - seg->flags_pd = cpu_to_be32(to_mpd((struct ib_pd *)wr->wr.fast_reg.page_list)->pdn); - seg->start_addr = cpu_to_be64(wr->wr.fast_reg.iova_start); - seg->len = cpu_to_be64(wr->wr.fast_reg.length); - seg->log2_page_size = wr->wr.fast_reg.page_shift; + seg->flags = convert_access(umrwr->access_flags); + if (!(wr->send_flags & MLX5_IB_SEND_UMR_UPDATE_MTT)) { + seg->flags_pd = cpu_to_be32(to_mpd(umrwr->pd)->pdn); + seg->start_addr = cpu_to_be64(umrwr->target.virt_addr); + } + seg->len = cpu_to_be64(umrwr->length); + seg->log2_page_size = umrwr->page_shift; seg->qpn_mkey7_0 = cpu_to_be32(0xffffff00 | - mlx5_mkey_variant(wr->wr.fast_reg.rkey)); + mlx5_mkey_variant(umrwr->mkey)); } static void set_frwr_pages(struct mlx5_wqe_data_seg *dseg, @@ -2927,6 +3042,14 @@ int mlx5_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr int mlx5_state; int err = 0; +#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING + /* + * Wait for any outstanding page faults, in case the user frees memory + * based upon this query's result. + */ + flush_workqueue(mlx5_ib_page_fault_wq); +#endif + mutex_lock(&qp->mutex); outb = kzalloc(sizeof(*outb), GFP_KERNEL); if (!outb) { diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index fef067c959fc..c0d0296e7a00 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -2341,9 +2341,9 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, nes_debug(NES_DBG_MR, "User base = 0x%lX, Virt base = 0x%lX, length = %u," " offset = %u, page size = %u.\n", (unsigned long int)start, (unsigned long int)virt, (u32)length, - region->offset, region->page_size); + ib_umem_offset(region), region->page_size); - skip_pages = ((u32)region->offset) >> 12; + skip_pages = ((u32)ib_umem_offset(region)) >> 12; if (ib_copy_from_udata(&req, udata, sizeof(req))) { ib_umem_release(region); @@ -2408,7 +2408,7 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, region_length -= skip_pages << 12; for (page_index = skip_pages; page_index < chunk_pages; page_index++) { skip_pages = 0; - if ((page_count != 0) && (page_count<<12)-(region->offset&(4096-1)) >= region->length) + if ((page_count != 0) && (page_count << 12) - (ib_umem_offset(region) & (4096 - 1)) >= region->length) goto enough_pages; if ((page_count&0x01FF) == 0) { if (page_count >= 1024 * 512) { diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c index ac02ce4e8040..f3cc8c9e65ae 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c @@ -96,7 +96,6 @@ struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr) struct ocrdma_pd *pd = get_ocrdma_pd(ibpd); struct ocrdma_dev *dev = get_ocrdma_dev(ibpd->device); union ib_gid sgid; - u8 zmac[ETH_ALEN]; if (!(attr->ah_flags & IB_AH_GRH)) return ERR_PTR(-EINVAL); @@ -118,9 +117,7 @@ struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr) goto av_conf_err; } - memset(&zmac, 0, ETH_ALEN); - if (pd->uctx && - memcmp(attr->dmac, &zmac, ETH_ALEN)) { + if (pd->uctx) { status = rdma_addr_find_dmac_by_grh(&sgid, &attr->grh.dgid, attr->dmac, &attr->vlan_id); if (status) { diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index 4c68305ee781..fb8d8c4dfbb9 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c @@ -805,7 +805,7 @@ struct ib_mr *ocrdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len, goto umem_err; mr->hwmr.pbe_size = mr->umem->page_size; - mr->hwmr.fbo = mr->umem->offset; + mr->hwmr.fbo = ib_umem_offset(mr->umem); mr->hwmr.va = usr_addr; mr->hwmr.len = len; mr->hwmr.remote_wr = (acc & IB_ACCESS_REMOTE_WRITE) ? 1 : 0; @@ -1410,6 +1410,8 @@ int ocrdma_query_qp(struct ib_qp *ibqp, mutex_unlock(&dev->dev_lock); if (status) goto mbx_err; + if (qp->qp_type == IB_QPT_UD) + qp_attr->qkey = params.qkey; qp_attr->qp_state = get_ibqp_state(IB_QPS_INIT); qp_attr->cur_qp_state = get_ibqp_state(IB_QPS_INIT); qp_attr->path_mtu = diff --git a/drivers/infiniband/hw/qib/qib_mr.c b/drivers/infiniband/hw/qib/qib_mr.c index 9bbb55347cc1..a77fb4fb14e4 100644 --- a/drivers/infiniband/hw/qib/qib_mr.c +++ b/drivers/infiniband/hw/qib/qib_mr.c @@ -258,7 +258,7 @@ struct ib_mr *qib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, mr->mr.user_base = start; mr->mr.iova = virt_addr; mr->mr.length = length; - mr->mr.offset = umem->offset; + mr->mr.offset = ib_umem_offset(umem); mr->mr.access_flags = mr_access_flags; mr->umem = umem; diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index d7562beb5423..8ba80a6d3a46 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -98,9 +98,15 @@ enum { IPOIB_MCAST_FLAG_FOUND = 0, /* used in set_multicast_list */ IPOIB_MCAST_FLAG_SENDONLY = 1, - IPOIB_MCAST_FLAG_BUSY = 2, /* joining or already joined */ + /* + * For IPOIB_MCAST_FLAG_BUSY + * When set, in flight join and mcast->mc is unreliable + * When clear and mcast->mc IS_ERR_OR_NULL, need to restart or + * haven't started yet + * When clear and mcast->mc is valid pointer, join was successful + */ + IPOIB_MCAST_FLAG_BUSY = 2, IPOIB_MCAST_FLAG_ATTACHED = 3, - IPOIB_MCAST_JOIN_STARTED = 4, MAX_SEND_CQE = 16, IPOIB_CM_COPYBREAK = 256, @@ -317,6 +323,7 @@ struct ipoib_dev_priv { struct list_head multicast_list; struct rb_root multicast_tree; + struct workqueue_struct *wq; struct delayed_work mcast_task; struct work_struct carrier_on_task; struct work_struct flush_light; @@ -477,10 +484,10 @@ void ipoib_ib_dev_flush_heavy(struct work_struct *work); void ipoib_pkey_event(struct work_struct *work); void ipoib_ib_dev_cleanup(struct net_device *dev); -int ipoib_ib_dev_open(struct net_device *dev, int flush); +int ipoib_ib_dev_open(struct net_device *dev); int ipoib_ib_dev_up(struct net_device *dev); -int ipoib_ib_dev_down(struct net_device *dev, int flush); -int ipoib_ib_dev_stop(struct net_device *dev, int flush); +int ipoib_ib_dev_down(struct net_device *dev); +int ipoib_ib_dev_stop(struct net_device *dev); void ipoib_pkey_dev_check_presence(struct net_device *dev); int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port); @@ -492,7 +499,7 @@ void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb); void ipoib_mcast_restart_task(struct work_struct *work); int ipoib_mcast_start_thread(struct net_device *dev); -int ipoib_mcast_stop_thread(struct net_device *dev, int flush); +int ipoib_mcast_stop_thread(struct net_device *dev); void ipoib_mcast_dev_down(struct net_device *dev); void ipoib_mcast_dev_flush(struct net_device *dev); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 933efcea0d03..56959adb6c7d 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -474,7 +474,7 @@ static int ipoib_cm_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *even } spin_lock_irq(&priv->lock); - queue_delayed_work(ipoib_workqueue, + queue_delayed_work(priv->wq, &priv->cm.stale_task, IPOIB_CM_RX_DELAY); /* Add this entry to passive ids list head, but do not re-add it * if IB_EVENT_QP_LAST_WQE_REACHED has moved it to flush list. */ @@ -576,7 +576,7 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) spin_lock_irqsave(&priv->lock, flags); list_splice_init(&priv->cm.rx_drain_list, &priv->cm.rx_reap_list); ipoib_cm_start_rx_drain(priv); - queue_work(ipoib_workqueue, &priv->cm.rx_reap_task); + queue_work(priv->wq, &priv->cm.rx_reap_task); spin_unlock_irqrestore(&priv->lock, flags); } else ipoib_warn(priv, "cm recv completion event with wrid %d (> %d)\n", @@ -603,7 +603,7 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) spin_lock_irqsave(&priv->lock, flags); list_move(&p->list, &priv->cm.rx_reap_list); spin_unlock_irqrestore(&priv->lock, flags); - queue_work(ipoib_workqueue, &priv->cm.rx_reap_task); + queue_work(priv->wq, &priv->cm.rx_reap_task); } return; } @@ -827,7 +827,7 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &tx->flags)) { list_move(&tx->list, &priv->cm.reap_list); - queue_work(ipoib_workqueue, &priv->cm.reap_task); + queue_work(priv->wq, &priv->cm.reap_task); } clear_bit(IPOIB_FLAG_OPER_UP, &tx->flags); @@ -1255,7 +1255,7 @@ static int ipoib_cm_tx_handler(struct ib_cm_id *cm_id, if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &tx->flags)) { list_move(&tx->list, &priv->cm.reap_list); - queue_work(ipoib_workqueue, &priv->cm.reap_task); + queue_work(priv->wq, &priv->cm.reap_task); } spin_unlock_irqrestore(&priv->lock, flags); @@ -1284,7 +1284,7 @@ struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path tx->dev = dev; list_add(&tx->list, &priv->cm.start_list); set_bit(IPOIB_FLAG_INITIALIZED, &tx->flags); - queue_work(ipoib_workqueue, &priv->cm.start_task); + queue_work(priv->wq, &priv->cm.start_task); return tx; } @@ -1295,7 +1295,7 @@ void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx) if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &tx->flags)) { spin_lock_irqsave(&priv->lock, flags); list_move(&tx->list, &priv->cm.reap_list); - queue_work(ipoib_workqueue, &priv->cm.reap_task); + queue_work(priv->wq, &priv->cm.reap_task); ipoib_dbg(priv, "Reap connection for gid %pI6\n", tx->neigh->daddr + 4); tx->neigh = NULL; @@ -1417,7 +1417,7 @@ void ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb, skb_queue_tail(&priv->cm.skb_queue, skb); if (e) - queue_work(ipoib_workqueue, &priv->cm.skb_task); + queue_work(priv->wq, &priv->cm.skb_task); } static void ipoib_cm_rx_reap(struct work_struct *work) @@ -1450,7 +1450,7 @@ static void ipoib_cm_stale_task(struct work_struct *work) } if (!list_empty(&priv->cm.passive_ids)) - queue_delayed_work(ipoib_workqueue, + queue_delayed_work(priv->wq, &priv->cm.stale_task, IPOIB_CM_RX_DELAY); spin_unlock_irq(&priv->lock); } diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 72626c348174..fe65abb5150c 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -655,7 +655,7 @@ void ipoib_reap_ah(struct work_struct *work) __ipoib_reap_ah(dev); if (!test_bit(IPOIB_STOP_REAPER, &priv->flags)) - queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, + queue_delayed_work(priv->wq, &priv->ah_reap_task, round_jiffies_relative(HZ)); } @@ -664,7 +664,7 @@ static void ipoib_ib_tx_timer_func(unsigned long ctx) drain_tx_cq((struct net_device *)ctx); } -int ipoib_ib_dev_open(struct net_device *dev, int flush) +int ipoib_ib_dev_open(struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(dev); int ret; @@ -696,7 +696,7 @@ int ipoib_ib_dev_open(struct net_device *dev, int flush) } clear_bit(IPOIB_STOP_REAPER, &priv->flags); - queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, + queue_delayed_work(priv->wq, &priv->ah_reap_task, round_jiffies_relative(HZ)); if (!test_and_set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) @@ -706,7 +706,7 @@ int ipoib_ib_dev_open(struct net_device *dev, int flush) dev_stop: if (!test_and_set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) napi_enable(&priv->napi); - ipoib_ib_dev_stop(dev, flush); + ipoib_ib_dev_stop(dev); return -1; } @@ -738,7 +738,7 @@ int ipoib_ib_dev_up(struct net_device *dev) return ipoib_mcast_start_thread(dev); } -int ipoib_ib_dev_down(struct net_device *dev, int flush) +int ipoib_ib_dev_down(struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(dev); @@ -747,7 +747,7 @@ int ipoib_ib_dev_down(struct net_device *dev, int flush) clear_bit(IPOIB_FLAG_OPER_UP, &priv->flags); netif_carrier_off(dev); - ipoib_mcast_stop_thread(dev, flush); + ipoib_mcast_stop_thread(dev); ipoib_mcast_dev_flush(dev); ipoib_flush_paths(dev); @@ -807,7 +807,7 @@ void ipoib_drain_cq(struct net_device *dev) local_bh_enable(); } -int ipoib_ib_dev_stop(struct net_device *dev, int flush) +int ipoib_ib_dev_stop(struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(dev); struct ib_qp_attr qp_attr; @@ -880,8 +880,7 @@ timeout: /* Wait for all AHs to be reaped */ set_bit(IPOIB_STOP_REAPER, &priv->flags); cancel_delayed_work(&priv->ah_reap_task); - if (flush) - flush_workqueue(ipoib_workqueue); + flush_workqueue(priv->wq); begin = jiffies; @@ -918,7 +917,7 @@ int ipoib_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port) (unsigned long) dev); if (dev->flags & IFF_UP) { - if (ipoib_ib_dev_open(dev, 1)) { + if (ipoib_ib_dev_open(dev)) { ipoib_transport_dev_cleanup(dev); return -ENODEV; } @@ -1040,12 +1039,12 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, } if (level >= IPOIB_FLUSH_NORMAL) - ipoib_ib_dev_down(dev, 0); + ipoib_ib_dev_down(dev); if (level == IPOIB_FLUSH_HEAVY) { if (test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) - ipoib_ib_dev_stop(dev, 0); - if (ipoib_ib_dev_open(dev, 0) != 0) + ipoib_ib_dev_stop(dev); + if (ipoib_ib_dev_open(dev) != 0) return; if (netif_queue_stopped(dev)) netif_start_queue(dev); @@ -1097,7 +1096,7 @@ void ipoib_ib_dev_cleanup(struct net_device *dev) */ ipoib_flush_paths(dev); - ipoib_mcast_stop_thread(dev, 1); + ipoib_mcast_stop_thread(dev); ipoib_mcast_dev_flush(dev); ipoib_transport_dev_cleanup(dev); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 58b5aa3b6f2d..6bad17d4d588 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -108,7 +108,7 @@ int ipoib_open(struct net_device *dev) set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); - if (ipoib_ib_dev_open(dev, 1)) { + if (ipoib_ib_dev_open(dev)) { if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) return 0; goto err_disable; @@ -139,7 +139,7 @@ int ipoib_open(struct net_device *dev) return 0; err_stop: - ipoib_ib_dev_stop(dev, 1); + ipoib_ib_dev_stop(dev); err_disable: clear_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); @@ -157,8 +157,8 @@ static int ipoib_stop(struct net_device *dev) netif_stop_queue(dev); - ipoib_ib_dev_down(dev, 1); - ipoib_ib_dev_stop(dev, 0); + ipoib_ib_dev_down(dev); + ipoib_ib_dev_stop(dev); if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) { struct ipoib_dev_priv *cpriv; @@ -839,7 +839,7 @@ static void ipoib_set_mcast_list(struct net_device *dev) return; } - queue_work(ipoib_workqueue, &priv->restart_task); + queue_work(priv->wq, &priv->restart_task); } static u32 ipoib_addr_hash(struct ipoib_neigh_hash *htbl, u8 *daddr) @@ -954,7 +954,7 @@ static void ipoib_reap_neigh(struct work_struct *work) __ipoib_reap_neigh(priv); if (!test_bit(IPOIB_STOP_NEIGH_GC, &priv->flags)) - queue_delayed_work(ipoib_workqueue, &priv->neigh_reap_task, + queue_delayed_work(priv->wq, &priv->neigh_reap_task, arp_tbl.gc_interval); } @@ -1133,7 +1133,7 @@ static int ipoib_neigh_hash_init(struct ipoib_dev_priv *priv) /* start garbage collection */ clear_bit(IPOIB_STOP_NEIGH_GC, &priv->flags); - queue_delayed_work(ipoib_workqueue, &priv->neigh_reap_task, + queue_delayed_work(priv->wq, &priv->neigh_reap_task, arp_tbl.gc_interval); return 0; @@ -1262,15 +1262,13 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port) { struct ipoib_dev_priv *priv = netdev_priv(dev); - if (ipoib_neigh_hash_init(priv) < 0) - goto out; /* Allocate RX/TX "rings" to hold queued skbs */ priv->rx_ring = kzalloc(ipoib_recvq_size * sizeof *priv->rx_ring, GFP_KERNEL); if (!priv->rx_ring) { printk(KERN_WARNING "%s: failed to allocate RX ring (%d entries)\n", ca->name, ipoib_recvq_size); - goto out_neigh_hash_cleanup; + goto out; } priv->tx_ring = vzalloc(ipoib_sendq_size * sizeof *priv->tx_ring); @@ -1285,16 +1283,24 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port) if (ipoib_ib_dev_init(dev, ca, port)) goto out_tx_ring_cleanup; + /* + * Must be after ipoib_ib_dev_init so we can allocate a per + * device wq there and use it here + */ + if (ipoib_neigh_hash_init(priv) < 0) + goto out_dev_uninit; + return 0; +out_dev_uninit: + ipoib_ib_dev_cleanup(dev); + out_tx_ring_cleanup: vfree(priv->tx_ring); out_rx_ring_cleanup: kfree(priv->rx_ring); -out_neigh_hash_cleanup: - ipoib_neigh_hash_uninit(dev); out: return -ENOMEM; } @@ -1317,6 +1323,12 @@ void ipoib_dev_cleanup(struct net_device *dev) } unregister_netdevice_many(&head); + /* + * Must be before ipoib_ib_dev_cleanup or we delete an in use + * work queue + */ + ipoib_neigh_hash_uninit(dev); + ipoib_ib_dev_cleanup(dev); kfree(priv->rx_ring); @@ -1324,8 +1336,6 @@ void ipoib_dev_cleanup(struct net_device *dev) priv->rx_ring = NULL; priv->tx_ring = NULL; - - ipoib_neigh_hash_uninit(dev); } static const struct header_ops ipoib_header_ops = { @@ -1636,7 +1646,7 @@ register_failed: /* Stop GC if started before flush */ set_bit(IPOIB_STOP_NEIGH_GC, &priv->flags); cancel_delayed_work(&priv->neigh_reap_task); - flush_workqueue(ipoib_workqueue); + flush_workqueue(priv->wq); event_failed: ipoib_dev_cleanup(priv->dev); @@ -1707,7 +1717,7 @@ static void ipoib_remove_one(struct ib_device *device) /* Stop GC */ set_bit(IPOIB_STOP_NEIGH_GC, &priv->flags); cancel_delayed_work(&priv->neigh_reap_task); - flush_workqueue(ipoib_workqueue); + flush_workqueue(priv->wq); unregister_netdev(priv->dev); free_netdev(priv->dev); @@ -1748,8 +1758,13 @@ static int __init ipoib_init_module(void) * unregister_netdev() and linkwatch_event take the rtnl lock, * so flush_scheduled_work() can deadlock during device * removal. + * + * In addition, bringing one device up and another down at the + * same time can deadlock a single workqueue, so we have this + * global fallback workqueue, but we also attempt to open a + * per device workqueue each time we bring an interface up */ - ipoib_workqueue = create_singlethread_workqueue("ipoib"); + ipoib_workqueue = create_singlethread_workqueue("ipoib_flush"); if (!ipoib_workqueue) { ret = -ENOMEM; goto err_fs; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index ffb83b5f7e80..bc50dd0d0e4d 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -190,12 +190,6 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, spin_unlock_irq(&priv->lock); priv->tx_wr.wr.ud.remote_qkey = priv->qkey; set_qkey = 1; - - if (!ipoib_cm_admin_enabled(dev)) { - rtnl_lock(); - dev_set_mtu(dev, min(priv->mcast_mtu, priv->admin_mtu)); - rtnl_unlock(); - } } if (!test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) { @@ -277,16 +271,27 @@ ipoib_mcast_sendonly_join_complete(int status, struct ipoib_mcast *mcast = multicast->context; struct net_device *dev = mcast->dev; + /* + * We have to take the mutex to force mcast_sendonly_join to + * return from ib_sa_multicast_join and set mcast->mc to a + * valid value. Otherwise we were racing with ourselves in + * that we might fail here, but get a valid return from + * ib_sa_multicast_join after we had cleared mcast->mc here, + * resulting in mis-matched joins and leaves and a deadlock + */ + mutex_lock(&mcast_mutex); + /* We trap for port events ourselves. */ if (status == -ENETRESET) - return 0; + goto out; if (!status) status = ipoib_mcast_join_finish(mcast, &multicast->rec); if (status) { if (mcast->logcount++ < 20) - ipoib_dbg_mcast(netdev_priv(dev), "multicast join failed for %pI6, status %d\n", + ipoib_dbg_mcast(netdev_priv(dev), "sendonly multicast " + "join failed for %pI6, status %d\n", mcast->mcmember.mgid.raw, status); /* Flush out any queued packets */ @@ -296,11 +301,15 @@ ipoib_mcast_sendonly_join_complete(int status, dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue)); } netif_tx_unlock_bh(dev); - - /* Clear the busy flag so we try again */ - status = test_and_clear_bit(IPOIB_MCAST_FLAG_BUSY, - &mcast->flags); } +out: + clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); + if (status) + mcast->mc = NULL; + complete(&mcast->done); + if (status == -ENETRESET) + status = 0; + mutex_unlock(&mcast_mutex); return status; } @@ -318,12 +327,14 @@ static int ipoib_mcast_sendonly_join(struct ipoib_mcast *mcast) int ret = 0; if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags)) { - ipoib_dbg_mcast(priv, "device shutting down, no multicast joins\n"); + ipoib_dbg_mcast(priv, "device shutting down, no sendonly " + "multicast joins\n"); return -ENODEV; } - if (test_and_set_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags)) { - ipoib_dbg_mcast(priv, "multicast entry busy, skipping\n"); + if (test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags)) { + ipoib_dbg_mcast(priv, "multicast entry busy, skipping " + "sendonly join\n"); return -EBUSY; } @@ -331,6 +342,9 @@ static int ipoib_mcast_sendonly_join(struct ipoib_mcast *mcast) rec.port_gid = priv->local_gid; rec.pkey = cpu_to_be16(priv->pkey); + mutex_lock(&mcast_mutex); + init_completion(&mcast->done); + set_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); mcast->mc = ib_sa_join_multicast(&ipoib_sa_client, priv->ca, priv->port, &rec, IB_SA_MCMEMBER_REC_MGID | @@ -343,12 +357,14 @@ static int ipoib_mcast_sendonly_join(struct ipoib_mcast *mcast) if (IS_ERR(mcast->mc)) { ret = PTR_ERR(mcast->mc); clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); - ipoib_warn(priv, "ib_sa_join_multicast failed (ret = %d)\n", - ret); + complete(&mcast->done); + ipoib_warn(priv, "ib_sa_join_multicast for sendonly join " + "failed (ret = %d)\n", ret); } else { - ipoib_dbg_mcast(priv, "no multicast record for %pI6, starting join\n", - mcast->mcmember.mgid.raw); + ipoib_dbg_mcast(priv, "no multicast record for %pI6, starting " + "sendonly join\n", mcast->mcmember.mgid.raw); } + mutex_unlock(&mcast_mutex); return ret; } @@ -359,18 +375,29 @@ void ipoib_mcast_carrier_on_task(struct work_struct *work) carrier_on_task); struct ib_port_attr attr; - /* - * Take rtnl_lock to avoid racing with ipoib_stop() and - * turning the carrier back on while a device is being - * removed. - */ if (ib_query_port(priv->ca, priv->port, &attr) || attr.state != IB_PORT_ACTIVE) { ipoib_dbg(priv, "Keeping carrier off until IB port is active\n"); return; } - rtnl_lock(); + /* + * Take rtnl_lock to avoid racing with ipoib_stop() and + * turning the carrier back on while a device is being + * removed. However, ipoib_stop() will attempt to flush + * the workqueue while holding the rtnl lock, so loop + * on trylock until either we get the lock or we see + * FLAG_ADMIN_UP go away as that signals that we are bailing + * and can safely ignore the carrier on work. + */ + while (!rtnl_trylock()) { + if (!test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) + return; + else + msleep(20); + } + if (!ipoib_cm_admin_enabled(priv->dev)) + dev_set_mtu(priv->dev, min(priv->mcast_mtu, priv->admin_mtu)); netif_carrier_on(priv->dev); rtnl_unlock(); } @@ -385,60 +412,63 @@ static int ipoib_mcast_join_complete(int status, ipoib_dbg_mcast(priv, "join completion for %pI6 (status %d)\n", mcast->mcmember.mgid.raw, status); + /* + * We have to take the mutex to force mcast_join to + * return from ib_sa_multicast_join and set mcast->mc to a + * valid value. Otherwise we were racing with ourselves in + * that we might fail here, but get a valid return from + * ib_sa_multicast_join after we had cleared mcast->mc here, + * resulting in mis-matched joins and leaves and a deadlock + */ + mutex_lock(&mcast_mutex); + /* We trap for port events ourselves. */ - if (status == -ENETRESET) { - status = 0; + if (status == -ENETRESET) goto out; - } if (!status) status = ipoib_mcast_join_finish(mcast, &multicast->rec); if (!status) { mcast->backoff = 1; - mutex_lock(&mcast_mutex); if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) - queue_delayed_work(ipoib_workqueue, - &priv->mcast_task, 0); - mutex_unlock(&mcast_mutex); + queue_delayed_work(priv->wq, &priv->mcast_task, 0); /* - * Defer carrier on work to ipoib_workqueue to avoid a + * Defer carrier on work to priv->wq to avoid a * deadlock on rtnl_lock here. */ if (mcast == priv->broadcast) - queue_work(ipoib_workqueue, &priv->carrier_on_task); - - status = 0; - goto out; - } - - if (mcast->logcount++ < 20) { - if (status == -ETIMEDOUT || status == -EAGAIN) { - ipoib_dbg_mcast(priv, "multicast join failed for %pI6, status %d\n", - mcast->mcmember.mgid.raw, status); - } else { - ipoib_warn(priv, "multicast join failed for %pI6, status %d\n", - mcast->mcmember.mgid.raw, status); + queue_work(priv->wq, &priv->carrier_on_task); + } else { + if (mcast->logcount++ < 20) { + if (status == -ETIMEDOUT || status == -EAGAIN) { + ipoib_dbg_mcast(priv, "multicast join failed for %pI6, status %d\n", + mcast->mcmember.mgid.raw, status); + } else { + ipoib_warn(priv, "multicast join failed for %pI6, status %d\n", + mcast->mcmember.mgid.raw, status); + } } - } - - mcast->backoff *= 2; - if (mcast->backoff > IPOIB_MAX_BACKOFF_SECONDS) - mcast->backoff = IPOIB_MAX_BACKOFF_SECONDS; - /* Clear the busy flag so we try again */ - status = test_and_clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); - - mutex_lock(&mcast_mutex); + mcast->backoff *= 2; + if (mcast->backoff > IPOIB_MAX_BACKOFF_SECONDS) + mcast->backoff = IPOIB_MAX_BACKOFF_SECONDS; + } +out: spin_lock_irq(&priv->lock); - if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) - queue_delayed_work(ipoib_workqueue, &priv->mcast_task, + clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); + if (status) + mcast->mc = NULL; + complete(&mcast->done); + if (status == -ENETRESET) + status = 0; + if (status && test_bit(IPOIB_MCAST_RUN, &priv->flags)) + queue_delayed_work(priv->wq, &priv->mcast_task, mcast->backoff * HZ); spin_unlock_irq(&priv->lock); mutex_unlock(&mcast_mutex); -out: - complete(&mcast->done); + return status; } @@ -487,10 +517,9 @@ static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast, rec.hop_limit = priv->broadcast->mcmember.hop_limit; } - set_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); + mutex_lock(&mcast_mutex); init_completion(&mcast->done); - set_bit(IPOIB_MCAST_JOIN_STARTED, &mcast->flags); - + set_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); mcast->mc = ib_sa_join_multicast(&ipoib_sa_client, priv->ca, priv->port, &rec, comp_mask, GFP_KERNEL, ipoib_mcast_join_complete, mcast); @@ -504,13 +533,11 @@ static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast, if (mcast->backoff > IPOIB_MAX_BACKOFF_SECONDS) mcast->backoff = IPOIB_MAX_BACKOFF_SECONDS; - mutex_lock(&mcast_mutex); if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) - queue_delayed_work(ipoib_workqueue, - &priv->mcast_task, + queue_delayed_work(priv->wq, &priv->mcast_task, mcast->backoff * HZ); - mutex_unlock(&mcast_mutex); } + mutex_unlock(&mcast_mutex); } void ipoib_mcast_join_task(struct work_struct *work) @@ -547,8 +574,8 @@ void ipoib_mcast_join_task(struct work_struct *work) ipoib_warn(priv, "failed to allocate broadcast group\n"); mutex_lock(&mcast_mutex); if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) - queue_delayed_work(ipoib_workqueue, - &priv->mcast_task, HZ); + queue_delayed_work(priv->wq, &priv->mcast_task, + HZ); mutex_unlock(&mcast_mutex); return; } @@ -563,7 +590,8 @@ void ipoib_mcast_join_task(struct work_struct *work) } if (!test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) { - if (!test_bit(IPOIB_MCAST_FLAG_BUSY, &priv->broadcast->flags)) + if (IS_ERR_OR_NULL(priv->broadcast->mc) && + !test_bit(IPOIB_MCAST_FLAG_BUSY, &priv->broadcast->flags)) ipoib_mcast_join(dev, priv->broadcast, 0); return; } @@ -571,23 +599,33 @@ void ipoib_mcast_join_task(struct work_struct *work) while (1) { struct ipoib_mcast *mcast = NULL; + /* + * Need the mutex so our flags are consistent, need the + * priv->lock so we don't race with list removals in either + * mcast_dev_flush or mcast_restart_task + */ + mutex_lock(&mcast_mutex); spin_lock_irq(&priv->lock); list_for_each_entry(mcast, &priv->multicast_list, list) { - if (!test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags) - && !test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags) - && !test_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags)) { + if (IS_ERR_OR_NULL(mcast->mc) && + !test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags) && + !test_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags)) { /* Found the next unjoined group */ break; } } spin_unlock_irq(&priv->lock); + mutex_unlock(&mcast_mutex); if (&mcast->list == &priv->multicast_list) { /* All done */ break; } - ipoib_mcast_join(dev, mcast, 1); + if (test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) + ipoib_mcast_sendonly_join(mcast); + else + ipoib_mcast_join(dev, mcast, 1); return; } @@ -604,13 +642,13 @@ int ipoib_mcast_start_thread(struct net_device *dev) mutex_lock(&mcast_mutex); if (!test_and_set_bit(IPOIB_MCAST_RUN, &priv->flags)) - queue_delayed_work(ipoib_workqueue, &priv->mcast_task, 0); + queue_delayed_work(priv->wq, &priv->mcast_task, 0); mutex_unlock(&mcast_mutex); return 0; } -int ipoib_mcast_stop_thread(struct net_device *dev, int flush) +int ipoib_mcast_stop_thread(struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(dev); @@ -621,8 +659,7 @@ int ipoib_mcast_stop_thread(struct net_device *dev, int flush) cancel_delayed_work(&priv->mcast_task); mutex_unlock(&mcast_mutex); - if (flush) - flush_workqueue(ipoib_workqueue); + flush_workqueue(priv->wq); return 0; } @@ -633,6 +670,9 @@ static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast) int ret = 0; if (test_and_clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags)) + ipoib_warn(priv, "ipoib_mcast_leave on an in-flight join\n"); + + if (!IS_ERR_OR_NULL(mcast->mc)) ib_sa_free_multicast(mcast->mc); if (test_and_clear_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags)) { @@ -685,6 +725,8 @@ void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb) memcpy(mcast->mcmember.mgid.raw, mgid, sizeof (union ib_gid)); __ipoib_mcast_add(dev, mcast); list_add_tail(&mcast->list, &priv->multicast_list); + if (!test_and_set_bit(IPOIB_MCAST_RUN, &priv->flags)) + queue_delayed_work(priv->wq, &priv->mcast_task, 0); } if (!mcast->ah) { @@ -698,8 +740,6 @@ void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb) if (test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags)) ipoib_dbg_mcast(priv, "no address vector, " "but multicast join already started\n"); - else if (test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) - ipoib_mcast_sendonly_join(mcast); /* * If lookup completes between here and out:, don't @@ -759,9 +799,12 @@ void ipoib_mcast_dev_flush(struct net_device *dev) spin_unlock_irqrestore(&priv->lock, flags); - /* seperate between the wait to the leave*/ + /* + * make sure the in-flight joins have finished before we attempt + * to leave + */ list_for_each_entry_safe(mcast, tmcast, &remove_list, list) - if (test_bit(IPOIB_MCAST_JOIN_STARTED, &mcast->flags)) + if (test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags)) wait_for_completion(&mcast->done); list_for_each_entry_safe(mcast, tmcast, &remove_list, list) { @@ -794,8 +837,6 @@ void ipoib_mcast_restart_task(struct work_struct *work) ipoib_dbg_mcast(priv, "restarting multicast task\n"); - ipoib_mcast_stop_thread(dev, 0); - local_irq_save(flags); netif_addr_lock(dev); spin_lock(&priv->lock); @@ -880,14 +921,38 @@ void ipoib_mcast_restart_task(struct work_struct *work) netif_addr_unlock(dev); local_irq_restore(flags); - /* We have to cancel outside of the spinlock */ + /* + * make sure the in-flight joins have finished before we attempt + * to leave + */ + list_for_each_entry_safe(mcast, tmcast, &remove_list, list) + if (test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags)) + wait_for_completion(&mcast->done); + + /* + * We have to cancel outside of the spinlock, but we have to + * take the rtnl lock or else we race with the removal of + * entries from the remove list in mcast_dev_flush as part + * of ipoib_stop(). We detect the drop of the ADMIN_UP flag + * to signal that we have hit this particular race, and we + * return since we know we don't need to do anything else + * anyway. + */ + while (!rtnl_trylock()) { + if (!test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) + return; + else + msleep(20); + } list_for_each_entry_safe(mcast, tmcast, &remove_list, list) { ipoib_mcast_leave(mcast->dev, mcast); ipoib_mcast_free(mcast); } - - if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) - ipoib_mcast_start_thread(dev); + /* + * Restart our join task if needed + */ + ipoib_mcast_start_thread(dev); + rtnl_unlock(); } #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index c56d5d44c53b..b72a753eb41d 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c @@ -145,10 +145,20 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca) int ret, size; int i; + /* + * the various IPoIB tasks assume they will never race against + * themselves, so always use a single thread workqueue + */ + priv->wq = create_singlethread_workqueue("ipoib_wq"); + if (!priv->wq) { + printk(KERN_WARNING "ipoib: failed to allocate device WQ\n"); + return -ENODEV; + } + priv->pd = ib_alloc_pd(priv->ca); if (IS_ERR(priv->pd)) { printk(KERN_WARNING "%s: failed to allocate PD\n", ca->name); - return -ENODEV; + goto out_free_wq; } priv->mr = ib_get_dma_mr(priv->pd, IB_ACCESS_LOCAL_WRITE); @@ -242,6 +252,10 @@ out_free_mr: out_free_pd: ib_dealloc_pd(priv->pd); + +out_free_wq: + destroy_workqueue(priv->wq); + priv->wq = NULL; return -ENODEV; } @@ -270,6 +284,12 @@ void ipoib_transport_dev_cleanup(struct net_device *dev) if (ib_dealloc_pd(priv->pd)) ipoib_warn(priv, "ib_dealloc_pd failed\n"); + + if (priv->wq) { + flush_workqueue(priv->wq); + destroy_workqueue(priv->wq); + priv->wq = NULL; + } } void ipoib_event(struct ib_event_handler *handler, diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 20ca6a619476..6a594aac2290 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -97,7 +97,7 @@ module_param_named(pi_enable, iser_pi_enable, bool, 0644); MODULE_PARM_DESC(pi_enable, "Enable T10-PI offload support (default:disabled)"); module_param_named(pi_guard, iser_pi_guard, int, 0644); -MODULE_PARM_DESC(pi_guard, "T10-PI guard_type, 0:CRC|1:IP_CSUM (default:IP_CSUM)"); +MODULE_PARM_DESC(pi_guard, "T10-PI guard_type [deprecated]"); static struct workqueue_struct *release_wq; struct iser_global ig; @@ -164,18 +164,42 @@ iscsi_iser_pdu_alloc(struct iscsi_task *task, uint8_t opcode) return 0; } -int iser_initialize_task_headers(struct iscsi_task *task, - struct iser_tx_desc *tx_desc) +/** + * iser_initialize_task_headers() - Initialize task headers + * @task: iscsi task + * @tx_desc: iser tx descriptor + * + * Notes: + * This routine may race with iser teardown flow for scsi + * error handling TMFs. So for TMF we should acquire the + * state mutex to avoid dereferencing the IB device which + * may have already been terminated. + */ +int +iser_initialize_task_headers(struct iscsi_task *task, + struct iser_tx_desc *tx_desc) { - struct iser_conn *iser_conn = task->conn->dd_data; + struct iser_conn *iser_conn = task->conn->dd_data; struct iser_device *device = iser_conn->ib_conn.device; struct iscsi_iser_task *iser_task = task->dd_data; u64 dma_addr; + const bool mgmt_task = !task->sc && !in_interrupt(); + int ret = 0; + + if (unlikely(mgmt_task)) + mutex_lock(&iser_conn->state_mutex); + + if (unlikely(iser_conn->state != ISER_CONN_UP)) { + ret = -ENODEV; + goto out; + } dma_addr = ib_dma_map_single(device->ib_device, (void *)tx_desc, ISER_HEADERS_LEN, DMA_TO_DEVICE); - if (ib_dma_mapping_error(device->ib_device, dma_addr)) - return -ENOMEM; + if (ib_dma_mapping_error(device->ib_device, dma_addr)) { + ret = -ENOMEM; + goto out; + } tx_desc->dma_addr = dma_addr; tx_desc->tx_sg[0].addr = tx_desc->dma_addr; @@ -183,7 +207,11 @@ int iser_initialize_task_headers(struct iscsi_task *task, tx_desc->tx_sg[0].lkey = device->mr->lkey; iser_task->iser_conn = iser_conn; - return 0; +out: + if (unlikely(mgmt_task)) + mutex_unlock(&iser_conn->state_mutex); + + return ret; } /** @@ -199,9 +227,14 @@ static int iscsi_iser_task_init(struct iscsi_task *task) { struct iscsi_iser_task *iser_task = task->dd_data; + int ret; - if (iser_initialize_task_headers(task, &iser_task->desc)) - return -ENOMEM; + ret = iser_initialize_task_headers(task, &iser_task->desc); + if (ret) { + iser_err("Failed to init task %p, err = %d\n", + iser_task, ret); + return ret; + } /* mgmt task */ if (!task->sc) @@ -508,8 +541,8 @@ iscsi_iser_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) */ if (iser_conn) { mutex_lock(&iser_conn->state_mutex); - iscsi_conn_stop(cls_conn, flag); iser_conn_terminate(iser_conn); + iscsi_conn_stop(cls_conn, flag); /* unbind */ iser_conn->iscsi_conn = NULL; @@ -541,12 +574,13 @@ iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session) static inline unsigned int iser_dif_prot_caps(int prot_caps) { - return ((prot_caps & IB_PROT_T10DIF_TYPE_1) ? SHOST_DIF_TYPE1_PROTECTION | - SHOST_DIX_TYPE1_PROTECTION : 0) | - ((prot_caps & IB_PROT_T10DIF_TYPE_2) ? SHOST_DIF_TYPE2_PROTECTION | - SHOST_DIX_TYPE2_PROTECTION : 0) | - ((prot_caps & IB_PROT_T10DIF_TYPE_3) ? SHOST_DIF_TYPE3_PROTECTION | - SHOST_DIX_TYPE3_PROTECTION : 0); + return ((prot_caps & IB_PROT_T10DIF_TYPE_1) ? + SHOST_DIF_TYPE1_PROTECTION | SHOST_DIX_TYPE0_PROTECTION | + SHOST_DIX_TYPE1_PROTECTION : 0) | + ((prot_caps & IB_PROT_T10DIF_TYPE_2) ? + SHOST_DIF_TYPE2_PROTECTION | SHOST_DIX_TYPE2_PROTECTION : 0) | + ((prot_caps & IB_PROT_T10DIF_TYPE_3) ? + SHOST_DIF_TYPE3_PROTECTION | SHOST_DIX_TYPE3_PROTECTION : 0); } /** @@ -569,6 +603,7 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep, struct Scsi_Host *shost; struct iser_conn *iser_conn = NULL; struct ib_conn *ib_conn; + u16 max_cmds; shost = iscsi_host_alloc(&iscsi_iser_sht, 0, 0); if (!shost) @@ -586,26 +621,41 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep, */ if (ep) { iser_conn = ep->dd_data; + max_cmds = iser_conn->max_cmds; + + mutex_lock(&iser_conn->state_mutex); + if (iser_conn->state != ISER_CONN_UP) { + iser_err("iser conn %p already started teardown\n", + iser_conn); + mutex_unlock(&iser_conn->state_mutex); + goto free_host; + } + ib_conn = &iser_conn->ib_conn; if (ib_conn->pi_support) { u32 sig_caps = ib_conn->device->dev_attr.sig_prot_cap; scsi_host_set_prot(shost, iser_dif_prot_caps(sig_caps)); - if (iser_pi_guard) - scsi_host_set_guard(shost, SHOST_DIX_GUARD_IP); - else - scsi_host_set_guard(shost, SHOST_DIX_GUARD_CRC); + scsi_host_set_guard(shost, SHOST_DIX_GUARD_IP | + SHOST_DIX_GUARD_CRC); } - } - if (iscsi_host_add(shost, ep ? - ib_conn->device->ib_device->dma_device : NULL)) - goto free_host; + if (iscsi_host_add(shost, + ib_conn->device->ib_device->dma_device)) { + mutex_unlock(&iser_conn->state_mutex); + goto free_host; + } + mutex_unlock(&iser_conn->state_mutex); + } else { + max_cmds = ISER_DEF_XMIT_CMDS_MAX; + if (iscsi_host_add(shost, NULL)) + goto free_host; + } - if (cmds_max > ISER_DEF_XMIT_CMDS_MAX) { + if (cmds_max > max_cmds) { iser_info("cmds_max changed from %u to %u\n", - cmds_max, ISER_DEF_XMIT_CMDS_MAX); - cmds_max = ISER_DEF_XMIT_CMDS_MAX; + cmds_max, max_cmds); + cmds_max = max_cmds; } cls_session = iscsi_session_setup(&iscsi_iser_transport, shost, diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h index cd4174ca9a76..5ce26817e7e1 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h @@ -69,34 +69,31 @@ #define DRV_NAME "iser" #define PFX DRV_NAME ": " -#define DRV_VER "1.4.8" +#define DRV_VER "1.5" #define iser_dbg(fmt, arg...) \ do { \ - if (iser_debug_level > 2) \ + if (unlikely(iser_debug_level > 2)) \ printk(KERN_DEBUG PFX "%s: " fmt,\ __func__ , ## arg); \ } while (0) #define iser_warn(fmt, arg...) \ do { \ - if (iser_debug_level > 0) \ + if (unlikely(iser_debug_level > 0)) \ pr_warn(PFX "%s: " fmt, \ __func__ , ## arg); \ } while (0) #define iser_info(fmt, arg...) \ do { \ - if (iser_debug_level > 1) \ + if (unlikely(iser_debug_level > 1)) \ pr_info(PFX "%s: " fmt, \ __func__ , ## arg); \ } while (0) -#define iser_err(fmt, arg...) \ - do { \ - printk(KERN_ERR PFX "%s: " fmt, \ - __func__ , ## arg); \ - } while (0) +#define iser_err(fmt, arg...) \ + pr_err(PFX "%s: " fmt, __func__ , ## arg) #define SHIFT_4K 12 #define SIZE_4K (1ULL << SHIFT_4K) @@ -144,6 +141,11 @@ ISER_MAX_TX_MISC_PDUS + \ ISER_MAX_RX_MISC_PDUS) +#define ISER_GET_MAX_XMIT_CMDS(send_wr) ((send_wr \ + - ISER_MAX_TX_MISC_PDUS \ + - ISER_MAX_RX_MISC_PDUS) / \ + (1 + ISER_INFLIGHT_DATAOUTS)) + #define ISER_WC_BATCH_COUNT 16 #define ISER_SIGNAL_CMD_COUNT 32 @@ -247,7 +249,6 @@ struct iscsi_endpoint; * @va: MR start address (buffer va) * @len: MR length * @mem_h: pointer to registration context (FMR/Fastreg) - * @is_mr: indicates weather we registered the buffer */ struct iser_mem_reg { u32 lkey; @@ -255,7 +256,6 @@ struct iser_mem_reg { u64 va; u64 len; void *mem_h; - int is_mr; }; /** @@ -323,8 +323,6 @@ struct iser_rx_desc { char pad[ISER_RX_PAD_SIZE]; } __attribute__((packed)); -#define ISER_MAX_CQ 4 - struct iser_conn; struct ib_conn; struct iscsi_iser_task; @@ -375,7 +373,7 @@ struct iser_device { struct list_head ig_list; int refcount; int comps_used; - struct iser_comp comps[ISER_MAX_CQ]; + struct iser_comp *comps; int (*iser_alloc_rdma_reg_res)(struct ib_conn *ib_conn, unsigned cmds_max); void (*iser_free_rdma_reg_res)(struct ib_conn *ib_conn); @@ -432,6 +430,7 @@ struct fast_reg_descriptor { * @cma_id: rdma_cm connection maneger handle * @qp: Connection Queue-pair * @post_recv_buf_count: post receive counter + * @sig_count: send work request signal count * @rx_wr: receive work request for batch posts * @device: reference to iser device * @comp: iser completion context @@ -452,6 +451,7 @@ struct ib_conn { struct rdma_cm_id *cma_id; struct ib_qp *qp; int post_recv_buf_count; + u8 sig_count; struct ib_recv_wr rx_wr[ISER_MIN_POSTED_RX]; struct iser_device *device; struct iser_comp *comp; @@ -482,6 +482,7 @@ struct ib_conn { * to max number of post recvs * @qp_max_recv_dtos_mask: (qp_max_recv_dtos - 1) * @min_posted_rx: (qp_max_recv_dtos >> 2) + * @max_cmds: maximum cmds allowed for this connection * @name: connection peer portal * @release_work: deffered work for release job * @state_mutex: protects iser onnection state @@ -507,6 +508,7 @@ struct iser_conn { unsigned qp_max_recv_dtos; unsigned qp_max_recv_dtos_mask; unsigned min_posted_rx; + u16 max_cmds; char name[ISER_OBJECT_NAME_SIZE]; struct work_struct release_work; struct mutex state_mutex; diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c index 5a489ea63732..3821633f1065 100644 --- a/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/drivers/infiniband/ulp/iser/iser_initiator.c @@ -369,7 +369,7 @@ static int iser_post_rx_bufs(struct iscsi_conn *conn, struct iscsi_hdr *req) return 0; } -static inline bool iser_signal_comp(int sig_count) +static inline bool iser_signal_comp(u8 sig_count) { return ((sig_count % ISER_SIGNAL_CMD_COUNT) == 0); } @@ -388,7 +388,7 @@ int iser_send_command(struct iscsi_conn *conn, struct iscsi_scsi_req *hdr = (struct iscsi_scsi_req *)task->hdr; struct scsi_cmnd *sc = task->sc; struct iser_tx_desc *tx_desc = &iser_task->desc; - static unsigned sig_count; + u8 sig_count = ++iser_conn->ib_conn.sig_count; edtl = ntohl(hdr->data_length); @@ -435,7 +435,7 @@ int iser_send_command(struct iscsi_conn *conn, iser_task->status = ISER_TASK_STATUS_STARTED; err = iser_post_send(&iser_conn->ib_conn, tx_desc, - iser_signal_comp(++sig_count)); + iser_signal_comp(sig_count)); if (!err) return 0; diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c index 6c5ce357fba6..abce9339333f 100644 --- a/drivers/infiniband/ulp/iser/iser_memory.c +++ b/drivers/infiniband/ulp/iser/iser_memory.c @@ -73,7 +73,6 @@ static int iser_start_rdma_unaligned_sg(struct iscsi_iser_task *iser_task, if (cmd_dir == ISER_DIR_OUT) { /* copy the unaligned sg the buffer which is used for RDMA */ - int i; char *p, *from; sgl = (struct scatterlist *)data->buf; @@ -409,7 +408,6 @@ int iser_reg_rdma_mem_fmr(struct iscsi_iser_task *iser_task, regd_buf->reg.rkey = device->mr->rkey; regd_buf->reg.len = ib_sg_dma_len(ibdev, &sg[0]); regd_buf->reg.va = ib_sg_dma_address(ibdev, &sg[0]); - regd_buf->reg.is_mr = 0; iser_dbg("PHYSICAL Mem.register: lkey: 0x%08X rkey: 0x%08X " "va: 0x%08lX sz: %ld]\n", @@ -440,13 +438,13 @@ int iser_reg_rdma_mem_fmr(struct iscsi_iser_task *iser_task, return 0; } -static inline void +static void iser_set_dif_domain(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs, struct ib_sig_domain *domain) { domain->sig_type = IB_SIG_TYPE_T10_DIF; - domain->sig.dif.pi_interval = sc->device->sector_size; - domain->sig.dif.ref_tag = scsi_get_lba(sc) & 0xffffffff; + domain->sig.dif.pi_interval = scsi_prot_interval(sc); + domain->sig.dif.ref_tag = scsi_prot_ref_tag(sc); /* * At the moment we hard code those, but in the future * we will take them from sc. @@ -454,8 +452,7 @@ iser_set_dif_domain(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs, domain->sig.dif.apptag_check_mask = 0xffff; domain->sig.dif.app_escape = true; domain->sig.dif.ref_escape = true; - if (scsi_get_prot_type(sc) == SCSI_PROT_DIF_TYPE1 || - scsi_get_prot_type(sc) == SCSI_PROT_DIF_TYPE2) + if (sc->prot_flags & SCSI_PROT_REF_INCREMENT) domain->sig.dif.ref_remap = true; }; @@ -473,26 +470,16 @@ iser_set_sig_attrs(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs) case SCSI_PROT_WRITE_STRIP: sig_attrs->wire.sig_type = IB_SIG_TYPE_NONE; iser_set_dif_domain(sc, sig_attrs, &sig_attrs->mem); - /* - * At the moment we use this modparam to tell what is - * the memory bg_type, in the future we will take it - * from sc. - */ - sig_attrs->mem.sig.dif.bg_type = iser_pi_guard ? IB_T10DIF_CSUM : - IB_T10DIF_CRC; + sig_attrs->mem.sig.dif.bg_type = sc->prot_flags & SCSI_PROT_IP_CHECKSUM ? + IB_T10DIF_CSUM : IB_T10DIF_CRC; break; case SCSI_PROT_READ_PASS: case SCSI_PROT_WRITE_PASS: iser_set_dif_domain(sc, sig_attrs, &sig_attrs->wire); sig_attrs->wire.sig.dif.bg_type = IB_T10DIF_CRC; iser_set_dif_domain(sc, sig_attrs, &sig_attrs->mem); - /* - * At the moment we use this modparam to tell what is - * the memory bg_type, in the future we will take it - * from sc. - */ - sig_attrs->mem.sig.dif.bg_type = iser_pi_guard ? IB_T10DIF_CSUM : - IB_T10DIF_CRC; + sig_attrs->mem.sig.dif.bg_type = sc->prot_flags & SCSI_PROT_IP_CHECKSUM ? + IB_T10DIF_CSUM : IB_T10DIF_CRC; break; default: iser_err("Unsupported PI operation %d\n", @@ -503,26 +490,28 @@ iser_set_sig_attrs(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs) return 0; } -static int +static inline void iser_set_prot_checks(struct scsi_cmnd *sc, u8 *mask) { - switch (scsi_get_prot_type(sc)) { - case SCSI_PROT_DIF_TYPE0: - break; - case SCSI_PROT_DIF_TYPE1: - case SCSI_PROT_DIF_TYPE2: - *mask = ISER_CHECK_GUARD | ISER_CHECK_REFTAG; - break; - case SCSI_PROT_DIF_TYPE3: - *mask = ISER_CHECK_GUARD; - break; - default: - iser_err("Unsupported protection type %d\n", - scsi_get_prot_type(sc)); - return -EINVAL; - } + *mask = 0; + if (sc->prot_flags & SCSI_PROT_REF_CHECK) + *mask |= ISER_CHECK_REFTAG; + if (sc->prot_flags & SCSI_PROT_GUARD_CHECK) + *mask |= ISER_CHECK_GUARD; +} - return 0; +static void +iser_inv_rkey(struct ib_send_wr *inv_wr, struct ib_mr *mr) +{ + u32 rkey; + + memset(inv_wr, 0, sizeof(*inv_wr)); + inv_wr->opcode = IB_WR_LOCAL_INV; + inv_wr->wr_id = ISER_FASTREG_LI_WRID; + inv_wr->ex.invalidate_rkey = mr->rkey; + + rkey = ib_inc_rkey(mr->rkey); + ib_update_fast_reg_key(mr, rkey); } static int @@ -536,26 +525,17 @@ iser_reg_sig_mr(struct iscsi_iser_task *iser_task, struct ib_send_wr *bad_wr, *wr = NULL; struct ib_sig_attrs sig_attrs; int ret; - u32 key; memset(&sig_attrs, 0, sizeof(sig_attrs)); ret = iser_set_sig_attrs(iser_task->sc, &sig_attrs); if (ret) goto err; - ret = iser_set_prot_checks(iser_task->sc, &sig_attrs.check_mask); - if (ret) - goto err; + iser_set_prot_checks(iser_task->sc, &sig_attrs.check_mask); if (!(desc->reg_indicators & ISER_SIG_KEY_VALID)) { - memset(&inv_wr, 0, sizeof(inv_wr)); - inv_wr.opcode = IB_WR_LOCAL_INV; - inv_wr.wr_id = ISER_FASTREG_LI_WRID; - inv_wr.ex.invalidate_rkey = pi_ctx->sig_mr->rkey; + iser_inv_rkey(&inv_wr, pi_ctx->sig_mr); wr = &inv_wr; - /* Bump the key */ - key = (u8)(pi_ctx->sig_mr->rkey & 0x000000FF); - ib_update_fast_reg_key(pi_ctx->sig_mr, ++key); } memset(&sig_wr, 0, sizeof(sig_wr)); @@ -585,12 +565,7 @@ iser_reg_sig_mr(struct iscsi_iser_task *iser_task, sig_sge->lkey = pi_ctx->sig_mr->lkey; sig_sge->addr = 0; - sig_sge->length = data_sge->length + prot_sge->length; - if (scsi_get_prot_op(iser_task->sc) == SCSI_PROT_WRITE_INSERT || - scsi_get_prot_op(iser_task->sc) == SCSI_PROT_READ_STRIP) { - sig_sge->length += (data_sge->length / - iser_task->sc->device->sector_size) * 8; - } + sig_sge->length = scsi_transfer_length(iser_task->sc); iser_dbg("sig_sge: addr: 0x%llx length: %u lkey: 0x%x\n", sig_sge->addr, sig_sge->length, @@ -613,7 +588,6 @@ static int iser_fast_reg_mr(struct iscsi_iser_task *iser_task, struct ib_fast_reg_page_list *frpl; struct ib_send_wr fastreg_wr, inv_wr; struct ib_send_wr *bad_wr, *wr = NULL; - u8 key; int ret, offset, size, plen; /* if there a single dma entry, dma mr suffices */ @@ -645,14 +619,8 @@ static int iser_fast_reg_mr(struct iscsi_iser_task *iser_task, } if (!(desc->reg_indicators & ind)) { - memset(&inv_wr, 0, sizeof(inv_wr)); - inv_wr.wr_id = ISER_FASTREG_LI_WRID; - inv_wr.opcode = IB_WR_LOCAL_INV; - inv_wr.ex.invalidate_rkey = mr->rkey; + iser_inv_rkey(&inv_wr, mr); wr = &inv_wr; - /* Bump the key */ - key = (u8)(mr->rkey & 0x000000FF); - ib_update_fast_reg_key(mr, ++key); } /* Prepare FASTREG WR */ @@ -770,15 +738,11 @@ int iser_reg_rdma_mem_fastreg(struct iscsi_iser_task *iser_task, regd_buf->reg.rkey = desc->pi_ctx->sig_mr->rkey; regd_buf->reg.va = sig_sge.addr; regd_buf->reg.len = sig_sge.length; - regd_buf->reg.is_mr = 1; } else { - if (desc) { + if (desc) regd_buf->reg.rkey = desc->data_mr->rkey; - regd_buf->reg.is_mr = 1; - } else { + else regd_buf->reg.rkey = device->mr->rkey; - regd_buf->reg.is_mr = 0; - } regd_buf->reg.lkey = data_sge.lkey; regd_buf->reg.va = data_sge.addr; diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index 67225bb82bb5..695a2704bd43 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c @@ -76,7 +76,7 @@ static void iser_event_handler(struct ib_event_handler *handler, static int iser_create_device_ib_res(struct iser_device *device) { struct ib_device_attr *dev_attr = &device->dev_attr; - int ret, i; + int ret, i, max_cqe; ret = ib_query_device(device->ib_device, dev_attr); if (ret) { @@ -104,11 +104,19 @@ static int iser_create_device_ib_res(struct iser_device *device) return -1; } - device->comps_used = min(ISER_MAX_CQ, + device->comps_used = min_t(int, num_online_cpus(), device->ib_device->num_comp_vectors); - iser_info("using %d CQs, device %s supports %d vectors\n", + + device->comps = kcalloc(device->comps_used, sizeof(*device->comps), + GFP_KERNEL); + if (!device->comps) + goto comps_err; + + max_cqe = min(ISER_MAX_CQ_LEN, dev_attr->max_cqe); + + iser_info("using %d CQs, device %s supports %d vectors max_cqe %d\n", device->comps_used, device->ib_device->name, - device->ib_device->num_comp_vectors); + device->ib_device->num_comp_vectors, max_cqe); device->pd = ib_alloc_pd(device->ib_device); if (IS_ERR(device->pd)) @@ -122,7 +130,7 @@ static int iser_create_device_ib_res(struct iser_device *device) iser_cq_callback, iser_cq_event_callback, (void *)comp, - ISER_MAX_CQ_LEN, i); + max_cqe, i); if (IS_ERR(comp->cq)) { comp->cq = NULL; goto cq_err; @@ -162,6 +170,8 @@ cq_err: } ib_dealloc_pd(device->pd); pd_err: + kfree(device->comps); +comps_err: iser_err("failed to allocate an IB resource\n"); return -1; } @@ -187,6 +197,9 @@ static void iser_free_device_ib_res(struct iser_device *device) (void)ib_dereg_mr(device->mr); (void)ib_dealloc_pd(device->pd); + kfree(device->comps); + device->comps = NULL; + device->mr = NULL; device->pd = NULL; } @@ -425,7 +438,10 @@ void iser_free_fastreg_pool(struct ib_conn *ib_conn) */ static int iser_create_ib_conn_res(struct ib_conn *ib_conn) { + struct iser_conn *iser_conn = container_of(ib_conn, struct iser_conn, + ib_conn); struct iser_device *device; + struct ib_device_attr *dev_attr; struct ib_qp_init_attr init_attr; int ret = -ENOMEM; int index, min_index = 0; @@ -433,6 +449,7 @@ static int iser_create_ib_conn_res(struct ib_conn *ib_conn) BUG_ON(ib_conn->device == NULL); device = ib_conn->device; + dev_attr = &device->dev_attr; memset(&init_attr, 0, sizeof init_attr); @@ -460,8 +477,20 @@ static int iser_create_ib_conn_res(struct ib_conn *ib_conn) if (ib_conn->pi_support) { init_attr.cap.max_send_wr = ISER_QP_SIG_MAX_REQ_DTOS + 1; init_attr.create_flags |= IB_QP_CREATE_SIGNATURE_EN; + iser_conn->max_cmds = + ISER_GET_MAX_XMIT_CMDS(ISER_QP_SIG_MAX_REQ_DTOS); } else { - init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS + 1; + if (dev_attr->max_qp_wr > ISER_QP_MAX_REQ_DTOS) { + init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS + 1; + iser_conn->max_cmds = + ISER_GET_MAX_XMIT_CMDS(ISER_QP_MAX_REQ_DTOS); + } else { + init_attr.cap.max_send_wr = dev_attr->max_qp_wr; + iser_conn->max_cmds = + ISER_GET_MAX_XMIT_CMDS(dev_attr->max_qp_wr); + iser_dbg("device %s supports max_send_wr %d\n", + device->ib_device->name, dev_attr->max_qp_wr); + } } ret = rdma_create_qp(ib_conn->cma_id, device->pd, &init_attr); @@ -475,7 +504,11 @@ static int iser_create_ib_conn_res(struct ib_conn *ib_conn) return ret; out_err: + mutex_lock(&ig.connlist_mutex); + ib_conn->comp->active_qps--; + mutex_unlock(&ig.connlist_mutex); iser_err("unable to alloc mem or create resource, err %d\n", ret); + return ret; } @@ -610,9 +643,11 @@ void iser_conn_release(struct iser_conn *iser_conn) mutex_unlock(&ig.connlist_mutex); mutex_lock(&iser_conn->state_mutex); - if (iser_conn->state != ISER_CONN_DOWN) + if (iser_conn->state != ISER_CONN_DOWN) { iser_warn("iser conn %p state %d, expected state down.\n", iser_conn, iser_conn->state); + iser_conn->state = ISER_CONN_DOWN; + } /* * In case we never got to bind stage, we still need to * release IB resources (which is safe to call more than once). @@ -662,8 +697,10 @@ int iser_conn_terminate(struct iser_conn *iser_conn) /* post an indication that all flush errors were consumed */ err = ib_post_send(ib_conn->qp, &ib_conn->beacon, &bad_wr); - if (err) + if (err) { iser_err("conn %p failed to post beacon", ib_conn); + return 1; + } wait_for_completion(&ib_conn->flush_comp); } @@ -846,20 +883,21 @@ static int iser_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *eve break; case RDMA_CM_EVENT_DISCONNECTED: case RDMA_CM_EVENT_ADDR_CHANGE: - iser_disconnected_handler(cma_id); + case RDMA_CM_EVENT_TIMEWAIT_EXIT: + iser_cleanup_handler(cma_id, false); break; case RDMA_CM_EVENT_DEVICE_REMOVAL: /* * we *must* destroy the device as we cannot rely * on iscsid to be around to initiate error handling. - * also implicitly destroy the cma_id. + * also if we are not in state DOWN implicitly destroy + * the cma_id. */ iser_cleanup_handler(cma_id, true); - iser_conn->ib_conn.cma_id = NULL; - ret = 1; - break; - case RDMA_CM_EVENT_TIMEWAIT_EXIT: - iser_cleanup_handler(cma_id, false); + if (iser_conn->state != ISER_CONN_DOWN) { + iser_conn->ib_conn.cma_id = NULL; + ret = 1; + } break; default: iser_err("Unexpected RDMA CM event (%d)\n", event->event); @@ -981,7 +1019,6 @@ int iser_reg_page_vec(struct ib_conn *ib_conn, mem_reg->rkey = mem->fmr->rkey; mem_reg->len = page_vec->length * SIZE_4K; mem_reg->va = io_addr; - mem_reg->is_mr = 1; mem_reg->mem_h = (void *)mem; mem_reg->va += page_vec->offset; @@ -1008,7 +1045,7 @@ void iser_unreg_mem_fmr(struct iscsi_iser_task *iser_task, struct iser_mem_reg *reg = &iser_task->rdma_regd[cmd_dir].reg; int ret; - if (!reg->is_mr) + if (!reg->mem_h) return; iser_dbg("PHYSICAL Mem.Unregister mem_h %p\n",reg->mem_h); @@ -1028,11 +1065,10 @@ void iser_unreg_mem_fastreg(struct iscsi_iser_task *iser_task, struct ib_conn *ib_conn = &iser_conn->ib_conn; struct fast_reg_descriptor *desc = reg->mem_h; - if (!reg->is_mr) + if (!desc) return; reg->mem_h = NULL; - reg->is_mr = 0; spin_lock_bh(&ib_conn->lock); list_add_tail(&desc->list, &ib_conn->fastreg.pool); spin_unlock_bh(&ib_conn->lock); @@ -1049,7 +1085,7 @@ int iser_post_recvl(struct iser_conn *iser_conn) sge.length = ISER_RX_LOGIN_SIZE; sge.lkey = ib_conn->device->mr->lkey; - rx_wr.wr_id = (unsigned long)iser_conn->login_resp_buf; + rx_wr.wr_id = (uintptr_t)iser_conn->login_resp_buf; rx_wr.sg_list = &sge; rx_wr.num_sge = 1; rx_wr.next = NULL; @@ -1073,7 +1109,7 @@ int iser_post_recvm(struct iser_conn *iser_conn, int count) for (rx_wr = ib_conn->rx_wr, i = 0; i < count; i++, rx_wr++) { rx_desc = &iser_conn->rx_descs[my_rx_head]; - rx_wr->wr_id = (unsigned long)rx_desc; + rx_wr->wr_id = (uintptr_t)rx_desc; rx_wr->sg_list = &rx_desc->rx_sg; rx_wr->num_sge = 1; rx_wr->next = rx_wr + 1; @@ -1110,7 +1146,7 @@ int iser_post_send(struct ib_conn *ib_conn, struct iser_tx_desc *tx_desc, DMA_TO_DEVICE); send_wr.next = NULL; - send_wr.wr_id = (unsigned long)tx_desc; + send_wr.wr_id = (uintptr_t)tx_desc; send_wr.sg_list = tx_desc->tx_sg; send_wr.num_sge = tx_desc->num_sge; send_wr.opcode = IB_WR_SEND; @@ -1160,6 +1196,7 @@ static void iser_handle_comp_error(struct ib_conn *ib_conn, struct ib_wc *wc) { + void *wr_id = (void *)(uintptr_t)wc->wr_id; struct iser_conn *iser_conn = container_of(ib_conn, struct iser_conn, ib_conn); @@ -1168,8 +1205,8 @@ iser_handle_comp_error(struct ib_conn *ib_conn, iscsi_conn_failure(iser_conn->iscsi_conn, ISCSI_ERR_CONN_FAILED); - if (is_iser_tx_desc(iser_conn, (void *)wc->wr_id)) { - struct iser_tx_desc *desc = (struct iser_tx_desc *)wc->wr_id; + if (is_iser_tx_desc(iser_conn, wr_id)) { + struct iser_tx_desc *desc = wr_id; if (desc->type == ISCSI_TX_DATAOUT) kmem_cache_free(ig.desc_cache, desc); @@ -1193,14 +1230,14 @@ static void iser_handle_wc(struct ib_wc *wc) struct iser_rx_desc *rx_desc; ib_conn = wc->qp->qp_context; - if (wc->status == IB_WC_SUCCESS) { + if (likely(wc->status == IB_WC_SUCCESS)) { if (wc->opcode == IB_WC_RECV) { - rx_desc = (struct iser_rx_desc *)wc->wr_id; + rx_desc = (struct iser_rx_desc *)(uintptr_t)wc->wr_id; iser_rcv_completion(rx_desc, wc->byte_len, ib_conn); } else if (wc->opcode == IB_WC_SEND) { - tx_desc = (struct iser_tx_desc *)wc->wr_id; + tx_desc = (struct iser_tx_desc *)(uintptr_t)wc->wr_id; iser_snd_completion(tx_desc, ib_conn); } else { iser_err("Unknown wc opcode %d\n", wc->opcode); diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 10641b7816f4..dafb3c531f96 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -22,7 +22,6 @@ #include <linux/socket.h> #include <linux/in.h> #include <linux/in6.h> -#include <linux/llist.h> #include <rdma/ib_verbs.h> #include <rdma/rdma_cm.h> #include <target/target_core_base.h> @@ -36,11 +35,17 @@ #define ISERT_MAX_CONN 8 #define ISER_MAX_RX_CQ_LEN (ISERT_QP_MAX_RECV_DTOS * ISERT_MAX_CONN) #define ISER_MAX_TX_CQ_LEN (ISERT_QP_MAX_REQ_DTOS * ISERT_MAX_CONN) +#define ISER_MAX_CQ_LEN (ISER_MAX_RX_CQ_LEN + ISER_MAX_TX_CQ_LEN + \ + ISERT_MAX_CONN) + +int isert_debug_level = 0; +module_param_named(debug_level, isert_debug_level, int, 0644); +MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0 (default:0)"); static DEFINE_MUTEX(device_list_mutex); static LIST_HEAD(device_list); -static struct workqueue_struct *isert_rx_wq; static struct workqueue_struct *isert_comp_wq; +static struct workqueue_struct *isert_release_wq; static void isert_unmap_cmd(struct isert_cmd *isert_cmd, struct isert_conn *isert_conn); @@ -54,19 +59,32 @@ isert_reg_rdma(struct iscsi_conn *conn, struct iscsi_cmd *cmd, struct isert_rdma_wr *wr); static int isert_put_response(struct iscsi_conn *conn, struct iscsi_cmd *cmd); +static int +isert_rdma_post_recvl(struct isert_conn *isert_conn); +static int +isert_rdma_accept(struct isert_conn *isert_conn); +struct rdma_cm_id *isert_setup_id(struct isert_np *isert_np); + +static inline bool +isert_prot_cmd(struct isert_conn *conn, struct se_cmd *cmd) +{ + return (conn->pi_support && + cmd->prot_op != TARGET_PROT_NORMAL); +} + static void isert_qp_event_callback(struct ib_event *e, void *context) { struct isert_conn *isert_conn = (struct isert_conn *)context; - pr_err("isert_qp_event_callback event: %d\n", e->event); + isert_err("conn %p event: %d\n", isert_conn, e->event); switch (e->event) { case IB_EVENT_COMM_EST: rdma_notify(isert_conn->conn_cm_id, IB_EVENT_COMM_EST); break; case IB_EVENT_QP_LAST_WQE_REACHED: - pr_warn("Reached TX IB_EVENT_QP_LAST_WQE_REACHED:\n"); + isert_warn("Reached TX IB_EVENT_QP_LAST_WQE_REACHED\n"); break; default: break; @@ -80,39 +98,41 @@ isert_query_device(struct ib_device *ib_dev, struct ib_device_attr *devattr) ret = ib_query_device(ib_dev, devattr); if (ret) { - pr_err("ib_query_device() failed: %d\n", ret); + isert_err("ib_query_device() failed: %d\n", ret); return ret; } - pr_debug("devattr->max_sge: %d\n", devattr->max_sge); - pr_debug("devattr->max_sge_rd: %d\n", devattr->max_sge_rd); + isert_dbg("devattr->max_sge: %d\n", devattr->max_sge); + isert_dbg("devattr->max_sge_rd: %d\n", devattr->max_sge_rd); return 0; } static int -isert_conn_setup_qp(struct isert_conn *isert_conn, struct rdma_cm_id *cma_id, - u8 protection) +isert_conn_setup_qp(struct isert_conn *isert_conn, struct rdma_cm_id *cma_id) { struct isert_device *device = isert_conn->conn_device; struct ib_qp_init_attr attr; - int ret, index, min_index = 0; + struct isert_comp *comp; + int ret, i, min = 0; mutex_lock(&device_list_mutex); - for (index = 0; index < device->cqs_used; index++) - if (device->cq_active_qps[index] < - device->cq_active_qps[min_index]) - min_index = index; - device->cq_active_qps[min_index]++; - pr_debug("isert_conn_setup_qp: Using min_index: %d\n", min_index); + for (i = 0; i < device->comps_used; i++) + if (device->comps[i].active_qps < + device->comps[min].active_qps) + min = i; + comp = &device->comps[min]; + comp->active_qps++; + isert_info("conn %p, using comp %p min_index: %d\n", + isert_conn, comp, min); mutex_unlock(&device_list_mutex); memset(&attr, 0, sizeof(struct ib_qp_init_attr)); attr.event_handler = isert_qp_event_callback; attr.qp_context = isert_conn; - attr.send_cq = device->dev_tx_cq[min_index]; - attr.recv_cq = device->dev_rx_cq[min_index]; + attr.send_cq = comp->cq; + attr.recv_cq = comp->cq; attr.cap.max_send_wr = ISERT_QP_MAX_REQ_DTOS; - attr.cap.max_recv_wr = ISERT_QP_MAX_RECV_DTOS; + attr.cap.max_recv_wr = ISERT_QP_MAX_RECV_DTOS + 1; /* * FIXME: Use devattr.max_sge - 2 for max_send_sge as * work-around for RDMA_READs with ConnectX-2. @@ -126,29 +146,29 @@ isert_conn_setup_qp(struct isert_conn *isert_conn, struct rdma_cm_id *cma_id, attr.cap.max_recv_sge = 1; attr.sq_sig_type = IB_SIGNAL_REQ_WR; attr.qp_type = IB_QPT_RC; - if (protection) + if (device->pi_capable) attr.create_flags |= IB_QP_CREATE_SIGNATURE_EN; - pr_debug("isert_conn_setup_qp cma_id->device: %p\n", - cma_id->device); - pr_debug("isert_conn_setup_qp conn_pd->device: %p\n", - isert_conn->conn_pd->device); - ret = rdma_create_qp(cma_id, isert_conn->conn_pd, &attr); if (ret) { - pr_err("rdma_create_qp failed for cma_id %d\n", ret); - return ret; + isert_err("rdma_create_qp failed for cma_id %d\n", ret); + goto err; } isert_conn->conn_qp = cma_id->qp; - pr_debug("rdma_create_qp() returned success >>>>>>>>>>>>>>>>>>>>>>>>>.\n"); return 0; +err: + mutex_lock(&device_list_mutex); + comp->active_qps--; + mutex_unlock(&device_list_mutex); + + return ret; } static void isert_cq_event_callback(struct ib_event *e, void *context) { - pr_debug("isert_cq_event_callback event: %d\n", e->event); + isert_dbg("event: %d\n", e->event); } static int @@ -182,6 +202,7 @@ isert_alloc_rx_descriptors(struct isert_conn *isert_conn) } isert_conn->conn_rx_desc_head = 0; + return 0; dma_map_fail: @@ -193,6 +214,8 @@ dma_map_fail: kfree(isert_conn->conn_rx_descs); isert_conn->conn_rx_descs = NULL; fail: + isert_err("conn %p failed to allocate rx descriptors\n", isert_conn); + return -ENOMEM; } @@ -216,27 +239,23 @@ isert_free_rx_descriptors(struct isert_conn *isert_conn) isert_conn->conn_rx_descs = NULL; } -static void isert_cq_tx_work(struct work_struct *); -static void isert_cq_tx_callback(struct ib_cq *, void *); -static void isert_cq_rx_work(struct work_struct *); -static void isert_cq_rx_callback(struct ib_cq *, void *); +static void isert_cq_work(struct work_struct *); +static void isert_cq_callback(struct ib_cq *, void *); static int isert_create_device_ib_res(struct isert_device *device) { struct ib_device *ib_dev = device->ib_device; - struct isert_cq_desc *cq_desc; struct ib_device_attr *dev_attr; - int ret = 0, i, j; - int max_rx_cqe, max_tx_cqe; + int ret = 0, i; + int max_cqe; dev_attr = &device->dev_attr; ret = isert_query_device(ib_dev, dev_attr); if (ret) return ret; - max_rx_cqe = min(ISER_MAX_RX_CQ_LEN, dev_attr->max_cqe); - max_tx_cqe = min(ISER_MAX_TX_CQ_LEN, dev_attr->max_cqe); + max_cqe = min(ISER_MAX_CQ_LEN, dev_attr->max_cqe); /* asign function handlers */ if (dev_attr->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS && @@ -254,55 +273,38 @@ isert_create_device_ib_res(struct isert_device *device) device->pi_capable = dev_attr->device_cap_flags & IB_DEVICE_SIGNATURE_HANDOVER ? true : false; - device->cqs_used = min_t(int, num_online_cpus(), - device->ib_device->num_comp_vectors); - device->cqs_used = min(ISERT_MAX_CQ, device->cqs_used); - pr_debug("Using %d CQs, device %s supports %d vectors support " - "Fast registration %d pi_capable %d\n", - device->cqs_used, device->ib_device->name, - device->ib_device->num_comp_vectors, device->use_fastreg, - device->pi_capable); - device->cq_desc = kzalloc(sizeof(struct isert_cq_desc) * - device->cqs_used, GFP_KERNEL); - if (!device->cq_desc) { - pr_err("Unable to allocate device->cq_desc\n"); + device->comps_used = min(ISERT_MAX_CQ, min_t(int, num_online_cpus(), + device->ib_device->num_comp_vectors)); + isert_info("Using %d CQs, %s supports %d vectors support " + "Fast registration %d pi_capable %d\n", + device->comps_used, device->ib_device->name, + device->ib_device->num_comp_vectors, device->use_fastreg, + device->pi_capable); + + device->comps = kcalloc(device->comps_used, sizeof(struct isert_comp), + GFP_KERNEL); + if (!device->comps) { + isert_err("Unable to allocate completion contexts\n"); return -ENOMEM; } - cq_desc = device->cq_desc; - - for (i = 0; i < device->cqs_used; i++) { - cq_desc[i].device = device; - cq_desc[i].cq_index = i; - - INIT_WORK(&cq_desc[i].cq_rx_work, isert_cq_rx_work); - device->dev_rx_cq[i] = ib_create_cq(device->ib_device, - isert_cq_rx_callback, - isert_cq_event_callback, - (void *)&cq_desc[i], - max_rx_cqe, i); - if (IS_ERR(device->dev_rx_cq[i])) { - ret = PTR_ERR(device->dev_rx_cq[i]); - device->dev_rx_cq[i] = NULL; - goto out_cq; - } - INIT_WORK(&cq_desc[i].cq_tx_work, isert_cq_tx_work); - device->dev_tx_cq[i] = ib_create_cq(device->ib_device, - isert_cq_tx_callback, - isert_cq_event_callback, - (void *)&cq_desc[i], - max_tx_cqe, i); - if (IS_ERR(device->dev_tx_cq[i])) { - ret = PTR_ERR(device->dev_tx_cq[i]); - device->dev_tx_cq[i] = NULL; - goto out_cq; - } + for (i = 0; i < device->comps_used; i++) { + struct isert_comp *comp = &device->comps[i]; - ret = ib_req_notify_cq(device->dev_rx_cq[i], IB_CQ_NEXT_COMP); - if (ret) + comp->device = device; + INIT_WORK(&comp->work, isert_cq_work); + comp->cq = ib_create_cq(device->ib_device, + isert_cq_callback, + isert_cq_event_callback, + (void *)comp, + max_cqe, i); + if (IS_ERR(comp->cq)) { + ret = PTR_ERR(comp->cq); + comp->cq = NULL; goto out_cq; + } - ret = ib_req_notify_cq(device->dev_tx_cq[i], IB_CQ_NEXT_COMP); + ret = ib_req_notify_cq(comp->cq, IB_CQ_NEXT_COMP); if (ret) goto out_cq; } @@ -310,19 +312,15 @@ isert_create_device_ib_res(struct isert_device *device) return 0; out_cq: - for (j = 0; j < i; j++) { - cq_desc = &device->cq_desc[j]; + for (i = 0; i < device->comps_used; i++) { + struct isert_comp *comp = &device->comps[i]; - if (device->dev_rx_cq[j]) { - cancel_work_sync(&cq_desc->cq_rx_work); - ib_destroy_cq(device->dev_rx_cq[j]); - } - if (device->dev_tx_cq[j]) { - cancel_work_sync(&cq_desc->cq_tx_work); - ib_destroy_cq(device->dev_tx_cq[j]); + if (comp->cq) { + cancel_work_sync(&comp->work); + ib_destroy_cq(comp->cq); } } - kfree(device->cq_desc); + kfree(device->comps); return ret; } @@ -330,21 +328,18 @@ out_cq: static void isert_free_device_ib_res(struct isert_device *device) { - struct isert_cq_desc *cq_desc; int i; - for (i = 0; i < device->cqs_used; i++) { - cq_desc = &device->cq_desc[i]; + isert_info("device %p\n", device); - cancel_work_sync(&cq_desc->cq_rx_work); - cancel_work_sync(&cq_desc->cq_tx_work); - ib_destroy_cq(device->dev_rx_cq[i]); - ib_destroy_cq(device->dev_tx_cq[i]); - device->dev_rx_cq[i] = NULL; - device->dev_tx_cq[i] = NULL; - } + for (i = 0; i < device->comps_used; i++) { + struct isert_comp *comp = &device->comps[i]; - kfree(device->cq_desc); + cancel_work_sync(&comp->work); + ib_destroy_cq(comp->cq); + comp->cq = NULL; + } + kfree(device->comps); } static void @@ -352,6 +347,7 @@ isert_device_try_release(struct isert_device *device) { mutex_lock(&device_list_mutex); device->refcount--; + isert_info("device %p refcount %d\n", device, device->refcount); if (!device->refcount) { isert_free_device_ib_res(device); list_del(&device->dev_node); @@ -370,6 +366,8 @@ isert_device_find_by_ib_dev(struct rdma_cm_id *cma_id) list_for_each_entry(device, &device_list, dev_node) { if (device->ib_device->node_guid == cma_id->device->node_guid) { device->refcount++; + isert_info("Found iser device %p refcount %d\n", + device, device->refcount); mutex_unlock(&device_list_mutex); return device; } @@ -393,6 +391,8 @@ isert_device_find_by_ib_dev(struct rdma_cm_id *cma_id) device->refcount++; list_add_tail(&device->dev_node, &device_list); + isert_info("Created a new iser device %p refcount %d\n", + device, device->refcount); mutex_unlock(&device_list_mutex); return device; @@ -407,7 +407,7 @@ isert_conn_free_fastreg_pool(struct isert_conn *isert_conn) if (list_empty(&isert_conn->conn_fr_pool)) return; - pr_debug("Freeing conn %p fastreg pool", isert_conn); + isert_info("Freeing conn %p fastreg pool", isert_conn); list_for_each_entry_safe(fr_desc, tmp, &isert_conn->conn_fr_pool, list) { @@ -425,87 +425,97 @@ isert_conn_free_fastreg_pool(struct isert_conn *isert_conn) } if (i < isert_conn->conn_fr_pool_size) - pr_warn("Pool still has %d regions registered\n", + isert_warn("Pool still has %d regions registered\n", isert_conn->conn_fr_pool_size - i); } static int +isert_create_pi_ctx(struct fast_reg_descriptor *desc, + struct ib_device *device, + struct ib_pd *pd) +{ + struct ib_mr_init_attr mr_init_attr; + struct pi_context *pi_ctx; + int ret; + + pi_ctx = kzalloc(sizeof(*desc->pi_ctx), GFP_KERNEL); + if (!pi_ctx) { + isert_err("Failed to allocate pi context\n"); + return -ENOMEM; + } + + pi_ctx->prot_frpl = ib_alloc_fast_reg_page_list(device, + ISCSI_ISER_SG_TABLESIZE); + if (IS_ERR(pi_ctx->prot_frpl)) { + isert_err("Failed to allocate prot frpl err=%ld\n", + PTR_ERR(pi_ctx->prot_frpl)); + ret = PTR_ERR(pi_ctx->prot_frpl); + goto err_pi_ctx; + } + + pi_ctx->prot_mr = ib_alloc_fast_reg_mr(pd, ISCSI_ISER_SG_TABLESIZE); + if (IS_ERR(pi_ctx->prot_mr)) { + isert_err("Failed to allocate prot frmr err=%ld\n", + PTR_ERR(pi_ctx->prot_mr)); + ret = PTR_ERR(pi_ctx->prot_mr); + goto err_prot_frpl; + } + desc->ind |= ISERT_PROT_KEY_VALID; + + memset(&mr_init_attr, 0, sizeof(mr_init_attr)); + mr_init_attr.max_reg_descriptors = 2; + mr_init_attr.flags |= IB_MR_SIGNATURE_EN; + pi_ctx->sig_mr = ib_create_mr(pd, &mr_init_attr); + if (IS_ERR(pi_ctx->sig_mr)) { + isert_err("Failed to allocate signature enabled mr err=%ld\n", + PTR_ERR(pi_ctx->sig_mr)); + ret = PTR_ERR(pi_ctx->sig_mr); + goto err_prot_mr; + } + + desc->pi_ctx = pi_ctx; + desc->ind |= ISERT_SIG_KEY_VALID; + desc->ind &= ~ISERT_PROTECTED; + + return 0; + +err_prot_mr: + ib_dereg_mr(desc->pi_ctx->prot_mr); +err_prot_frpl: + ib_free_fast_reg_page_list(desc->pi_ctx->prot_frpl); +err_pi_ctx: + kfree(desc->pi_ctx); + + return ret; +} + +static int isert_create_fr_desc(struct ib_device *ib_device, struct ib_pd *pd, - struct fast_reg_descriptor *fr_desc, u8 protection) + struct fast_reg_descriptor *fr_desc) { int ret; fr_desc->data_frpl = ib_alloc_fast_reg_page_list(ib_device, ISCSI_ISER_SG_TABLESIZE); if (IS_ERR(fr_desc->data_frpl)) { - pr_err("Failed to allocate data frpl err=%ld\n", - PTR_ERR(fr_desc->data_frpl)); + isert_err("Failed to allocate data frpl err=%ld\n", + PTR_ERR(fr_desc->data_frpl)); return PTR_ERR(fr_desc->data_frpl); } fr_desc->data_mr = ib_alloc_fast_reg_mr(pd, ISCSI_ISER_SG_TABLESIZE); if (IS_ERR(fr_desc->data_mr)) { - pr_err("Failed to allocate data frmr err=%ld\n", - PTR_ERR(fr_desc->data_mr)); + isert_err("Failed to allocate data frmr err=%ld\n", + PTR_ERR(fr_desc->data_mr)); ret = PTR_ERR(fr_desc->data_mr); goto err_data_frpl; } - pr_debug("Create fr_desc %p page_list %p\n", - fr_desc, fr_desc->data_frpl->page_list); fr_desc->ind |= ISERT_DATA_KEY_VALID; - if (protection) { - struct ib_mr_init_attr mr_init_attr = {0}; - struct pi_context *pi_ctx; - - fr_desc->pi_ctx = kzalloc(sizeof(*fr_desc->pi_ctx), GFP_KERNEL); - if (!fr_desc->pi_ctx) { - pr_err("Failed to allocate pi context\n"); - ret = -ENOMEM; - goto err_data_mr; - } - pi_ctx = fr_desc->pi_ctx; - - pi_ctx->prot_frpl = ib_alloc_fast_reg_page_list(ib_device, - ISCSI_ISER_SG_TABLESIZE); - if (IS_ERR(pi_ctx->prot_frpl)) { - pr_err("Failed to allocate prot frpl err=%ld\n", - PTR_ERR(pi_ctx->prot_frpl)); - ret = PTR_ERR(pi_ctx->prot_frpl); - goto err_pi_ctx; - } - - pi_ctx->prot_mr = ib_alloc_fast_reg_mr(pd, ISCSI_ISER_SG_TABLESIZE); - if (IS_ERR(pi_ctx->prot_mr)) { - pr_err("Failed to allocate prot frmr err=%ld\n", - PTR_ERR(pi_ctx->prot_mr)); - ret = PTR_ERR(pi_ctx->prot_mr); - goto err_prot_frpl; - } - fr_desc->ind |= ISERT_PROT_KEY_VALID; - - mr_init_attr.max_reg_descriptors = 2; - mr_init_attr.flags |= IB_MR_SIGNATURE_EN; - pi_ctx->sig_mr = ib_create_mr(pd, &mr_init_attr); - if (IS_ERR(pi_ctx->sig_mr)) { - pr_err("Failed to allocate signature enabled mr err=%ld\n", - PTR_ERR(pi_ctx->sig_mr)); - ret = PTR_ERR(pi_ctx->sig_mr); - goto err_prot_mr; - } - fr_desc->ind |= ISERT_SIG_KEY_VALID; - } - fr_desc->ind &= ~ISERT_PROTECTED; + isert_dbg("Created fr_desc %p\n", fr_desc); return 0; -err_prot_mr: - ib_dereg_mr(fr_desc->pi_ctx->prot_mr); -err_prot_frpl: - ib_free_fast_reg_page_list(fr_desc->pi_ctx->prot_frpl); -err_pi_ctx: - kfree(fr_desc->pi_ctx); -err_data_mr: - ib_dereg_mr(fr_desc->data_mr); + err_data_frpl: ib_free_fast_reg_page_list(fr_desc->data_frpl); @@ -513,7 +523,7 @@ err_data_frpl: } static int -isert_conn_create_fastreg_pool(struct isert_conn *isert_conn, u8 pi_support) +isert_conn_create_fastreg_pool(struct isert_conn *isert_conn) { struct fast_reg_descriptor *fr_desc; struct isert_device *device = isert_conn->conn_device; @@ -531,16 +541,15 @@ isert_conn_create_fastreg_pool(struct isert_conn *isert_conn, u8 pi_support) for (i = 0; i < tag_num; i++) { fr_desc = kzalloc(sizeof(*fr_desc), GFP_KERNEL); if (!fr_desc) { - pr_err("Failed to allocate fast_reg descriptor\n"); + isert_err("Failed to allocate fast_reg descriptor\n"); ret = -ENOMEM; goto err; } ret = isert_create_fr_desc(device->ib_device, - isert_conn->conn_pd, fr_desc, - pi_support); + isert_conn->conn_pd, fr_desc); if (ret) { - pr_err("Failed to create fastreg descriptor err=%d\n", + isert_err("Failed to create fastreg descriptor err=%d\n", ret); kfree(fr_desc); goto err; @@ -550,7 +559,7 @@ isert_conn_create_fastreg_pool(struct isert_conn *isert_conn, u8 pi_support) isert_conn->conn_fr_pool_size++; } - pr_debug("Creating conn %p fastreg pool size=%d", + isert_dbg("Creating conn %p fastreg pool size=%d", isert_conn, isert_conn->conn_fr_pool_size); return 0; @@ -563,47 +572,45 @@ err: static int isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) { - struct iscsi_np *np = cma_id->context; - struct isert_np *isert_np = np->np_context; + struct isert_np *isert_np = cma_id->context; + struct iscsi_np *np = isert_np->np; struct isert_conn *isert_conn; struct isert_device *device; struct ib_device *ib_dev = cma_id->device; int ret = 0; - u8 pi_support; spin_lock_bh(&np->np_thread_lock); if (!np->enabled) { spin_unlock_bh(&np->np_thread_lock); - pr_debug("iscsi_np is not enabled, reject connect request\n"); + isert_dbg("iscsi_np is not enabled, reject connect request\n"); return rdma_reject(cma_id, NULL, 0); } spin_unlock_bh(&np->np_thread_lock); - pr_debug("Entering isert_connect_request cma_id: %p, context: %p\n", + isert_dbg("cma_id: %p, portal: %p\n", cma_id, cma_id->context); isert_conn = kzalloc(sizeof(struct isert_conn), GFP_KERNEL); if (!isert_conn) { - pr_err("Unable to allocate isert_conn\n"); + isert_err("Unable to allocate isert_conn\n"); return -ENOMEM; } isert_conn->state = ISER_CONN_INIT; INIT_LIST_HEAD(&isert_conn->conn_accept_node); init_completion(&isert_conn->conn_login_comp); + init_completion(&isert_conn->login_req_comp); init_completion(&isert_conn->conn_wait); - init_completion(&isert_conn->conn_wait_comp_err); kref_init(&isert_conn->conn_kref); mutex_init(&isert_conn->conn_mutex); spin_lock_init(&isert_conn->conn_lock); INIT_LIST_HEAD(&isert_conn->conn_fr_pool); - cma_id->context = isert_conn; isert_conn->conn_cm_id = cma_id; isert_conn->login_buf = kzalloc(ISCSI_DEF_MAX_RECV_SEG_LEN + ISER_RX_LOGIN_SIZE, GFP_KERNEL); if (!isert_conn->login_buf) { - pr_err("Unable to allocate isert_conn->login_buf\n"); + isert_err("Unable to allocate isert_conn->login_buf\n"); ret = -ENOMEM; goto out; } @@ -611,7 +618,7 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) isert_conn->login_req_buf = isert_conn->login_buf; isert_conn->login_rsp_buf = isert_conn->login_buf + ISCSI_DEF_MAX_RECV_SEG_LEN; - pr_debug("Set login_buf: %p login_req_buf: %p login_rsp_buf: %p\n", + isert_dbg("Set login_buf: %p login_req_buf: %p login_rsp_buf: %p\n", isert_conn->login_buf, isert_conn->login_req_buf, isert_conn->login_rsp_buf); @@ -621,7 +628,7 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) ret = ib_dma_mapping_error(ib_dev, isert_conn->login_req_dma); if (ret) { - pr_err("ib_dma_mapping_error failed for login_req_dma: %d\n", + isert_err("ib_dma_mapping_error failed for login_req_dma: %d\n", ret); isert_conn->login_req_dma = 0; goto out_login_buf; @@ -633,7 +640,7 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) ret = ib_dma_mapping_error(ib_dev, isert_conn->login_rsp_dma); if (ret) { - pr_err("ib_dma_mapping_error failed for login_rsp_dma: %d\n", + isert_err("ib_dma_mapping_error failed for login_rsp_dma: %d\n", ret); isert_conn->login_rsp_dma = 0; goto out_req_dma_map; @@ -649,13 +656,13 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) isert_conn->initiator_depth = min_t(u8, event->param.conn.initiator_depth, device->dev_attr.max_qp_init_rd_atom); - pr_debug("Using initiator_depth: %u\n", isert_conn->initiator_depth); + isert_dbg("Using initiator_depth: %u\n", isert_conn->initiator_depth); isert_conn->conn_device = device; isert_conn->conn_pd = ib_alloc_pd(isert_conn->conn_device->ib_device); if (IS_ERR(isert_conn->conn_pd)) { ret = PTR_ERR(isert_conn->conn_pd); - pr_err("ib_alloc_pd failed for conn %p: ret=%d\n", + isert_err("ib_alloc_pd failed for conn %p: ret=%d\n", isert_conn, ret); goto out_pd; } @@ -664,20 +671,20 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) IB_ACCESS_LOCAL_WRITE); if (IS_ERR(isert_conn->conn_mr)) { ret = PTR_ERR(isert_conn->conn_mr); - pr_err("ib_get_dma_mr failed for conn %p: ret=%d\n", + isert_err("ib_get_dma_mr failed for conn %p: ret=%d\n", isert_conn, ret); goto out_mr; } - pi_support = np->tpg_np->tpg->tpg_attrib.t10_pi; - if (pi_support && !device->pi_capable) { - pr_err("Protection information requested but not supported, " - "rejecting connect request\n"); - ret = rdma_reject(cma_id, NULL, 0); - goto out_mr; - } + ret = isert_conn_setup_qp(isert_conn, cma_id); + if (ret) + goto out_conn_dev; - ret = isert_conn_setup_qp(isert_conn, cma_id, pi_support); + ret = isert_rdma_post_recvl(isert_conn); + if (ret) + goto out_conn_dev; + + ret = isert_rdma_accept(isert_conn); if (ret) goto out_conn_dev; @@ -685,7 +692,7 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) list_add_tail(&isert_conn->conn_accept_node, &isert_np->np_accept_list); mutex_unlock(&isert_np->np_accept_mutex); - pr_debug("isert_connect_request() up np_sem np: %p\n", np); + isert_info("np %p: Allow accept_np to continue\n", np); up(&isert_np->np_sem); return 0; @@ -705,6 +712,7 @@ out_login_buf: kfree(isert_conn->login_buf); out: kfree(isert_conn); + rdma_reject(cma_id, NULL, 0); return ret; } @@ -713,24 +721,25 @@ isert_connect_release(struct isert_conn *isert_conn) { struct ib_device *ib_dev = isert_conn->conn_cm_id->device; struct isert_device *device = isert_conn->conn_device; - int cq_index; - pr_debug("Entering isert_connect_release(): >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); + isert_dbg("conn %p\n", isert_conn); if (device && device->use_fastreg) isert_conn_free_fastreg_pool(isert_conn); + isert_free_rx_descriptors(isert_conn); + rdma_destroy_id(isert_conn->conn_cm_id); + if (isert_conn->conn_qp) { - cq_index = ((struct isert_cq_desc *) - isert_conn->conn_qp->recv_cq->cq_context)->cq_index; - pr_debug("isert_connect_release: cq_index: %d\n", cq_index); - isert_conn->conn_device->cq_active_qps[cq_index]--; + struct isert_comp *comp = isert_conn->conn_qp->recv_cq->cq_context; - rdma_destroy_qp(isert_conn->conn_cm_id); - } + isert_dbg("dec completion context %p active_qps\n", comp); + mutex_lock(&device_list_mutex); + comp->active_qps--; + mutex_unlock(&device_list_mutex); - isert_free_rx_descriptors(isert_conn); - rdma_destroy_id(isert_conn->conn_cm_id); + ib_destroy_qp(isert_conn->conn_qp); + } ib_dereg_mr(isert_conn->conn_mr); ib_dealloc_pd(isert_conn->conn_pd); @@ -747,16 +756,24 @@ isert_connect_release(struct isert_conn *isert_conn) if (device) isert_device_try_release(device); - - pr_debug("Leaving isert_connect_release >>>>>>>>>>>>\n"); } static void isert_connected_handler(struct rdma_cm_id *cma_id) { - struct isert_conn *isert_conn = cma_id->context; + struct isert_conn *isert_conn = cma_id->qp->qp_context; - kref_get(&isert_conn->conn_kref); + isert_info("conn %p\n", isert_conn); + + if (!kref_get_unless_zero(&isert_conn->conn_kref)) { + isert_warn("conn %p connect_release is running\n", isert_conn); + return; + } + + mutex_lock(&isert_conn->conn_mutex); + if (isert_conn->state != ISER_CONN_FULL_FEATURE) + isert_conn->state = ISER_CONN_UP; + mutex_unlock(&isert_conn->conn_mutex); } static void @@ -765,8 +782,8 @@ isert_release_conn_kref(struct kref *kref) struct isert_conn *isert_conn = container_of(kref, struct isert_conn, conn_kref); - pr_debug("Calling isert_connect_release for final kref %s/%d\n", - current->comm, current->pid); + isert_info("conn %p final kref %s/%d\n", isert_conn, current->comm, + current->pid); isert_connect_release(isert_conn); } @@ -777,75 +794,111 @@ isert_put_conn(struct isert_conn *isert_conn) kref_put(&isert_conn->conn_kref, isert_release_conn_kref); } +/** + * isert_conn_terminate() - Initiate connection termination + * @isert_conn: isert connection struct + * + * Notes: + * In case the connection state is FULL_FEATURE, move state + * to TEMINATING and start teardown sequence (rdma_disconnect). + * In case the connection state is UP, complete flush as well. + * + * This routine must be called with conn_mutex held. Thus it is + * safe to call multiple times. + */ static void -isert_disconnect_work(struct work_struct *work) +isert_conn_terminate(struct isert_conn *isert_conn) { - struct isert_conn *isert_conn = container_of(work, - struct isert_conn, conn_logout_work); + int err; - pr_debug("isert_disconnect_work(): >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); - mutex_lock(&isert_conn->conn_mutex); - if (isert_conn->state == ISER_CONN_UP) + switch (isert_conn->state) { + case ISER_CONN_TERMINATING: + break; + case ISER_CONN_UP: + case ISER_CONN_FULL_FEATURE: /* FALLTHRU */ + isert_info("Terminating conn %p state %d\n", + isert_conn, isert_conn->state); isert_conn->state = ISER_CONN_TERMINATING; - - if (isert_conn->post_recv_buf_count == 0 && - atomic_read(&isert_conn->post_send_buf_count) == 0) { - mutex_unlock(&isert_conn->conn_mutex); - goto wake_up; - } - if (!isert_conn->conn_cm_id) { - mutex_unlock(&isert_conn->conn_mutex); - isert_put_conn(isert_conn); - return; + err = rdma_disconnect(isert_conn->conn_cm_id); + if (err) + isert_warn("Failed rdma_disconnect isert_conn %p\n", + isert_conn); + break; + default: + isert_warn("conn %p teminating in state %d\n", + isert_conn, isert_conn->state); } +} - if (isert_conn->disconnect) { - /* Send DREQ/DREP towards our initiator */ - rdma_disconnect(isert_conn->conn_cm_id); - } +static int +isert_np_cma_handler(struct isert_np *isert_np, + enum rdma_cm_event_type event) +{ + isert_dbg("isert np %p, handling event %d\n", isert_np, event); - mutex_unlock(&isert_conn->conn_mutex); + switch (event) { + case RDMA_CM_EVENT_DEVICE_REMOVAL: + isert_np->np_cm_id = NULL; + break; + case RDMA_CM_EVENT_ADDR_CHANGE: + isert_np->np_cm_id = isert_setup_id(isert_np); + if (IS_ERR(isert_np->np_cm_id)) { + isert_err("isert np %p setup id failed: %ld\n", + isert_np, PTR_ERR(isert_np->np_cm_id)); + isert_np->np_cm_id = NULL; + } + break; + default: + isert_err("isert np %p Unexpected event %d\n", + isert_np, event); + } -wake_up: - complete(&isert_conn->conn_wait); + return -1; } static int -isert_disconnected_handler(struct rdma_cm_id *cma_id, bool disconnect) +isert_disconnected_handler(struct rdma_cm_id *cma_id, + enum rdma_cm_event_type event) { + struct isert_np *isert_np = cma_id->context; struct isert_conn *isert_conn; - if (!cma_id->qp) { - struct isert_np *isert_np = cma_id->context; + if (isert_np->np_cm_id == cma_id) + return isert_np_cma_handler(cma_id->context, event); - isert_np->np_cm_id = NULL; - return -1; - } + isert_conn = cma_id->qp->qp_context; - isert_conn = (struct isert_conn *)cma_id->context; + mutex_lock(&isert_conn->conn_mutex); + isert_conn_terminate(isert_conn); + mutex_unlock(&isert_conn->conn_mutex); - isert_conn->disconnect = disconnect; - INIT_WORK(&isert_conn->conn_logout_work, isert_disconnect_work); - schedule_work(&isert_conn->conn_logout_work); + isert_info("conn %p completing conn_wait\n", isert_conn); + complete(&isert_conn->conn_wait); return 0; } +static void +isert_connect_error(struct rdma_cm_id *cma_id) +{ + struct isert_conn *isert_conn = cma_id->qp->qp_context; + + isert_put_conn(isert_conn); +} + static int isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) { int ret = 0; - bool disconnect = false; - pr_debug("isert_cma_handler: event %d status %d conn %p id %p\n", - event->event, event->status, cma_id->context, cma_id); + isert_info("event %d status %d id %p np %p\n", event->event, + event->status, cma_id, cma_id->context); switch (event->event) { case RDMA_CM_EVENT_CONNECT_REQUEST: ret = isert_connect_request(cma_id, event); if (ret) - pr_err("isert_cma_handler failed RDMA_CM_EVENT: 0x%08x %d\n", - event->event, ret); + isert_err("failed handle connect request %d\n", ret); break; case RDMA_CM_EVENT_ESTABLISHED: isert_connected_handler(cma_id); @@ -853,13 +906,16 @@ isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) case RDMA_CM_EVENT_ADDR_CHANGE: /* FALLTHRU */ case RDMA_CM_EVENT_DISCONNECTED: /* FALLTHRU */ case RDMA_CM_EVENT_DEVICE_REMOVAL: /* FALLTHRU */ - disconnect = true; case RDMA_CM_EVENT_TIMEWAIT_EXIT: /* FALLTHRU */ - ret = isert_disconnected_handler(cma_id, disconnect); + ret = isert_disconnected_handler(cma_id, event->event); break; + case RDMA_CM_EVENT_REJECTED: /* FALLTHRU */ + case RDMA_CM_EVENT_UNREACHABLE: /* FALLTHRU */ case RDMA_CM_EVENT_CONNECT_ERROR: + isert_connect_error(cma_id); + break; default: - pr_err("Unhandled RDMA CMA event: %d\n", event->event); + isert_err("Unhandled RDMA CMA event: %d\n", event->event); break; } @@ -876,7 +932,7 @@ isert_post_recv(struct isert_conn *isert_conn, u32 count) for (rx_wr = isert_conn->conn_rx_wr, i = 0; i < count; i++, rx_wr++) { rx_desc = &isert_conn->conn_rx_descs[rx_head]; - rx_wr->wr_id = (unsigned long)rx_desc; + rx_wr->wr_id = (uintptr_t)rx_desc; rx_wr->sg_list = &rx_desc->rx_sg; rx_wr->num_sge = 1; rx_wr->next = rx_wr + 1; @@ -890,10 +946,10 @@ isert_post_recv(struct isert_conn *isert_conn, u32 count) ret = ib_post_recv(isert_conn->conn_qp, isert_conn->conn_rx_wr, &rx_wr_failed); if (ret) { - pr_err("ib_post_recv() failed with ret: %d\n", ret); + isert_err("ib_post_recv() failed with ret: %d\n", ret); isert_conn->post_recv_buf_count -= count; } else { - pr_debug("isert_post_recv(): Posted %d RX buffers\n", count); + isert_dbg("isert_post_recv(): Posted %d RX buffers\n", count); isert_conn->conn_rx_desc_head = rx_head; } return ret; @@ -910,19 +966,15 @@ isert_post_send(struct isert_conn *isert_conn, struct iser_tx_desc *tx_desc) ISER_HEADERS_LEN, DMA_TO_DEVICE); send_wr.next = NULL; - send_wr.wr_id = (unsigned long)tx_desc; + send_wr.wr_id = (uintptr_t)tx_desc; send_wr.sg_list = tx_desc->tx_sg; send_wr.num_sge = tx_desc->num_sge; send_wr.opcode = IB_WR_SEND; send_wr.send_flags = IB_SEND_SIGNALED; - atomic_inc(&isert_conn->post_send_buf_count); - ret = ib_post_send(isert_conn->conn_qp, &send_wr, &send_wr_failed); - if (ret) { - pr_err("ib_post_send() failed, ret: %d\n", ret); - atomic_dec(&isert_conn->post_send_buf_count); - } + if (ret) + isert_err("ib_post_send() failed, ret: %d\n", ret); return ret; } @@ -945,7 +997,7 @@ isert_create_send_desc(struct isert_conn *isert_conn, if (tx_desc->tx_sg[0].lkey != isert_conn->conn_mr->lkey) { tx_desc->tx_sg[0].lkey = isert_conn->conn_mr->lkey; - pr_debug("tx_desc %p lkey mismatch, fixing\n", tx_desc); + isert_dbg("tx_desc %p lkey mismatch, fixing\n", tx_desc); } } @@ -959,7 +1011,7 @@ isert_init_tx_hdrs(struct isert_conn *isert_conn, dma_addr = ib_dma_map_single(ib_dev, (void *)tx_desc, ISER_HEADERS_LEN, DMA_TO_DEVICE); if (ib_dma_mapping_error(ib_dev, dma_addr)) { - pr_err("ib_dma_mapping_error() failed\n"); + isert_err("ib_dma_mapping_error() failed\n"); return -ENOMEM; } @@ -968,40 +1020,24 @@ isert_init_tx_hdrs(struct isert_conn *isert_conn, tx_desc->tx_sg[0].length = ISER_HEADERS_LEN; tx_desc->tx_sg[0].lkey = isert_conn->conn_mr->lkey; - pr_debug("isert_init_tx_hdrs: Setup tx_sg[0].addr: 0x%llx length: %u" - " lkey: 0x%08x\n", tx_desc->tx_sg[0].addr, - tx_desc->tx_sg[0].length, tx_desc->tx_sg[0].lkey); + isert_dbg("Setup tx_sg[0].addr: 0x%llx length: %u lkey: 0x%x\n", + tx_desc->tx_sg[0].addr, tx_desc->tx_sg[0].length, + tx_desc->tx_sg[0].lkey); return 0; } static void isert_init_send_wr(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd, - struct ib_send_wr *send_wr, bool coalesce) + struct ib_send_wr *send_wr) { struct iser_tx_desc *tx_desc = &isert_cmd->tx_desc; isert_cmd->rdma_wr.iser_ib_op = ISER_IB_SEND; - send_wr->wr_id = (unsigned long)&isert_cmd->tx_desc; + send_wr->wr_id = (uintptr_t)&isert_cmd->tx_desc; send_wr->opcode = IB_WR_SEND; send_wr->sg_list = &tx_desc->tx_sg[0]; send_wr->num_sge = isert_cmd->tx_desc.num_sge; - /* - * Coalesce send completion interrupts by only setting IB_SEND_SIGNALED - * bit for every ISERT_COMP_BATCH_COUNT number of ib_post_send() calls. - */ - mutex_lock(&isert_conn->conn_mutex); - if (coalesce && isert_conn->state == ISER_CONN_UP && - ++isert_conn->conn_comp_batch < ISERT_COMP_BATCH_COUNT) { - tx_desc->llnode_active = true; - llist_add(&tx_desc->comp_llnode, &isert_conn->conn_comp_llist); - mutex_unlock(&isert_conn->conn_mutex); - return; - } - isert_conn->conn_comp_batch = 0; - tx_desc->comp_llnode_batch = llist_del_all(&isert_conn->conn_comp_llist); - mutex_unlock(&isert_conn->conn_mutex); - send_wr->send_flags = IB_SEND_SIGNALED; } @@ -1017,22 +1053,21 @@ isert_rdma_post_recvl(struct isert_conn *isert_conn) sge.length = ISER_RX_LOGIN_SIZE; sge.lkey = isert_conn->conn_mr->lkey; - pr_debug("Setup sge: addr: %llx length: %d 0x%08x\n", + isert_dbg("Setup sge: addr: %llx length: %d 0x%08x\n", sge.addr, sge.length, sge.lkey); memset(&rx_wr, 0, sizeof(struct ib_recv_wr)); - rx_wr.wr_id = (unsigned long)isert_conn->login_req_buf; + rx_wr.wr_id = (uintptr_t)isert_conn->login_req_buf; rx_wr.sg_list = &sge; rx_wr.num_sge = 1; isert_conn->post_recv_buf_count++; ret = ib_post_recv(isert_conn->conn_qp, &rx_wr, &rx_wr_fail); if (ret) { - pr_err("ib_post_recv() failed: %d\n", ret); + isert_err("ib_post_recv() failed: %d\n", ret); isert_conn->post_recv_buf_count--; } - pr_debug("ib_post_recv(): returned success >>>>>>>>>>>>>>>>>>>>>>>>\n"); return ret; } @@ -1072,13 +1107,9 @@ isert_put_login_tx(struct iscsi_conn *conn, struct iscsi_login *login, if (login->login_complete) { if (!conn->sess->sess_ops->SessionType && isert_conn->conn_device->use_fastreg) { - /* Normal Session and fastreg is used */ - u8 pi_support = login->np->tpg_np->tpg->tpg_attrib.t10_pi; - - ret = isert_conn_create_fastreg_pool(isert_conn, - pi_support); + ret = isert_conn_create_fastreg_pool(isert_conn); if (ret) { - pr_err("Conn: %p failed to create" + isert_err("Conn: %p failed to create" " fastreg pool\n", isert_conn); return ret; } @@ -1092,7 +1123,10 @@ isert_put_login_tx(struct iscsi_conn *conn, struct iscsi_login *login, if (ret) return ret; - isert_conn->state = ISER_CONN_UP; + /* Now we are in FULL_FEATURE phase */ + mutex_lock(&isert_conn->conn_mutex); + isert_conn->state = ISER_CONN_FULL_FEATURE; + mutex_unlock(&isert_conn->conn_mutex); goto post_send; } @@ -1109,18 +1143,17 @@ post_send: } static void -isert_rx_login_req(struct iser_rx_desc *rx_desc, int rx_buflen, - struct isert_conn *isert_conn) +isert_rx_login_req(struct isert_conn *isert_conn) { + struct iser_rx_desc *rx_desc = (void *)isert_conn->login_req_buf; + int rx_buflen = isert_conn->login_req_len; struct iscsi_conn *conn = isert_conn->conn; struct iscsi_login *login = conn->conn_login; int size; - if (!login) { - pr_err("conn->conn_login is NULL\n"); - dump_stack(); - return; - } + isert_info("conn %p\n", isert_conn); + + WARN_ON_ONCE(!login); if (login->first_request) { struct iscsi_login_req *login_req = @@ -1146,8 +1179,9 @@ isert_rx_login_req(struct iser_rx_desc *rx_desc, int rx_buflen, memcpy(&login->req[0], (void *)&rx_desc->iscsi_header, ISCSI_HDR_LEN); size = min(rx_buflen, MAX_KEY_VALUE_PAIRS); - pr_debug("Using login payload size: %d, rx_buflen: %d MAX_KEY_VALUE_PAIRS: %d\n", - size, rx_buflen, MAX_KEY_VALUE_PAIRS); + isert_dbg("Using login payload size: %d, rx_buflen: %d " + "MAX_KEY_VALUE_PAIRS: %d\n", size, rx_buflen, + MAX_KEY_VALUE_PAIRS); memcpy(login->req_buf, &rx_desc->data[0], size); if (login->first_request) { @@ -1166,7 +1200,7 @@ static struct iscsi_cmd cmd = iscsit_allocate_cmd(conn, TASK_INTERRUPTIBLE); if (!cmd) { - pr_err("Unable to allocate iscsi_cmd + isert_cmd\n"); + isert_err("Unable to allocate iscsi_cmd + isert_cmd\n"); return NULL; } isert_cmd = iscsit_priv_cmd(cmd); @@ -1209,8 +1243,8 @@ isert_handle_scsi_cmd(struct isert_conn *isert_conn, sg = &cmd->se_cmd.t_data_sg[0]; sg_nents = max(1UL, DIV_ROUND_UP(imm_data_len, PAGE_SIZE)); - pr_debug("Copying Immediate SG: %p sg_nents: %u from %p imm_data_len: %d\n", - sg, sg_nents, &rx_desc->data[0], imm_data_len); + isert_dbg("Copying Immediate SG: %p sg_nents: %u from %p imm_data_len: %d\n", + sg, sg_nents, &rx_desc->data[0], imm_data_len); sg_copy_from_buffer(sg, sg_nents, &rx_desc->data[0], imm_data_len); @@ -1254,13 +1288,15 @@ isert_handle_iscsi_dataout(struct isert_conn *isert_conn, * FIXME: Unexpected unsolicited_data out */ if (!cmd->unsolicited_data) { - pr_err("Received unexpected solicited data payload\n"); + isert_err("Received unexpected solicited data payload\n"); dump_stack(); return -1; } - pr_debug("Unsolicited DataOut unsol_data_len: %u, write_data_done: %u, data_length: %u\n", - unsol_data_len, cmd->write_data_done, cmd->se_cmd.data_length); + isert_dbg("Unsolicited DataOut unsol_data_len: %u, " + "write_data_done: %u, data_length: %u\n", + unsol_data_len, cmd->write_data_done, + cmd->se_cmd.data_length); sg_off = cmd->write_data_done / PAGE_SIZE; sg_start = &cmd->se_cmd.t_data_sg[sg_off]; @@ -1270,12 +1306,13 @@ isert_handle_iscsi_dataout(struct isert_conn *isert_conn, * FIXME: Non page-aligned unsolicited_data out */ if (page_off) { - pr_err("Received unexpected non-page aligned data payload\n"); + isert_err("unexpected non-page aligned data payload\n"); dump_stack(); return -1; } - pr_debug("Copying DataOut: sg_start: %p, sg_off: %u sg_nents: %u from %p %u\n", - sg_start, sg_off, sg_nents, &rx_desc->data[0], unsol_data_len); + isert_dbg("Copying DataOut: sg_start: %p, sg_off: %u " + "sg_nents: %u from %p %u\n", sg_start, sg_off, + sg_nents, &rx_desc->data[0], unsol_data_len); sg_copy_from_buffer(sg_start, sg_nents, &rx_desc->data[0], unsol_data_len); @@ -1322,8 +1359,8 @@ isert_handle_text_cmd(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd text_in = kzalloc(payload_length, GFP_KERNEL); if (!text_in) { - pr_err("Unable to allocate text_in of payload_length: %u\n", - payload_length); + isert_err("Unable to allocate text_in of payload_length: %u\n", + payload_length); return -ENOMEM; } cmd->text_in_ptr = text_in; @@ -1348,8 +1385,8 @@ isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc, if (sess->sess_ops->SessionType && (!(opcode & ISCSI_OP_TEXT) || !(opcode & ISCSI_OP_LOGOUT))) { - pr_err("Got illegal opcode: 0x%02x in SessionType=Discovery," - " ignoring\n", opcode); + isert_err("Got illegal opcode: 0x%02x in SessionType=Discovery," + " ignoring\n", opcode); return 0; } @@ -1395,10 +1432,6 @@ isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc, break; ret = iscsit_handle_logout_cmd(conn, cmd, (unsigned char *)hdr); - if (ret > 0) - wait_for_completion_timeout(&conn->conn_logout_comp, - SECONDS_FOR_LOGOUT_COMP * - HZ); break; case ISCSI_OP_TEXT: cmd = isert_allocate_cmd(conn); @@ -1410,7 +1443,7 @@ isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc, rx_desc, (struct iscsi_text *)hdr); break; default: - pr_err("Got unknown iSCSI OpCode: 0x%02x\n", opcode); + isert_err("Got unknown iSCSI OpCode: 0x%02x\n", opcode); dump_stack(); break; } @@ -1431,23 +1464,23 @@ isert_rx_do_work(struct iser_rx_desc *rx_desc, struct isert_conn *isert_conn) if (iser_hdr->flags & ISER_RSV) { read_stag = be32_to_cpu(iser_hdr->read_stag); read_va = be64_to_cpu(iser_hdr->read_va); - pr_debug("ISER_RSV: read_stag: 0x%08x read_va: 0x%16llx\n", - read_stag, (unsigned long long)read_va); + isert_dbg("ISER_RSV: read_stag: 0x%x read_va: 0x%llx\n", + read_stag, (unsigned long long)read_va); } if (iser_hdr->flags & ISER_WSV) { write_stag = be32_to_cpu(iser_hdr->write_stag); write_va = be64_to_cpu(iser_hdr->write_va); - pr_debug("ISER_WSV: write__stag: 0x%08x write_va: 0x%16llx\n", - write_stag, (unsigned long long)write_va); + isert_dbg("ISER_WSV: write_stag: 0x%x write_va: 0x%llx\n", + write_stag, (unsigned long long)write_va); } - pr_debug("ISER ISCSI_CTRL PDU\n"); + isert_dbg("ISER ISCSI_CTRL PDU\n"); break; case ISER_HELLO: - pr_err("iSER Hello message\n"); + isert_err("iSER Hello message\n"); break; default: - pr_warn("Unknown iSER hdr flags: 0x%02x\n", iser_hdr->flags); + isert_warn("Unknown iSER hdr flags: 0x%02x\n", iser_hdr->flags); break; } @@ -1457,7 +1490,7 @@ isert_rx_do_work(struct iser_rx_desc *rx_desc, struct isert_conn *isert_conn) static void isert_rx_completion(struct iser_rx_desc *desc, struct isert_conn *isert_conn, - unsigned long xfer_len) + u32 xfer_len) { struct ib_device *ib_dev = isert_conn->conn_cm_id->device; struct iscsi_hdr *hdr; @@ -1467,34 +1500,43 @@ isert_rx_completion(struct iser_rx_desc *desc, struct isert_conn *isert_conn, if ((char *)desc == isert_conn->login_req_buf) { rx_dma = isert_conn->login_req_dma; rx_buflen = ISER_RX_LOGIN_SIZE; - pr_debug("ISER login_buf: Using rx_dma: 0x%llx, rx_buflen: %d\n", + isert_dbg("login_buf: Using rx_dma: 0x%llx, rx_buflen: %d\n", rx_dma, rx_buflen); } else { rx_dma = desc->dma_addr; rx_buflen = ISER_RX_PAYLOAD_SIZE; - pr_debug("ISER req_buf: Using rx_dma: 0x%llx, rx_buflen: %d\n", + isert_dbg("req_buf: Using rx_dma: 0x%llx, rx_buflen: %d\n", rx_dma, rx_buflen); } ib_dma_sync_single_for_cpu(ib_dev, rx_dma, rx_buflen, DMA_FROM_DEVICE); hdr = &desc->iscsi_header; - pr_debug("iSCSI opcode: 0x%02x, ITT: 0x%08x, flags: 0x%02x dlen: %d\n", + isert_dbg("iSCSI opcode: 0x%02x, ITT: 0x%08x, flags: 0x%02x dlen: %d\n", hdr->opcode, hdr->itt, hdr->flags, (int)(xfer_len - ISER_HEADERS_LEN)); - if ((char *)desc == isert_conn->login_req_buf) - isert_rx_login_req(desc, xfer_len - ISER_HEADERS_LEN, - isert_conn); - else + if ((char *)desc == isert_conn->login_req_buf) { + isert_conn->login_req_len = xfer_len - ISER_HEADERS_LEN; + if (isert_conn->conn) { + struct iscsi_login *login = isert_conn->conn->conn_login; + + if (login && !login->first_request) + isert_rx_login_req(isert_conn); + } + mutex_lock(&isert_conn->conn_mutex); + complete(&isert_conn->login_req_comp); + mutex_unlock(&isert_conn->conn_mutex); + } else { isert_rx_do_work(desc, isert_conn); + } ib_dma_sync_single_for_device(ib_dev, rx_dma, rx_buflen, DMA_FROM_DEVICE); isert_conn->post_recv_buf_count--; - pr_debug("iSERT: Decremented post_recv_buf_count: %d\n", - isert_conn->post_recv_buf_count); + isert_dbg("Decremented post_recv_buf_count: %d\n", + isert_conn->post_recv_buf_count); if ((char *)desc == isert_conn->login_req_buf) return; @@ -1505,7 +1547,7 @@ isert_rx_completion(struct iser_rx_desc *desc, struct isert_conn *isert_conn, ISERT_MIN_POSTED_RX); err = isert_post_recv(isert_conn, count); if (err) { - pr_err("isert_post_recv() count: %d failed, %d\n", + isert_err("isert_post_recv() count: %d failed, %d\n", count, err); } } @@ -1534,12 +1576,12 @@ isert_map_data_buf(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd, data->dma_nents = ib_dma_map_sg(ib_dev, data->sg, data->nents, data->dma_dir); if (unlikely(!data->dma_nents)) { - pr_err("Cmd: unable to dma map SGs %p\n", sg); + isert_err("Cmd: unable to dma map SGs %p\n", sg); return -EINVAL; } - pr_debug("Mapped cmd: %p count: %u sg: %p sg_nents: %u rdma_len %d\n", - isert_cmd, data->dma_nents, data->sg, data->nents, data->len); + isert_dbg("Mapped cmd: %p count: %u sg: %p sg_nents: %u rdma_len %d\n", + isert_cmd, data->dma_nents, data->sg, data->nents, data->len); return 0; } @@ -1560,21 +1602,21 @@ isert_unmap_cmd(struct isert_cmd *isert_cmd, struct isert_conn *isert_conn) { struct isert_rdma_wr *wr = &isert_cmd->rdma_wr; - pr_debug("isert_unmap_cmd: %p\n", isert_cmd); + isert_dbg("Cmd %p\n", isert_cmd); if (wr->data.sg) { - pr_debug("isert_unmap_cmd: %p unmap_sg op\n", isert_cmd); + isert_dbg("Cmd %p unmap_sg op\n", isert_cmd); isert_unmap_data_buf(isert_conn, &wr->data); } if (wr->send_wr) { - pr_debug("isert_unmap_cmd: %p free send_wr\n", isert_cmd); + isert_dbg("Cmd %p free send_wr\n", isert_cmd); kfree(wr->send_wr); wr->send_wr = NULL; } if (wr->ib_sge) { - pr_debug("isert_unmap_cmd: %p free ib_sge\n", isert_cmd); + isert_dbg("Cmd %p free ib_sge\n", isert_cmd); kfree(wr->ib_sge); wr->ib_sge = NULL; } @@ -1586,11 +1628,10 @@ isert_unreg_rdma(struct isert_cmd *isert_cmd, struct isert_conn *isert_conn) struct isert_rdma_wr *wr = &isert_cmd->rdma_wr; LIST_HEAD(unmap_list); - pr_debug("unreg_fastreg_cmd: %p\n", isert_cmd); + isert_dbg("Cmd %p\n", isert_cmd); if (wr->fr_desc) { - pr_debug("unreg_fastreg_cmd: %p free fr_desc %p\n", - isert_cmd, wr->fr_desc); + isert_dbg("Cmd %p free fr_desc %p\n", isert_cmd, wr->fr_desc); if (wr->fr_desc->ind & ISERT_PROTECTED) { isert_unmap_data_buf(isert_conn, &wr->prot); wr->fr_desc->ind &= ~ISERT_PROTECTED; @@ -1602,7 +1643,7 @@ isert_unreg_rdma(struct isert_cmd *isert_cmd, struct isert_conn *isert_conn) } if (wr->data.sg) { - pr_debug("unreg_fastreg_cmd: %p unmap_sg op\n", isert_cmd); + isert_dbg("Cmd %p unmap_sg op\n", isert_cmd); isert_unmap_data_buf(isert_conn, &wr->data); } @@ -1618,7 +1659,7 @@ isert_put_cmd(struct isert_cmd *isert_cmd, bool comp_err) struct iscsi_conn *conn = isert_conn->conn; struct isert_device *device = isert_conn->conn_device; - pr_debug("Entering isert_put_cmd: %p\n", isert_cmd); + isert_dbg("Cmd %p\n", isert_cmd); switch (cmd->iscsi_opcode) { case ISCSI_OP_SCSI_CMD: @@ -1668,7 +1709,7 @@ isert_put_cmd(struct isert_cmd *isert_cmd, bool comp_err) * associated cmd->se_cmd needs to be released. */ if (cmd->se_cmd.se_tfo != NULL) { - pr_debug("Calling transport_generic_free_cmd from" + isert_dbg("Calling transport_generic_free_cmd from" " isert_put_cmd for 0x%02x\n", cmd->iscsi_opcode); transport_generic_free_cmd(&cmd->se_cmd, 0); @@ -1687,7 +1728,7 @@ static void isert_unmap_tx_desc(struct iser_tx_desc *tx_desc, struct ib_device *ib_dev) { if (tx_desc->dma_addr != 0) { - pr_debug("Calling ib_dma_unmap_single for tx_desc->dma_addr\n"); + isert_dbg("unmap single for tx_desc->dma_addr\n"); ib_dma_unmap_single(ib_dev, tx_desc->dma_addr, ISER_HEADERS_LEN, DMA_TO_DEVICE); tx_desc->dma_addr = 0; @@ -1699,7 +1740,7 @@ isert_completion_put(struct iser_tx_desc *tx_desc, struct isert_cmd *isert_cmd, struct ib_device *ib_dev, bool comp_err) { if (isert_cmd->pdu_buf_dma != 0) { - pr_debug("Calling ib_dma_unmap_single for isert_cmd->pdu_buf_dma\n"); + isert_dbg("unmap single for isert_cmd->pdu_buf_dma\n"); ib_dma_unmap_single(ib_dev, isert_cmd->pdu_buf_dma, isert_cmd->pdu_buf_len, DMA_TO_DEVICE); isert_cmd->pdu_buf_dma = 0; @@ -1717,7 +1758,7 @@ isert_check_pi_status(struct se_cmd *se_cmd, struct ib_mr *sig_mr) ret = ib_check_mr_status(sig_mr, IB_MR_CHECK_SIG_STATUS, &mr_status); if (ret) { - pr_err("ib_check_mr_status failed, ret %d\n", ret); + isert_err("ib_check_mr_status failed, ret %d\n", ret); goto fail_mr_status; } @@ -1740,12 +1781,12 @@ isert_check_pi_status(struct se_cmd *se_cmd, struct ib_mr *sig_mr) do_div(sec_offset_err, block_size); se_cmd->bad_sector = sec_offset_err + se_cmd->t_task_lba; - pr_err("isert: PI error found type %d at sector 0x%llx " - "expected 0x%x vs actual 0x%x\n", - mr_status.sig_err.err_type, - (unsigned long long)se_cmd->bad_sector, - mr_status.sig_err.expected, - mr_status.sig_err.actual); + isert_err("PI error found type %d at sector 0x%llx " + "expected 0x%x vs actual 0x%x\n", + mr_status.sig_err.err_type, + (unsigned long long)se_cmd->bad_sector, + mr_status.sig_err.expected, + mr_status.sig_err.actual); ret = 1; } @@ -1801,7 +1842,7 @@ isert_completion_rdma_read(struct iser_tx_desc *tx_desc, cmd->write_data_done = wr->data.len; wr->send_wr_num = 0; - pr_debug("Cmd: %p RDMA_READ comp calling execute_cmd\n", isert_cmd); + isert_dbg("Cmd: %p RDMA_READ comp calling execute_cmd\n", isert_cmd); spin_lock_bh(&cmd->istate_lock); cmd->cmd_flags |= ICF_GOT_LAST_DATAOUT; cmd->i_state = ISTATE_RECEIVED_LAST_DATAOUT; @@ -1823,36 +1864,22 @@ isert_do_control_comp(struct work_struct *work) struct ib_device *ib_dev = isert_conn->conn_cm_id->device; struct iscsi_cmd *cmd = isert_cmd->iscsi_cmd; + isert_dbg("Cmd %p i_state %d\n", isert_cmd, cmd->i_state); + switch (cmd->i_state) { case ISTATE_SEND_TASKMGTRSP: - pr_debug("Calling iscsit_tmr_post_handler >>>>>>>>>>>>>>>>>\n"); - - atomic_dec(&isert_conn->post_send_buf_count); iscsit_tmr_post_handler(cmd, cmd->conn); - - cmd->i_state = ISTATE_SENT_STATUS; - isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev, false); - break; - case ISTATE_SEND_REJECT: - pr_debug("Got isert_do_control_comp ISTATE_SEND_REJECT: >>>\n"); - atomic_dec(&isert_conn->post_send_buf_count); - + case ISTATE_SEND_REJECT: /* FALLTHRU */ + case ISTATE_SEND_TEXTRSP: /* FALLTHRU */ cmd->i_state = ISTATE_SENT_STATUS; - isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev, false); + isert_completion_put(&isert_cmd->tx_desc, isert_cmd, + ib_dev, false); break; case ISTATE_SEND_LOGOUTRSP: - pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n"); - - atomic_dec(&isert_conn->post_send_buf_count); iscsit_logout_post_handler(cmd, cmd->conn); break; - case ISTATE_SEND_TEXTRSP: - atomic_dec(&isert_conn->post_send_buf_count); - cmd->i_state = ISTATE_SENT_STATUS; - isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev, false); - break; default: - pr_err("Unknown do_control_comp i_state %d\n", cmd->i_state); + isert_err("Unknown i_state %d\n", cmd->i_state); dump_stack(); break; } @@ -1865,7 +1892,6 @@ isert_response_completion(struct iser_tx_desc *tx_desc, struct ib_device *ib_dev) { struct iscsi_cmd *cmd = isert_cmd->iscsi_cmd; - struct isert_rdma_wr *wr = &isert_cmd->rdma_wr; if (cmd->i_state == ISTATE_SEND_TASKMGTRSP || cmd->i_state == ISTATE_SEND_LOGOUTRSP || @@ -1878,267 +1904,151 @@ isert_response_completion(struct iser_tx_desc *tx_desc, return; } - /** - * If send_wr_num is 0 this means that we got - * RDMA completion and we cleared it and we should - * simply decrement the response post. else the - * response is incorporated in send_wr_num, just - * sub it. - **/ - if (wr->send_wr_num) - atomic_sub(wr->send_wr_num, &isert_conn->post_send_buf_count); - else - atomic_dec(&isert_conn->post_send_buf_count); - cmd->i_state = ISTATE_SENT_STATUS; isert_completion_put(tx_desc, isert_cmd, ib_dev, false); } static void -__isert_send_completion(struct iser_tx_desc *tx_desc, - struct isert_conn *isert_conn) +isert_send_completion(struct iser_tx_desc *tx_desc, + struct isert_conn *isert_conn) { struct ib_device *ib_dev = isert_conn->conn_cm_id->device; struct isert_cmd *isert_cmd = tx_desc->isert_cmd; struct isert_rdma_wr *wr; if (!isert_cmd) { - atomic_dec(&isert_conn->post_send_buf_count); isert_unmap_tx_desc(tx_desc, ib_dev); return; } wr = &isert_cmd->rdma_wr; + isert_dbg("Cmd %p iser_ib_op %d\n", isert_cmd, wr->iser_ib_op); + switch (wr->iser_ib_op) { case ISER_IB_RECV: - pr_err("isert_send_completion: Got ISER_IB_RECV\n"); + isert_err("Got ISER_IB_RECV\n"); dump_stack(); break; case ISER_IB_SEND: - pr_debug("isert_send_completion: Got ISER_IB_SEND\n"); isert_response_completion(tx_desc, isert_cmd, isert_conn, ib_dev); break; case ISER_IB_RDMA_WRITE: - pr_debug("isert_send_completion: Got ISER_IB_RDMA_WRITE\n"); - atomic_sub(wr->send_wr_num, &isert_conn->post_send_buf_count); isert_completion_rdma_write(tx_desc, isert_cmd); break; case ISER_IB_RDMA_READ: - pr_debug("isert_send_completion: Got ISER_IB_RDMA_READ:\n"); - - atomic_sub(wr->send_wr_num, &isert_conn->post_send_buf_count); isert_completion_rdma_read(tx_desc, isert_cmd); break; default: - pr_err("Unknown wr->iser_ib_op: 0x%02x\n", wr->iser_ib_op); + isert_err("Unknown wr->iser_ib_op: 0x%x\n", wr->iser_ib_op); dump_stack(); break; } } -static void -isert_send_completion(struct iser_tx_desc *tx_desc, - struct isert_conn *isert_conn) -{ - struct llist_node *llnode = tx_desc->comp_llnode_batch; - struct iser_tx_desc *t; - /* - * Drain coalesced completion llist starting from comp_llnode_batch - * setup in isert_init_send_wr(), and then complete trailing tx_desc. - */ - while (llnode) { - t = llist_entry(llnode, struct iser_tx_desc, comp_llnode); - llnode = llist_next(llnode); - __isert_send_completion(t, isert_conn); - } - __isert_send_completion(tx_desc, isert_conn); -} - -static void -isert_cq_drain_comp_llist(struct isert_conn *isert_conn, struct ib_device *ib_dev) +/** + * is_isert_tx_desc() - Indicate if the completion wr_id + * is a TX descriptor or not. + * @isert_conn: iser connection + * @wr_id: completion WR identifier + * + * Since we cannot rely on wc opcode in FLUSH errors + * we must work around it by checking if the wr_id address + * falls in the iser connection rx_descs buffer. If so + * it is an RX descriptor, otherwize it is a TX. + */ +static inline bool +is_isert_tx_desc(struct isert_conn *isert_conn, void *wr_id) { - struct llist_node *llnode; - struct isert_rdma_wr *wr; - struct iser_tx_desc *t; + void *start = isert_conn->conn_rx_descs; + int len = ISERT_QP_MAX_RECV_DTOS * sizeof(*isert_conn->conn_rx_descs); - mutex_lock(&isert_conn->conn_mutex); - llnode = llist_del_all(&isert_conn->conn_comp_llist); - isert_conn->conn_comp_batch = 0; - mutex_unlock(&isert_conn->conn_mutex); - - while (llnode) { - t = llist_entry(llnode, struct iser_tx_desc, comp_llnode); - llnode = llist_next(llnode); - wr = &t->isert_cmd->rdma_wr; - - /** - * If send_wr_num is 0 this means that we got - * RDMA completion and we cleared it and we should - * simply decrement the response post. else the - * response is incorporated in send_wr_num, just - * sub it. - **/ - if (wr->send_wr_num) - atomic_sub(wr->send_wr_num, - &isert_conn->post_send_buf_count); - else - atomic_dec(&isert_conn->post_send_buf_count); + if (wr_id >= start && wr_id < start + len) + return false; - isert_completion_put(t, t->isert_cmd, ib_dev, true); - } + return true; } static void -isert_cq_tx_comp_err(struct iser_tx_desc *tx_desc, struct isert_conn *isert_conn) +isert_cq_comp_err(struct isert_conn *isert_conn, struct ib_wc *wc) { - struct ib_device *ib_dev = isert_conn->conn_cm_id->device; - struct isert_cmd *isert_cmd = tx_desc->isert_cmd; - struct llist_node *llnode = tx_desc->comp_llnode_batch; - struct isert_rdma_wr *wr; - struct iser_tx_desc *t; - - while (llnode) { - t = llist_entry(llnode, struct iser_tx_desc, comp_llnode); - llnode = llist_next(llnode); - wr = &t->isert_cmd->rdma_wr; + if (wc->wr_id == ISER_BEACON_WRID) { + isert_info("conn %p completing conn_wait_comp_err\n", + isert_conn); + complete(&isert_conn->conn_wait_comp_err); + } else if (is_isert_tx_desc(isert_conn, (void *)(uintptr_t)wc->wr_id)) { + struct ib_device *ib_dev = isert_conn->conn_cm_id->device; + struct isert_cmd *isert_cmd; + struct iser_tx_desc *desc; - /** - * If send_wr_num is 0 this means that we got - * RDMA completion and we cleared it and we should - * simply decrement the response post. else the - * response is incorporated in send_wr_num, just - * sub it. - **/ - if (wr->send_wr_num) - atomic_sub(wr->send_wr_num, - &isert_conn->post_send_buf_count); + desc = (struct iser_tx_desc *)(uintptr_t)wc->wr_id; + isert_cmd = desc->isert_cmd; + if (!isert_cmd) + isert_unmap_tx_desc(desc, ib_dev); else - atomic_dec(&isert_conn->post_send_buf_count); - - isert_completion_put(t, t->isert_cmd, ib_dev, true); - } - tx_desc->comp_llnode_batch = NULL; - - if (!isert_cmd) - isert_unmap_tx_desc(tx_desc, ib_dev); - else - isert_completion_put(tx_desc, isert_cmd, ib_dev, true); -} - -static void -isert_cq_rx_comp_err(struct isert_conn *isert_conn) -{ - struct ib_device *ib_dev = isert_conn->conn_cm_id->device; - struct iscsi_conn *conn = isert_conn->conn; - - if (isert_conn->post_recv_buf_count) - return; - - isert_cq_drain_comp_llist(isert_conn, ib_dev); - - if (conn->sess) { - target_sess_cmd_list_set_waiting(conn->sess->se_sess); - target_wait_for_sess_cmds(conn->sess->se_sess); + isert_completion_put(desc, isert_cmd, ib_dev, true); + } else { + isert_conn->post_recv_buf_count--; + if (!isert_conn->post_recv_buf_count) + iscsit_cause_connection_reinstatement(isert_conn->conn, 0); } - - while (atomic_read(&isert_conn->post_send_buf_count)) - msleep(3000); - - mutex_lock(&isert_conn->conn_mutex); - isert_conn->state = ISER_CONN_DOWN; - mutex_unlock(&isert_conn->conn_mutex); - - iscsit_cause_connection_reinstatement(isert_conn->conn, 0); - - complete(&isert_conn->conn_wait_comp_err); } static void -isert_cq_tx_work(struct work_struct *work) +isert_handle_wc(struct ib_wc *wc) { - struct isert_cq_desc *cq_desc = container_of(work, - struct isert_cq_desc, cq_tx_work); - struct isert_device *device = cq_desc->device; - int cq_index = cq_desc->cq_index; - struct ib_cq *tx_cq = device->dev_tx_cq[cq_index]; struct isert_conn *isert_conn; struct iser_tx_desc *tx_desc; - struct ib_wc wc; - - while (ib_poll_cq(tx_cq, 1, &wc) == 1) { - tx_desc = (struct iser_tx_desc *)(unsigned long)wc.wr_id; - isert_conn = wc.qp->qp_context; + struct iser_rx_desc *rx_desc; - if (wc.status == IB_WC_SUCCESS) { - isert_send_completion(tx_desc, isert_conn); + isert_conn = wc->qp->qp_context; + if (likely(wc->status == IB_WC_SUCCESS)) { + if (wc->opcode == IB_WC_RECV) { + rx_desc = (struct iser_rx_desc *)(uintptr_t)wc->wr_id; + isert_rx_completion(rx_desc, isert_conn, wc->byte_len); } else { - pr_debug("TX wc.status != IB_WC_SUCCESS >>>>>>>>>>>>>>\n"); - pr_debug("TX wc.status: 0x%08x\n", wc.status); - pr_debug("TX wc.vendor_err: 0x%08x\n", wc.vendor_err); - - if (wc.wr_id != ISER_FASTREG_LI_WRID) { - if (tx_desc->llnode_active) - continue; - - atomic_dec(&isert_conn->post_send_buf_count); - isert_cq_tx_comp_err(tx_desc, isert_conn); - } + tx_desc = (struct iser_tx_desc *)(uintptr_t)wc->wr_id; + isert_send_completion(tx_desc, isert_conn); } - } - - ib_req_notify_cq(tx_cq, IB_CQ_NEXT_COMP); -} - -static void -isert_cq_tx_callback(struct ib_cq *cq, void *context) -{ - struct isert_cq_desc *cq_desc = (struct isert_cq_desc *)context; + } else { + if (wc->status != IB_WC_WR_FLUSH_ERR) + isert_err("wr id %llx status %d vend_err %x\n", + wc->wr_id, wc->status, wc->vendor_err); + else + isert_dbg("flush error: wr id %llx\n", wc->wr_id); - queue_work(isert_comp_wq, &cq_desc->cq_tx_work); + if (wc->wr_id != ISER_FASTREG_LI_WRID) + isert_cq_comp_err(isert_conn, wc); + } } static void -isert_cq_rx_work(struct work_struct *work) +isert_cq_work(struct work_struct *work) { - struct isert_cq_desc *cq_desc = container_of(work, - struct isert_cq_desc, cq_rx_work); - struct isert_device *device = cq_desc->device; - int cq_index = cq_desc->cq_index; - struct ib_cq *rx_cq = device->dev_rx_cq[cq_index]; - struct isert_conn *isert_conn; - struct iser_rx_desc *rx_desc; - struct ib_wc wc; - unsigned long xfer_len; + enum { isert_poll_budget = 65536 }; + struct isert_comp *comp = container_of(work, struct isert_comp, + work); + struct ib_wc *const wcs = comp->wcs; + int i, n, completed = 0; - while (ib_poll_cq(rx_cq, 1, &wc) == 1) { - rx_desc = (struct iser_rx_desc *)(unsigned long)wc.wr_id; - isert_conn = wc.qp->qp_context; + while ((n = ib_poll_cq(comp->cq, ARRAY_SIZE(comp->wcs), wcs)) > 0) { + for (i = 0; i < n; i++) + isert_handle_wc(&wcs[i]); - if (wc.status == IB_WC_SUCCESS) { - xfer_len = (unsigned long)wc.byte_len; - isert_rx_completion(rx_desc, isert_conn, xfer_len); - } else { - pr_debug("RX wc.status != IB_WC_SUCCESS >>>>>>>>>>>>>>\n"); - if (wc.status != IB_WC_WR_FLUSH_ERR) { - pr_debug("RX wc.status: 0x%08x\n", wc.status); - pr_debug("RX wc.vendor_err: 0x%08x\n", - wc.vendor_err); - } - isert_conn->post_recv_buf_count--; - isert_cq_rx_comp_err(isert_conn); - } + completed += n; + if (completed >= isert_poll_budget) + break; } - ib_req_notify_cq(rx_cq, IB_CQ_NEXT_COMP); + ib_req_notify_cq(comp->cq, IB_CQ_NEXT_COMP); } static void -isert_cq_rx_callback(struct ib_cq *cq, void *context) +isert_cq_callback(struct ib_cq *cq, void *context) { - struct isert_cq_desc *cq_desc = (struct isert_cq_desc *)context; + struct isert_comp *comp = context; - queue_work(isert_rx_wq, &cq_desc->cq_rx_work); + queue_work(isert_comp_wq, &comp->work); } static int @@ -2147,13 +2057,10 @@ isert_post_response(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd) struct ib_send_wr *wr_failed; int ret; - atomic_inc(&isert_conn->post_send_buf_count); - ret = ib_post_send(isert_conn->conn_qp, &isert_cmd->tx_desc.send_wr, &wr_failed); if (ret) { - pr_err("ib_post_send failed with %d\n", ret); - atomic_dec(&isert_conn->post_send_buf_count); + isert_err("ib_post_send failed with %d\n", ret); return ret; } return ret; @@ -2200,9 +2107,9 @@ isert_put_response(struct iscsi_conn *conn, struct iscsi_cmd *cmd) isert_cmd->tx_desc.num_sge = 2; } - isert_init_send_wr(isert_conn, isert_cmd, send_wr, false); + isert_init_send_wr(isert_conn, isert_cmd, send_wr); - pr_debug("Posting SCSI Response IB_WR_SEND >>>>>>>>>>>>>>>>>>>>>>\n"); + isert_dbg("Posting SCSI Response\n"); return isert_post_response(isert_conn, isert_cmd); } @@ -2231,8 +2138,16 @@ isert_get_sup_prot_ops(struct iscsi_conn *conn) struct isert_conn *isert_conn = (struct isert_conn *)conn->context; struct isert_device *device = isert_conn->conn_device; - if (device->pi_capable) - return TARGET_PROT_ALL; + if (conn->tpg->tpg_attrib.t10_pi) { + if (device->pi_capable) { + isert_info("conn %p PI offload enabled\n", isert_conn); + isert_conn->pi_support = true; + return TARGET_PROT_ALL; + } + } + + isert_info("conn %p PI offload disabled\n", isert_conn); + isert_conn->pi_support = false; return TARGET_PROT_NORMAL; } @@ -2250,9 +2165,9 @@ isert_put_nopin(struct iscsi_cmd *cmd, struct iscsi_conn *conn, &isert_cmd->tx_desc.iscsi_header, nopout_response); isert_init_tx_hdrs(isert_conn, &isert_cmd->tx_desc); - isert_init_send_wr(isert_conn, isert_cmd, send_wr, false); + isert_init_send_wr(isert_conn, isert_cmd, send_wr); - pr_debug("Posting NOPIN Response IB_WR_SEND >>>>>>>>>>>>>>>>>>>>>>\n"); + isert_dbg("conn %p Posting NOPIN Response\n", isert_conn); return isert_post_response(isert_conn, isert_cmd); } @@ -2268,9 +2183,9 @@ isert_put_logout_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn) iscsit_build_logout_rsp(cmd, conn, (struct iscsi_logout_rsp *) &isert_cmd->tx_desc.iscsi_header); isert_init_tx_hdrs(isert_conn, &isert_cmd->tx_desc); - isert_init_send_wr(isert_conn, isert_cmd, send_wr, false); + isert_init_send_wr(isert_conn, isert_cmd, send_wr); - pr_debug("Posting Logout Response IB_WR_SEND >>>>>>>>>>>>>>>>>>>>>>\n"); + isert_dbg("conn %p Posting Logout Response\n", isert_conn); return isert_post_response(isert_conn, isert_cmd); } @@ -2286,9 +2201,9 @@ isert_put_tm_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn) iscsit_build_task_mgt_rsp(cmd, conn, (struct iscsi_tm_rsp *) &isert_cmd->tx_desc.iscsi_header); isert_init_tx_hdrs(isert_conn, &isert_cmd->tx_desc); - isert_init_send_wr(isert_conn, isert_cmd, send_wr, false); + isert_init_send_wr(isert_conn, isert_cmd, send_wr); - pr_debug("Posting Task Management Response IB_WR_SEND >>>>>>>>>>>>>>>>>>>>>>\n"); + isert_dbg("conn %p Posting Task Management Response\n", isert_conn); return isert_post_response(isert_conn, isert_cmd); } @@ -2318,9 +2233,9 @@ isert_put_reject(struct iscsi_cmd *cmd, struct iscsi_conn *conn) tx_dsg->lkey = isert_conn->conn_mr->lkey; isert_cmd->tx_desc.num_sge = 2; - isert_init_send_wr(isert_conn, isert_cmd, send_wr, false); + isert_init_send_wr(isert_conn, isert_cmd, send_wr); - pr_debug("Posting Reject IB_WR_SEND >>>>>>>>>>>>>>>>>>>>>>\n"); + isert_dbg("conn %p Posting Reject\n", isert_conn); return isert_post_response(isert_conn, isert_cmd); } @@ -2358,9 +2273,9 @@ isert_put_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn) tx_dsg->lkey = isert_conn->conn_mr->lkey; isert_cmd->tx_desc.num_sge = 2; } - isert_init_send_wr(isert_conn, isert_cmd, send_wr, false); + isert_init_send_wr(isert_conn, isert_cmd, send_wr); - pr_debug("Posting Text Response IB_WR_SEND >>>>>>>>>>>>>>>>>>>>>>\n"); + isert_dbg("conn %p Text Reject\n", isert_conn); return isert_post_response(isert_conn, isert_cmd); } @@ -2383,30 +2298,31 @@ isert_build_rdma_wr(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd, send_wr->sg_list = ib_sge; send_wr->num_sge = sg_nents; - send_wr->wr_id = (unsigned long)&isert_cmd->tx_desc; + send_wr->wr_id = (uintptr_t)&isert_cmd->tx_desc; /* * Perform mapping of TCM scatterlist memory ib_sge dma_addr. */ for_each_sg(sg_start, tmp_sg, sg_nents, i) { - pr_debug("ISER RDMA from SGL dma_addr: 0x%16llx dma_len: %u, page_off: %u\n", - (unsigned long long)tmp_sg->dma_address, - tmp_sg->length, page_off); + isert_dbg("RDMA from SGL dma_addr: 0x%llx dma_len: %u, " + "page_off: %u\n", + (unsigned long long)tmp_sg->dma_address, + tmp_sg->length, page_off); ib_sge->addr = ib_sg_dma_address(ib_dev, tmp_sg) + page_off; ib_sge->length = min_t(u32, data_left, ib_sg_dma_len(ib_dev, tmp_sg) - page_off); ib_sge->lkey = isert_conn->conn_mr->lkey; - pr_debug("RDMA ib_sge: addr: 0x%16llx length: %u lkey: %08x\n", - ib_sge->addr, ib_sge->length, ib_sge->lkey); + isert_dbg("RDMA ib_sge: addr: 0x%llx length: %u lkey: %x\n", + ib_sge->addr, ib_sge->length, ib_sge->lkey); page_off = 0; data_left -= ib_sge->length; ib_sge++; - pr_debug("Incrementing ib_sge pointer to %p\n", ib_sge); + isert_dbg("Incrementing ib_sge pointer to %p\n", ib_sge); } - pr_debug("Set outgoing sg_list: %p num_sg: %u from TCM SGLs\n", - send_wr->sg_list, send_wr->num_sge); + isert_dbg("Set outgoing sg_list: %p num_sg: %u from TCM SGLs\n", + send_wr->sg_list, send_wr->num_sge); return sg_nents; } @@ -2438,7 +2354,7 @@ isert_map_rdma(struct iscsi_conn *conn, struct iscsi_cmd *cmd, ib_sge = kzalloc(sizeof(struct ib_sge) * data->nents, GFP_KERNEL); if (!ib_sge) { - pr_warn("Unable to allocate ib_sge\n"); + isert_warn("Unable to allocate ib_sge\n"); ret = -ENOMEM; goto unmap_cmd; } @@ -2448,7 +2364,7 @@ isert_map_rdma(struct iscsi_conn *conn, struct iscsi_cmd *cmd, wr->send_wr = kzalloc(sizeof(struct ib_send_wr) * wr->send_wr_num, GFP_KERNEL); if (!wr->send_wr) { - pr_debug("Unable to allocate wr->send_wr\n"); + isert_dbg("Unable to allocate wr->send_wr\n"); ret = -ENOMEM; goto unmap_cmd; } @@ -2512,9 +2428,9 @@ isert_map_fr_pagelist(struct ib_device *ib_dev, chunk_start = start_addr; end_addr = start_addr + ib_sg_dma_len(ib_dev, tmp_sg); - pr_debug("SGL[%d] dma_addr: 0x%16llx len: %u\n", - i, (unsigned long long)tmp_sg->dma_address, - tmp_sg->length); + isert_dbg("SGL[%d] dma_addr: 0x%llx len: %u\n", + i, (unsigned long long)tmp_sg->dma_address, + tmp_sg->length); if ((end_addr & ~PAGE_MASK) && i < last_ent) { new_chunk = 0; @@ -2525,8 +2441,8 @@ isert_map_fr_pagelist(struct ib_device *ib_dev, page = chunk_start & PAGE_MASK; do { fr_pl[n_pages++] = page; - pr_debug("Mapped page_list[%d] page_addr: 0x%16llx\n", - n_pages - 1, page); + isert_dbg("Mapped page_list[%d] page_addr: 0x%llx\n", + n_pages - 1, page); page += PAGE_SIZE; } while (page < end_addr); } @@ -2534,6 +2450,21 @@ isert_map_fr_pagelist(struct ib_device *ib_dev, return n_pages; } +static inline void +isert_inv_rkey(struct ib_send_wr *inv_wr, struct ib_mr *mr) +{ + u32 rkey; + + memset(inv_wr, 0, sizeof(*inv_wr)); + inv_wr->wr_id = ISER_FASTREG_LI_WRID; + inv_wr->opcode = IB_WR_LOCAL_INV; + inv_wr->ex.invalidate_rkey = mr->rkey; + + /* Bump the key */ + rkey = ib_inc_rkey(mr->rkey); + ib_update_fast_reg_key(mr, rkey); +} + static int isert_fast_reg_mr(struct isert_conn *isert_conn, struct fast_reg_descriptor *fr_desc, @@ -2548,15 +2479,13 @@ isert_fast_reg_mr(struct isert_conn *isert_conn, struct ib_send_wr *bad_wr, *wr = NULL; int ret, pagelist_len; u32 page_off; - u8 key; if (mem->dma_nents == 1) { sge->lkey = isert_conn->conn_mr->lkey; sge->addr = ib_sg_dma_address(ib_dev, &mem->sg[0]); sge->length = ib_sg_dma_len(ib_dev, &mem->sg[0]); - pr_debug("%s:%d sge: addr: 0x%llx length: %u lkey: %x\n", - __func__, __LINE__, sge->addr, sge->length, - sge->lkey); + isert_dbg("sge: addr: 0x%llx length: %u lkey: %x\n", + sge->addr, sge->length, sge->lkey); return 0; } @@ -2572,21 +2501,15 @@ isert_fast_reg_mr(struct isert_conn *isert_conn, page_off = mem->offset % PAGE_SIZE; - pr_debug("Use fr_desc %p sg_nents %d offset %u\n", - fr_desc, mem->nents, mem->offset); + isert_dbg("Use fr_desc %p sg_nents %d offset %u\n", + fr_desc, mem->nents, mem->offset); pagelist_len = isert_map_fr_pagelist(ib_dev, mem->sg, mem->nents, &frpl->page_list[0]); - if (!(fr_desc->ind & ISERT_DATA_KEY_VALID)) { - memset(&inv_wr, 0, sizeof(inv_wr)); - inv_wr.wr_id = ISER_FASTREG_LI_WRID; - inv_wr.opcode = IB_WR_LOCAL_INV; - inv_wr.ex.invalidate_rkey = mr->rkey; + if (!(fr_desc->ind & ind)) { + isert_inv_rkey(&inv_wr, mr); wr = &inv_wr; - /* Bump the key */ - key = (u8)(mr->rkey & 0x000000FF); - ib_update_fast_reg_key(mr, ++key); } /* Prepare FASTREG WR */ @@ -2608,7 +2531,7 @@ isert_fast_reg_mr(struct isert_conn *isert_conn, ret = ib_post_send(isert_conn->conn_qp, wr, &bad_wr); if (ret) { - pr_err("fast registration failed, ret:%d\n", ret); + isert_err("fast registration failed, ret:%d\n", ret); return ret; } fr_desc->ind &= ~ind; @@ -2617,9 +2540,8 @@ isert_fast_reg_mr(struct isert_conn *isert_conn, sge->addr = frpl->page_list[0] + page_off; sge->length = mem->len; - pr_debug("%s:%d sge: addr: 0x%llx length: %u lkey: %x\n", - __func__, __LINE__, sge->addr, sge->length, - sge->lkey); + isert_dbg("sge: addr: 0x%llx length: %u lkey: %x\n", + sge->addr, sge->length, sge->lkey); return ret; } @@ -2665,7 +2587,7 @@ isert_set_sig_attrs(struct se_cmd *se_cmd, struct ib_sig_attrs *sig_attrs) isert_set_dif_domain(se_cmd, sig_attrs, &sig_attrs->mem); break; default: - pr_err("Unsupported PI operation %d\n", se_cmd->prot_op); + isert_err("Unsupported PI operation %d\n", se_cmd->prot_op); return -EINVAL; } @@ -2681,17 +2603,16 @@ isert_set_prot_checks(u8 prot_checks) } static int -isert_reg_sig_mr(struct isert_conn *isert_conn, struct se_cmd *se_cmd, - struct fast_reg_descriptor *fr_desc, - struct ib_sge *data_sge, struct ib_sge *prot_sge, - struct ib_sge *sig_sge) +isert_reg_sig_mr(struct isert_conn *isert_conn, + struct se_cmd *se_cmd, + struct isert_rdma_wr *rdma_wr, + struct fast_reg_descriptor *fr_desc) { struct ib_send_wr sig_wr, inv_wr; struct ib_send_wr *bad_wr, *wr = NULL; struct pi_context *pi_ctx = fr_desc->pi_ctx; struct ib_sig_attrs sig_attrs; int ret; - u32 key; memset(&sig_attrs, 0, sizeof(sig_attrs)); ret = isert_set_sig_attrs(se_cmd, &sig_attrs); @@ -2701,26 +2622,20 @@ isert_reg_sig_mr(struct isert_conn *isert_conn, struct se_cmd *se_cmd, sig_attrs.check_mask = isert_set_prot_checks(se_cmd->prot_checks); if (!(fr_desc->ind & ISERT_SIG_KEY_VALID)) { - memset(&inv_wr, 0, sizeof(inv_wr)); - inv_wr.opcode = IB_WR_LOCAL_INV; - inv_wr.wr_id = ISER_FASTREG_LI_WRID; - inv_wr.ex.invalidate_rkey = pi_ctx->sig_mr->rkey; + isert_inv_rkey(&inv_wr, pi_ctx->sig_mr); wr = &inv_wr; - /* Bump the key */ - key = (u8)(pi_ctx->sig_mr->rkey & 0x000000FF); - ib_update_fast_reg_key(pi_ctx->sig_mr, ++key); } memset(&sig_wr, 0, sizeof(sig_wr)); sig_wr.opcode = IB_WR_REG_SIG_MR; sig_wr.wr_id = ISER_FASTREG_LI_WRID; - sig_wr.sg_list = data_sge; + sig_wr.sg_list = &rdma_wr->ib_sg[DATA]; sig_wr.num_sge = 1; sig_wr.wr.sig_handover.access_flags = IB_ACCESS_LOCAL_WRITE; sig_wr.wr.sig_handover.sig_attrs = &sig_attrs; sig_wr.wr.sig_handover.sig_mr = pi_ctx->sig_mr; if (se_cmd->t_prot_sg) - sig_wr.wr.sig_handover.prot = prot_sge; + sig_wr.wr.sig_handover.prot = &rdma_wr->ib_sg[PROT]; if (!wr) wr = &sig_wr; @@ -2729,39 +2644,98 @@ isert_reg_sig_mr(struct isert_conn *isert_conn, struct se_cmd *se_cmd, ret = ib_post_send(isert_conn->conn_qp, wr, &bad_wr); if (ret) { - pr_err("fast registration failed, ret:%d\n", ret); + isert_err("fast registration failed, ret:%d\n", ret); goto err; } fr_desc->ind &= ~ISERT_SIG_KEY_VALID; - sig_sge->lkey = pi_ctx->sig_mr->lkey; - sig_sge->addr = 0; - sig_sge->length = se_cmd->data_length; + rdma_wr->ib_sg[SIG].lkey = pi_ctx->sig_mr->lkey; + rdma_wr->ib_sg[SIG].addr = 0; + rdma_wr->ib_sg[SIG].length = se_cmd->data_length; if (se_cmd->prot_op != TARGET_PROT_DIN_STRIP && se_cmd->prot_op != TARGET_PROT_DOUT_INSERT) /* * We have protection guards on the wire * so we need to set a larget transfer */ - sig_sge->length += se_cmd->prot_length; + rdma_wr->ib_sg[SIG].length += se_cmd->prot_length; - pr_debug("sig_sge: addr: 0x%llx length: %u lkey: %x\n", - sig_sge->addr, sig_sge->length, - sig_sge->lkey); + isert_dbg("sig_sge: addr: 0x%llx length: %u lkey: %x\n", + rdma_wr->ib_sg[SIG].addr, rdma_wr->ib_sg[SIG].length, + rdma_wr->ib_sg[SIG].lkey); err: return ret; } static int +isert_handle_prot_cmd(struct isert_conn *isert_conn, + struct isert_cmd *isert_cmd, + struct isert_rdma_wr *wr) +{ + struct isert_device *device = isert_conn->conn_device; + struct se_cmd *se_cmd = &isert_cmd->iscsi_cmd->se_cmd; + int ret; + + if (!wr->fr_desc->pi_ctx) { + ret = isert_create_pi_ctx(wr->fr_desc, + device->ib_device, + isert_conn->conn_pd); + if (ret) { + isert_err("conn %p failed to allocate pi_ctx\n", + isert_conn); + return ret; + } + } + + if (se_cmd->t_prot_sg) { + ret = isert_map_data_buf(isert_conn, isert_cmd, + se_cmd->t_prot_sg, + se_cmd->t_prot_nents, + se_cmd->prot_length, + 0, wr->iser_ib_op, &wr->prot); + if (ret) { + isert_err("conn %p failed to map protection buffer\n", + isert_conn); + return ret; + } + + memset(&wr->ib_sg[PROT], 0, sizeof(wr->ib_sg[PROT])); + ret = isert_fast_reg_mr(isert_conn, wr->fr_desc, &wr->prot, + ISERT_PROT_KEY_VALID, &wr->ib_sg[PROT]); + if (ret) { + isert_err("conn %p failed to fast reg mr\n", + isert_conn); + goto unmap_prot_cmd; + } + } + + ret = isert_reg_sig_mr(isert_conn, se_cmd, wr, wr->fr_desc); + if (ret) { + isert_err("conn %p failed to fast reg mr\n", + isert_conn); + goto unmap_prot_cmd; + } + wr->fr_desc->ind |= ISERT_PROTECTED; + + return 0; + +unmap_prot_cmd: + if (se_cmd->t_prot_sg) + isert_unmap_data_buf(isert_conn, &wr->prot); + + return ret; +} + +static int isert_reg_rdma(struct iscsi_conn *conn, struct iscsi_cmd *cmd, struct isert_rdma_wr *wr) { struct se_cmd *se_cmd = &cmd->se_cmd; struct isert_cmd *isert_cmd = iscsit_priv_cmd(cmd); struct isert_conn *isert_conn = conn->context; - struct ib_sge data_sge; - struct ib_send_wr *send_wr; struct fast_reg_descriptor *fr_desc = NULL; + struct ib_send_wr *send_wr; + struct ib_sge *ib_sg; u32 offset; int ret = 0; unsigned long flags; @@ -2775,8 +2749,7 @@ isert_reg_rdma(struct iscsi_conn *conn, struct iscsi_cmd *cmd, if (ret) return ret; - if (wr->data.dma_nents != 1 || - se_cmd->prot_op != TARGET_PROT_NORMAL) { + if (wr->data.dma_nents != 1 || isert_prot_cmd(isert_conn, se_cmd)) { spin_lock_irqsave(&isert_conn->conn_lock, flags); fr_desc = list_first_entry(&isert_conn->conn_fr_pool, struct fast_reg_descriptor, list); @@ -2786,38 +2759,21 @@ isert_reg_rdma(struct iscsi_conn *conn, struct iscsi_cmd *cmd, } ret = isert_fast_reg_mr(isert_conn, fr_desc, &wr->data, - ISERT_DATA_KEY_VALID, &data_sge); + ISERT_DATA_KEY_VALID, &wr->ib_sg[DATA]); if (ret) goto unmap_cmd; - if (se_cmd->prot_op != TARGET_PROT_NORMAL) { - struct ib_sge prot_sge, sig_sge; - - if (se_cmd->t_prot_sg) { - ret = isert_map_data_buf(isert_conn, isert_cmd, - se_cmd->t_prot_sg, - se_cmd->t_prot_nents, - se_cmd->prot_length, - 0, wr->iser_ib_op, &wr->prot); - if (ret) - goto unmap_cmd; - - ret = isert_fast_reg_mr(isert_conn, fr_desc, &wr->prot, - ISERT_PROT_KEY_VALID, &prot_sge); - if (ret) - goto unmap_prot_cmd; - } - - ret = isert_reg_sig_mr(isert_conn, se_cmd, fr_desc, - &data_sge, &prot_sge, &sig_sge); + if (isert_prot_cmd(isert_conn, se_cmd)) { + ret = isert_handle_prot_cmd(isert_conn, isert_cmd, wr); if (ret) - goto unmap_prot_cmd; + goto unmap_cmd; - fr_desc->ind |= ISERT_PROTECTED; - memcpy(&wr->s_ib_sge, &sig_sge, sizeof(sig_sge)); - } else - memcpy(&wr->s_ib_sge, &data_sge, sizeof(data_sge)); + ib_sg = &wr->ib_sg[SIG]; + } else { + ib_sg = &wr->ib_sg[DATA]; + } + memcpy(&wr->s_ib_sge, ib_sg, sizeof(*ib_sg)); wr->ib_sge = &wr->s_ib_sge; wr->send_wr_num = 1; memset(&wr->s_send_wr, 0, sizeof(*send_wr)); @@ -2827,12 +2783,12 @@ isert_reg_rdma(struct iscsi_conn *conn, struct iscsi_cmd *cmd, send_wr = &isert_cmd->rdma_wr.s_send_wr; send_wr->sg_list = &wr->s_ib_sge; send_wr->num_sge = 1; - send_wr->wr_id = (unsigned long)&isert_cmd->tx_desc; + send_wr->wr_id = (uintptr_t)&isert_cmd->tx_desc; if (wr->iser_ib_op == ISER_IB_RDMA_WRITE) { send_wr->opcode = IB_WR_RDMA_WRITE; send_wr->wr.rdma.remote_addr = isert_cmd->read_va; send_wr->wr.rdma.rkey = isert_cmd->read_stag; - send_wr->send_flags = se_cmd->prot_op == TARGET_PROT_NORMAL ? + send_wr->send_flags = !isert_prot_cmd(isert_conn, se_cmd) ? 0 : IB_SEND_SIGNALED; } else { send_wr->opcode = IB_WR_RDMA_READ; @@ -2842,9 +2798,7 @@ isert_reg_rdma(struct iscsi_conn *conn, struct iscsi_cmd *cmd, } return 0; -unmap_prot_cmd: - if (se_cmd->t_prot_sg) - isert_unmap_data_buf(isert_conn, &wr->prot); + unmap_cmd: if (fr_desc) { spin_lock_irqsave(&isert_conn->conn_lock, flags); @@ -2867,16 +2821,17 @@ isert_put_datain(struct iscsi_conn *conn, struct iscsi_cmd *cmd) struct ib_send_wr *wr_failed; int rc; - pr_debug("Cmd: %p RDMA_WRITE data_length: %u\n", + isert_dbg("Cmd: %p RDMA_WRITE data_length: %u\n", isert_cmd, se_cmd->data_length); + wr->iser_ib_op = ISER_IB_RDMA_WRITE; rc = device->reg_rdma_mem(conn, cmd, wr); if (rc) { - pr_err("Cmd: %p failed to prepare RDMA res\n", isert_cmd); + isert_err("Cmd: %p failed to prepare RDMA res\n", isert_cmd); return rc; } - if (se_cmd->prot_op == TARGET_PROT_NORMAL) { + if (!isert_prot_cmd(isert_conn, se_cmd)) { /* * Build isert_conn->tx_desc for iSCSI response PDU and attach */ @@ -2886,24 +2841,20 @@ isert_put_datain(struct iscsi_conn *conn, struct iscsi_cmd *cmd) &isert_cmd->tx_desc.iscsi_header); isert_init_tx_hdrs(isert_conn, &isert_cmd->tx_desc); isert_init_send_wr(isert_conn, isert_cmd, - &isert_cmd->tx_desc.send_wr, false); + &isert_cmd->tx_desc.send_wr); isert_cmd->rdma_wr.s_send_wr.next = &isert_cmd->tx_desc.send_wr; wr->send_wr_num += 1; } - atomic_add(wr->send_wr_num, &isert_conn->post_send_buf_count); - rc = ib_post_send(isert_conn->conn_qp, wr->send_wr, &wr_failed); - if (rc) { - pr_warn("ib_post_send() failed for IB_WR_RDMA_WRITE\n"); - atomic_sub(wr->send_wr_num, &isert_conn->post_send_buf_count); - } + if (rc) + isert_warn("ib_post_send() failed for IB_WR_RDMA_WRITE\n"); - if (se_cmd->prot_op == TARGET_PROT_NORMAL) - pr_debug("Cmd: %p posted RDMA_WRITE + Response for iSER Data " + if (!isert_prot_cmd(isert_conn, se_cmd)) + isert_dbg("Cmd: %p posted RDMA_WRITE + Response for iSER Data " "READ\n", isert_cmd); else - pr_debug("Cmd: %p posted RDMA_WRITE for iSER Data READ\n", + isert_dbg("Cmd: %p posted RDMA_WRITE for iSER Data READ\n", isert_cmd); return 1; @@ -2920,23 +2871,20 @@ isert_get_dataout(struct iscsi_conn *conn, struct iscsi_cmd *cmd, bool recovery) struct ib_send_wr *wr_failed; int rc; - pr_debug("Cmd: %p RDMA_READ data_length: %u write_data_done: %u\n", + isert_dbg("Cmd: %p RDMA_READ data_length: %u write_data_done: %u\n", isert_cmd, se_cmd->data_length, cmd->write_data_done); wr->iser_ib_op = ISER_IB_RDMA_READ; rc = device->reg_rdma_mem(conn, cmd, wr); if (rc) { - pr_err("Cmd: %p failed to prepare RDMA res\n", isert_cmd); + isert_err("Cmd: %p failed to prepare RDMA res\n", isert_cmd); return rc; } - atomic_add(wr->send_wr_num, &isert_conn->post_send_buf_count); - rc = ib_post_send(isert_conn->conn_qp, wr->send_wr, &wr_failed); - if (rc) { - pr_warn("ib_post_send() failed for IB_WR_RDMA_READ\n"); - atomic_sub(wr->send_wr_num, &isert_conn->post_send_buf_count); - } - pr_debug("Cmd: %p posted RDMA_READ memory for ISER Data WRITE\n", + if (rc) + isert_warn("ib_post_send() failed for IB_WR_RDMA_READ\n"); + + isert_dbg("Cmd: %p posted RDMA_READ memory for ISER Data WRITE\n", isert_cmd); return 0; @@ -2952,7 +2900,7 @@ isert_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state) ret = isert_put_nopin(cmd, conn, false); break; default: - pr_err("Unknown immediate state: 0x%02x\n", state); + isert_err("Unknown immediate state: 0x%02x\n", state); ret = -EINVAL; break; } @@ -2963,15 +2911,14 @@ isert_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state) static int isert_response_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state) { + struct isert_conn *isert_conn = conn->context; int ret; switch (state) { case ISTATE_SEND_LOGOUTRSP: ret = isert_put_logout_rsp(cmd, conn); - if (!ret) { - pr_debug("Returning iSER Logout -EAGAIN\n"); - ret = -EAGAIN; - } + if (!ret) + isert_conn->logout_posted = true; break; case ISTATE_SEND_NOPIN: ret = isert_put_nopin(cmd, conn, true); @@ -2993,7 +2940,7 @@ isert_response_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state) ret = isert_put_response(conn, cmd); break; default: - pr_err("Unknown response state: 0x%02x\n", state); + isert_err("Unknown response state: 0x%02x\n", state); ret = -EINVAL; break; } @@ -3001,27 +2948,64 @@ isert_response_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state) return ret; } +struct rdma_cm_id * +isert_setup_id(struct isert_np *isert_np) +{ + struct iscsi_np *np = isert_np->np; + struct rdma_cm_id *id; + struct sockaddr *sa; + int ret; + + sa = (struct sockaddr *)&np->np_sockaddr; + isert_dbg("ksockaddr: %p, sa: %p\n", &np->np_sockaddr, sa); + + id = rdma_create_id(isert_cma_handler, isert_np, + RDMA_PS_TCP, IB_QPT_RC); + if (IS_ERR(id)) { + isert_err("rdma_create_id() failed: %ld\n", PTR_ERR(id)); + ret = PTR_ERR(id); + goto out; + } + isert_dbg("id %p context %p\n", id, id->context); + + ret = rdma_bind_addr(id, sa); + if (ret) { + isert_err("rdma_bind_addr() failed: %d\n", ret); + goto out_id; + } + + ret = rdma_listen(id, ISERT_RDMA_LISTEN_BACKLOG); + if (ret) { + isert_err("rdma_listen() failed: %d\n", ret); + goto out_id; + } + + return id; +out_id: + rdma_destroy_id(id); +out: + return ERR_PTR(ret); +} + static int isert_setup_np(struct iscsi_np *np, struct __kernel_sockaddr_storage *ksockaddr) { struct isert_np *isert_np; struct rdma_cm_id *isert_lid; - struct sockaddr *sa; int ret; isert_np = kzalloc(sizeof(struct isert_np), GFP_KERNEL); if (!isert_np) { - pr_err("Unable to allocate struct isert_np\n"); + isert_err("Unable to allocate struct isert_np\n"); return -ENOMEM; } sema_init(&isert_np->np_sem, 0); mutex_init(&isert_np->np_accept_mutex); INIT_LIST_HEAD(&isert_np->np_accept_list); init_completion(&isert_np->np_login_comp); + isert_np->np = np; - sa = (struct sockaddr *)ksockaddr; - pr_debug("ksockaddr: %p, sa: %p\n", ksockaddr, sa); /* * Setup the np->np_sockaddr from the passed sockaddr setup * in iscsi_target_configfs.c code.. @@ -3029,37 +3013,20 @@ isert_setup_np(struct iscsi_np *np, memcpy(&np->np_sockaddr, ksockaddr, sizeof(struct __kernel_sockaddr_storage)); - isert_lid = rdma_create_id(isert_cma_handler, np, RDMA_PS_TCP, - IB_QPT_RC); + isert_lid = isert_setup_id(isert_np); if (IS_ERR(isert_lid)) { - pr_err("rdma_create_id() for isert_listen_handler failed: %ld\n", - PTR_ERR(isert_lid)); ret = PTR_ERR(isert_lid); goto out; } - ret = rdma_bind_addr(isert_lid, sa); - if (ret) { - pr_err("rdma_bind_addr() for isert_lid failed: %d\n", ret); - goto out_lid; - } - - ret = rdma_listen(isert_lid, ISERT_RDMA_LISTEN_BACKLOG); - if (ret) { - pr_err("rdma_listen() for isert_lid failed: %d\n", ret); - goto out_lid; - } - isert_np->np_cm_id = isert_lid; np->np_context = isert_np; - pr_debug("Setup isert_lid->context: %p\n", isert_lid->context); return 0; -out_lid: - rdma_destroy_id(isert_lid); out: kfree(isert_np); + return ret; } @@ -3075,16 +3042,12 @@ isert_rdma_accept(struct isert_conn *isert_conn) cp.retry_count = 7; cp.rnr_retry_count = 7; - pr_debug("Before rdma_accept >>>>>>>>>>>>>>>>>>>>.\n"); - ret = rdma_accept(cm_id, &cp); if (ret) { - pr_err("rdma_accept() failed with: %d\n", ret); + isert_err("rdma_accept() failed with: %d\n", ret); return ret; } - pr_debug("After rdma_accept >>>>>>>>>>>>>>>>>>>>>.\n"); - return 0; } @@ -3094,7 +3057,15 @@ isert_get_login_rx(struct iscsi_conn *conn, struct iscsi_login *login) struct isert_conn *isert_conn = (struct isert_conn *)conn->context; int ret; - pr_debug("isert_get_login_rx before conn_login_comp conn: %p\n", conn); + isert_info("before login_req comp conn: %p\n", isert_conn); + ret = wait_for_completion_interruptible(&isert_conn->login_req_comp); + if (ret) { + isert_err("isert_conn %p interrupted before got login req\n", + isert_conn); + return ret; + } + reinit_completion(&isert_conn->login_req_comp); + /* * For login requests after the first PDU, isert_rx_login_req() will * kick schedule_delayed_work(&conn->login_work) as the packet is @@ -3104,11 +3075,15 @@ isert_get_login_rx(struct iscsi_conn *conn, struct iscsi_login *login) if (!login->first_request) return 0; + isert_rx_login_req(isert_conn); + + isert_info("before conn_login_comp conn: %p\n", conn); ret = wait_for_completion_interruptible(&isert_conn->conn_login_comp); if (ret) return ret; - pr_debug("isert_get_login_rx processing login->req: %p\n", login->req); + isert_info("processing login->req: %p\n", login->req); + return 0; } @@ -3161,7 +3136,7 @@ accept_wait: spin_lock_bh(&np->np_thread_lock); if (np->np_thread_state >= ISCSI_NP_THREAD_RESET) { spin_unlock_bh(&np->np_thread_lock); - pr_debug("np_thread_state %d for isert_accept_np\n", + isert_dbg("np_thread_state %d for isert_accept_np\n", np->np_thread_state); /** * No point in stalling here when np_thread @@ -3186,17 +3161,10 @@ accept_wait: isert_conn->conn = conn; max_accept = 0; - ret = isert_rdma_post_recvl(isert_conn); - if (ret) - return ret; - - ret = isert_rdma_accept(isert_conn); - if (ret) - return ret; - isert_set_conn_info(np, conn, isert_conn); - pr_debug("Processing isert_accept_np: isert_conn: %p\n", isert_conn); + isert_dbg("Processing isert_conn: %p\n", isert_conn); + return 0; } @@ -3204,25 +3172,103 @@ static void isert_free_np(struct iscsi_np *np) { struct isert_np *isert_np = (struct isert_np *)np->np_context; + struct isert_conn *isert_conn, *n; if (isert_np->np_cm_id) rdma_destroy_id(isert_np->np_cm_id); + /* + * FIXME: At this point we don't have a good way to insure + * that at this point we don't have hanging connections that + * completed RDMA establishment but didn't start iscsi login + * process. So work-around this by cleaning up what ever piled + * up in np_accept_list. + */ + mutex_lock(&isert_np->np_accept_mutex); + if (!list_empty(&isert_np->np_accept_list)) { + isert_info("Still have isert connections, cleaning up...\n"); + list_for_each_entry_safe(isert_conn, n, + &isert_np->np_accept_list, + conn_accept_node) { + isert_info("cleaning isert_conn %p state (%d)\n", + isert_conn, isert_conn->state); + isert_connect_release(isert_conn); + } + } + mutex_unlock(&isert_np->np_accept_mutex); + np->np_context = NULL; kfree(isert_np); } +static void isert_release_work(struct work_struct *work) +{ + struct isert_conn *isert_conn = container_of(work, + struct isert_conn, + release_work); + + isert_info("Starting release conn %p\n", isert_conn); + + wait_for_completion(&isert_conn->conn_wait); + + mutex_lock(&isert_conn->conn_mutex); + isert_conn->state = ISER_CONN_DOWN; + mutex_unlock(&isert_conn->conn_mutex); + + isert_info("Destroying conn %p\n", isert_conn); + isert_put_conn(isert_conn); +} + +static void +isert_wait4logout(struct isert_conn *isert_conn) +{ + struct iscsi_conn *conn = isert_conn->conn; + + isert_info("conn %p\n", isert_conn); + + if (isert_conn->logout_posted) { + isert_info("conn %p wait for conn_logout_comp\n", isert_conn); + wait_for_completion_timeout(&conn->conn_logout_comp, + SECONDS_FOR_LOGOUT_COMP * HZ); + } +} + +static void +isert_wait4cmds(struct iscsi_conn *conn) +{ + isert_info("iscsi_conn %p\n", conn); + + if (conn->sess) { + target_sess_cmd_list_set_waiting(conn->sess->se_sess); + target_wait_for_sess_cmds(conn->sess->se_sess); + } +} + +static void +isert_wait4flush(struct isert_conn *isert_conn) +{ + struct ib_recv_wr *bad_wr; + + isert_info("conn %p\n", isert_conn); + + init_completion(&isert_conn->conn_wait_comp_err); + isert_conn->beacon.wr_id = ISER_BEACON_WRID; + /* post an indication that all flush errors were consumed */ + if (ib_post_recv(isert_conn->conn_qp, &isert_conn->beacon, &bad_wr)) { + isert_err("conn %p failed to post beacon", isert_conn); + return; + } + + wait_for_completion(&isert_conn->conn_wait_comp_err); +} + static void isert_wait_conn(struct iscsi_conn *conn) { struct isert_conn *isert_conn = conn->context; - pr_debug("isert_wait_conn: Starting \n"); + isert_info("Starting conn %p\n", isert_conn); mutex_lock(&isert_conn->conn_mutex); - if (isert_conn->conn_cm_id && !isert_conn->disconnect) { - pr_debug("Calling rdma_disconnect from isert_wait_conn\n"); - rdma_disconnect(isert_conn->conn_cm_id); - } /* * Only wait for conn_wait_comp_err if the isert_conn made it * into full feature phase.. @@ -3231,14 +3277,15 @@ static void isert_wait_conn(struct iscsi_conn *conn) mutex_unlock(&isert_conn->conn_mutex); return; } - if (isert_conn->state == ISER_CONN_UP) - isert_conn->state = ISER_CONN_TERMINATING; + isert_conn_terminate(isert_conn); mutex_unlock(&isert_conn->conn_mutex); - wait_for_completion(&isert_conn->conn_wait_comp_err); + isert_wait4cmds(conn); + isert_wait4flush(isert_conn); + isert_wait4logout(isert_conn); - wait_for_completion(&isert_conn->conn_wait); - isert_put_conn(isert_conn); + INIT_WORK(&isert_conn->release_work, isert_release_work); + queue_work(isert_release_wq, &isert_conn->release_work); } static void isert_free_conn(struct iscsi_conn *conn) @@ -3273,35 +3320,39 @@ static int __init isert_init(void) { int ret; - isert_rx_wq = alloc_workqueue("isert_rx_wq", 0, 0); - if (!isert_rx_wq) { - pr_err("Unable to allocate isert_rx_wq\n"); + isert_comp_wq = alloc_workqueue("isert_comp_wq", 0, 0); + if (!isert_comp_wq) { + isert_err("Unable to allocate isert_comp_wq\n"); + ret = -ENOMEM; return -ENOMEM; } - isert_comp_wq = alloc_workqueue("isert_comp_wq", 0, 0); - if (!isert_comp_wq) { - pr_err("Unable to allocate isert_comp_wq\n"); + isert_release_wq = alloc_workqueue("isert_release_wq", WQ_UNBOUND, + WQ_UNBOUND_MAX_ACTIVE); + if (!isert_release_wq) { + isert_err("Unable to allocate isert_release_wq\n"); ret = -ENOMEM; - goto destroy_rx_wq; + goto destroy_comp_wq; } iscsit_register_transport(&iser_target_transport); - pr_debug("iSER_TARGET[0] - Loaded iser_target_transport\n"); + isert_info("iSER_TARGET[0] - Loaded iser_target_transport\n"); + return 0; -destroy_rx_wq: - destroy_workqueue(isert_rx_wq); +destroy_comp_wq: + destroy_workqueue(isert_comp_wq); + return ret; } static void __exit isert_exit(void) { flush_scheduled_work(); + destroy_workqueue(isert_release_wq); destroy_workqueue(isert_comp_wq); - destroy_workqueue(isert_rx_wq); iscsit_unregister_transport(&iser_target_transport); - pr_debug("iSER_TARGET[0] - Released iser_target_transport\n"); + isert_info("iSER_TARGET[0] - Released iser_target_transport\n"); } MODULE_DESCRIPTION("iSER-Target for mainline target infrastructure"); diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h index 04f51f7bf614..8dc8415d152d 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.h +++ b/drivers/infiniband/ulp/isert/ib_isert.h @@ -4,9 +4,37 @@ #include <rdma/ib_verbs.h> #include <rdma/rdma_cm.h> +#define DRV_NAME "isert" +#define PFX DRV_NAME ": " + +#define isert_dbg(fmt, arg...) \ + do { \ + if (unlikely(isert_debug_level > 2)) \ + printk(KERN_DEBUG PFX "%s: " fmt,\ + __func__ , ## arg); \ + } while (0) + +#define isert_warn(fmt, arg...) \ + do { \ + if (unlikely(isert_debug_level > 0)) \ + pr_warn(PFX "%s: " fmt, \ + __func__ , ## arg); \ + } while (0) + +#define isert_info(fmt, arg...) \ + do { \ + if (unlikely(isert_debug_level > 1)) \ + pr_info(PFX "%s: " fmt, \ + __func__ , ## arg); \ + } while (0) + +#define isert_err(fmt, arg...) \ + pr_err(PFX "%s: " fmt, __func__ , ## arg) + #define ISERT_RDMA_LISTEN_BACKLOG 10 #define ISCSI_ISER_SG_TABLESIZE 256 #define ISER_FASTREG_LI_WRID 0xffffffffffffffffULL +#define ISER_BEACON_WRID 0xfffffffffffffffeULL enum isert_desc_type { ISCSI_TX_CONTROL, @@ -23,6 +51,7 @@ enum iser_ib_op_code { enum iser_conn_state { ISER_CONN_INIT, ISER_CONN_UP, + ISER_CONN_FULL_FEATURE, ISER_CONN_TERMINATING, ISER_CONN_DOWN, }; @@ -44,9 +73,6 @@ struct iser_tx_desc { struct ib_sge tx_sg[2]; int num_sge; struct isert_cmd *isert_cmd; - struct llist_node *comp_llnode_batch; - struct llist_node comp_llnode; - bool llnode_active; struct ib_send_wr send_wr; } __packed; @@ -81,6 +107,12 @@ struct isert_data_buf { enum dma_data_direction dma_dir; }; +enum { + DATA = 0, + PROT = 1, + SIG = 2, +}; + struct isert_rdma_wr { struct list_head wr_list; struct isert_cmd *isert_cmd; @@ -90,6 +122,7 @@ struct isert_rdma_wr { int send_wr_num; struct ib_send_wr *send_wr; struct ib_send_wr s_send_wr; + struct ib_sge ib_sg[3]; struct isert_data_buf data; struct isert_data_buf prot; struct fast_reg_descriptor *fr_desc; @@ -117,14 +150,15 @@ struct isert_device; struct isert_conn { enum iser_conn_state state; int post_recv_buf_count; - atomic_t post_send_buf_count; u32 responder_resources; u32 initiator_depth; + bool pi_support; u32 max_sge; char *login_buf; char *login_req_buf; char *login_rsp_buf; u64 login_req_dma; + int login_req_len; u64 login_rsp_dma; unsigned int conn_rx_desc_head; struct iser_rx_desc *conn_rx_descs; @@ -132,13 +166,13 @@ struct isert_conn { struct iscsi_conn *conn; struct list_head conn_accept_node; struct completion conn_login_comp; + struct completion login_req_comp; struct iser_tx_desc conn_login_tx_desc; struct rdma_cm_id *conn_cm_id; struct ib_pd *conn_pd; struct ib_mr *conn_mr; struct ib_qp *conn_qp; struct isert_device *conn_device; - struct work_struct conn_logout_work; struct mutex conn_mutex; struct completion conn_wait; struct completion conn_wait_comp_err; @@ -147,31 +181,38 @@ struct isert_conn { int conn_fr_pool_size; /* lock to protect fastreg pool */ spinlock_t conn_lock; -#define ISERT_COMP_BATCH_COUNT 8 - int conn_comp_batch; - struct llist_head conn_comp_llist; - bool disconnect; + struct work_struct release_work; + struct ib_recv_wr beacon; + bool logout_posted; }; #define ISERT_MAX_CQ 64 -struct isert_cq_desc { - struct isert_device *device; - int cq_index; - struct work_struct cq_rx_work; - struct work_struct cq_tx_work; +/** + * struct isert_comp - iSER completion context + * + * @device: pointer to device handle + * @cq: completion queue + * @wcs: work completion array + * @active_qps: Number of active QPs attached + * to completion context + * @work: completion work handle + */ +struct isert_comp { + struct isert_device *device; + struct ib_cq *cq; + struct ib_wc wcs[16]; + int active_qps; + struct work_struct work; }; struct isert_device { int use_fastreg; bool pi_capable; - int cqs_used; int refcount; - int cq_active_qps[ISERT_MAX_CQ]; struct ib_device *ib_device; - struct ib_cq *dev_rx_cq[ISERT_MAX_CQ]; - struct ib_cq *dev_tx_cq[ISERT_MAX_CQ]; - struct isert_cq_desc *cq_desc; + struct isert_comp *comps; + int comps_used; struct list_head dev_node; struct ib_device_attr dev_attr; int (*reg_rdma_mem)(struct iscsi_conn *conn, @@ -182,6 +223,7 @@ struct isert_device { }; struct isert_np { + struct iscsi_np *np; struct semaphore np_sem; struct rdma_cm_id *np_cm_id; struct mutex np_accept_mutex; diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 5461924c9f10..0747c0595a9d 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -2740,7 +2740,6 @@ static struct scsi_host_template srp_template = { .info = srp_target_info, .queuecommand = srp_queuecommand, .change_queue_depth = srp_change_queue_depth, - .change_queue_type = scsi_change_queue_type, .eh_abort_handler = srp_abort, .eh_device_reset_handler = srp_reset_device, .eh_host_reset_handler = srp_reset_host, @@ -2929,7 +2928,7 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) return -ENOMEM; sep_opt = options; - while ((p = strsep(&sep_opt, ",")) != NULL) { + while ((p = strsep(&sep_opt, ",\n")) != NULL) { if (!*p) continue; diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index dc829682701a..eb694ddad79f 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -1708,17 +1708,17 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch, switch (srp_cmd->task_attr) { case SRP_CMD_SIMPLE_Q: - cmd->sam_task_attr = MSG_SIMPLE_TAG; + cmd->sam_task_attr = TCM_SIMPLE_TAG; break; case SRP_CMD_ORDERED_Q: default: - cmd->sam_task_attr = MSG_ORDERED_TAG; + cmd->sam_task_attr = TCM_ORDERED_TAG; break; case SRP_CMD_HEAD_OF_Q: - cmd->sam_task_attr = MSG_HEAD_TAG; + cmd->sam_task_attr = TCM_HEAD_TAG; break; case SRP_CMD_ACA: - cmd->sam_task_attr = MSG_ACA_TAG; + cmd->sam_task_attr = TCM_ACA_TAG; break; } @@ -1733,7 +1733,7 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch, sizeof(srp_cmd->lun)); rc = target_submit_cmd(cmd, ch->sess, srp_cmd->cdb, &send_ioctx->sense_data[0], unpacked_lun, data_len, - MSG_SIMPLE_TAG, dir, TARGET_SCF_ACK_KREF); + TCM_SIMPLE_TAG, dir, TARGET_SCF_ACK_KREF); if (rc != 0) { ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; goto send_sense; diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 8afa28e4570e..18d4b2c8fe55 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -28,6 +28,13 @@ #include <linux/cdev.h> #include "input-compat.h" +enum evdev_clock_type { + EV_CLK_REAL = 0, + EV_CLK_MONO, + EV_CLK_BOOT, + EV_CLK_MAX +}; + struct evdev { int open; struct input_handle handle; @@ -49,12 +56,32 @@ struct evdev_client { struct fasync_struct *fasync; struct evdev *evdev; struct list_head node; - int clkid; + int clk_type; bool revoked; unsigned int bufsize; struct input_event buffer[]; }; +static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid) +{ + switch (clkid) { + + case CLOCK_REALTIME: + client->clk_type = EV_CLK_REAL; + break; + case CLOCK_MONOTONIC: + client->clk_type = EV_CLK_MONO; + break; + case CLOCK_BOOTTIME: + client->clk_type = EV_CLK_BOOT; + break; + default: + return -EINVAL; + } + + return 0; +} + /* flush queued events of type @type, caller must hold client->buffer_lock */ static void __evdev_flush_queue(struct evdev_client *client, unsigned int type) { @@ -108,8 +135,11 @@ static void evdev_queue_syn_dropped(struct evdev_client *client) struct input_event ev; ktime_t time; - time = (client->clkid == CLOCK_MONOTONIC) ? - ktime_get() : ktime_get_real(); + time = client->clk_type == EV_CLK_REAL ? + ktime_get_real() : + client->clk_type == EV_CLK_MONO ? + ktime_get() : + ktime_get_boottime(); ev.time = ktime_to_timeval(time); ev.type = EV_SYN; @@ -159,7 +189,7 @@ static void __pass_event(struct evdev_client *client, static void evdev_pass_values(struct evdev_client *client, const struct input_value *vals, unsigned int count, - ktime_t mono, ktime_t real) + ktime_t *ev_time) { struct evdev *evdev = client->evdev; const struct input_value *v; @@ -169,8 +199,7 @@ static void evdev_pass_values(struct evdev_client *client, if (client->revoked) return; - event.time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ? - mono : real); + event.time = ktime_to_timeval(ev_time[client->clk_type]); /* Interrupts are disabled, just acquire the lock. */ spin_lock(&client->buffer_lock); @@ -198,21 +227,22 @@ static void evdev_events(struct input_handle *handle, { struct evdev *evdev = handle->private; struct evdev_client *client; - ktime_t time_mono, time_real; + ktime_t ev_time[EV_CLK_MAX]; - time_mono = ktime_get(); - time_real = ktime_mono_to_real(time_mono); + ev_time[EV_CLK_MONO] = ktime_get(); + ev_time[EV_CLK_REAL] = ktime_mono_to_real(ev_time[EV_CLK_MONO]); + ev_time[EV_CLK_BOOT] = ktime_mono_to_any(ev_time[EV_CLK_MONO], + TK_OFFS_BOOT); rcu_read_lock(); client = rcu_dereference(evdev->grab); if (client) - evdev_pass_values(client, vals, count, time_mono, time_real); + evdev_pass_values(client, vals, count, ev_time); else list_for_each_entry_rcu(client, &evdev->client_list, node) - evdev_pass_values(client, vals, count, - time_mono, time_real); + evdev_pass_values(client, vals, count, ev_time); rcu_read_unlock(); } @@ -877,10 +907,8 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, case EVIOCSCLOCKID: if (copy_from_user(&i, p, sizeof(unsigned int))) return -EFAULT; - if (i != CLOCK_MONOTONIC && i != CLOCK_REALTIME) - return -EINVAL; - client->clkid = i; - return 0; + + return evdev_set_clk_type(client, i); case EVIOCGKEYCODE: return evdev_handle_get_keycode(dev, p); diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index e29c04e2aff4..e853a2134680 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -527,14 +527,14 @@ EXPORT_SYMBOL(gameport_set_phys); */ static void gameport_init_port(struct gameport *gameport) { - static atomic_t gameport_no = ATOMIC_INIT(0); + static atomic_t gameport_no = ATOMIC_INIT(-1); __module_get(THIS_MODULE); mutex_init(&gameport->drv_mutex); device_initialize(&gameport->dev); dev_set_name(&gameport->dev, "gameport%lu", - (unsigned long)atomic_inc_return(&gameport_no) - 1); + (unsigned long)atomic_inc_return(&gameport_no)); gameport->dev.bus = &gameport_bus; gameport->dev.release = gameport_release_port; if (gameport->parent) diff --git a/drivers/input/input.c b/drivers/input/input.c index 0f175f55782b..213e3a1903ee 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -1775,7 +1775,7 @@ EXPORT_SYMBOL_GPL(input_class); */ struct input_dev *input_allocate_device(void) { - static atomic_t input_no = ATOMIC_INIT(0); + static atomic_t input_no = ATOMIC_INIT(-1); struct input_dev *dev; dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL); @@ -1790,7 +1790,7 @@ struct input_dev *input_allocate_device(void) INIT_LIST_HEAD(&dev->node); dev_set_name(&dev->dev, "input%lu", - (unsigned long) atomic_inc_return(&input_no) - 1); + (unsigned long)atomic_inc_return(&input_no)); __module_get(THIS_MODULE); } @@ -1974,18 +1974,22 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev) events = mt_slots + 1; /* count SYN_MT_REPORT and SYN_REPORT */ - for (i = 0; i < ABS_CNT; i++) { - if (test_bit(i, dev->absbit)) { - if (input_is_mt_axis(i)) - events += mt_slots; - else - events++; + if (test_bit(EV_ABS, dev->evbit)) { + for (i = 0; i < ABS_CNT; i++) { + if (test_bit(i, dev->absbit)) { + if (input_is_mt_axis(i)) + events += mt_slots; + else + events++; + } } } - for (i = 0; i < REL_CNT; i++) - if (test_bit(i, dev->relbit)) - events++; + if (test_bit(EV_REL, dev->evbit)) { + for (i = 0; i < REL_CNT; i++) + if (test_bit(i, dev->relbit)) + events++; + } /* Make room for KEY and MSC events */ events += 7; diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index fc55f0d15b70..3aa2f3f3da5b 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -886,8 +886,8 @@ static void xpad_led_set(struct led_classdev *led_cdev, static int xpad_led_probe(struct usb_xpad *xpad) { - static atomic_t led_seq = ATOMIC_INIT(0); - long led_no; + static atomic_t led_seq = ATOMIC_INIT(-1); + unsigned long led_no; struct xpad_led *led; struct led_classdev *led_cdev; int error; @@ -899,9 +899,9 @@ static int xpad_led_probe(struct usb_xpad *xpad) if (!led) return -ENOMEM; - led_no = (long)atomic_inc_return(&led_seq) - 1; + led_no = atomic_inc_return(&led_seq); - snprintf(led->name, sizeof(led->name), "xpad%ld", led_no); + snprintf(led->name, sizeof(led->name), "xpad%lu", led_no); led->xpad = xpad; led_cdev = &led->led_cdev; diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index a3958c63d7d5..a5d9b3f3c871 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -559,6 +559,7 @@ config KEYBOARD_SH_KEYSC config KEYBOARD_STMPE tristate "STMPE keypad support" depends on MFD_STMPE + depends on OF select INPUT_MATRIXKMAP help Say Y here if you want to use the keypad controller on STMPE I/O @@ -665,14 +666,14 @@ config KEYBOARD_CROS_EC To compile this driver as a module, choose M here: the module will be called cros_ec_keyb. -config KEYBOARD_CAP1106 - tristate "Microchip CAP1106 touch sensor" +config KEYBOARD_CAP11XX + tristate "Microchip CAP11XX based touch sensors" depends on OF && I2C select REGMAP_I2C help - Say Y here to enable the CAP1106 touch sensor driver. + Say Y here to enable the CAP11XX touch sensor driver. To compile this driver as a module, choose M here: the - module will be called cap1106. + module will be called cap11xx. endif diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 0a3345634d79..febafa527eb6 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -11,7 +11,7 @@ obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o -obj-$(CONFIG_KEYBOARD_CAP1106) += cap1106.o +obj-$(CONFIG_KEYBOARD_CAP11XX) += cap11xx.o obj-$(CONFIG_KEYBOARD_CLPS711X) += clps711x-keypad.o obj-$(CONFIG_KEYBOARD_CROS_EC) += cros_ec_keyb.o obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c index d3b8c58fcfdb..e04a3b4e55d6 100644 --- a/drivers/input/keyboard/amikbd.c +++ b/drivers/input/keyboard/amikbd.c @@ -45,6 +45,7 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); MODULE_DESCRIPTION("Amiga keyboard driver"); MODULE_LICENSE("GPL"); +#ifdef CONFIG_HW_CONSOLE static unsigned char amikbd_keycode[0x78] __initdata = { [0] = KEY_GRAVE, [1] = KEY_1, @@ -144,6 +145,32 @@ static unsigned char amikbd_keycode[0x78] __initdata = { [103] = KEY_RIGHTMETA }; +static void __init amikbd_init_console_keymaps(void) +{ + /* We can spare 512 bytes on stack for temp_map in init path. */ + unsigned short temp_map[NR_KEYS]; + int i, j; + + for (i = 0; i < MAX_NR_KEYMAPS; i++) { + if (!key_maps[i]) + continue; + memset(temp_map, 0, sizeof(temp_map)); + for (j = 0; j < 0x78; j++) { + if (!amikbd_keycode[j]) + continue; + temp_map[j] = key_maps[i][amikbd_keycode[j]]; + } + for (j = 0; j < NR_KEYS; j++) { + if (!temp_map[j]) + temp_map[j] = 0xf200; + } + memcpy(key_maps[i], temp_map, sizeof(temp_map)); + } +} +#else /* !CONFIG_HW_CONSOLE */ +static inline void amikbd_init_console_keymaps(void) {} +#endif /* !CONFIG_HW_CONSOLE */ + static const char *amikbd_messages[8] = { [0] = KERN_ALERT "amikbd: Ctrl-Amiga-Amiga reset warning!!\n", [1] = KERN_WARNING "amikbd: keyboard lost sync\n", @@ -186,7 +213,7 @@ static irqreturn_t amikbd_interrupt(int irq, void *data) static int __init amikbd_probe(struct platform_device *pdev) { struct input_dev *dev; - int i, j, err; + int i, err; dev = input_allocate_device(); if (!dev) { @@ -207,22 +234,8 @@ static int __init amikbd_probe(struct platform_device *pdev) for (i = 0; i < 0x78; i++) set_bit(i, dev->keybit); - for (i = 0; i < MAX_NR_KEYMAPS; i++) { - static u_short temp_map[NR_KEYS] __initdata; - if (!key_maps[i]) - continue; - memset(temp_map, 0, sizeof(temp_map)); - for (j = 0; j < 0x78; j++) { - if (!amikbd_keycode[j]) - continue; - temp_map[j] = key_maps[i][amikbd_keycode[j]]; - } - for (j = 0; j < NR_KEYS; j++) { - if (!temp_map[j]) - temp_map[j] = 0xf200; - } - memcpy(key_maps[i], temp_map, sizeof(temp_map)); - } + amikbd_init_console_keymaps(); + ciaa.cra &= ~0x41; /* serial data in, turn off TA */ err = request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", dev); diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 6f5d79569136..e27a25892db4 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -456,8 +456,9 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, keycode = atkbd->keycode[code]; - if (keycode != ATKBD_KEY_NULL) - input_event(dev, EV_MSC, MSC_SCAN, code); + if (!(atkbd->release && test_bit(code, atkbd->force_release_mask))) + if (keycode != ATKBD_KEY_NULL) + input_event(dev, EV_MSC, MSC_SCAN, code); switch (keycode) { case ATKBD_KEY_NULL: @@ -511,6 +512,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, input_sync(dev); if (value && test_bit(code, atkbd->force_release_mask)) { + input_event(dev, EV_MSC, MSC_SCAN, code); input_report_key(dev, keycode, 0); input_sync(dev); } diff --git a/drivers/input/keyboard/cap1106.c b/drivers/input/keyboard/cap1106.c deleted file mode 100644 index d70b65a14ced..000000000000 --- a/drivers/input/keyboard/cap1106.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Input driver for Microchip CAP1106, 6 channel capacitive touch sensor - * - * http://www.microchip.com/wwwproducts/Devices.aspx?product=CAP1106 - * - * (c) 2014 Daniel Mack <linux@zonque.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/input.h> -#include <linux/of_irq.h> -#include <linux/regmap.h> -#include <linux/i2c.h> -#include <linux/gpio/consumer.h> - -#define CAP1106_REG_MAIN_CONTROL 0x00 -#define CAP1106_REG_MAIN_CONTROL_GAIN_SHIFT (6) -#define CAP1106_REG_MAIN_CONTROL_GAIN_MASK (0xc0) -#define CAP1106_REG_MAIN_CONTROL_DLSEEP BIT(4) -#define CAP1106_REG_GENERAL_STATUS 0x02 -#define CAP1106_REG_SENSOR_INPUT 0x03 -#define CAP1106_REG_NOISE_FLAG_STATUS 0x0a -#define CAP1106_REG_SENOR_DELTA(X) (0x10 + (X)) -#define CAP1106_REG_SENSITIVITY_CONTROL 0x1f -#define CAP1106_REG_CONFIG 0x20 -#define CAP1106_REG_SENSOR_ENABLE 0x21 -#define CAP1106_REG_SENSOR_CONFIG 0x22 -#define CAP1106_REG_SENSOR_CONFIG2 0x23 -#define CAP1106_REG_SAMPLING_CONFIG 0x24 -#define CAP1106_REG_CALIBRATION 0x26 -#define CAP1106_REG_INT_ENABLE 0x27 -#define CAP1106_REG_REPEAT_RATE 0x28 -#define CAP1106_REG_MT_CONFIG 0x2a -#define CAP1106_REG_MT_PATTERN_CONFIG 0x2b -#define CAP1106_REG_MT_PATTERN 0x2d -#define CAP1106_REG_RECALIB_CONFIG 0x2f -#define CAP1106_REG_SENSOR_THRESH(X) (0x30 + (X)) -#define CAP1106_REG_SENSOR_NOISE_THRESH 0x38 -#define CAP1106_REG_STANDBY_CHANNEL 0x40 -#define CAP1106_REG_STANDBY_CONFIG 0x41 -#define CAP1106_REG_STANDBY_SENSITIVITY 0x42 -#define CAP1106_REG_STANDBY_THRESH 0x43 -#define CAP1106_REG_CONFIG2 0x44 -#define CAP1106_REG_SENSOR_BASE_CNT(X) (0x50 + (X)) -#define CAP1106_REG_SENSOR_CALIB (0xb1 + (X)) -#define CAP1106_REG_SENSOR_CALIB_LSB1 0xb9 -#define CAP1106_REG_SENSOR_CALIB_LSB2 0xba -#define CAP1106_REG_PRODUCT_ID 0xfd -#define CAP1106_REG_MANUFACTURER_ID 0xfe -#define CAP1106_REG_REVISION 0xff - -#define CAP1106_NUM_CHN 6 -#define CAP1106_PRODUCT_ID 0x55 -#define CAP1106_MANUFACTURER_ID 0x5d - -struct cap1106_priv { - struct regmap *regmap; - struct input_dev *idev; - - /* config */ - unsigned short keycodes[CAP1106_NUM_CHN]; -}; - -static const struct reg_default cap1106_reg_defaults[] = { - { CAP1106_REG_MAIN_CONTROL, 0x00 }, - { CAP1106_REG_GENERAL_STATUS, 0x00 }, - { CAP1106_REG_SENSOR_INPUT, 0x00 }, - { CAP1106_REG_NOISE_FLAG_STATUS, 0x00 }, - { CAP1106_REG_SENSITIVITY_CONTROL, 0x2f }, - { CAP1106_REG_CONFIG, 0x20 }, - { CAP1106_REG_SENSOR_ENABLE, 0x3f }, - { CAP1106_REG_SENSOR_CONFIG, 0xa4 }, - { CAP1106_REG_SENSOR_CONFIG2, 0x07 }, - { CAP1106_REG_SAMPLING_CONFIG, 0x39 }, - { CAP1106_REG_CALIBRATION, 0x00 }, - { CAP1106_REG_INT_ENABLE, 0x3f }, - { CAP1106_REG_REPEAT_RATE, 0x3f }, - { CAP1106_REG_MT_CONFIG, 0x80 }, - { CAP1106_REG_MT_PATTERN_CONFIG, 0x00 }, - { CAP1106_REG_MT_PATTERN, 0x3f }, - { CAP1106_REG_RECALIB_CONFIG, 0x8a }, - { CAP1106_REG_SENSOR_THRESH(0), 0x40 }, - { CAP1106_REG_SENSOR_THRESH(1), 0x40 }, - { CAP1106_REG_SENSOR_THRESH(2), 0x40 }, - { CAP1106_REG_SENSOR_THRESH(3), 0x40 }, - { CAP1106_REG_SENSOR_THRESH(4), 0x40 }, - { CAP1106_REG_SENSOR_THRESH(5), 0x40 }, - { CAP1106_REG_SENSOR_NOISE_THRESH, 0x01 }, - { CAP1106_REG_STANDBY_CHANNEL, 0x00 }, - { CAP1106_REG_STANDBY_CONFIG, 0x39 }, - { CAP1106_REG_STANDBY_SENSITIVITY, 0x02 }, - { CAP1106_REG_STANDBY_THRESH, 0x40 }, - { CAP1106_REG_CONFIG2, 0x40 }, - { CAP1106_REG_SENSOR_CALIB_LSB1, 0x00 }, - { CAP1106_REG_SENSOR_CALIB_LSB2, 0x00 }, -}; - -static bool cap1106_volatile_reg(struct device *dev, unsigned int reg) -{ - switch (reg) { - case CAP1106_REG_MAIN_CONTROL: - case CAP1106_REG_SENSOR_INPUT: - case CAP1106_REG_SENOR_DELTA(0): - case CAP1106_REG_SENOR_DELTA(1): - case CAP1106_REG_SENOR_DELTA(2): - case CAP1106_REG_SENOR_DELTA(3): - case CAP1106_REG_SENOR_DELTA(4): - case CAP1106_REG_SENOR_DELTA(5): - case CAP1106_REG_PRODUCT_ID: - case CAP1106_REG_MANUFACTURER_ID: - case CAP1106_REG_REVISION: - return true; - } - - return false; -} - -static const struct regmap_config cap1106_regmap_config = { - .reg_bits = 8, - .val_bits = 8, - - .max_register = CAP1106_REG_REVISION, - .reg_defaults = cap1106_reg_defaults, - - .num_reg_defaults = ARRAY_SIZE(cap1106_reg_defaults), - .cache_type = REGCACHE_RBTREE, - .volatile_reg = cap1106_volatile_reg, -}; - -static irqreturn_t cap1106_thread_func(int irq_num, void *data) -{ - struct cap1106_priv *priv = data; - unsigned int status; - int ret, i; - - /* - * Deassert interrupt. This needs to be done before reading the status - * registers, which will not carry valid values otherwise. - */ - ret = regmap_update_bits(priv->regmap, CAP1106_REG_MAIN_CONTROL, 1, 0); - if (ret < 0) - goto out; - - ret = regmap_read(priv->regmap, CAP1106_REG_SENSOR_INPUT, &status); - if (ret < 0) - goto out; - - for (i = 0; i < CAP1106_NUM_CHN; i++) - input_report_key(priv->idev, priv->keycodes[i], - status & (1 << i)); - - input_sync(priv->idev); - -out: - return IRQ_HANDLED; -} - -static int cap1106_set_sleep(struct cap1106_priv *priv, bool sleep) -{ - return regmap_update_bits(priv->regmap, CAP1106_REG_MAIN_CONTROL, - CAP1106_REG_MAIN_CONTROL_DLSEEP, - sleep ? CAP1106_REG_MAIN_CONTROL_DLSEEP : 0); -} - -static int cap1106_input_open(struct input_dev *idev) -{ - struct cap1106_priv *priv = input_get_drvdata(idev); - - return cap1106_set_sleep(priv, false); -} - -static void cap1106_input_close(struct input_dev *idev) -{ - struct cap1106_priv *priv = input_get_drvdata(idev); - - cap1106_set_sleep(priv, true); -} - -static int cap1106_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) -{ - struct device *dev = &i2c_client->dev; - struct cap1106_priv *priv; - struct device_node *node; - int i, error, irq, gain = 0; - unsigned int val, rev; - u32 gain32, keycodes[CAP1106_NUM_CHN]; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->regmap = devm_regmap_init_i2c(i2c_client, &cap1106_regmap_config); - if (IS_ERR(priv->regmap)) - return PTR_ERR(priv->regmap); - - error = regmap_read(priv->regmap, CAP1106_REG_PRODUCT_ID, &val); - if (error) - return error; - - if (val != CAP1106_PRODUCT_ID) { - dev_err(dev, "Product ID: Got 0x%02x, expected 0x%02x\n", - val, CAP1106_PRODUCT_ID); - return -ENODEV; - } - - error = regmap_read(priv->regmap, CAP1106_REG_MANUFACTURER_ID, &val); - if (error) - return error; - - if (val != CAP1106_MANUFACTURER_ID) { - dev_err(dev, "Manufacturer ID: Got 0x%02x, expected 0x%02x\n", - val, CAP1106_MANUFACTURER_ID); - return -ENODEV; - } - - error = regmap_read(priv->regmap, CAP1106_REG_REVISION, &rev); - if (error < 0) - return error; - - dev_info(dev, "CAP1106 detected, revision 0x%02x\n", rev); - i2c_set_clientdata(i2c_client, priv); - node = dev->of_node; - - if (!of_property_read_u32(node, "microchip,sensor-gain", &gain32)) { - if (is_power_of_2(gain32) && gain32 <= 8) - gain = ilog2(gain32); - else - dev_err(dev, "Invalid sensor-gain value %d\n", gain32); - } - - BUILD_BUG_ON(ARRAY_SIZE(keycodes) != ARRAY_SIZE(priv->keycodes)); - - /* Provide some useful defaults */ - for (i = 0; i < ARRAY_SIZE(keycodes); i++) - keycodes[i] = KEY_A + i; - - of_property_read_u32_array(node, "linux,keycodes", - keycodes, ARRAY_SIZE(keycodes)); - - for (i = 0; i < ARRAY_SIZE(keycodes); i++) - priv->keycodes[i] = keycodes[i]; - - error = regmap_update_bits(priv->regmap, CAP1106_REG_MAIN_CONTROL, - CAP1106_REG_MAIN_CONTROL_GAIN_MASK, - gain << CAP1106_REG_MAIN_CONTROL_GAIN_SHIFT); - if (error) - return error; - - /* Disable autorepeat. The Linux input system has its own handling. */ - error = regmap_write(priv->regmap, CAP1106_REG_REPEAT_RATE, 0); - if (error) - return error; - - priv->idev = devm_input_allocate_device(dev); - if (!priv->idev) - return -ENOMEM; - - priv->idev->name = "CAP1106 capacitive touch sensor"; - priv->idev->id.bustype = BUS_I2C; - priv->idev->evbit[0] = BIT_MASK(EV_KEY); - - if (of_property_read_bool(node, "autorepeat")) - __set_bit(EV_REP, priv->idev->evbit); - - for (i = 0; i < CAP1106_NUM_CHN; i++) - __set_bit(priv->keycodes[i], priv->idev->keybit); - - __clear_bit(KEY_RESERVED, priv->idev->keybit); - - priv->idev->keycode = priv->keycodes; - priv->idev->keycodesize = sizeof(priv->keycodes[0]); - priv->idev->keycodemax = ARRAY_SIZE(priv->keycodes); - - priv->idev->id.vendor = CAP1106_MANUFACTURER_ID; - priv->idev->id.product = CAP1106_PRODUCT_ID; - priv->idev->id.version = rev; - - priv->idev->open = cap1106_input_open; - priv->idev->close = cap1106_input_close; - - input_set_drvdata(priv->idev, priv); - - /* - * Put the device in deep sleep mode for now. - * ->open() will bring it back once the it is actually needed. - */ - cap1106_set_sleep(priv, true); - - error = input_register_device(priv->idev); - if (error) - return error; - - irq = irq_of_parse_and_map(node, 0); - if (!irq) { - dev_err(dev, "Unable to parse or map IRQ\n"); - return -ENXIO; - } - - error = devm_request_threaded_irq(dev, irq, NULL, cap1106_thread_func, - IRQF_ONESHOT, dev_name(dev), priv); - if (error) - return error; - - return 0; -} - -static const struct of_device_id cap1106_dt_ids[] = { - { .compatible = "microchip,cap1106", }, - {} -}; -MODULE_DEVICE_TABLE(of, cap1106_dt_ids); - -static const struct i2c_device_id cap1106_i2c_ids[] = { - { "cap1106", 0 }, - {} -}; -MODULE_DEVICE_TABLE(i2c, cap1106_i2c_ids); - -static struct i2c_driver cap1106_i2c_driver = { - .driver = { - .name = "cap1106", - .owner = THIS_MODULE, - .of_match_table = cap1106_dt_ids, - }, - .id_table = cap1106_i2c_ids, - .probe = cap1106_i2c_probe, -}; - -module_i2c_driver(cap1106_i2c_driver); - -MODULE_ALIAS("platform:cap1106"); -MODULE_DESCRIPTION("Microchip CAP1106 driver"); -MODULE_AUTHOR("Daniel Mack <linux@zonque.org>"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c new file mode 100644 index 000000000000..4f59f0bab28f --- /dev/null +++ b/drivers/input/keyboard/cap11xx.c @@ -0,0 +1,376 @@ +/* + * Input driver for Microchip CAP11xx based capacitive touch sensors + * + * (c) 2014 Daniel Mack <linux@zonque.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/input.h> +#include <linux/of_irq.h> +#include <linux/regmap.h> +#include <linux/i2c.h> +#include <linux/gpio/consumer.h> + +#define CAP11XX_REG_MAIN_CONTROL 0x00 +#define CAP11XX_REG_MAIN_CONTROL_GAIN_SHIFT (6) +#define CAP11XX_REG_MAIN_CONTROL_GAIN_MASK (0xc0) +#define CAP11XX_REG_MAIN_CONTROL_DLSEEP BIT(4) +#define CAP11XX_REG_GENERAL_STATUS 0x02 +#define CAP11XX_REG_SENSOR_INPUT 0x03 +#define CAP11XX_REG_NOISE_FLAG_STATUS 0x0a +#define CAP11XX_REG_SENOR_DELTA(X) (0x10 + (X)) +#define CAP11XX_REG_SENSITIVITY_CONTROL 0x1f +#define CAP11XX_REG_CONFIG 0x20 +#define CAP11XX_REG_SENSOR_ENABLE 0x21 +#define CAP11XX_REG_SENSOR_CONFIG 0x22 +#define CAP11XX_REG_SENSOR_CONFIG2 0x23 +#define CAP11XX_REG_SAMPLING_CONFIG 0x24 +#define CAP11XX_REG_CALIBRATION 0x26 +#define CAP11XX_REG_INT_ENABLE 0x27 +#define CAP11XX_REG_REPEAT_RATE 0x28 +#define CAP11XX_REG_MT_CONFIG 0x2a +#define CAP11XX_REG_MT_PATTERN_CONFIG 0x2b +#define CAP11XX_REG_MT_PATTERN 0x2d +#define CAP11XX_REG_RECALIB_CONFIG 0x2f +#define CAP11XX_REG_SENSOR_THRESH(X) (0x30 + (X)) +#define CAP11XX_REG_SENSOR_NOISE_THRESH 0x38 +#define CAP11XX_REG_STANDBY_CHANNEL 0x40 +#define CAP11XX_REG_STANDBY_CONFIG 0x41 +#define CAP11XX_REG_STANDBY_SENSITIVITY 0x42 +#define CAP11XX_REG_STANDBY_THRESH 0x43 +#define CAP11XX_REG_CONFIG2 0x44 +#define CAP11XX_REG_CONFIG2_ALT_POL BIT(6) +#define CAP11XX_REG_SENSOR_BASE_CNT(X) (0x50 + (X)) +#define CAP11XX_REG_SENSOR_CALIB (0xb1 + (X)) +#define CAP11XX_REG_SENSOR_CALIB_LSB1 0xb9 +#define CAP11XX_REG_SENSOR_CALIB_LSB2 0xba +#define CAP11XX_REG_PRODUCT_ID 0xfd +#define CAP11XX_REG_MANUFACTURER_ID 0xfe +#define CAP11XX_REG_REVISION 0xff + +#define CAP11XX_MANUFACTURER_ID 0x5d + +struct cap11xx_priv { + struct regmap *regmap; + struct input_dev *idev; + + /* config */ + u32 keycodes[]; +}; + +struct cap11xx_hw_model { + u8 product_id; + unsigned int num_channels; +}; + +enum { + CAP1106, + CAP1126, + CAP1188, +}; + +static const struct cap11xx_hw_model cap11xx_devices[] = { + [CAP1106] = { .product_id = 0x55, .num_channels = 6 }, + [CAP1126] = { .product_id = 0x53, .num_channels = 6 }, + [CAP1188] = { .product_id = 0x50, .num_channels = 8 }, +}; + +static const struct reg_default cap11xx_reg_defaults[] = { + { CAP11XX_REG_MAIN_CONTROL, 0x00 }, + { CAP11XX_REG_GENERAL_STATUS, 0x00 }, + { CAP11XX_REG_SENSOR_INPUT, 0x00 }, + { CAP11XX_REG_NOISE_FLAG_STATUS, 0x00 }, + { CAP11XX_REG_SENSITIVITY_CONTROL, 0x2f }, + { CAP11XX_REG_CONFIG, 0x20 }, + { CAP11XX_REG_SENSOR_ENABLE, 0x3f }, + { CAP11XX_REG_SENSOR_CONFIG, 0xa4 }, + { CAP11XX_REG_SENSOR_CONFIG2, 0x07 }, + { CAP11XX_REG_SAMPLING_CONFIG, 0x39 }, + { CAP11XX_REG_CALIBRATION, 0x00 }, + { CAP11XX_REG_INT_ENABLE, 0x3f }, + { CAP11XX_REG_REPEAT_RATE, 0x3f }, + { CAP11XX_REG_MT_CONFIG, 0x80 }, + { CAP11XX_REG_MT_PATTERN_CONFIG, 0x00 }, + { CAP11XX_REG_MT_PATTERN, 0x3f }, + { CAP11XX_REG_RECALIB_CONFIG, 0x8a }, + { CAP11XX_REG_SENSOR_THRESH(0), 0x40 }, + { CAP11XX_REG_SENSOR_THRESH(1), 0x40 }, + { CAP11XX_REG_SENSOR_THRESH(2), 0x40 }, + { CAP11XX_REG_SENSOR_THRESH(3), 0x40 }, + { CAP11XX_REG_SENSOR_THRESH(4), 0x40 }, + { CAP11XX_REG_SENSOR_THRESH(5), 0x40 }, + { CAP11XX_REG_SENSOR_NOISE_THRESH, 0x01 }, + { CAP11XX_REG_STANDBY_CHANNEL, 0x00 }, + { CAP11XX_REG_STANDBY_CONFIG, 0x39 }, + { CAP11XX_REG_STANDBY_SENSITIVITY, 0x02 }, + { CAP11XX_REG_STANDBY_THRESH, 0x40 }, + { CAP11XX_REG_CONFIG2, 0x40 }, + { CAP11XX_REG_SENSOR_CALIB_LSB1, 0x00 }, + { CAP11XX_REG_SENSOR_CALIB_LSB2, 0x00 }, +}; + +static bool cap11xx_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CAP11XX_REG_MAIN_CONTROL: + case CAP11XX_REG_SENSOR_INPUT: + case CAP11XX_REG_SENOR_DELTA(0): + case CAP11XX_REG_SENOR_DELTA(1): + case CAP11XX_REG_SENOR_DELTA(2): + case CAP11XX_REG_SENOR_DELTA(3): + case CAP11XX_REG_SENOR_DELTA(4): + case CAP11XX_REG_SENOR_DELTA(5): + case CAP11XX_REG_PRODUCT_ID: + case CAP11XX_REG_MANUFACTURER_ID: + case CAP11XX_REG_REVISION: + return true; + } + + return false; +} + +static const struct regmap_config cap11xx_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = CAP11XX_REG_REVISION, + .reg_defaults = cap11xx_reg_defaults, + + .num_reg_defaults = ARRAY_SIZE(cap11xx_reg_defaults), + .cache_type = REGCACHE_RBTREE, + .volatile_reg = cap11xx_volatile_reg, +}; + +static irqreturn_t cap11xx_thread_func(int irq_num, void *data) +{ + struct cap11xx_priv *priv = data; + unsigned int status; + int ret, i; + + /* + * Deassert interrupt. This needs to be done before reading the status + * registers, which will not carry valid values otherwise. + */ + ret = regmap_update_bits(priv->regmap, CAP11XX_REG_MAIN_CONTROL, 1, 0); + if (ret < 0) + goto out; + + ret = regmap_read(priv->regmap, CAP11XX_REG_SENSOR_INPUT, &status); + if (ret < 0) + goto out; + + for (i = 0; i < priv->idev->keycodemax; i++) + input_report_key(priv->idev, priv->keycodes[i], + status & (1 << i)); + + input_sync(priv->idev); + +out: + return IRQ_HANDLED; +} + +static int cap11xx_set_sleep(struct cap11xx_priv *priv, bool sleep) +{ + return regmap_update_bits(priv->regmap, CAP11XX_REG_MAIN_CONTROL, + CAP11XX_REG_MAIN_CONTROL_DLSEEP, + sleep ? CAP11XX_REG_MAIN_CONTROL_DLSEEP : 0); +} + +static int cap11xx_input_open(struct input_dev *idev) +{ + struct cap11xx_priv *priv = input_get_drvdata(idev); + + return cap11xx_set_sleep(priv, false); +} + +static void cap11xx_input_close(struct input_dev *idev) +{ + struct cap11xx_priv *priv = input_get_drvdata(idev); + + cap11xx_set_sleep(priv, true); +} + +static int cap11xx_i2c_probe(struct i2c_client *i2c_client, + const struct i2c_device_id *id) +{ + struct device *dev = &i2c_client->dev; + struct cap11xx_priv *priv; + struct device_node *node; + const struct cap11xx_hw_model *cap; + int i, error, irq, gain = 0; + unsigned int val, rev; + u32 gain32; + + if (id->driver_data >= ARRAY_SIZE(cap11xx_devices)) { + dev_err(dev, "Invalid device ID %lu\n", id->driver_data); + return -EINVAL; + } + + cap = &cap11xx_devices[id->driver_data]; + if (!cap || !cap->num_channels) { + dev_err(dev, "Invalid device configuration\n"); + return -EINVAL; + } + + priv = devm_kzalloc(dev, + sizeof(*priv) + + cap->num_channels * sizeof(priv->keycodes[0]), + GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->regmap = devm_regmap_init_i2c(i2c_client, &cap11xx_regmap_config); + if (IS_ERR(priv->regmap)) + return PTR_ERR(priv->regmap); + + error = regmap_read(priv->regmap, CAP11XX_REG_PRODUCT_ID, &val); + if (error) + return error; + + if (val != cap->product_id) { + dev_err(dev, "Product ID: Got 0x%02x, expected 0x%02x\n", + val, cap->product_id); + return -ENXIO; + } + + error = regmap_read(priv->regmap, CAP11XX_REG_MANUFACTURER_ID, &val); + if (error) + return error; + + if (val != CAP11XX_MANUFACTURER_ID) { + dev_err(dev, "Manufacturer ID: Got 0x%02x, expected 0x%02x\n", + val, CAP11XX_MANUFACTURER_ID); + return -ENXIO; + } + + error = regmap_read(priv->regmap, CAP11XX_REG_REVISION, &rev); + if (error < 0) + return error; + + dev_info(dev, "CAP11XX detected, revision 0x%02x\n", rev); + i2c_set_clientdata(i2c_client, priv); + node = dev->of_node; + + if (!of_property_read_u32(node, "microchip,sensor-gain", &gain32)) { + if (is_power_of_2(gain32) && gain32 <= 8) + gain = ilog2(gain32); + else + dev_err(dev, "Invalid sensor-gain value %d\n", gain32); + } + + if (of_property_read_bool(node, "microchip,irq-active-high")) { + error = regmap_update_bits(priv->regmap, CAP11XX_REG_CONFIG2, + CAP11XX_REG_CONFIG2_ALT_POL, 0); + if (error) + return error; + } + + /* Provide some useful defaults */ + for (i = 0; i < cap->num_channels; i++) + priv->keycodes[i] = KEY_A + i; + + of_property_read_u32_array(node, "linux,keycodes", + priv->keycodes, cap->num_channels); + + error = regmap_update_bits(priv->regmap, CAP11XX_REG_MAIN_CONTROL, + CAP11XX_REG_MAIN_CONTROL_GAIN_MASK, + gain << CAP11XX_REG_MAIN_CONTROL_GAIN_SHIFT); + if (error) + return error; + + /* Disable autorepeat. The Linux input system has its own handling. */ + error = regmap_write(priv->regmap, CAP11XX_REG_REPEAT_RATE, 0); + if (error) + return error; + + priv->idev = devm_input_allocate_device(dev); + if (!priv->idev) + return -ENOMEM; + + priv->idev->name = "CAP11XX capacitive touch sensor"; + priv->idev->id.bustype = BUS_I2C; + priv->idev->evbit[0] = BIT_MASK(EV_KEY); + + if (of_property_read_bool(node, "autorepeat")) + __set_bit(EV_REP, priv->idev->evbit); + + for (i = 0; i < cap->num_channels; i++) + __set_bit(priv->keycodes[i], priv->idev->keybit); + + __clear_bit(KEY_RESERVED, priv->idev->keybit); + + priv->idev->keycode = priv->keycodes; + priv->idev->keycodesize = sizeof(priv->keycodes[0]); + priv->idev->keycodemax = cap->num_channels; + + priv->idev->id.vendor = CAP11XX_MANUFACTURER_ID; + priv->idev->id.product = cap->product_id; + priv->idev->id.version = rev; + + priv->idev->open = cap11xx_input_open; + priv->idev->close = cap11xx_input_close; + + input_set_drvdata(priv->idev, priv); + + /* + * Put the device in deep sleep mode for now. + * ->open() will bring it back once the it is actually needed. + */ + cap11xx_set_sleep(priv, true); + + error = input_register_device(priv->idev); + if (error) + return error; + + irq = irq_of_parse_and_map(node, 0); + if (!irq) { + dev_err(dev, "Unable to parse or map IRQ\n"); + return -ENXIO; + } + + error = devm_request_threaded_irq(dev, irq, NULL, cap11xx_thread_func, + IRQF_ONESHOT, dev_name(dev), priv); + if (error) + return error; + + return 0; +} + +static const struct of_device_id cap11xx_dt_ids[] = { + { .compatible = "microchip,cap1106", }, + { .compatible = "microchip,cap1126", }, + { .compatible = "microchip,cap1188", }, + {} +}; +MODULE_DEVICE_TABLE(of, cap11xx_dt_ids); + +static const struct i2c_device_id cap11xx_i2c_ids[] = { + { "cap1106", CAP1106 }, + { "cap1126", CAP1126 }, + { "cap1188", CAP1188 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, cap11xx_i2c_ids); + +static struct i2c_driver cap11xx_i2c_driver = { + .driver = { + .name = "cap11xx", + .owner = THIS_MODULE, + .of_match_table = cap11xx_dt_ids, + }, + .id_table = cap11xx_i2c_ids, + .probe = cap11xx_i2c_probe, +}; + +module_i2c_driver(cap11xx_i2c_driver); + +MODULE_ALIAS("platform:cap11xx"); +MODULE_DESCRIPTION("Microchip CAP11XX driver"); +MODULE_AUTHOR("Daniel Mack <linux@zonque.org>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 8f3a24e15402..883d6aed5b9a 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -29,14 +29,19 @@ #include <linux/of.h> #include <linux/of_platform.h> #include <linux/of_gpio.h> +#include <linux/of_irq.h> #include <linux/spinlock.h> struct gpio_button_data { const struct gpio_keys_button *button; struct input_dev *input; - struct timer_list timer; - struct work_struct work; - unsigned int timer_debounce; /* in msecs */ + + struct timer_list release_timer; + unsigned int release_delay; /* in msecs, for IRQ-only buttons */ + + struct delayed_work work; + unsigned int software_debounce; /* in msecs, for GPIO-driven buttons */ + unsigned int irq; spinlock_t lock; bool disabled; @@ -115,11 +120,14 @@ static void gpio_keys_disable_button(struct gpio_button_data *bdata) { if (!bdata->disabled) { /* - * Disable IRQ and possible debouncing timer. + * Disable IRQ and associated timer/work structure. */ disable_irq(bdata->irq); - if (bdata->timer_debounce) - del_timer_sync(&bdata->timer); + + if (gpio_is_valid(bdata->button->gpio)) + cancel_delayed_work_sync(&bdata->work); + else + del_timer_sync(&bdata->release_timer); bdata->disabled = true; } @@ -342,7 +350,7 @@ static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata) static void gpio_keys_gpio_work_func(struct work_struct *work) { struct gpio_button_data *bdata = - container_of(work, struct gpio_button_data, work); + container_of(work, struct gpio_button_data, work.work); gpio_keys_gpio_report_event(bdata); @@ -350,13 +358,6 @@ static void gpio_keys_gpio_work_func(struct work_struct *work) pm_relax(bdata->input->dev.parent); } -static void gpio_keys_gpio_timer(unsigned long _data) -{ - struct gpio_button_data *bdata = (struct gpio_button_data *)_data; - - schedule_work(&bdata->work); -} - static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id) { struct gpio_button_data *bdata = dev_id; @@ -365,11 +366,10 @@ static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id) if (bdata->button->wakeup) pm_stay_awake(bdata->input->dev.parent); - if (bdata->timer_debounce) - mod_timer(&bdata->timer, - jiffies + msecs_to_jiffies(bdata->timer_debounce)); - else - schedule_work(&bdata->work); + + mod_delayed_work(system_wq, + &bdata->work, + msecs_to_jiffies(bdata->software_debounce)); return IRQ_HANDLED; } @@ -407,7 +407,7 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id) input_event(input, EV_KEY, button->code, 1); input_sync(input); - if (!bdata->timer_debounce) { + if (!bdata->release_delay) { input_event(input, EV_KEY, button->code, 0); input_sync(input); goto out; @@ -416,9 +416,9 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id) bdata->key_pressed = true; } - if (bdata->timer_debounce) - mod_timer(&bdata->timer, - jiffies + msecs_to_jiffies(bdata->timer_debounce)); + if (bdata->release_delay) + mod_timer(&bdata->release_timer, + jiffies + msecs_to_jiffies(bdata->release_delay)); out: spin_unlock_irqrestore(&bdata->lock, flags); return IRQ_HANDLED; @@ -428,10 +428,10 @@ static void gpio_keys_quiesce_key(void *data) { struct gpio_button_data *bdata = data; - if (bdata->timer_debounce) - del_timer_sync(&bdata->timer); - - cancel_work_sync(&bdata->work); + if (gpio_is_valid(bdata->button->gpio)) + cancel_delayed_work_sync(&bdata->work); + else + del_timer_sync(&bdata->release_timer); } static int gpio_keys_setup_key(struct platform_device *pdev, @@ -465,23 +465,25 @@ static int gpio_keys_setup_key(struct platform_device *pdev, button->debounce_interval * 1000); /* use timer if gpiolib doesn't provide debounce */ if (error < 0) - bdata->timer_debounce = + bdata->software_debounce = button->debounce_interval; } - irq = gpio_to_irq(button->gpio); - if (irq < 0) { - error = irq; - dev_err(dev, - "Unable to get irq number for GPIO %d, error %d\n", - button->gpio, error); - return error; + if (button->irq) { + bdata->irq = button->irq; + } else { + irq = gpio_to_irq(button->gpio); + if (irq < 0) { + error = irq; + dev_err(dev, + "Unable to get irq number for GPIO %d, error %d\n", + button->gpio, error); + return error; + } + bdata->irq = irq; } - bdata->irq = irq; - INIT_WORK(&bdata->work, gpio_keys_gpio_work_func); - setup_timer(&bdata->timer, - gpio_keys_gpio_timer, (unsigned long)bdata); + INIT_DELAYED_WORK(&bdata->work, gpio_keys_gpio_work_func); isr = gpio_keys_gpio_isr; irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; @@ -498,8 +500,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev, return -EINVAL; } - bdata->timer_debounce = button->debounce_interval; - setup_timer(&bdata->timer, + bdata->release_delay = button->debounce_interval; + setup_timer(&bdata->release_timer, gpio_keys_irq_timer, (unsigned long)bdata); isr = gpio_keys_irq_isr; @@ -509,7 +511,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev, input_set_capability(input, button->type ?: EV_KEY, button->code); /* - * Install custom action to cancel debounce timer and + * Install custom action to cancel release timer and * workqueue item. */ error = devm_add_action(&pdev->dev, gpio_keys_quiesce_key, bdata); @@ -617,29 +619,30 @@ gpio_keys_get_devtree_pdata(struct device *dev) i = 0; for_each_child_of_node(node, pp) { - int gpio; enum of_gpio_flags flags; - if (!of_find_property(pp, "gpios", NULL)) { - pdata->nbuttons--; - dev_warn(dev, "Found button without gpios\n"); - continue; - } + button = &pdata->buttons[i++]; - gpio = of_get_gpio_flags(pp, 0, &flags); - if (gpio < 0) { - error = gpio; - if (error != -EPROBE_DEFER) - dev_err(dev, - "Failed to get gpio flags, error: %d\n", - error); - return ERR_PTR(error); + button->gpio = of_get_gpio_flags(pp, 0, &flags); + if (button->gpio < 0) { + error = button->gpio; + if (error != -ENOENT) { + if (error != -EPROBE_DEFER) + dev_err(dev, + "Failed to get gpio flags, error: %d\n", + error); + return ERR_PTR(error); + } + } else { + button->active_low = flags & OF_GPIO_ACTIVE_LOW; } - button = &pdata->buttons[i++]; + button->irq = irq_of_parse_and_map(pp, 0); - button->gpio = gpio; - button->active_low = flags & OF_GPIO_ACTIVE_LOW; + if (!gpio_is_valid(button->gpio) && !button->irq) { + dev_err(dev, "Found button without gpios or irqs\n"); + return ERR_PTR(-EINVAL); + } if (of_property_read_u32(pp, "linux,code", &button->code)) { dev_err(dev, "Button without keycode: 0x%x\n", @@ -654,6 +657,8 @@ gpio_keys_get_devtree_pdata(struct device *dev) button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); + button->can_disable = !!of_get_property(pp, "linux,can-disable", NULL); + if (of_property_read_u32(pp, "debounce-interval", &button->debounce_interval)) button->debounce_interval = 5; diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index 610a8af795a1..5b152f25a8e1 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c @@ -473,7 +473,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv) if (error) goto bail1; - init_completion(&dev->cmd_done); + reinit_completion(&dev->cmd_done); serio_write(serio, 0); serio_write(serio, 0); serio_write(serio, HIL_PKT_CMD >> 8); @@ -482,7 +482,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv) if (error) goto bail1; - init_completion(&dev->cmd_done); + reinit_completion(&dev->cmd_done); serio_write(serio, 0); serio_write(serio, 0); serio_write(serio, HIL_PKT_CMD >> 8); @@ -491,7 +491,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv) if (error) goto bail1; - init_completion(&dev->cmd_done); + reinit_completion(&dev->cmd_done); serio_write(serio, 0); serio_write(serio, 0); serio_write(serio, HIL_PKT_CMD >> 8); diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c index cb32e2b506b7..21bea52d4365 100644 --- a/drivers/input/keyboard/lm8323.c +++ b/drivers/input/keyboard/lm8323.c @@ -616,6 +616,8 @@ static ssize_t lm8323_set_disable(struct device *dev, unsigned int i; ret = kstrtouint(buf, 10, &i); + if (ret) + return ret; mutex_lock(&lm->lock); lm->kp_enabled = !i; diff --git a/drivers/input/keyboard/lpc32xx-keys.c b/drivers/input/keyboard/lpc32xx-keys.c index 8c079371c2e7..265d641c40e2 100644 --- a/drivers/input/keyboard/lpc32xx-keys.c +++ b/drivers/input/keyboard/lpc32xx-keys.c @@ -66,7 +66,6 @@ struct lpc32xx_kscan_drv { struct input_dev *input; struct clk *clk; - struct resource *iores; void __iomem *kscan_base; unsigned int irq; @@ -188,32 +187,27 @@ static int lpc32xx_kscan_probe(struct platform_device *pdev) return -EINVAL; } - kscandat = kzalloc(sizeof(struct lpc32xx_kscan_drv), GFP_KERNEL); - if (!kscandat) { - dev_err(&pdev->dev, "failed to allocate memory\n"); + kscandat = devm_kzalloc(&pdev->dev, sizeof(*kscandat), + GFP_KERNEL); + if (!kscandat) return -ENOMEM; - } error = lpc32xx_parse_dt(&pdev->dev, kscandat); if (error) { dev_err(&pdev->dev, "failed to parse device tree\n"); - goto err_free_mem; + return error; } keymap_size = sizeof(kscandat->keymap[0]) * (kscandat->matrix_sz << kscandat->row_shift); - kscandat->keymap = kzalloc(keymap_size, GFP_KERNEL); - if (!kscandat->keymap) { - dev_err(&pdev->dev, "could not allocate memory for keymap\n"); - error = -ENOMEM; - goto err_free_mem; - } + kscandat->keymap = devm_kzalloc(&pdev->dev, keymap_size, GFP_KERNEL); + if (!kscandat->keymap) + return -ENOMEM; - kscandat->input = input = input_allocate_device(); + kscandat->input = input = devm_input_allocate_device(&pdev->dev); if (!input) { dev_err(&pdev->dev, "failed to allocate input device\n"); - error = -ENOMEM; - goto err_free_keymap; + return -ENOMEM; } /* Setup key input */ @@ -234,39 +228,26 @@ static int lpc32xx_kscan_probe(struct platform_device *pdev) kscandat->keymap, kscandat->input); if (error) { dev_err(&pdev->dev, "failed to build keymap\n"); - goto err_free_input; + return error; } input_set_drvdata(kscandat->input, kscandat); - kscandat->iores = request_mem_region(res->start, resource_size(res), - pdev->name); - if (!kscandat->iores) { - dev_err(&pdev->dev, "failed to request I/O memory\n"); - error = -EBUSY; - goto err_free_input; - } - - kscandat->kscan_base = ioremap(kscandat->iores->start, - resource_size(kscandat->iores)); - if (!kscandat->kscan_base) { - dev_err(&pdev->dev, "failed to remap I/O memory\n"); - error = -EBUSY; - goto err_release_memregion; - } + kscandat->kscan_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(kscandat->kscan_base)) + return PTR_ERR(kscandat->kscan_base); /* Get the key scanner clock */ - kscandat->clk = clk_get(&pdev->dev, NULL); + kscandat->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(kscandat->clk)) { dev_err(&pdev->dev, "failed to get clock\n"); - error = PTR_ERR(kscandat->clk); - goto err_unmap; + return PTR_ERR(kscandat->clk); } /* Configure the key scanner */ error = clk_prepare_enable(kscandat->clk); if (error) - goto err_clk_put; + return error; writel(kscandat->deb_clks, LPC32XX_KS_DEB(kscandat->kscan_base)); writel(kscandat->scan_delay, LPC32XX_KS_SCAN_CTL(kscandat->kscan_base)); @@ -277,52 +258,20 @@ static int lpc32xx_kscan_probe(struct platform_device *pdev) writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); clk_disable_unprepare(kscandat->clk); - error = request_irq(irq, lpc32xx_kscan_irq, 0, pdev->name, kscandat); + error = devm_request_irq(&pdev->dev, irq, lpc32xx_kscan_irq, 0, + pdev->name, kscandat); if (error) { dev_err(&pdev->dev, "failed to request irq\n"); - goto err_clk_put; + return error; } error = input_register_device(kscandat->input); if (error) { dev_err(&pdev->dev, "failed to register input device\n"); - goto err_free_irq; + return error; } platform_set_drvdata(pdev, kscandat); - return 0; - -err_free_irq: - free_irq(irq, kscandat); -err_clk_put: - clk_put(kscandat->clk); -err_unmap: - iounmap(kscandat->kscan_base); -err_release_memregion: - release_mem_region(kscandat->iores->start, - resource_size(kscandat->iores)); -err_free_input: - input_free_device(kscandat->input); -err_free_keymap: - kfree(kscandat->keymap); -err_free_mem: - kfree(kscandat); - - return error; -} - -static int lpc32xx_kscan_remove(struct platform_device *pdev) -{ - struct lpc32xx_kscan_drv *kscandat = platform_get_drvdata(pdev); - - free_irq(platform_get_irq(pdev, 0), kscandat); - clk_put(kscandat->clk); - iounmap(kscandat->kscan_base); - release_mem_region(kscandat->iores->start, - resource_size(kscandat->iores)); - input_unregister_device(kscandat->input); - kfree(kscandat->keymap); - kfree(kscandat); return 0; } @@ -378,7 +327,6 @@ MODULE_DEVICE_TABLE(of, lpc32xx_kscan_match); static struct platform_driver lpc32xx_kscan_driver = { .probe = lpc32xx_kscan_probe, - .remove = lpc32xx_kscan_remove, .driver = { .name = DRV_NAME, .pm = &lpc32xx_kscan_pm_ops, diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c index 009c82256e89..3aa2ec45bcab 100644 --- a/drivers/input/keyboard/mpr121_touchkey.c +++ b/drivers/input/keyboard/mpr121_touchkey.c @@ -214,13 +214,14 @@ static int mpr_touchkey_probe(struct i2c_client *client, return -EINVAL; } - mpr121 = kzalloc(sizeof(struct mpr121_touchkey), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!mpr121 || !input_dev) { - dev_err(&client->dev, "Failed to allocate memory\n"); - error = -ENOMEM; - goto err_free_mem; - } + mpr121 = devm_kzalloc(&client->dev, sizeof(*mpr121), + GFP_KERNEL); + if (!mpr121) + return -ENOMEM; + + input_dev = devm_input_allocate_device(&client->dev); + if (!input_dev) + return -ENOMEM; mpr121->client = client; mpr121->input_dev = input_dev; @@ -243,44 +244,26 @@ static int mpr_touchkey_probe(struct i2c_client *client, error = mpr121_phys_init(pdata, mpr121, client); if (error) { dev_err(&client->dev, "Failed to init register\n"); - goto err_free_mem; + return error; } - error = request_threaded_irq(client->irq, NULL, + error = devm_request_threaded_irq(&client->dev, client->irq, NULL, mpr_touchkey_interrupt, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, client->dev.driver->name, mpr121); if (error) { dev_err(&client->dev, "Failed to register interrupt\n"); - goto err_free_mem; + return error; } error = input_register_device(input_dev); if (error) - goto err_free_irq; + return error; i2c_set_clientdata(client, mpr121); device_init_wakeup(&client->dev, pdata->wakeup); return 0; - -err_free_irq: - free_irq(client->irq, mpr121); -err_free_mem: - input_free_device(input_dev); - kfree(mpr121); - return error; -} - -static int mpr_touchkey_remove(struct i2c_client *client) -{ - struct mpr121_touchkey *mpr121 = i2c_get_clientdata(client); - - free_irq(client->irq, mpr121); - input_unregister_device(mpr121->input_dev); - kfree(mpr121); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -327,7 +310,6 @@ static struct i2c_driver mpr_touchkey_driver = { }, .id_table = mpr121_id, .probe = mpr_touchkey_probe, - .remove = mpr_touchkey_remove, }; module_i2c_driver(mpr_touchkey_driver); diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 6ab3e7c96329..a90d6bdc499e 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c @@ -741,37 +741,27 @@ static int pxa27x_keypad_probe(struct platform_device *pdev) return -ENXIO; } - keypad = kzalloc(sizeof(struct pxa27x_keypad), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!keypad || !input_dev) { - dev_err(&pdev->dev, "failed to allocate memory\n"); - error = -ENOMEM; - goto failed_free; - } + keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), + GFP_KERNEL); + if (!keypad) + return -ENOMEM; + + input_dev = devm_input_allocate_device(&pdev->dev); + if (!input_dev) + return -ENOMEM; keypad->pdata = pdata; keypad->input_dev = input_dev; keypad->irq = irq; - res = request_mem_region(res->start, resource_size(res), pdev->name); - if (res == NULL) { - dev_err(&pdev->dev, "failed to request I/O memory\n"); - error = -EBUSY; - goto failed_free; - } - - keypad->mmio_base = ioremap(res->start, resource_size(res)); - if (keypad->mmio_base == NULL) { - dev_err(&pdev->dev, "failed to remap I/O memory\n"); - error = -ENXIO; - goto failed_free_mem; - } + keypad->mmio_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(keypad->mmio_base)) + return PTR_ERR(keypad->mmio_base); - keypad->clk = clk_get(&pdev->dev, NULL); + keypad->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(keypad->clk)) { dev_err(&pdev->dev, "failed to get keypad clock\n"); - error = PTR_ERR(keypad->clk); - goto failed_free_io; + return PTR_ERR(keypad->clk); } input_dev->name = pdev->name; @@ -802,7 +792,7 @@ static int pxa27x_keypad_probe(struct platform_device *pdev) } if (error) { dev_err(&pdev->dev, "failed to build keycode\n"); - goto failed_put_clk; + return error; } keypad->row_shift = get_count_order(pdata->matrix_key_cols); @@ -812,61 +802,26 @@ static int pxa27x_keypad_probe(struct platform_device *pdev) input_dev->evbit[0] |= BIT_MASK(EV_REL); } - error = request_irq(irq, pxa27x_keypad_irq_handler, 0, - pdev->name, keypad); + error = devm_request_irq(&pdev->dev, irq, pxa27x_keypad_irq_handler, + 0, pdev->name, keypad); if (error) { dev_err(&pdev->dev, "failed to request IRQ\n"); - goto failed_put_clk; + return error; } /* Register the input device */ error = input_register_device(input_dev); if (error) { dev_err(&pdev->dev, "failed to register input device\n"); - goto failed_free_irq; + return error; } platform_set_drvdata(pdev, keypad); device_init_wakeup(&pdev->dev, 1); return 0; - -failed_free_irq: - free_irq(irq, keypad); -failed_put_clk: - clk_put(keypad->clk); -failed_free_io: - iounmap(keypad->mmio_base); -failed_free_mem: - release_mem_region(res->start, resource_size(res)); -failed_free: - input_free_device(input_dev); - kfree(keypad); - return error; } -static int pxa27x_keypad_remove(struct platform_device *pdev) -{ - struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); - struct resource *res; - - free_irq(keypad->irq, keypad); - clk_put(keypad->clk); - - input_unregister_device(keypad->input_dev); - iounmap(keypad->mmio_base); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, resource_size(res)); - - kfree(keypad); - - return 0; -} - -/* work with hotplug and coldplug */ -MODULE_ALIAS("platform:pxa27x-keypad"); - #ifdef CONFIG_OF static const struct of_device_id pxa27x_keypad_dt_match[] = { { .compatible = "marvell,pxa27x-keypad" }, @@ -877,7 +832,6 @@ MODULE_DEVICE_TABLE(of, pxa27x_keypad_dt_match); static struct platform_driver pxa27x_keypad_driver = { .probe = pxa27x_keypad_probe, - .remove = pxa27x_keypad_remove, .driver = { .name = "pxa27x-keypad", .of_match_table = of_match_ptr(pxa27x_keypad_dt_match), @@ -888,3 +842,5 @@ module_platform_driver(pxa27x_keypad_driver); MODULE_DESCRIPTION("PXA27x Keypad Controller Driver"); MODULE_LICENSE("GPL"); +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:pxa27x-keypad"); diff --git a/drivers/input/keyboard/stmpe-keypad.c b/drivers/input/keyboard/stmpe-keypad.c index ef5e67fb567e..fe6e3f22eed7 100644 --- a/drivers/input/keyboard/stmpe-keypad.c +++ b/drivers/input/keyboard/stmpe-keypad.c @@ -45,13 +45,14 @@ #define STMPE_KEYPAD_MAX_ROWS 8 #define STMPE_KEYPAD_MAX_COLS 8 #define STMPE_KEYPAD_ROW_SHIFT 3 -#define STMPE_KEYPAD_KEYMAP_SIZE \ +#define STMPE_KEYPAD_KEYMAP_MAX_SIZE \ (STMPE_KEYPAD_MAX_ROWS * STMPE_KEYPAD_MAX_COLS) /** * struct stmpe_keypad_variant - model-specific attributes * @auto_increment: whether the KPC_DATA_BYTE register address * auto-increments on multiple read + * @set_pullup: whether the pins need to have their pull-ups set * @num_data: number of data bytes * @num_normal_data: number of normal keys' data bytes * @max_cols: maximum number of columns supported @@ -61,6 +62,7 @@ */ struct stmpe_keypad_variant { bool auto_increment; + bool set_pullup; int num_data; int num_normal_data; int max_cols; @@ -81,6 +83,7 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = { }, [STMPE2401] = { .auto_increment = false, + .set_pullup = true, .num_data = 3, .num_normal_data = 2, .max_cols = 8, @@ -90,6 +93,7 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = { }, [STMPE2403] = { .auto_increment = true, + .set_pullup = true, .num_data = 5, .num_normal_data = 3, .max_cols = 8, @@ -99,16 +103,30 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = { }, }; +/** + * struct stmpe_keypad - STMPE keypad state container + * @stmpe: pointer to parent STMPE device + * @input: spawned input device + * @variant: STMPE variant + * @debounce_ms: debounce interval, in ms. Maximum is + * %STMPE_KEYPAD_MAX_DEBOUNCE. + * @scan_count: number of key scanning cycles to confirm key data. + * Maximum is %STMPE_KEYPAD_MAX_SCAN_COUNT. + * @no_autorepeat: disable key autorepeat + * @rows: bitmask for the rows + * @cols: bitmask for the columns + * @keymap: the keymap + */ struct stmpe_keypad { struct stmpe *stmpe; struct input_dev *input; const struct stmpe_keypad_variant *variant; - const struct stmpe_keypad_platform_data *plat; - + unsigned int debounce_ms; + unsigned int scan_count; + bool no_autorepeat; unsigned int rows; unsigned int cols; - - unsigned short keymap[STMPE_KEYPAD_KEYMAP_SIZE]; + unsigned short keymap[STMPE_KEYPAD_KEYMAP_MAX_SIZE]; }; static int stmpe_keypad_read_data(struct stmpe_keypad *keypad, u8 *data) @@ -171,7 +189,10 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad) unsigned int col_gpios = variant->col_gpios; unsigned int row_gpios = variant->row_gpios; struct stmpe *stmpe = keypad->stmpe; + u8 pureg = stmpe->regs[STMPE_IDX_GPPUR_LSB]; unsigned int pins = 0; + unsigned int pu_pins = 0; + int ret; int i; /* @@ -188,8 +209,10 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad) for (i = 0; i < variant->max_cols; i++) { int num = __ffs(col_gpios); - if (keypad->cols & (1 << i)) + if (keypad->cols & (1 << i)) { pins |= 1 << num; + pu_pins |= 1 << num; + } col_gpios &= ~(1 << num); } @@ -203,20 +226,43 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad) row_gpios &= ~(1 << num); } - return stmpe_set_altfunc(stmpe, pins, STMPE_BLOCK_KEYPAD); + ret = stmpe_set_altfunc(stmpe, pins, STMPE_BLOCK_KEYPAD); + if (ret) + return ret; + + /* + * On STMPE24xx, set pin bias to pull-up on all keypad input + * pins (columns), this incidentally happen to be maximum 8 pins + * and placed at GPIO0-7 so only the LSB of the pull up register + * ever needs to be written. + */ + if (variant->set_pullup) { + u8 val; + + ret = stmpe_reg_read(stmpe, pureg); + if (ret) + return ret; + + /* Do not touch unused pins, may be used for GPIO */ + val = ret & ~pu_pins; + val |= pu_pins; + + ret = stmpe_reg_write(stmpe, pureg, val); + } + + return 0; } static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad) { - const struct stmpe_keypad_platform_data *plat = keypad->plat; const struct stmpe_keypad_variant *variant = keypad->variant; struct stmpe *stmpe = keypad->stmpe; int ret; - if (plat->debounce_ms > STMPE_KEYPAD_MAX_DEBOUNCE) + if (keypad->debounce_ms > STMPE_KEYPAD_MAX_DEBOUNCE) return -EINVAL; - if (plat->scan_count > STMPE_KEYPAD_MAX_SCAN_COUNT) + if (keypad->scan_count > STMPE_KEYPAD_MAX_SCAN_COUNT) return -EINVAL; ret = stmpe_enable(stmpe, STMPE_BLOCK_KEYPAD); @@ -245,7 +291,7 @@ static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad) ret = stmpe_set_bits(stmpe, STMPE_KPC_CTRL_MSB, STMPE_KPC_CTRL_MSB_SCAN_COUNT, - plat->scan_count << 4); + keypad->scan_count << 4); if (ret < 0) return ret; @@ -253,17 +299,18 @@ static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad) STMPE_KPC_CTRL_LSB_SCAN | STMPE_KPC_CTRL_LSB_DEBOUNCE, STMPE_KPC_CTRL_LSB_SCAN | - (plat->debounce_ms << 1)); + (keypad->debounce_ms << 1)); } -static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad) +static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad, + u32 used_rows, u32 used_cols) { int row, col; - for (row = 0; row < STMPE_KEYPAD_MAX_ROWS; row++) { - for (col = 0; col < STMPE_KEYPAD_MAX_COLS; col++) { + for (row = 0; row < used_rows; row++) { + for (col = 0; col < used_cols; col++) { int code = MATRIX_SCAN_CODE(row, col, - STMPE_KEYPAD_ROW_SHIFT); + STMPE_KEYPAD_ROW_SHIFT); if (keypad->keymap[code] != KEY_RESERVED) { keypad->rows |= 1 << row; keypad->cols |= 1 << col; @@ -272,51 +319,17 @@ static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad) } } -#ifdef CONFIG_OF -static const struct stmpe_keypad_platform_data * -stmpe_keypad_of_probe(struct device *dev) -{ - struct device_node *np = dev->of_node; - struct stmpe_keypad_platform_data *plat; - - if (!np) - return ERR_PTR(-ENODEV); - - plat = devm_kzalloc(dev, sizeof(*plat), GFP_KERNEL); - if (!plat) - return ERR_PTR(-ENOMEM); - - of_property_read_u32(np, "debounce-interval", &plat->debounce_ms); - of_property_read_u32(np, "st,scan-count", &plat->scan_count); - - plat->no_autorepeat = of_property_read_bool(np, "st,no-autorepeat"); - - return plat; -} -#else -static inline const struct stmpe_keypad_platform_data * -stmpe_keypad_of_probe(struct device *dev) -{ - return ERR_PTR(-EINVAL); -} -#endif - static int stmpe_keypad_probe(struct platform_device *pdev) { struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); - const struct stmpe_keypad_platform_data *plat; + struct device_node *np = pdev->dev.of_node; struct stmpe_keypad *keypad; struct input_dev *input; + u32 rows; + u32 cols; int error; int irq; - plat = stmpe->pdata->keypad; - if (!plat) { - plat = stmpe_keypad_of_probe(&pdev->dev); - if (IS_ERR(plat)) - return PTR_ERR(plat); - } - irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; @@ -326,6 +339,13 @@ static int stmpe_keypad_probe(struct platform_device *pdev) if (!keypad) return -ENOMEM; + keypad->stmpe = stmpe; + keypad->variant = &stmpe_keypad_variants[stmpe->partnum]; + + of_property_read_u32(np, "debounce-interval", &keypad->debounce_ms); + of_property_read_u32(np, "st,scan-count", &keypad->scan_count); + keypad->no_autorepeat = of_property_read_bool(np, "st,no-autorepeat"); + input = devm_input_allocate_device(&pdev->dev); if (!input) return -ENOMEM; @@ -334,23 +354,22 @@ static int stmpe_keypad_probe(struct platform_device *pdev) input->id.bustype = BUS_I2C; input->dev.parent = &pdev->dev; - error = matrix_keypad_build_keymap(plat->keymap_data, NULL, - STMPE_KEYPAD_MAX_ROWS, - STMPE_KEYPAD_MAX_COLS, + error = matrix_keypad_parse_of_params(&pdev->dev, &rows, &cols); + if (error) + return error; + + error = matrix_keypad_build_keymap(NULL, NULL, rows, cols, keypad->keymap, input); if (error) return error; input_set_capability(input, EV_MSC, MSC_SCAN); - if (!plat->no_autorepeat) + if (!keypad->no_autorepeat) __set_bit(EV_REP, input->evbit); - stmpe_keypad_fill_used_pins(keypad); + stmpe_keypad_fill_used_pins(keypad, rows, cols); - keypad->stmpe = stmpe; - keypad->plat = plat; keypad->input = input; - keypad->variant = &stmpe_keypad_variants[stmpe->partnum]; error = stmpe_keypad_chip_init(keypad); if (error < 0) diff --git a/drivers/input/misc/88pm860x_onkey.c b/drivers/input/misc/88pm860x_onkey.c index cfdca6e99779..cc87443aa2ee 100644 --- a/drivers/input/misc/88pm860x_onkey.c +++ b/drivers/input/misc/88pm860x_onkey.c @@ -112,8 +112,7 @@ static int pm860x_onkey_probe(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int pm860x_onkey_suspend(struct device *dev) +static int __maybe_unused pm860x_onkey_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); @@ -122,7 +121,7 @@ static int pm860x_onkey_suspend(struct device *dev) chip->wakeup_flag |= 1 << PM8607_IRQ_ONKEY; return 0; } -static int pm860x_onkey_resume(struct device *dev) +static int __maybe_unused pm860x_onkey_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); @@ -131,7 +130,6 @@ static int pm860x_onkey_resume(struct device *dev) chip->wakeup_flag &= ~(1 << PM8607_IRQ_ONKEY); return 0; } -#endif static SIMPLE_DEV_PM_OPS(pm860x_onkey_pm_ops, pm860x_onkey_suspend, pm860x_onkey_resume); diff --git a/drivers/input/misc/ad714x-i2c.c b/drivers/input/misc/ad714x-i2c.c index e0f522516ef5..189bdc8e91a5 100644 --- a/drivers/input/misc/ad714x-i2c.c +++ b/drivers/input/misc/ad714x-i2c.c @@ -13,17 +13,15 @@ #include <linux/pm.h> #include "ad714x.h" -#ifdef CONFIG_PM_SLEEP -static int ad714x_i2c_suspend(struct device *dev) +static int __maybe_unused ad714x_i2c_suspend(struct device *dev) { return ad714x_disable(i2c_get_clientdata(to_i2c_client(dev))); } -static int ad714x_i2c_resume(struct device *dev) +static int __maybe_unused ad714x_i2c_resume(struct device *dev) { return ad714x_enable(i2c_get_clientdata(to_i2c_client(dev))); } -#endif static SIMPLE_DEV_PM_OPS(ad714x_i2c_pm, ad714x_i2c_suspend, ad714x_i2c_resume); diff --git a/drivers/input/misc/ad714x-spi.c b/drivers/input/misc/ad714x-spi.c index 3a90b710e309..a79e50b58bf5 100644 --- a/drivers/input/misc/ad714x-spi.c +++ b/drivers/input/misc/ad714x-spi.c @@ -16,17 +16,15 @@ #define AD714x_SPI_CMD_PREFIX 0xE000 /* bits 15:11 */ #define AD714x_SPI_READ BIT(10) -#ifdef CONFIG_PM_SLEEP -static int ad714x_spi_suspend(struct device *dev) +static int __maybe_unused ad714x_spi_suspend(struct device *dev) { return ad714x_disable(spi_get_drvdata(to_spi_device(dev))); } -static int ad714x_spi_resume(struct device *dev) +static int __maybe_unused ad714x_spi_resume(struct device *dev) { return ad714x_enable(spi_get_drvdata(to_spi_device(dev))); } -#endif static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume); diff --git a/drivers/input/misc/adxl34x-i2c.c b/drivers/input/misc/adxl34x-i2c.c index 416f47ddcc90..470bfd6f0830 100644 --- a/drivers/input/misc/adxl34x-i2c.c +++ b/drivers/input/misc/adxl34x-i2c.c @@ -105,8 +105,7 @@ static int adxl34x_i2c_remove(struct i2c_client *client) return adxl34x_remove(ac); } -#ifdef CONFIG_PM_SLEEP -static int adxl34x_i2c_suspend(struct device *dev) +static int __maybe_unused adxl34x_i2c_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct adxl34x *ac = i2c_get_clientdata(client); @@ -116,7 +115,7 @@ static int adxl34x_i2c_suspend(struct device *dev) return 0; } -static int adxl34x_i2c_resume(struct device *dev) +static int __maybe_unused adxl34x_i2c_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct adxl34x *ac = i2c_get_clientdata(client); @@ -125,7 +124,6 @@ static int adxl34x_i2c_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(adxl34x_i2c_pm, adxl34x_i2c_suspend, adxl34x_i2c_resume); diff --git a/drivers/input/misc/adxl34x-spi.c b/drivers/input/misc/adxl34x-spi.c index 76dc0679d3b1..da6e76b58dab 100644 --- a/drivers/input/misc/adxl34x-spi.c +++ b/drivers/input/misc/adxl34x-spi.c @@ -94,8 +94,7 @@ static int adxl34x_spi_remove(struct spi_device *spi) return adxl34x_remove(ac); } -#ifdef CONFIG_PM_SLEEP -static int adxl34x_spi_suspend(struct device *dev) +static int __maybe_unused adxl34x_spi_suspend(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct adxl34x *ac = spi_get_drvdata(spi); @@ -105,7 +104,7 @@ static int adxl34x_spi_suspend(struct device *dev) return 0; } -static int adxl34x_spi_resume(struct device *dev) +static int __maybe_unused adxl34x_spi_resume(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct adxl34x *ac = spi_get_drvdata(spi); @@ -114,7 +113,6 @@ static int adxl34x_spi_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(adxl34x_spi_pm, adxl34x_spi_suspend, adxl34x_spi_resume); diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c index cab87f5ce6d3..a364e109ca7c 100644 --- a/drivers/input/misc/drv260x.c +++ b/drivers/input/misc/drv260x.c @@ -639,8 +639,7 @@ static int drv260x_probe(struct i2c_client *client, return 0; } -#ifdef CONFIG_PM_SLEEP -static int drv260x_suspend(struct device *dev) +static int __maybe_unused drv260x_suspend(struct device *dev) { struct drv260x_data *haptics = dev_get_drvdata(dev); int ret = 0; @@ -672,7 +671,7 @@ out: return ret; } -static int drv260x_resume(struct device *dev) +static int __maybe_unused drv260x_resume(struct device *dev) { struct drv260x_data *haptics = dev_get_drvdata(dev); int ret = 0; @@ -702,7 +701,6 @@ out: mutex_unlock(&haptics->input_dev->mutex); return ret; } -#endif static SIMPLE_DEV_PM_OPS(drv260x_pm_ops, drv260x_suspend, drv260x_resume); diff --git a/drivers/input/misc/drv2667.c b/drivers/input/misc/drv2667.c index 0f437581cc04..a021744e608c 100644 --- a/drivers/input/misc/drv2667.c +++ b/drivers/input/misc/drv2667.c @@ -406,8 +406,7 @@ static int drv2667_probe(struct i2c_client *client, return 0; } -#ifdef CONFIG_PM_SLEEP -static int drv2667_suspend(struct device *dev) +static int __maybe_unused drv2667_suspend(struct device *dev) { struct drv2667_data *haptics = dev_get_drvdata(dev); int ret = 0; @@ -436,7 +435,7 @@ out: return ret; } -static int drv2667_resume(struct device *dev) +static int __maybe_unused drv2667_resume(struct device *dev) { struct drv2667_data *haptics = dev_get_drvdata(dev); int ret = 0; @@ -464,7 +463,6 @@ out: mutex_unlock(&haptics->input_dev->mutex); return ret; } -#endif static SIMPLE_DEV_PM_OPS(drv2667_pm_ops, drv2667_suspend, drv2667_resume); diff --git a/drivers/input/misc/gp2ap002a00f.c b/drivers/input/misc/gp2ap002a00f.c index de21e317da32..0ac176d66a6f 100644 --- a/drivers/input/misc/gp2ap002a00f.c +++ b/drivers/input/misc/gp2ap002a00f.c @@ -225,8 +225,7 @@ static int gp2a_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int gp2a_suspend(struct device *dev) +static int __maybe_unused gp2a_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct gp2a_data *dt = i2c_get_clientdata(client); @@ -244,7 +243,7 @@ static int gp2a_suspend(struct device *dev) return retval; } -static int gp2a_resume(struct device *dev) +static int __maybe_unused gp2a_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct gp2a_data *dt = i2c_get_clientdata(client); @@ -261,7 +260,6 @@ static int gp2a_resume(struct device *dev) return retval; } -#endif static SIMPLE_DEV_PM_OPS(gp2a_pm, gp2a_suspend, gp2a_resume); diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c index afed8e2b2f94..ac1fa5f44580 100644 --- a/drivers/input/misc/ims-pcu.c +++ b/drivers/input/misc/ims-pcu.c @@ -1851,7 +1851,7 @@ static int ims_pcu_identify_type(struct ims_pcu *pcu, u8 *device_id) static int ims_pcu_init_application_mode(struct ims_pcu *pcu) { - static atomic_t device_no = ATOMIC_INIT(0); + static atomic_t device_no = ATOMIC_INIT(-1); const struct ims_pcu_device_info *info; int error; @@ -1882,7 +1882,7 @@ static int ims_pcu_init_application_mode(struct ims_pcu *pcu) } /* Device appears to be operable, complete initialization */ - pcu->device_no = atomic_inc_return(&device_no) - 1; + pcu->device_no = atomic_inc_return(&device_no); /* * PCU-B devices, both GEN_1 and GEN_2 do not have OFN sensor diff --git a/drivers/input/misc/kxtj9.c b/drivers/input/misc/kxtj9.c index d708478bc5b5..6e29349da537 100644 --- a/drivers/input/misc/kxtj9.c +++ b/drivers/input/misc/kxtj9.c @@ -615,8 +615,7 @@ static int kxtj9_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int kxtj9_suspend(struct device *dev) +static int __maybe_unused kxtj9_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct kxtj9_data *tj9 = i2c_get_clientdata(client); @@ -631,7 +630,7 @@ static int kxtj9_suspend(struct device *dev) return 0; } -static int kxtj9_resume(struct device *dev) +static int __maybe_unused kxtj9_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct kxtj9_data *tj9 = i2c_get_clientdata(client); @@ -646,7 +645,6 @@ static int kxtj9_resume(struct device *dev) mutex_unlock(&input_dev->mutex); return retval; } -#endif static SIMPLE_DEV_PM_OPS(kxtj9_pm_ops, kxtj9_suspend, kxtj9_resume); diff --git a/drivers/input/misc/max77693-haptic.c b/drivers/input/misc/max77693-haptic.c index 034093ee63bc..39e930c10ebb 100644 --- a/drivers/input/misc/max77693-haptic.c +++ b/drivers/input/misc/max77693-haptic.c @@ -309,8 +309,7 @@ static int max77693_haptic_probe(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int max77693_haptic_suspend(struct device *dev) +static int __maybe_unused max77693_haptic_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct max77693_haptic *haptic = platform_get_drvdata(pdev); @@ -323,7 +322,7 @@ static int max77693_haptic_suspend(struct device *dev) return 0; } -static int max77693_haptic_resume(struct device *dev) +static int __maybe_unused max77693_haptic_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct max77693_haptic *haptic = platform_get_drvdata(pdev); @@ -335,7 +334,6 @@ static int max77693_haptic_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(max77693_haptic_pm_ops, max77693_haptic_suspend, max77693_haptic_resume); diff --git a/drivers/input/misc/max8925_onkey.c b/drivers/input/misc/max8925_onkey.c index 297e2a9169d5..7c49b8d23894 100644 --- a/drivers/input/misc/max8925_onkey.c +++ b/drivers/input/misc/max8925_onkey.c @@ -133,8 +133,7 @@ static int max8925_onkey_probe(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int max8925_onkey_suspend(struct device *dev) +static int __maybe_unused max8925_onkey_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct max8925_onkey_info *info = platform_get_drvdata(pdev); @@ -148,7 +147,7 @@ static int max8925_onkey_suspend(struct device *dev) return 0; } -static int max8925_onkey_resume(struct device *dev) +static int __maybe_unused max8925_onkey_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct max8925_onkey_info *info = platform_get_drvdata(pdev); @@ -161,7 +160,6 @@ static int max8925_onkey_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(max8925_onkey_pm_ops, max8925_onkey_suspend, max8925_onkey_resume); diff --git a/drivers/input/misc/max8997_haptic.c b/drivers/input/misc/max8997_haptic.c index 5b3154edf822..d0f687281339 100644 --- a/drivers/input/misc/max8997_haptic.c +++ b/drivers/input/misc/max8997_haptic.c @@ -378,8 +378,7 @@ static int max8997_haptic_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int max8997_haptic_suspend(struct device *dev) +static int __maybe_unused max8997_haptic_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct max8997_haptic *chip = platform_get_drvdata(pdev); @@ -388,7 +387,6 @@ static int max8997_haptic_suspend(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(max8997_haptic_pm_ops, max8997_haptic_suspend, NULL); diff --git a/drivers/input/misc/palmas-pwrbutton.c b/drivers/input/misc/palmas-pwrbutton.c index 066c5ab632c8..1f9b5ee92746 100644 --- a/drivers/input/misc/palmas-pwrbutton.c +++ b/drivers/input/misc/palmas-pwrbutton.c @@ -260,7 +260,6 @@ static int palmas_pwron_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP /** * palmas_pwron_suspend() - suspend handler * @dev: power button device @@ -269,7 +268,7 @@ static int palmas_pwron_remove(struct platform_device *pdev) * * Return: 0 */ -static int palmas_pwron_suspend(struct device *dev) +static int __maybe_unused palmas_pwron_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct palmas_pwron *pwron = platform_get_drvdata(pdev); @@ -290,7 +289,7 @@ static int palmas_pwron_suspend(struct device *dev) * * Return: 0 */ -static int palmas_pwron_resume(struct device *dev) +static int __maybe_unused palmas_pwron_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct palmas_pwron *pwron = platform_get_drvdata(pdev); @@ -300,7 +299,6 @@ static int palmas_pwron_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(palmas_pwron_pm, palmas_pwron_suspend, palmas_pwron_resume); diff --git a/drivers/input/misc/pm8xxx-vibrator.c b/drivers/input/misc/pm8xxx-vibrator.c index e9c77a95717e..5113877153d7 100644 --- a/drivers/input/misc/pm8xxx-vibrator.c +++ b/drivers/input/misc/pm8xxx-vibrator.c @@ -199,8 +199,7 @@ static int pm8xxx_vib_probe(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int pm8xxx_vib_suspend(struct device *dev) +static int __maybe_unused pm8xxx_vib_suspend(struct device *dev) { struct pm8xxx_vib *vib = dev_get_drvdata(dev); @@ -209,7 +208,6 @@ static int pm8xxx_vib_suspend(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(pm8xxx_vib_pm_ops, pm8xxx_vib_suspend, NULL); diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c index cb799177cbd5..c4ca20e63221 100644 --- a/drivers/input/misc/pmic8xxx-pwrkey.c +++ b/drivers/input/misc/pmic8xxx-pwrkey.c @@ -53,8 +53,7 @@ static irqreturn_t pwrkey_release_irq(int irq, void *_pwr) return IRQ_HANDLED; } -#ifdef CONFIG_PM_SLEEP -static int pmic8xxx_pwrkey_suspend(struct device *dev) +static int __maybe_unused pmic8xxx_pwrkey_suspend(struct device *dev) { struct pmic8xxx_pwrkey *pwrkey = dev_get_drvdata(dev); @@ -64,7 +63,7 @@ static int pmic8xxx_pwrkey_suspend(struct device *dev) return 0; } -static int pmic8xxx_pwrkey_resume(struct device *dev) +static int __maybe_unused pmic8xxx_pwrkey_resume(struct device *dev) { struct pmic8xxx_pwrkey *pwrkey = dev_get_drvdata(dev); @@ -73,7 +72,6 @@ static int pmic8xxx_pwrkey_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(pm8xxx_pwr_key_pm_ops, pmic8xxx_pwrkey_suspend, pmic8xxx_pwrkey_resume); diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c index 294aa48bad50..a28ee70ff158 100644 --- a/drivers/input/misc/pwm-beeper.c +++ b/drivers/input/misc/pwm-beeper.c @@ -144,8 +144,7 @@ static int pwm_beeper_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int pwm_beeper_suspend(struct device *dev) +static int __maybe_unused pwm_beeper_suspend(struct device *dev) { struct pwm_beeper *beeper = dev_get_drvdata(dev); @@ -155,7 +154,7 @@ static int pwm_beeper_suspend(struct device *dev) return 0; } -static int pwm_beeper_resume(struct device *dev) +static int __maybe_unused pwm_beeper_resume(struct device *dev) { struct pwm_beeper *beeper = dev_get_drvdata(dev); @@ -170,6 +169,7 @@ static int pwm_beeper_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(pwm_beeper_pm_ops, pwm_beeper_suspend, pwm_beeper_resume); +#ifdef CONFIG_PM_SLEEP #define PWM_BEEPER_PM_OPS (&pwm_beeper_pm_ops) #else #define PWM_BEEPER_PM_OPS NULL diff --git a/drivers/input/misc/sirfsoc-onkey.c b/drivers/input/misc/sirfsoc-onkey.c index 4faf9f8d1240..9d5b89befe6f 100644 --- a/drivers/input/misc/sirfsoc-onkey.c +++ b/drivers/input/misc/sirfsoc-onkey.c @@ -179,8 +179,7 @@ static int sirfsoc_pwrc_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int sirfsoc_pwrc_resume(struct device *dev) +static int __maybe_unused sirfsoc_pwrc_resume(struct device *dev) { struct sirfsoc_pwrc_drvdata *pwrcdrv = dev_get_drvdata(dev); struct input_dev *input = pwrcdrv->input; @@ -196,7 +195,6 @@ static int sirfsoc_pwrc_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(sirfsoc_pwrc_pm_ops, NULL, sirfsoc_pwrc_resume); diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c index ccd6dd18f8f6..fc17b9592f54 100644 --- a/drivers/input/misc/twl4030-vibra.c +++ b/drivers/input/misc/twl4030-vibra.c @@ -157,8 +157,7 @@ static void twl4030_vibra_close(struct input_dev *input) } /*** Module ***/ -#ifdef CONFIG_PM_SLEEP -static int twl4030_vibra_suspend(struct device *dev) +static int __maybe_unused twl4030_vibra_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct vibra_info *info = platform_get_drvdata(pdev); @@ -169,12 +168,11 @@ static int twl4030_vibra_suspend(struct device *dev) return 0; } -static int twl4030_vibra_resume(struct device *dev) +static int __maybe_unused twl4030_vibra_resume(struct device *dev) { vibra_disable_leds(); return 0; } -#endif static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops, twl4030_vibra_suspend, twl4030_vibra_resume); diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c index 96e0e0c0ccb1..0e0d094df2e6 100644 --- a/drivers/input/misc/twl6040-vibra.c +++ b/drivers/input/misc/twl6040-vibra.c @@ -236,8 +236,7 @@ static void twl6040_vibra_close(struct input_dev *input) mutex_unlock(&info->mutex); } -#ifdef CONFIG_PM_SLEEP -static int twl6040_vibra_suspend(struct device *dev) +static int __maybe_unused twl6040_vibra_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct vibra_info *info = platform_get_drvdata(pdev); @@ -251,7 +250,6 @@ static int twl6040_vibra_suspend(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL); diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 366fc7ad5eb6..d8b46b0f2dbe 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig @@ -215,6 +215,36 @@ config MOUSE_CYAPA To compile this driver as a module, choose M here: the module will be called cyapa. +config MOUSE_ELAN_I2C + tristate "ELAN I2C Touchpad support" + depends on I2C + help + This driver adds support for Elan I2C/SMbus Trackpads. + + Say Y here if you have a ELAN I2C/SMbus Touchpad. + + To compile this driver as a module, choose M here: the module will be + called elan_i2c. + +config MOUSE_ELAN_I2C_I2C + bool "Enable I2C support" + depends on MOUSE_ELAN_I2C + default y + help + Say Y here if Elan Touchpad in your system is connected to + a standard I2C controller. + + If unsure, say Y. + +config MOUSE_ELAN_I2C_SMBUS + bool "Enable SMbus support" + depends on MOUSE_ELAN_I2C + help + Say Y here if Elan Touchpad in your system is connected to + a SMbus adapter. + + If unsure, say Y. + config MOUSE_INPORT tristate "InPort/MS/ATIXL busmouse" depends on ISA diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index dda507f8b3a2..560003dcac37 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o obj-$(CONFIG_MOUSE_CYAPA) += cyapa.o +obj-$(CONFIG_MOUSE_ELAN_I2C) += elan_i2c.o obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o obj-$(CONFIG_MOUSE_INPORT) += inport.o obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o @@ -34,3 +35,7 @@ psmouse-$(CONFIG_MOUSE_PS2_SENTELIC) += sentelic.o psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o psmouse-$(CONFIG_MOUSE_PS2_CYPRESS) += cypress_ps2.o + +elan_i2c-objs := elan_i2c_core.o +elan_i2c-$(CONFIG_MOUSE_ELAN_I2C_I2C) += elan_i2c_i2c.o +elan_i2c-$(CONFIG_MOUSE_ELAN_I2C_SMBUS) += elan_i2c_smbus.o diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index d125a019383f..d88d73d83552 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -881,6 +881,34 @@ static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt, unsigned char *pkt, unsigned char pkt_id) { + /* + * packet-fmt b7 b6 b5 b4 b3 b2 b1 b0 + * Byte0 TWO & MULTI L 1 R M 1 Y0-2 Y0-1 Y0-0 + * Byte0 NEW L 1 X1-5 1 1 Y0-2 Y0-1 Y0-0 + * Byte1 Y0-10 Y0-9 Y0-8 Y0-7 Y0-6 Y0-5 Y0-4 Y0-3 + * Byte2 X0-11 1 X0-10 X0-9 X0-8 X0-7 X0-6 X0-5 + * Byte3 X1-11 1 X0-4 X0-3 1 X0-2 X0-1 X0-0 + * Byte4 TWO X1-10 TWO X1-9 X1-8 X1-7 X1-6 X1-5 X1-4 + * Byte4 MULTI X1-10 TWO X1-9 X1-8 X1-7 X1-6 Y1-5 1 + * Byte4 NEW X1-10 TWO X1-9 X1-8 X1-7 X1-6 0 0 + * Byte5 TWO & NEW Y1-10 0 Y1-9 Y1-8 Y1-7 Y1-6 Y1-5 Y1-4 + * Byte5 MULTI Y1-10 0 Y1-9 Y1-8 Y1-7 Y1-6 F-1 F-0 + * L: Left button + * R / M: Non-clickpads: Right / Middle button + * Clickpads: When > 2 fingers are down, and some fingers + * are in the button area, then the 2 coordinates reported + * are for fingers outside the button area and these report + * extra fingers being present in the right / left button + * area. Note these fingers are not added to the F field! + * so if a TWO packet is received and R = 1 then there are + * 3 fingers down, etc. + * TWO: 1: Two touches present, byte 0/4/5 are in TWO fmt + * 0: If byte 4 bit 0 is 1, then byte 0/4/5 are in MULTI fmt + * otherwise byte 0 bit 4 must be set and byte 0/4/5 are + * in NEW fmt + * F: Number of fingers - 3, 0 means 3 fingers, 1 means 4 ... + */ + mt[0].x = ((pkt[2] & 0x80) << 4); mt[0].x |= ((pkt[2] & 0x3F) << 5); mt[0].x |= ((pkt[3] & 0x30) >> 1); @@ -919,18 +947,21 @@ static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt, static int alps_get_mt_count(struct input_mt_pos *mt) { - int i; + int i, fingers = 0; - for (i = 0; i < MAX_TOUCHES && mt[i].x != 0 && mt[i].y != 0; i++) - /* empty */; + for (i = 0; i < MAX_TOUCHES; i++) { + if (mt[i].x != 0 || mt[i].y != 0) + fingers++; + } - return i; + return fingers; } static int alps_decode_packet_v7(struct alps_fields *f, unsigned char *p, struct psmouse *psmouse) { + struct alps_data *priv = psmouse->private; unsigned char pkt_id; pkt_id = alps_get_packet_id_v7(p); @@ -938,19 +969,52 @@ static int alps_decode_packet_v7(struct alps_fields *f, return 0; if (pkt_id == V7_PACKET_ID_UNKNOWN) return -1; + /* + * NEW packets are send to indicate a discontinuity in the finger + * coordinate reporting. Specifically a finger may have moved from + * slot 0 to 1 or vice versa. INPUT_MT_TRACK takes care of this for + * us. + * + * NEW packets have 3 problems: + * 1) They do not contain middle / right button info (on non clickpads) + * this can be worked around by preserving the old button state + * 2) They do not contain an accurate fingercount, and they are + * typically send when the number of fingers changes. We cannot use + * the old finger count as that may mismatch with the amount of + * touch coordinates we've available in the NEW packet + * 3) Their x data for the second touch is inaccurate leading to + * a possible jump of the x coordinate by 16 units when the first + * non NEW packet comes in + * Since problems 2 & 3 cannot be worked around, just ignore them. + */ + if (pkt_id == V7_PACKET_ID_NEW) + return 1; alps_get_finger_coordinate_v7(f->mt, p, pkt_id); - if (pkt_id == V7_PACKET_ID_TWO || pkt_id == V7_PACKET_ID_MULTI) { - f->left = (p[0] & 0x80) >> 7; + if (pkt_id == V7_PACKET_ID_TWO) + f->fingers = alps_get_mt_count(f->mt); + else /* pkt_id == V7_PACKET_ID_MULTI */ + f->fingers = 3 + (p[5] & 0x03); + + f->left = (p[0] & 0x80) >> 7; + if (priv->flags & ALPS_BUTTONPAD) { + if (p[0] & 0x20) + f->fingers++; + if (p[0] & 0x10) + f->fingers++; + } else { f->right = (p[0] & 0x20) >> 5; f->middle = (p[0] & 0x10) >> 4; } - if (pkt_id == V7_PACKET_ID_TWO) - f->fingers = alps_get_mt_count(f->mt); - else if (pkt_id == V7_PACKET_ID_MULTI) - f->fingers = 3 + (p[5] & 0x03); + /* Sometimes a single touch is reported in mt[1] rather then mt[0] */ + if (f->fingers == 1 && f->mt[0].x == 0 && f->mt[0].y == 0) { + f->mt[0].x = f->mt[1].x; + f->mt[0].y = f->mt[1].y; + f->mt[1].x = 0; + f->mt[1].y = 0; + } return 0; } diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c index b409c3d7d4fb..1bece8cad46f 100644 --- a/drivers/input/mouse/cyapa.c +++ b/drivers/input/mouse/cyapa.c @@ -6,7 +6,7 @@ * Daniel Kurtz <djkurtz@chromium.org> * Benson Leung <bleung@chromium.org> * - * Copyright (C) 2011-2012 Cypress Semiconductor, Inc. + * Copyright (C) 2011-2014 Cypress Semiconductor, Inc. * Copyright (C) 2011-2012 Google, Inc. * * This file is subject to the terms and conditions of the GNU General Public @@ -206,7 +206,6 @@ struct cyapa { struct i2c_client *client; struct input_dev *input; char phys[32]; /* device physical location */ - int irq; bool irq_wake; /* irq wake is enabled */ bool smbus; @@ -422,8 +421,8 @@ static ssize_t cyapa_read_block(struct cyapa *cyapa, u8 cmd_idx, u8 *values) */ static int cyapa_get_state(struct cyapa *cyapa) { - int ret; u8 status[BL_STATUS_SIZE]; + int error; cyapa->state = CYAPA_STATE_NO_DEVICE; @@ -433,18 +432,18 @@ static int cyapa_get_state(struct cyapa *cyapa) * If the device is in operation mode, this will be the DATA regs. * */ - ret = cyapa_i2c_reg_read_block(cyapa, BL_HEAD_OFFSET, BL_STATUS_SIZE, - status); + error = cyapa_i2c_reg_read_block(cyapa, BL_HEAD_OFFSET, BL_STATUS_SIZE, + status); /* * On smbus systems in OP mode, the i2c_reg_read will fail with * -ETIMEDOUT. In this case, try again using the smbus equivalent * command. This should return a BL_HEAD indicating CYAPA_STATE_OP. */ - if (cyapa->smbus && (ret == -ETIMEDOUT || ret == -ENXIO)) - ret = cyapa_read_block(cyapa, CYAPA_CMD_BL_STATUS, status); + if (cyapa->smbus && (error == -ETIMEDOUT || error == -ENXIO)) + error = cyapa_read_block(cyapa, CYAPA_CMD_BL_STATUS, status); - if (ret != BL_STATUS_SIZE) + if (error != BL_STATUS_SIZE) goto error; if ((status[REG_OP_STATUS] & OP_STATUS_SRC) == OP_STATUS_SRC) { @@ -454,7 +453,7 @@ static int cyapa_get_state(struct cyapa *cyapa) cyapa->state = CYAPA_STATE_OP; break; default: - ret = -EAGAIN; + error = -EAGAIN; goto error; } } else { @@ -468,7 +467,7 @@ static int cyapa_get_state(struct cyapa *cyapa) return 0; error: - return (ret < 0) ? ret : -EAGAIN; + return (error < 0) ? error : -EAGAIN; } /* @@ -487,31 +486,31 @@ error: */ static int cyapa_poll_state(struct cyapa *cyapa, unsigned int timeout) { - int ret; + int error; int tries = timeout / 100; - ret = cyapa_get_state(cyapa); - while ((ret || cyapa->state >= CYAPA_STATE_BL_BUSY) && tries--) { + error = cyapa_get_state(cyapa); + while ((error || cyapa->state >= CYAPA_STATE_BL_BUSY) && tries--) { msleep(100); - ret = cyapa_get_state(cyapa); + error = cyapa_get_state(cyapa); } - return (ret == -EAGAIN || ret == -ETIMEDOUT) ? -ETIMEDOUT : ret; + return (error == -EAGAIN || error == -ETIMEDOUT) ? -ETIMEDOUT : error; } static int cyapa_bl_deactivate(struct cyapa *cyapa) { - int ret; + int error; - ret = cyapa_i2c_reg_write_block(cyapa, 0, sizeof(bl_deactivate), - bl_deactivate); - if (ret < 0) - return ret; + error = cyapa_i2c_reg_write_block(cyapa, 0, sizeof(bl_deactivate), + bl_deactivate); + if (error) + return error; /* wait for bootloader to switch to idle state; should take < 100ms */ msleep(100); - ret = cyapa_poll_state(cyapa, 500); - if (ret < 0) - return ret; + error = cyapa_poll_state(cyapa, 500); + if (error) + return error; if (cyapa->state != CYAPA_STATE_BL_IDLE) return -EAGAIN; return 0; @@ -532,11 +531,11 @@ static int cyapa_bl_deactivate(struct cyapa *cyapa) */ static int cyapa_bl_exit(struct cyapa *cyapa) { - int ret; + int error; - ret = cyapa_i2c_reg_write_block(cyapa, 0, sizeof(bl_exit), bl_exit); - if (ret < 0) - return ret; + error = cyapa_i2c_reg_write_block(cyapa, 0, sizeof(bl_exit), bl_exit); + if (error) + return error; /* * Wait for bootloader to exit, and operation mode to start. @@ -548,9 +547,9 @@ static int cyapa_bl_exit(struct cyapa *cyapa) * updated to new firmware, it must first calibrate its sensors, which * can take up to an additional 2 seconds. */ - ret = cyapa_poll_state(cyapa, 2000); - if (ret < 0) - return ret; + error = cyapa_poll_state(cyapa, 2000); + if (error < 0) + return error; if (cyapa->state != CYAPA_STATE_OP) return -EAGAIN; @@ -577,10 +576,13 @@ static int cyapa_set_power_mode(struct cyapa *cyapa, u8 power_mode) power = ret & ~PWR_MODE_MASK; power |= power_mode & PWR_MODE_MASK; ret = cyapa_write_byte(cyapa, CYAPA_CMD_POWER_MODE, power); - if (ret < 0) + if (ret < 0) { dev_err(dev, "failed to set power_mode 0x%02x err = %d\n", power_mode, ret); - return ret; + return ret; + } + + return 0; } static int cyapa_get_query_data(struct cyapa *cyapa) @@ -637,28 +639,28 @@ static int cyapa_check_is_operational(struct cyapa *cyapa) { struct device *dev = &cyapa->client->dev; static const char unique_str[] = "CYTRA"; - int ret; + int error; - ret = cyapa_poll_state(cyapa, 2000); - if (ret < 0) - return ret; + error = cyapa_poll_state(cyapa, 2000); + if (error) + return error; switch (cyapa->state) { case CYAPA_STATE_BL_ACTIVE: - ret = cyapa_bl_deactivate(cyapa); - if (ret) - return ret; + error = cyapa_bl_deactivate(cyapa); + if (error) + return error; /* Fallthrough state */ case CYAPA_STATE_BL_IDLE: - ret = cyapa_bl_exit(cyapa); - if (ret) - return ret; + error = cyapa_bl_exit(cyapa); + if (error) + return error; /* Fallthrough state */ case CYAPA_STATE_OP: - ret = cyapa_get_query_data(cyapa); - if (ret < 0) - return ret; + error = cyapa_get_query_data(cyapa); + if (error) + return error; /* only support firmware protocol gen3 */ if (cyapa->gen != CYAPA_GEN3) { @@ -753,18 +755,42 @@ static u8 cyapa_check_adapter_functionality(struct i2c_client *client) return ret; } +static int cyapa_open(struct input_dev *input) +{ + struct cyapa *cyapa = input_get_drvdata(input); + struct i2c_client *client = cyapa->client; + int error; + + error = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE); + if (error) { + dev_err(&client->dev, "set active power failed: %d\n", error); + return error; + } + + enable_irq(client->irq); + return 0; +} + +static void cyapa_close(struct input_dev *input) +{ + struct cyapa *cyapa = input_get_drvdata(input); + + disable_irq(cyapa->client->irq); + cyapa_set_power_mode(cyapa, PWR_MODE_OFF); +} + static int cyapa_create_input_dev(struct cyapa *cyapa) { struct device *dev = &cyapa->client->dev; - int ret; struct input_dev *input; + int error; if (!cyapa->physical_size_x || !cyapa->physical_size_y) return -EINVAL; - input = cyapa->input = input_allocate_device(); + input = devm_input_allocate_device(dev); if (!input) { - dev_err(dev, "allocate memory for input device failed\n"); + dev_err(dev, "failed to allocate memory for input device.\n"); return -ENOMEM; } @@ -772,14 +798,17 @@ static int cyapa_create_input_dev(struct cyapa *cyapa) input->phys = cyapa->phys; input->id.bustype = BUS_I2C; input->id.version = 1; - input->id.product = 0; /* means any product in eventcomm. */ + input->id.product = 0; /* Means any product in eventcomm. */ input->dev.parent = &cyapa->client->dev; + input->open = cyapa_open; + input->close = cyapa_close; + input_set_drvdata(input, cyapa); __set_bit(EV_ABS, input->evbit); - /* finger position */ + /* Finger position */ input_set_abs_params(input, ABS_MT_POSITION_X, 0, cyapa->max_abs_x, 0, 0); input_set_abs_params(input, ABS_MT_POSITION_Y, 0, cyapa->max_abs_y, 0, @@ -801,35 +830,25 @@ static int cyapa_create_input_dev(struct cyapa *cyapa) if (cyapa->btn_capability == CAPABILITY_LEFT_BTN_MASK) __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); - /* handle pointer emulation and unused slots in core */ - ret = input_mt_init_slots(input, CYAPA_MAX_MT_SLOTS, - INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED); - if (ret) { - dev_err(dev, "allocate memory for MT slots failed, %d\n", ret); - goto err_free_device; + /* Handle pointer emulation and unused slots in core */ + error = input_mt_init_slots(input, CYAPA_MAX_MT_SLOTS, + INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED); + if (error) { + dev_err(dev, "failed to initialize MT slots: %d\n", error); + return error; } - /* Register the device in input subsystem */ - ret = input_register_device(input); - if (ret) { - dev_err(dev, "input device register failed, %d\n", ret); - goto err_free_device; - } + cyapa->input = input; return 0; - -err_free_device: - input_free_device(input); - cyapa->input = NULL; - return ret; } static int cyapa_probe(struct i2c_client *client, const struct i2c_device_id *dev_id) { - int ret; - u8 adapter_func; - struct cyapa *cyapa; struct device *dev = &client->dev; + struct cyapa *cyapa; + u8 adapter_func; + int error; adapter_func = cyapa_check_adapter_functionality(client); if (adapter_func == CYAPA_ADAPTER_FUNC_NONE) { @@ -837,11 +856,9 @@ static int cyapa_probe(struct i2c_client *client, return -EIO; } - cyapa = kzalloc(sizeof(struct cyapa), GFP_KERNEL); - if (!cyapa) { - dev_err(dev, "allocate memory for cyapa failed\n"); + cyapa = devm_kzalloc(dev, sizeof(struct cyapa), GFP_KERNEL); + if (!cyapa) return -ENOMEM; - } cyapa->gen = CYAPA_GEN3; cyapa->client = client; @@ -852,67 +869,61 @@ static int cyapa_probe(struct i2c_client *client, /* i2c isn't supported, use smbus */ if (adapter_func == CYAPA_ADAPTER_FUNC_SMBUS) cyapa->smbus = true; + cyapa->state = CYAPA_STATE_NO_DEVICE; - ret = cyapa_check_is_operational(cyapa); - if (ret) { - dev_err(dev, "device not operational, %d\n", ret); - goto err_mem_free; - } - ret = cyapa_create_input_dev(cyapa); - if (ret) { - dev_err(dev, "create input_dev instance failed, %d\n", ret); - goto err_mem_free; + error = cyapa_check_is_operational(cyapa); + if (error) { + dev_err(dev, "device not operational, %d\n", error); + return error; } - ret = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE); - if (ret) { - dev_err(dev, "set active power failed, %d\n", ret); - goto err_unregister_device; + /* Power down the device until we need it */ + error = cyapa_set_power_mode(cyapa, PWR_MODE_OFF); + if (error) { + dev_err(dev, "failed to quiesce the device: %d\n", error); + return error; } - cyapa->irq = client->irq; - ret = request_threaded_irq(cyapa->irq, - NULL, - cyapa_irq, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - "cyapa", - cyapa); - if (ret) { - dev_err(dev, "IRQ request failed: %d\n, ", ret); - goto err_unregister_device; + error = cyapa_create_input_dev(cyapa); + if (error) + return error; + + error = devm_request_threaded_irq(dev, client->irq, + NULL, cyapa_irq, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + "cyapa", cyapa); + if (error) { + dev_err(dev, "failed to request threaded irq: %d\n", error); + return error; } - return 0; + /* Disable IRQ until the device is opened */ + disable_irq(client->irq); -err_unregister_device: - input_unregister_device(cyapa->input); -err_mem_free: - kfree(cyapa); - - return ret; -} - -static int cyapa_remove(struct i2c_client *client) -{ - struct cyapa *cyapa = i2c_get_clientdata(client); - - free_irq(cyapa->irq, cyapa); - input_unregister_device(cyapa->input); - cyapa_set_power_mode(cyapa, PWR_MODE_OFF); - kfree(cyapa); + /* Register the device in input subsystem */ + error = input_register_device(cyapa->input); + if (error) { + dev_err(dev, "failed to register input device: %d\n", error); + return error; + } return 0; } -#ifdef CONFIG_PM_SLEEP -static int cyapa_suspend(struct device *dev) +static int __maybe_unused cyapa_suspend(struct device *dev) { - int ret; + struct i2c_client *client = to_i2c_client(dev); + struct cyapa *cyapa = i2c_get_clientdata(client); + struct input_dev *input = cyapa->input; u8 power_mode; - struct cyapa *cyapa = dev_get_drvdata(dev); + int error; - disable_irq(cyapa->irq); + error = mutex_lock_interruptible(&input->mutex); + if (error) + return error; + + disable_irq(client->irq); /* * Set trackpad device to idle mode if wakeup is allowed, @@ -920,31 +931,44 @@ static int cyapa_suspend(struct device *dev) */ power_mode = device_may_wakeup(dev) ? PWR_MODE_IDLE : PWR_MODE_OFF; - ret = cyapa_set_power_mode(cyapa, power_mode); - if (ret < 0) - dev_err(dev, "set power mode failed, %d\n", ret); + error = cyapa_set_power_mode(cyapa, power_mode); + if (error) + dev_err(dev, "resume: set power mode to %d failed: %d\n", + power_mode, error); if (device_may_wakeup(dev)) - cyapa->irq_wake = (enable_irq_wake(cyapa->irq) == 0); + cyapa->irq_wake = (enable_irq_wake(client->irq) == 0); + + mutex_unlock(&input->mutex); + return 0; } -static int cyapa_resume(struct device *dev) +static int __maybe_unused cyapa_resume(struct device *dev) { - int ret; - struct cyapa *cyapa = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + struct cyapa *cyapa = i2c_get_clientdata(client); + struct input_dev *input = cyapa->input; + u8 power_mode; + int error; + + mutex_lock(&input->mutex); if (device_may_wakeup(dev) && cyapa->irq_wake) - disable_irq_wake(cyapa->irq); + disable_irq_wake(client->irq); + + power_mode = input->users ? PWR_MODE_FULL_ACTIVE : PWR_MODE_OFF; + error = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE); + if (error) + dev_warn(dev, "resume: set power mode to %d failed: %d\n", + power_mode, error); + + enable_irq(client->irq); - ret = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE); - if (ret) - dev_warn(dev, "resume active power failed, %d\n", ret); + mutex_unlock(&input->mutex); - enable_irq(cyapa->irq); return 0; } -#endif /* CONFIG_PM_SLEEP */ static SIMPLE_DEV_PM_OPS(cyapa_pm_ops, cyapa_suspend, cyapa_resume); @@ -962,7 +986,6 @@ static struct i2c_driver cyapa_driver = { }, .probe = cyapa_probe, - .remove = cyapa_remove, .id_table = cyapa_id_table, }; diff --git a/drivers/input/mouse/elan_i2c.h b/drivers/input/mouse/elan_i2c.h new file mode 100644 index 000000000000..2e838626205f --- /dev/null +++ b/drivers/input/mouse/elan_i2c.h @@ -0,0 +1,86 @@ +/* + * Elan I2C/SMBus Touchpad driver + * + * Copyright (c) 2013 ELAN Microelectronics Corp. + * + * Author: æž—æ”¿ç¶ (Duson Lin) <dusonlin@emc.com.tw> + * Version: 1.5.5 + * + * Based on cyapa driver: + * copyright (c) 2011-2012 Cypress Semiconductor, Inc. + * copyright (c) 2011-2012 Google, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * Trademarks are the property of their respective owners. + */ + +#ifndef _ELAN_I2C_H +#define _ELAN_i2C_H + +#include <linux/types.h> + +#define ETP_ENABLE_ABS 0x0001 +#define ETP_ENABLE_CALIBRATE 0x0002 +#define ETP_DISABLE_CALIBRATE 0x0000 +#define ETP_DISABLE_POWER 0x0001 + +/* IAP Firmware handling */ +#define ETP_FW_NAME "elan_i2c.bin" +#define ETP_IAP_START_ADDR 0x0083 +#define ETP_FW_IAP_PAGE_ERR (1 << 5) +#define ETP_FW_IAP_INTF_ERR (1 << 4) +#define ETP_FW_PAGE_SIZE 64 +#define ETP_FW_PAGE_COUNT 768 +#define ETP_FW_SIZE (ETP_FW_PAGE_SIZE * ETP_FW_PAGE_COUNT) + +struct i2c_client; +struct completion; + +enum tp_mode { + IAP_MODE = 1, + MAIN_MODE +}; + +struct elan_transport_ops { + int (*initialize)(struct i2c_client *client); + int (*sleep_control)(struct i2c_client *, bool sleep); + int (*power_control)(struct i2c_client *, bool enable); + int (*set_mode)(struct i2c_client *client, u8 mode); + + int (*calibrate)(struct i2c_client *client); + int (*calibrate_result)(struct i2c_client *client, u8 *val); + + int (*get_baseline_data)(struct i2c_client *client, + bool max_baseliune, u8 *value); + + int (*get_version)(struct i2c_client *client, bool iap, u8 *version); + int (*get_sm_version)(struct i2c_client *client, u8 *version); + int (*get_checksum)(struct i2c_client *client, bool iap, u16 *csum); + int (*get_product_id)(struct i2c_client *client, u8 *id); + + int (*get_max)(struct i2c_client *client, + unsigned int *max_x, unsigned int *max_y); + int (*get_resolution)(struct i2c_client *client, + u8 *hw_res_x, u8 *hw_res_y); + int (*get_num_traces)(struct i2c_client *client, + unsigned int *x_tracenum, + unsigned int *y_tracenum); + + int (*iap_get_mode)(struct i2c_client *client, enum tp_mode *mode); + int (*iap_reset)(struct i2c_client *client); + + int (*prepare_fw_update)(struct i2c_client *client); + int (*write_fw_block)(struct i2c_client *client, + const u8 *page, u16 checksum, int idx); + int (*finish_fw_update)(struct i2c_client *client, + struct completion *reset_done); + + int (*get_report)(struct i2c_client *client, u8 *report); +}; + +extern const struct elan_transport_ops elan_smbus_ops, elan_i2c_ops; + +#endif /* _ELAN_I2C_H */ diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c new file mode 100644 index 000000000000..0cb2be48d537 --- /dev/null +++ b/drivers/input/mouse/elan_i2c_core.c @@ -0,0 +1,1137 @@ +/* + * Elan I2C/SMBus Touchpad driver + * + * Copyright (c) 2013 ELAN Microelectronics Corp. + * + * Author: æž—æ”¿ç¶ (Duson Lin) <dusonlin@emc.com.tw> + * Version: 1.5.5 + * + * Based on cyapa driver: + * copyright (c) 2011-2012 Cypress Semiconductor, Inc. + * copyright (c) 2011-2012 Google, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * Trademarks are the property of their respective owners. + */ + +#include <linux/acpi.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/firmware.h> +#include <linux/i2c.h> +#include <linux/init.h> +#include <linux/input/mt.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/input.h> +#include <linux/uaccess.h> +#include <linux/jiffies.h> +#include <linux/completion.h> +#include <linux/of.h> +#include <linux/regulator/consumer.h> +#include <asm/unaligned.h> + +#include "elan_i2c.h" + +#define DRIVER_NAME "elan_i2c" +#define ELAN_DRIVER_VERSION "1.5.5" +#define ETP_PRESSURE_OFFSET 25 +#define ETP_MAX_PRESSURE 255 +#define ETP_FWIDTH_REDUCE 90 +#define ETP_FINGER_WIDTH 15 +#define ETP_RETRY_COUNT 3 + +#define ETP_MAX_FINGERS 5 +#define ETP_FINGER_DATA_LEN 5 +#define ETP_REPORT_ID 0x5D +#define ETP_REPORT_ID_OFFSET 2 +#define ETP_TOUCH_INFO_OFFSET 3 +#define ETP_FINGER_DATA_OFFSET 4 +#define ETP_MAX_REPORT_LEN 34 + +/* The main device structure */ +struct elan_tp_data { + struct i2c_client *client; + struct input_dev *input; + struct regulator *vcc; + + const struct elan_transport_ops *ops; + + /* for fw update */ + struct completion fw_completion; + bool in_fw_update; + + struct mutex sysfs_mutex; + + unsigned int max_x; + unsigned int max_y; + unsigned int width_x; + unsigned int width_y; + unsigned int x_res; + unsigned int y_res; + + u8 product_id; + u8 fw_version; + u8 sm_version; + u8 iap_version; + u16 fw_checksum; + + u8 mode; + + bool irq_wake; + + u8 min_baseline; + u8 max_baseline; + bool baseline_ready; +}; + +static int elan_enable_power(struct elan_tp_data *data) +{ + int repeat = ETP_RETRY_COUNT; + int error; + + error = regulator_enable(data->vcc); + if (error) { + dev_err(&data->client->dev, + "Failed to enable regulator: %d\n", error); + return error; + } + + do { + error = data->ops->power_control(data->client, true); + if (error >= 0) + return 0; + + msleep(30); + } while (--repeat > 0); + + return error; +} + +static int elan_disable_power(struct elan_tp_data *data) +{ + int repeat = ETP_RETRY_COUNT; + int error; + + do { + error = data->ops->power_control(data->client, false); + if (!error) { + error = regulator_disable(data->vcc); + if (error) { + dev_err(&data->client->dev, + "Failed to disable regulator: %d\n", + error); + /* Attempt to power the chip back up */ + data->ops->power_control(data->client, true); + break; + } + + return 0; + } + + msleep(30); + } while (--repeat > 0); + + return error; +} + +static int elan_sleep(struct elan_tp_data *data) +{ + int repeat = ETP_RETRY_COUNT; + int error; + + do { + error = data->ops->sleep_control(data->client, true); + if (!error) + return 0; + + msleep(30); + } while (--repeat > 0); + + return error; +} + +static int __elan_initialize(struct elan_tp_data *data) +{ + struct i2c_client *client = data->client; + int error; + + error = data->ops->initialize(client); + if (error) { + dev_err(&client->dev, "device initialize failed: %d\n", error); + return error; + } + + data->mode |= ETP_ENABLE_ABS; + error = data->ops->set_mode(client, data->mode); + if (error) { + dev_err(&client->dev, + "failed to switch to absolute mode: %d\n", error); + return error; + } + + error = data->ops->sleep_control(client, false); + if (error) { + dev_err(&client->dev, + "failed to wake device up: %d\n", error); + return error; + } + + return 0; +} + +static int elan_initialize(struct elan_tp_data *data) +{ + int repeat = ETP_RETRY_COUNT; + int error; + + do { + error = __elan_initialize(data); + if (!error) + return 0; + + repeat--; + msleep(30); + } while (--repeat > 0); + + return error; +} + +static int elan_query_device_info(struct elan_tp_data *data) +{ + int error; + + error = data->ops->get_product_id(data->client, &data->product_id); + if (error) + return error; + + error = data->ops->get_version(data->client, false, &data->fw_version); + if (error) + return error; + + error = data->ops->get_checksum(data->client, false, + &data->fw_checksum); + if (error) + return error; + + error = data->ops->get_sm_version(data->client, &data->sm_version); + if (error) + return error; + + error = data->ops->get_version(data->client, true, &data->iap_version); + if (error) + return error; + + return 0; +} + +static unsigned int elan_convert_resolution(u8 val) +{ + /* + * (value from firmware) * 10 + 790 = dpi + * + * We also have to convert dpi to dots/mm (*10/254 to avoid floating + * point). + */ + + return ((int)(char)val * 10 + 790) * 10 / 254; +} + +static int elan_query_device_parameters(struct elan_tp_data *data) +{ + unsigned int x_traces, y_traces; + u8 hw_x_res, hw_y_res; + int error; + + error = data->ops->get_max(data->client, &data->max_x, &data->max_y); + if (error) + return error; + + error = data->ops->get_num_traces(data->client, &x_traces, &y_traces); + if (error) + return error; + + data->width_x = data->max_x / x_traces; + data->width_y = data->max_y / y_traces; + + error = data->ops->get_resolution(data->client, &hw_x_res, &hw_y_res); + if (error) + return error; + + data->x_res = elan_convert_resolution(hw_x_res); + data->y_res = elan_convert_resolution(hw_y_res); + + return 0; +} + +/* + ********************************************************** + * IAP firmware updater related routines + ********************************************************** + */ +static int elan_write_fw_block(struct elan_tp_data *data, + const u8 *page, u16 checksum, int idx) +{ + int retry = ETP_RETRY_COUNT; + int error; + + do { + error = data->ops->write_fw_block(data->client, + page, checksum, idx); + if (!error) + return 0; + + dev_dbg(&data->client->dev, + "IAP retrying page %d (error: %d)\n", idx, error); + } while (--retry > 0); + + return error; +} + +static int __elan_update_firmware(struct elan_tp_data *data, + const struct firmware *fw) +{ + struct i2c_client *client = data->client; + struct device *dev = &client->dev; + int i, j; + int error; + u16 iap_start_addr; + u16 boot_page_count; + u16 sw_checksum = 0, fw_checksum = 0; + + error = data->ops->prepare_fw_update(client); + if (error) + return error; + + iap_start_addr = get_unaligned_le16(&fw->data[ETP_IAP_START_ADDR * 2]); + + boot_page_count = (iap_start_addr * 2) / ETP_FW_PAGE_SIZE; + for (i = boot_page_count; i < ETP_FW_PAGE_COUNT; i++) { + u16 checksum = 0; + const u8 *page = &fw->data[i * ETP_FW_PAGE_SIZE]; + + for (j = 0; j < ETP_FW_PAGE_SIZE; j += 2) + checksum += ((page[j + 1] << 8) | page[j]); + + error = elan_write_fw_block(data, page, checksum, i); + if (error) { + dev_err(dev, "write page %d fail: %d\n", i, error); + return error; + } + + sw_checksum += checksum; + } + + /* Wait WDT reset and power on reset */ + msleep(600); + + error = data->ops->finish_fw_update(client, &data->fw_completion); + if (error) + return error; + + error = data->ops->get_checksum(client, true, &fw_checksum); + if (error) + return error; + + if (sw_checksum != fw_checksum) { + dev_err(dev, "checksum diff sw=[%04X], fw=[%04X]\n", + sw_checksum, fw_checksum); + return -EIO; + } + + return 0; +} + +static int elan_update_firmware(struct elan_tp_data *data, + const struct firmware *fw) +{ + struct i2c_client *client = data->client; + int retval; + + dev_dbg(&client->dev, "Starting firmware update....\n"); + + disable_irq(client->irq); + data->in_fw_update = true; + + retval = __elan_update_firmware(data, fw); + if (retval) { + dev_err(&client->dev, "firmware update failed: %d\n", retval); + data->ops->iap_reset(client); + } else { + /* Reinitialize TP after fw is updated */ + elan_initialize(data); + elan_query_device_info(data); + } + + data->in_fw_update = false; + enable_irq(client->irq); + + return retval; +} + +/* + ******************************************************************* + * SYSFS attributes + ******************************************************************* + */ +static ssize_t elan_sysfs_read_fw_checksum(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "0x%04x\n", data->fw_checksum); +} + +static ssize_t elan_sysfs_read_product_id(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d.0\n", data->product_id); +} + +static ssize_t elan_sysfs_read_fw_ver(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d.0\n", data->fw_version); +} + +static ssize_t elan_sysfs_read_sm_ver(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d.0\n", data->sm_version); +} + +static ssize_t elan_sysfs_read_iap_ver(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d.0\n", data->iap_version); +} + +static ssize_t elan_sysfs_update_fw(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + const struct firmware *fw; + int error; + + error = request_firmware(&fw, ETP_FW_NAME, dev); + if (error) { + dev_err(dev, "cannot load firmware %s: %d\n", + ETP_FW_NAME, error); + return error; + } + + /* Firmware must be exactly PAGE_NUM * PAGE_SIZE bytes */ + if (fw->size != ETP_FW_SIZE) { + dev_err(dev, "invalid firmware size = %zu, expected %d.\n", + fw->size, ETP_FW_SIZE); + error = -EBADF; + goto out_release_fw; + } + + error = mutex_lock_interruptible(&data->sysfs_mutex); + if (error) + goto out_release_fw; + + error = elan_update_firmware(data, fw); + + mutex_unlock(&data->sysfs_mutex); + +out_release_fw: + release_firmware(fw); + return error ?: count; +} + +static ssize_t calibrate_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + int tries = 20; + int retval; + int error; + u8 val[3]; + + retval = mutex_lock_interruptible(&data->sysfs_mutex); + if (retval) + return retval; + + disable_irq(client->irq); + + data->mode |= ETP_ENABLE_CALIBRATE; + retval = data->ops->set_mode(client, data->mode); + if (retval) { + dev_err(dev, "failed to enable calibration mode: %d\n", + retval); + goto out; + } + + retval = data->ops->calibrate(client); + if (retval) { + dev_err(dev, "failed to start calibration: %d\n", + retval); + goto out_disable_calibrate; + } + + val[0] = 0xff; + do { + /* Wait 250ms before checking if calibration has completed. */ + msleep(250); + + retval = data->ops->calibrate_result(client, val); + if (retval) + dev_err(dev, "failed to check calibration result: %d\n", + retval); + else if (val[0] == 0) + break; /* calibration done */ + + } while (--tries); + + if (tries == 0) { + dev_err(dev, "failed to calibrate. Timeout.\n"); + retval = -ETIMEDOUT; + } + +out_disable_calibrate: + data->mode &= ~ETP_ENABLE_CALIBRATE; + error = data->ops->set_mode(data->client, data->mode); + if (error) { + dev_err(dev, "failed to disable calibration mode: %d\n", + error); + if (!retval) + retval = error; + } +out: + enable_irq(client->irq); + mutex_unlock(&data->sysfs_mutex); + return retval ?: count; +} + +static ssize_t elan_sysfs_read_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + int error; + enum tp_mode mode; + + error = mutex_lock_interruptible(&data->sysfs_mutex); + if (error) + return error; + + error = data->ops->iap_get_mode(data->client, &mode); + + mutex_unlock(&data->sysfs_mutex); + + if (error) + return error; + + return sprintf(buf, "%d\n", (int)mode); +} + +static DEVICE_ATTR(product_id, S_IRUGO, elan_sysfs_read_product_id, NULL); +static DEVICE_ATTR(firmware_version, S_IRUGO, elan_sysfs_read_fw_ver, NULL); +static DEVICE_ATTR(sample_version, S_IRUGO, elan_sysfs_read_sm_ver, NULL); +static DEVICE_ATTR(iap_version, S_IRUGO, elan_sysfs_read_iap_ver, NULL); +static DEVICE_ATTR(fw_checksum, S_IRUGO, elan_sysfs_read_fw_checksum, NULL); +static DEVICE_ATTR(mode, S_IRUGO, elan_sysfs_read_mode, NULL); +static DEVICE_ATTR(update_fw, S_IWUSR, NULL, elan_sysfs_update_fw); + +static DEVICE_ATTR_WO(calibrate); + +static struct attribute *elan_sysfs_entries[] = { + &dev_attr_product_id.attr, + &dev_attr_firmware_version.attr, + &dev_attr_sample_version.attr, + &dev_attr_iap_version.attr, + &dev_attr_fw_checksum.attr, + &dev_attr_calibrate.attr, + &dev_attr_mode.attr, + &dev_attr_update_fw.attr, + NULL, +}; + +static const struct attribute_group elan_sysfs_group = { + .attrs = elan_sysfs_entries, +}; + +static ssize_t acquire_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + int error; + int retval; + + retval = mutex_lock_interruptible(&data->sysfs_mutex); + if (retval) + return retval; + + disable_irq(client->irq); + + data->baseline_ready = false; + + data->mode |= ETP_ENABLE_CALIBRATE; + retval = data->ops->set_mode(data->client, data->mode); + if (retval) { + dev_err(dev, "Failed to enable calibration mode to get baseline: %d\n", + retval); + goto out; + } + + msleep(250); + + retval = data->ops->get_baseline_data(data->client, true, + &data->max_baseline); + if (retval) { + dev_err(dev, "Failed to read max baseline form device: %d\n", + retval); + goto out_disable_calibrate; + } + + retval = data->ops->get_baseline_data(data->client, false, + &data->min_baseline); + if (retval) { + dev_err(dev, "Failed to read min baseline form device: %d\n", + retval); + goto out_disable_calibrate; + } + + data->baseline_ready = true; + +out_disable_calibrate: + data->mode &= ~ETP_ENABLE_CALIBRATE; + error = data->ops->set_mode(data->client, data->mode); + if (error) { + dev_err(dev, "Failed to disable calibration mode after acquiring baseline: %d\n", + error); + if (!retval) + retval = error; + } +out: + enable_irq(client->irq); + mutex_unlock(&data->sysfs_mutex); + return retval ?: count; +} + +static ssize_t min_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + int retval; + + retval = mutex_lock_interruptible(&data->sysfs_mutex); + if (retval) + return retval; + + if (!data->baseline_ready) { + retval = -ENODATA; + goto out; + } + + retval = snprintf(buf, PAGE_SIZE, "%d", data->min_baseline); + +out: + mutex_unlock(&data->sysfs_mutex); + return retval; +} + +static ssize_t max_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + int retval; + + retval = mutex_lock_interruptible(&data->sysfs_mutex); + if (retval) + return retval; + + if (!data->baseline_ready) { + retval = -ENODATA; + goto out; + } + + retval = snprintf(buf, PAGE_SIZE, "%d", data->max_baseline); + +out: + mutex_unlock(&data->sysfs_mutex); + return retval; +} + + +static DEVICE_ATTR_WO(acquire); +static DEVICE_ATTR_RO(min); +static DEVICE_ATTR_RO(max); + +static struct attribute *elan_baseline_sysfs_entries[] = { + &dev_attr_acquire.attr, + &dev_attr_min.attr, + &dev_attr_max.attr, + NULL, +}; + +static const struct attribute_group elan_baseline_sysfs_group = { + .name = "baseline", + .attrs = elan_baseline_sysfs_entries, +}; + +static const struct attribute_group *elan_sysfs_groups[] = { + &elan_sysfs_group, + &elan_baseline_sysfs_group, + NULL +}; + +/* + ****************************************************************** + * Elan isr functions + ****************************************************************** + */ +static void elan_report_contact(struct elan_tp_data *data, + int contact_num, bool contact_valid, + u8 *finger_data) +{ + struct input_dev *input = data->input; + unsigned int pos_x, pos_y; + unsigned int pressure, mk_x, mk_y; + unsigned int area_x, area_y, major, minor, new_pressure; + + + if (contact_valid) { + pos_x = ((finger_data[0] & 0xf0) << 4) | + finger_data[1]; + pos_y = ((finger_data[0] & 0x0f) << 8) | + finger_data[2]; + mk_x = (finger_data[3] & 0x0f); + mk_y = (finger_data[3] >> 4); + pressure = finger_data[4]; + + if (pos_x > data->max_x || pos_y > data->max_y) { + dev_dbg(input->dev.parent, + "[%d] x=%d y=%d over max (%d, %d)", + contact_num, pos_x, pos_y, + data->max_x, data->max_y); + return; + } + + /* + * To avoid treating large finger as palm, let's reduce the + * width x and y per trace. + */ + area_x = mk_x * (data->width_x - ETP_FWIDTH_REDUCE); + area_y = mk_y * (data->width_y - ETP_FWIDTH_REDUCE); + + major = max(area_x, area_y); + minor = min(area_x, area_y); + + new_pressure = pressure + ETP_PRESSURE_OFFSET; + if (new_pressure > ETP_MAX_PRESSURE) + new_pressure = ETP_MAX_PRESSURE; + + input_mt_slot(input, contact_num); + input_mt_report_slot_state(input, MT_TOOL_FINGER, true); + input_report_abs(input, ABS_MT_POSITION_X, pos_x); + input_report_abs(input, ABS_MT_POSITION_Y, data->max_y - pos_y); + input_report_abs(input, ABS_MT_PRESSURE, new_pressure); + input_report_abs(input, ABS_TOOL_WIDTH, mk_x); + input_report_abs(input, ABS_MT_TOUCH_MAJOR, major); + input_report_abs(input, ABS_MT_TOUCH_MINOR, minor); + } else { + input_mt_slot(input, contact_num); + input_mt_report_slot_state(input, MT_TOOL_FINGER, false); + } +} + +static void elan_report_absolute(struct elan_tp_data *data, u8 *packet) +{ + struct input_dev *input = data->input; + u8 *finger_data = &packet[ETP_FINGER_DATA_OFFSET]; + int i; + u8 tp_info = packet[ETP_TOUCH_INFO_OFFSET]; + bool contact_valid; + + for (i = 0; i < ETP_MAX_FINGERS; i++) { + contact_valid = tp_info & (1U << (3 + i)); + elan_report_contact(data, i, contact_valid, finger_data); + + if (contact_valid) + finger_data += ETP_FINGER_DATA_LEN; + } + + input_report_key(input, BTN_LEFT, tp_info & 0x01); + input_mt_report_pointer_emulation(input, true); + input_sync(input); +} + +static irqreturn_t elan_isr(int irq, void *dev_id) +{ + struct elan_tp_data *data = dev_id; + struct device *dev = &data->client->dev; + int error; + u8 report[ETP_MAX_REPORT_LEN]; + + /* + * When device is connected to i2c bus, when all IAP page writes + * complete, the driver will receive interrupt and must read + * 0000 to confirm that IAP is finished. + */ + if (data->in_fw_update) { + complete(&data->fw_completion); + goto out; + } + + error = data->ops->get_report(data->client, report); + if (error) + goto out; + + if (report[ETP_REPORT_ID_OFFSET] != ETP_REPORT_ID) + dev_err(dev, "invalid report id data (%x)\n", + report[ETP_REPORT_ID_OFFSET]); + else + elan_report_absolute(data, report); + +out: + return IRQ_HANDLED; +} + +/* + ****************************************************************** + * Elan initialization functions + ****************************************************************** + */ +static int elan_setup_input_device(struct elan_tp_data *data) +{ + struct device *dev = &data->client->dev; + struct input_dev *input; + unsigned int max_width = max(data->width_x, data->width_y); + unsigned int min_width = min(data->width_x, data->width_y); + int error; + + input = devm_input_allocate_device(dev); + if (!input) + return -ENOMEM; + + input->name = "Elan Touchpad"; + input->id.bustype = BUS_I2C; + input_set_drvdata(input, data); + + error = input_mt_init_slots(input, ETP_MAX_FINGERS, + INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED); + if (error) { + dev_err(dev, "failed to initialize MT slots: %d\n", error); + return error; + } + + __set_bit(EV_ABS, input->evbit); + __set_bit(INPUT_PROP_POINTER, input->propbit); + __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); + __set_bit(BTN_LEFT, input->keybit); + + /* Set up ST parameters */ + input_set_abs_params(input, ABS_X, 0, data->max_x, 0, 0); + input_set_abs_params(input, ABS_Y, 0, data->max_y, 0, 0); + input_abs_set_res(input, ABS_X, data->x_res); + input_abs_set_res(input, ABS_Y, data->y_res); + input_set_abs_params(input, ABS_PRESSURE, 0, ETP_MAX_PRESSURE, 0, 0); + input_set_abs_params(input, ABS_TOOL_WIDTH, 0, ETP_FINGER_WIDTH, 0, 0); + + /* And MT parameters */ + input_set_abs_params(input, ABS_MT_POSITION_X, 0, data->max_x, 0, 0); + input_set_abs_params(input, ABS_MT_POSITION_Y, 0, data->max_y, 0, 0); + input_abs_set_res(input, ABS_MT_POSITION_X, data->x_res); + input_abs_set_res(input, ABS_MT_POSITION_Y, data->y_res); + input_set_abs_params(input, ABS_MT_PRESSURE, 0, + ETP_MAX_PRESSURE, 0, 0); + input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, + ETP_FINGER_WIDTH * max_width, 0, 0); + input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, + ETP_FINGER_WIDTH * min_width, 0, 0); + + data->input = input; + + return 0; +} + +static void elan_disable_regulator(void *_data) +{ + struct elan_tp_data *data = _data; + + regulator_disable(data->vcc); +} + +static void elan_remove_sysfs_groups(void *_data) +{ + struct elan_tp_data *data = _data; + + sysfs_remove_groups(&data->client->dev.kobj, elan_sysfs_groups); +} + +static int elan_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + const struct elan_transport_ops *transport_ops; + struct device *dev = &client->dev; + struct elan_tp_data *data; + unsigned long irqflags; + int error; + + if (IS_ENABLED(CONFIG_MOUSE_ELAN_I2C_I2C) && + i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + transport_ops = &elan_i2c_ops; + } else if (IS_ENABLED(CONFIG_MOUSE_ELAN_I2C_SMBUS) && + i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_BLOCK_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK)) { + transport_ops = &elan_smbus_ops; + } else { + dev_err(dev, "not a supported I2C/SMBus adapter\n"); + return -EIO; + } + + data = devm_kzalloc(&client->dev, sizeof(struct elan_tp_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; + + i2c_set_clientdata(client, data); + + data->ops = transport_ops; + data->client = client; + init_completion(&data->fw_completion); + mutex_init(&data->sysfs_mutex); + + data->vcc = devm_regulator_get(&client->dev, "vcc"); + if (IS_ERR(data->vcc)) { + error = PTR_ERR(data->vcc); + if (error != -EPROBE_DEFER) + dev_err(&client->dev, + "Failed to get 'vcc' regulator: %d\n", + error); + return error; + } + + error = regulator_enable(data->vcc); + if (error) { + dev_err(&client->dev, + "Failed to enable regulator: %d\n", error); + return error; + } + + error = devm_add_action(&client->dev, + elan_disable_regulator, data); + if (error) { + regulator_disable(data->vcc); + dev_err(&client->dev, + "Failed to add disable regulator action: %d\n", + error); + return error; + } + + /* Initialize the touchpad. */ + error = elan_initialize(data); + if (error) + return error; + + error = elan_query_device_info(data); + if (error) + return error; + + error = elan_query_device_parameters(data); + if (error) + return error; + + dev_dbg(&client->dev, + "Elan Touchpad Information:\n" + " Module product ID: 0x%04x\n" + " Firmware Version: 0x%04x\n" + " Sample Version: 0x%04x\n" + " IAP Version: 0x%04x\n" + " Max ABS X,Y: %d,%d\n" + " Width X,Y: %d,%d\n" + " Resolution X,Y: %d,%d (dots/mm)\n", + data->product_id, + data->fw_version, + data->sm_version, + data->iap_version, + data->max_x, data->max_y, + data->width_x, data->width_y, + data->x_res, data->y_res); + + /* Set up input device properties based on queried parameters. */ + error = elan_setup_input_device(data); + if (error) + return error; + + /* + * Systems using device tree should set up interrupt via DTS, + * the rest will use the default falling edge interrupts. + */ + irqflags = client->dev.of_node ? 0 : IRQF_TRIGGER_FALLING; + + error = devm_request_threaded_irq(&client->dev, client->irq, + NULL, elan_isr, + irqflags | IRQF_ONESHOT, + client->name, data); + if (error) { + dev_err(&client->dev, "cannot register irq=%d\n", client->irq); + return error; + } + + error = sysfs_create_groups(&client->dev.kobj, elan_sysfs_groups); + if (error) { + dev_err(&client->dev, "failed to create sysfs attributes: %d\n", + error); + return error; + } + + error = devm_add_action(&client->dev, + elan_remove_sysfs_groups, data); + if (error) { + elan_remove_sysfs_groups(data); + dev_err(&client->dev, + "Failed to add sysfs cleanup action: %d\n", + error); + return error; + } + + error = input_register_device(data->input); + if (error) { + dev_err(&client->dev, "failed to register input device: %d\n", + error); + return error; + } + + /* + * Systems using device tree should set up wakeup via DTS, + * the rest will configure device as wakeup source by default. + */ + if (!client->dev.of_node) + device_init_wakeup(&client->dev, true); + + return 0; +} + +static int __maybe_unused elan_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + int ret; + + /* + * We are taking the mutex to make sure sysfs operations are + * complete before we attempt to bring the device into low[er] + * power mode. + */ + ret = mutex_lock_interruptible(&data->sysfs_mutex); + if (ret) + return ret; + + disable_irq(client->irq); + + if (device_may_wakeup(dev)) { + ret = elan_sleep(data); + /* Enable wake from IRQ */ + data->irq_wake = (enable_irq_wake(client->irq) == 0); + } else { + ret = elan_disable_power(data); + } + + mutex_unlock(&data->sysfs_mutex); + return ret; +} + +static int __maybe_unused elan_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + int error; + + if (device_may_wakeup(dev) && data->irq_wake) { + disable_irq_wake(client->irq); + data->irq_wake = false; + } + + error = elan_enable_power(data); + if (error) + dev_err(dev, "power up when resuming failed: %d\n", error); + + error = elan_initialize(data); + if (error) + dev_err(dev, "initialize when resuming failed: %d\n", error); + + enable_irq(data->client->irq); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(elan_pm_ops, elan_suspend, elan_resume); + +static const struct i2c_device_id elan_id[] = { + { DRIVER_NAME, 0 }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, elan_id); + +#ifdef CONFIG_ACPI +static const struct acpi_device_id elan_acpi_id[] = { + { "ELAN0000", 0 }, + { } +}; +MODULE_DEVICE_TABLE(acpi, elan_acpi_id); +#endif + +#ifdef CONFIG_OF +static const struct of_device_id elan_of_match[] = { + { .compatible = "elan,ekth3000" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, elan_of_match); +#endif + +static struct i2c_driver elan_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .pm = &elan_pm_ops, + .acpi_match_table = ACPI_PTR(elan_acpi_id), + .of_match_table = of_match_ptr(elan_of_match), + }, + .probe = elan_probe, + .id_table = elan_id, +}; + +module_i2c_driver(elan_driver); + +MODULE_AUTHOR("Duson Lin <dusonlin@emc.com.tw>"); +MODULE_DESCRIPTION("Elan I2C/SMBus Touchpad driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(ELAN_DRIVER_VERSION); diff --git a/drivers/input/mouse/elan_i2c_i2c.c b/drivers/input/mouse/elan_i2c_i2c.c new file mode 100644 index 000000000000..97d4937fc244 --- /dev/null +++ b/drivers/input/mouse/elan_i2c_i2c.c @@ -0,0 +1,611 @@ +/* + * Elan I2C/SMBus Touchpad driver - I2C interface + * + * Copyright (c) 2013 ELAN Microelectronics Corp. + * + * Author: æž—æ”¿ç¶ (Duson Lin) <dusonlin@emc.com.tw> + * Version: 1.5.5 + * + * Based on cyapa driver: + * copyright (c) 2011-2012 Cypress Semiconductor, Inc. + * copyright (c) 2011-2012 Google, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * Trademarks are the property of their respective owners. + */ + +#include <linux/completion.h> +#include <linux/delay.h> +#include <linux/i2c.h> +#include <linux/interrupt.h> +#include <linux/jiffies.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <asm/unaligned.h> + +#include "elan_i2c.h" + +/* Elan i2c commands */ +#define ETP_I2C_RESET 0x0100 +#define ETP_I2C_WAKE_UP 0x0800 +#define ETP_I2C_SLEEP 0x0801 +#define ETP_I2C_DESC_CMD 0x0001 +#define ETP_I2C_REPORT_DESC_CMD 0x0002 +#define ETP_I2C_STAND_CMD 0x0005 +#define ETP_I2C_UNIQUEID_CMD 0x0101 +#define ETP_I2C_FW_VERSION_CMD 0x0102 +#define ETP_I2C_SM_VERSION_CMD 0x0103 +#define ETP_I2C_XY_TRACENUM_CMD 0x0105 +#define ETP_I2C_MAX_X_AXIS_CMD 0x0106 +#define ETP_I2C_MAX_Y_AXIS_CMD 0x0107 +#define ETP_I2C_RESOLUTION_CMD 0x0108 +#define ETP_I2C_IAP_VERSION_CMD 0x0110 +#define ETP_I2C_SET_CMD 0x0300 +#define ETP_I2C_POWER_CMD 0x0307 +#define ETP_I2C_FW_CHECKSUM_CMD 0x030F +#define ETP_I2C_IAP_CTRL_CMD 0x0310 +#define ETP_I2C_IAP_CMD 0x0311 +#define ETP_I2C_IAP_RESET_CMD 0x0314 +#define ETP_I2C_IAP_CHECKSUM_CMD 0x0315 +#define ETP_I2C_CALIBRATE_CMD 0x0316 +#define ETP_I2C_MAX_BASELINE_CMD 0x0317 +#define ETP_I2C_MIN_BASELINE_CMD 0x0318 + +#define ETP_I2C_REPORT_LEN 34 +#define ETP_I2C_DESC_LENGTH 30 +#define ETP_I2C_REPORT_DESC_LENGTH 158 +#define ETP_I2C_INF_LENGTH 2 +#define ETP_I2C_IAP_PASSWORD 0x1EA5 +#define ETP_I2C_IAP_RESET 0xF0F0 +#define ETP_I2C_MAIN_MODE_ON (1 << 9) +#define ETP_I2C_IAP_REG_L 0x01 +#define ETP_I2C_IAP_REG_H 0x06 + +static int elan_i2c_read_block(struct i2c_client *client, + u16 reg, u8 *val, u16 len) +{ + __le16 buf[] = { + cpu_to_le16(reg), + }; + struct i2c_msg msgs[] = { + { + .addr = client->addr, + .flags = client->flags & I2C_M_TEN, + .len = sizeof(buf), + .buf = (u8 *)buf, + }, + { + .addr = client->addr, + .flags = (client->flags & I2C_M_TEN) | I2C_M_RD, + .len = len, + .buf = val, + } + }; + int ret; + + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + return ret == ARRAY_SIZE(msgs) ? 0 : (ret < 0 ? ret : -EIO); +} + +static int elan_i2c_read_cmd(struct i2c_client *client, u16 reg, u8 *val) +{ + int retval; + + retval = elan_i2c_read_block(client, reg, val, ETP_I2C_INF_LENGTH); + if (retval < 0) { + dev_err(&client->dev, "reading cmd (0x%04x) fail.\n", reg); + return retval; + } + + return 0; +} + +static int elan_i2c_write_cmd(struct i2c_client *client, u16 reg, u16 cmd) +{ + __le16 buf[] = { + cpu_to_le16(reg), + cpu_to_le16(cmd), + }; + struct i2c_msg msg = { + .addr = client->addr, + .flags = client->flags & I2C_M_TEN, + .len = sizeof(buf), + .buf = (u8 *)buf, + }; + int ret; + + ret = i2c_transfer(client->adapter, &msg, 1); + return ret == 1 ? 0 : (ret < 0 ? ret : -EIO); +} + +static int elan_i2c_initialize(struct i2c_client *client) +{ + struct device *dev = &client->dev; + int error; + u8 val[256]; + + error = elan_i2c_write_cmd(client, ETP_I2C_STAND_CMD, ETP_I2C_RESET); + if (error) { + dev_err(dev, "device reset failed: %d\n", error); + return error; + } + + /* Wait for the device to reset */ + msleep(100); + + /* get reset acknowledgement 0000 */ + error = i2c_master_recv(client, val, ETP_I2C_INF_LENGTH); + if (error < 0) { + dev_err(dev, "failed to read reset response: %d\n", error); + return error; + } + + error = elan_i2c_read_block(client, ETP_I2C_DESC_CMD, + val, ETP_I2C_DESC_LENGTH); + if (error) { + dev_err(dev, "cannot get device descriptor: %d\n", error); + return error; + } + + error = elan_i2c_read_block(client, ETP_I2C_REPORT_DESC_CMD, + val, ETP_I2C_REPORT_DESC_LENGTH); + if (error) { + dev_err(dev, "fetching report descriptor failed.: %d\n", error); + return error; + } + + return 0; +} + +static int elan_i2c_sleep_control(struct i2c_client *client, bool sleep) +{ + return elan_i2c_write_cmd(client, ETP_I2C_STAND_CMD, + sleep ? ETP_I2C_SLEEP : ETP_I2C_WAKE_UP); +} + +static int elan_i2c_power_control(struct i2c_client *client, bool enable) +{ + u8 val[2]; + u16 reg; + int error; + + error = elan_i2c_read_cmd(client, ETP_I2C_POWER_CMD, val); + if (error) { + dev_err(&client->dev, + "failed to read current power state: %d\n", + error); + return error; + } + + reg = le16_to_cpup((__le16 *)val); + if (enable) + reg &= ~ETP_DISABLE_POWER; + else + reg |= ETP_DISABLE_POWER; + + error = elan_i2c_write_cmd(client, ETP_I2C_POWER_CMD, reg); + if (error) { + dev_err(&client->dev, + "failed to write current power state: %d\n", + error); + return error; + } + + return 0; +} + +static int elan_i2c_set_mode(struct i2c_client *client, u8 mode) +{ + return elan_i2c_write_cmd(client, ETP_I2C_SET_CMD, mode); +} + + +static int elan_i2c_calibrate(struct i2c_client *client) +{ + return elan_i2c_write_cmd(client, ETP_I2C_CALIBRATE_CMD, 1); +} + +static int elan_i2c_calibrate_result(struct i2c_client *client, u8 *val) +{ + return elan_i2c_read_block(client, ETP_I2C_CALIBRATE_CMD, val, 1); +} + +static int elan_i2c_get_baseline_data(struct i2c_client *client, + bool max_baseline, u8 *value) +{ + int error; + u8 val[3]; + + error = elan_i2c_read_cmd(client, + max_baseline ? ETP_I2C_MAX_BASELINE_CMD : + ETP_I2C_MIN_BASELINE_CMD, + val); + if (error) + return error; + + *value = le16_to_cpup((__le16 *)val); + + return 0; +} + +static int elan_i2c_get_version(struct i2c_client *client, + bool iap, u8 *version) +{ + int error; + u8 val[3]; + + error = elan_i2c_read_cmd(client, + iap ? ETP_I2C_IAP_VERSION_CMD : + ETP_I2C_FW_VERSION_CMD, + val); + if (error) { + dev_err(&client->dev, "failed to get %s version: %d\n", + iap ? "IAP" : "FW", error); + return error; + } + + *version = val[0]; + return 0; +} + +static int elan_i2c_get_sm_version(struct i2c_client *client, u8 *version) +{ + int error; + u8 val[3]; + + error = elan_i2c_read_cmd(client, ETP_I2C_SM_VERSION_CMD, val); + if (error) { + dev_err(&client->dev, "failed to get SM version: %d\n", error); + return error; + } + + *version = val[0]; + return 0; +} + +static int elan_i2c_get_product_id(struct i2c_client *client, u8 *id) +{ + int error; + u8 val[3]; + + error = elan_i2c_read_cmd(client, ETP_I2C_UNIQUEID_CMD, val); + if (error) { + dev_err(&client->dev, "failed to get product ID: %d\n", error); + return error; + } + + *id = val[0]; + return 0; +} + +static int elan_i2c_get_checksum(struct i2c_client *client, + bool iap, u16 *csum) +{ + int error; + u8 val[3]; + + error = elan_i2c_read_cmd(client, + iap ? ETP_I2C_IAP_CHECKSUM_CMD : + ETP_I2C_FW_CHECKSUM_CMD, + val); + if (error) { + dev_err(&client->dev, "failed to get %s checksum: %d\n", + iap ? "IAP" : "FW", error); + return error; + } + + *csum = le16_to_cpup((__le16 *)val); + return 0; +} + +static int elan_i2c_get_max(struct i2c_client *client, + unsigned int *max_x, unsigned int *max_y) +{ + int error; + u8 val[3]; + + error = elan_i2c_read_cmd(client, ETP_I2C_MAX_X_AXIS_CMD, val); + if (error) { + dev_err(&client->dev, "failed to get X dimension: %d\n", error); + return error; + } + + *max_x = le16_to_cpup((__le16 *)val) & 0x0fff; + + error = elan_i2c_read_cmd(client, ETP_I2C_MAX_Y_AXIS_CMD, val); + if (error) { + dev_err(&client->dev, "failed to get Y dimension: %d\n", error); + return error; + } + + *max_y = le16_to_cpup((__le16 *)val) & 0x0fff; + + return 0; +} + +static int elan_i2c_get_resolution(struct i2c_client *client, + u8 *hw_res_x, u8 *hw_res_y) +{ + int error; + u8 val[3]; + + error = elan_i2c_read_cmd(client, ETP_I2C_RESOLUTION_CMD, val); + if (error) { + dev_err(&client->dev, "failed to get resolution: %d\n", error); + return error; + } + + *hw_res_x = val[0]; + *hw_res_y = val[1]; + + return 0; +} + +static int elan_i2c_get_num_traces(struct i2c_client *client, + unsigned int *x_traces, + unsigned int *y_traces) +{ + int error; + u8 val[3]; + + error = elan_i2c_read_cmd(client, ETP_I2C_XY_TRACENUM_CMD, val); + if (error) { + dev_err(&client->dev, "failed to get trace info: %d\n", error); + return error; + } + + *x_traces = val[0] - 1; + *y_traces = val[1] - 1; + + return 0; +} + +static int elan_i2c_iap_get_mode(struct i2c_client *client, enum tp_mode *mode) +{ + int error; + u16 constant; + u8 val[3]; + + error = elan_i2c_read_cmd(client, ETP_I2C_IAP_CTRL_CMD, val); + if (error) { + dev_err(&client->dev, + "failed to read iap control register: %d\n", + error); + return error; + } + + constant = le16_to_cpup((__le16 *)val); + dev_dbg(&client->dev, "iap control reg: 0x%04x.\n", constant); + + *mode = (constant & ETP_I2C_MAIN_MODE_ON) ? MAIN_MODE : IAP_MODE; + + return 0; +} + +static int elan_i2c_iap_reset(struct i2c_client *client) +{ + int error; + + error = elan_i2c_write_cmd(client, ETP_I2C_IAP_RESET_CMD, + ETP_I2C_IAP_RESET); + if (error) { + dev_err(&client->dev, "cannot reset IC: %d\n", error); + return error; + } + + return 0; +} + +static int elan_i2c_set_flash_key(struct i2c_client *client) +{ + int error; + + error = elan_i2c_write_cmd(client, ETP_I2C_IAP_CMD, + ETP_I2C_IAP_PASSWORD); + if (error) { + dev_err(&client->dev, "cannot set flash key: %d\n", error); + return error; + } + + return 0; +} + +static int elan_i2c_prepare_fw_update(struct i2c_client *client) +{ + struct device *dev = &client->dev; + int error; + enum tp_mode mode; + u8 val[3]; + u16 password; + + /* Get FW in which mode (IAP_MODE/MAIN_MODE) */ + error = elan_i2c_iap_get_mode(client, &mode); + if (error) + return error; + + if (mode == IAP_MODE) { + /* Reset IC */ + error = elan_i2c_iap_reset(client); + if (error) + return error; + + msleep(30); + } + + /* Set flash key*/ + error = elan_i2c_set_flash_key(client); + if (error) + return error; + + /* Wait for F/W IAP initialization */ + msleep(mode == MAIN_MODE ? 100 : 30); + + /* Check if we are in IAP mode or not */ + error = elan_i2c_iap_get_mode(client, &mode); + if (error) + return error; + + if (mode == MAIN_MODE) { + dev_err(dev, "wrong mode: %d\n", mode); + return -EIO; + } + + /* Set flash key again */ + error = elan_i2c_set_flash_key(client); + if (error) + return error; + + /* Wait for F/W IAP initialization */ + msleep(30); + + /* read back to check we actually enabled successfully. */ + error = elan_i2c_read_cmd(client, ETP_I2C_IAP_CMD, val); + if (error) { + dev_err(dev, "cannot read iap password: %d\n", + error); + return error; + } + + password = le16_to_cpup((__le16 *)val); + if (password != ETP_I2C_IAP_PASSWORD) { + dev_err(dev, "wrong iap password: 0x%X\n", password); + return -EIO; + } + + return 0; +} + +static int elan_i2c_write_fw_block(struct i2c_client *client, + const u8 *page, u16 checksum, int idx) +{ + struct device *dev = &client->dev; + u8 page_store[ETP_FW_PAGE_SIZE + 4]; + u8 val[3]; + u16 result; + int ret, error; + + page_store[0] = ETP_I2C_IAP_REG_L; + page_store[1] = ETP_I2C_IAP_REG_H; + memcpy(&page_store[2], page, ETP_FW_PAGE_SIZE); + /* recode checksum at last two bytes */ + put_unaligned_le16(checksum, &page_store[ETP_FW_PAGE_SIZE + 2]); + + ret = i2c_master_send(client, page_store, sizeof(page_store)); + if (ret != sizeof(page_store)) { + error = ret < 0 ? ret : -EIO; + dev_err(dev, "Failed to write page %d: %d\n", idx, error); + return error; + } + + /* Wait for F/W to update one page ROM data. */ + msleep(20); + + error = elan_i2c_read_cmd(client, ETP_I2C_IAP_CTRL_CMD, val); + if (error) { + dev_err(dev, "Failed to read IAP write result: %d\n", error); + return error; + } + + result = le16_to_cpup((__le16 *)val); + if (result & (ETP_FW_IAP_PAGE_ERR | ETP_FW_IAP_INTF_ERR)) { + dev_err(dev, "IAP reports failed write: %04hx\n", + result); + return -EIO; + } + + return 0; +} + +static int elan_i2c_finish_fw_update(struct i2c_client *client, + struct completion *completion) +{ + struct device *dev = &client->dev; + long ret; + int error; + int len; + u8 buffer[ETP_I2C_INF_LENGTH]; + + reinit_completion(completion); + enable_irq(client->irq); + + error = elan_i2c_write_cmd(client, ETP_I2C_STAND_CMD, ETP_I2C_RESET); + if (!error) + ret = wait_for_completion_interruptible_timeout(completion, + msecs_to_jiffies(300)); + disable_irq(client->irq); + + if (error) { + dev_err(dev, "device reset failed: %d\n", error); + return error; + } else if (ret == 0) { + dev_err(dev, "timeout waiting for device reset\n"); + return -ETIMEDOUT; + } else if (ret < 0) { + error = ret; + dev_err(dev, "error waiting for device reset: %d\n", error); + return error; + } + + len = i2c_master_recv(client, buffer, ETP_I2C_INF_LENGTH); + if (len != ETP_I2C_INF_LENGTH) { + error = len < 0 ? len : -EIO; + dev_err(dev, "failed to read INT signal: %d (%d)\n", + error, len); + return error; + } + + return 0; +} + +static int elan_i2c_get_report(struct i2c_client *client, u8 *report) +{ + int len; + + len = i2c_master_recv(client, report, ETP_I2C_REPORT_LEN); + if (len < 0) { + dev_err(&client->dev, "failed to read report data: %d\n", len); + return len; + } + + if (len != ETP_I2C_REPORT_LEN) { + dev_err(&client->dev, + "wrong report length (%d vs %d expected)\n", + len, ETP_I2C_REPORT_LEN); + return -EIO; + } + + return 0; +} + +const struct elan_transport_ops elan_i2c_ops = { + .initialize = elan_i2c_initialize, + .sleep_control = elan_i2c_sleep_control, + .power_control = elan_i2c_power_control, + .set_mode = elan_i2c_set_mode, + + .calibrate = elan_i2c_calibrate, + .calibrate_result = elan_i2c_calibrate_result, + + .get_baseline_data = elan_i2c_get_baseline_data, + + .get_version = elan_i2c_get_version, + .get_sm_version = elan_i2c_get_sm_version, + .get_product_id = elan_i2c_get_product_id, + .get_checksum = elan_i2c_get_checksum, + + .get_max = elan_i2c_get_max, + .get_resolution = elan_i2c_get_resolution, + .get_num_traces = elan_i2c_get_num_traces, + + .iap_get_mode = elan_i2c_iap_get_mode, + .iap_reset = elan_i2c_iap_reset, + + .prepare_fw_update = elan_i2c_prepare_fw_update, + .write_fw_block = elan_i2c_write_fw_block, + .finish_fw_update = elan_i2c_finish_fw_update, + + .get_report = elan_i2c_get_report, +}; diff --git a/drivers/input/mouse/elan_i2c_smbus.c b/drivers/input/mouse/elan_i2c_smbus.c new file mode 100644 index 000000000000..359bf8583d54 --- /dev/null +++ b/drivers/input/mouse/elan_i2c_smbus.c @@ -0,0 +1,514 @@ +/* + * Elan I2C/SMBus Touchpad driver - SMBus interface + * + * Copyright (c) 2013 ELAN Microelectronics Corp. + * + * Author: æž—æ”¿ç¶ (Duson Lin) <dusonlin@emc.com.tw> + * Version: 1.5.5 + * + * Based on cyapa driver: + * copyright (c) 2011-2012 Cypress Semiconductor, Inc. + * copyright (c) 2011-2012 Google, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * Trademarks are the property of their respective owners. + */ + +#include <linux/delay.h> +#include <linux/i2c.h> +#include <linux/init.h> +#include <linux/kernel.h> + +#include "elan_i2c.h" + +/* Elan SMbus commands */ +#define ETP_SMBUS_IAP_CMD 0x00 +#define ETP_SMBUS_ENABLE_TP 0x20 +#define ETP_SMBUS_SLEEP_CMD 0x21 +#define ETP_SMBUS_IAP_PASSWORD_WRITE 0x29 +#define ETP_SMBUS_IAP_PASSWORD_READ 0x80 +#define ETP_SMBUS_WRITE_FW_BLOCK 0x2A +#define ETP_SMBUS_IAP_RESET_CMD 0x2B +#define ETP_SMBUS_RANGE_CMD 0xA0 +#define ETP_SMBUS_FW_VERSION_CMD 0xA1 +#define ETP_SMBUS_XY_TRACENUM_CMD 0xA2 +#define ETP_SMBUS_SM_VERSION_CMD 0xA3 +#define ETP_SMBUS_UNIQUEID_CMD 0xA3 +#define ETP_SMBUS_RESOLUTION_CMD 0xA4 +#define ETP_SMBUS_HELLOPACKET_CMD 0xA7 +#define ETP_SMBUS_PACKET_QUERY 0xA8 +#define ETP_SMBUS_IAP_VERSION_CMD 0xAC +#define ETP_SMBUS_IAP_CTRL_CMD 0xAD +#define ETP_SMBUS_IAP_CHECKSUM_CMD 0xAE +#define ETP_SMBUS_FW_CHECKSUM_CMD 0xAF +#define ETP_SMBUS_MAX_BASELINE_CMD 0xC3 +#define ETP_SMBUS_MIN_BASELINE_CMD 0xC4 +#define ETP_SMBUS_CALIBRATE_QUERY 0xC5 + +#define ETP_SMBUS_REPORT_LEN 32 +#define ETP_SMBUS_REPORT_OFFSET 2 +#define ETP_SMBUS_HELLOPACKET_LEN 5 +#define ETP_SMBUS_IAP_PASSWORD 0x1234 +#define ETP_SMBUS_IAP_MODE_ON (1 << 6) + +static int elan_smbus_initialize(struct i2c_client *client) +{ + u8 check[ETP_SMBUS_HELLOPACKET_LEN] = { 0x55, 0x55, 0x55, 0x55, 0x55 }; + u8 values[ETP_SMBUS_HELLOPACKET_LEN] = { 0, 0, 0, 0, 0 }; + int len, error; + + /* Get hello packet */ + len = i2c_smbus_read_block_data(client, + ETP_SMBUS_HELLOPACKET_CMD, values); + if (len != ETP_SMBUS_HELLOPACKET_LEN) { + dev_err(&client->dev, "hello packet length fail: %d\n", len); + error = len < 0 ? len : -EIO; + return error; + } + + /* compare hello packet */ + if (memcmp(values, check, ETP_SMBUS_HELLOPACKET_LEN)) { + dev_err(&client->dev, "hello packet fail [%*px]\n", + ETP_SMBUS_HELLOPACKET_LEN, values); + return -ENXIO; + } + + /* enable tp */ + error = i2c_smbus_write_byte(client, ETP_SMBUS_ENABLE_TP); + if (error) { + dev_err(&client->dev, "failed to enable touchpad: %d\n", error); + return error; + } + + return 0; +} + +static int elan_smbus_set_mode(struct i2c_client *client, u8 mode) +{ + u8 cmd[4] = { 0x00, 0x07, 0x00, mode }; + + return i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD, + sizeof(cmd), cmd); +} + +static int elan_smbus_sleep_control(struct i2c_client *client, bool sleep) +{ + if (sleep) + return i2c_smbus_write_byte(client, ETP_SMBUS_SLEEP_CMD); + else + return 0; /* XXX should we send ETP_SMBUS_ENABLE_TP here? */ +} + +static int elan_smbus_power_control(struct i2c_client *client, bool enable) +{ + return 0; /* A no-op */ +} + +static int elan_smbus_calibrate(struct i2c_client *client) +{ + u8 cmd[4] = { 0x00, 0x08, 0x00, 0x01 }; + + return i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD, + sizeof(cmd), cmd); +} + +static int elan_smbus_calibrate_result(struct i2c_client *client, u8 *val) +{ + int error; + + error = i2c_smbus_read_block_data(client, + ETP_SMBUS_CALIBRATE_QUERY, val); + if (error < 0) + return error; + + return 0; +} + +static int elan_smbus_get_baseline_data(struct i2c_client *client, + bool max_baseline, u8 *value) +{ + int error; + u8 val[3]; + + error = i2c_smbus_read_block_data(client, + max_baseline ? + ETP_SMBUS_MAX_BASELINE_CMD : + ETP_SMBUS_MIN_BASELINE_CMD, + val); + if (error < 0) + return error; + + *value = be16_to_cpup((__be16 *)val); + + return 0; +} + +static int elan_smbus_get_version(struct i2c_client *client, + bool iap, u8 *version) +{ + int error; + u8 val[3]; + + error = i2c_smbus_read_block_data(client, + iap ? ETP_SMBUS_IAP_VERSION_CMD : + ETP_SMBUS_FW_VERSION_CMD, + val); + if (error < 0) { + dev_err(&client->dev, "failed to get %s version: %d\n", + iap ? "IAP" : "FW", error); + return error; + } + + *version = val[2]; + return 0; +} + +static int elan_smbus_get_sm_version(struct i2c_client *client, u8 *version) +{ + int error; + u8 val[3]; + + error = i2c_smbus_read_block_data(client, + ETP_SMBUS_SM_VERSION_CMD, val); + if (error < 0) { + dev_err(&client->dev, "failed to get SM version: %d\n", error); + return error; + } + + *version = val[0]; /* XXX Why 0 and not 2 as in IAP/FW versions? */ + return 0; +} + +static int elan_smbus_get_product_id(struct i2c_client *client, u8 *id) +{ + int error; + u8 val[3]; + + error = i2c_smbus_read_block_data(client, + ETP_SMBUS_UNIQUEID_CMD, val); + if (error < 0) { + dev_err(&client->dev, "failed to get product ID: %d\n", error); + return error; + } + + *id = val[1]; + return 0; +} + +static int elan_smbus_get_checksum(struct i2c_client *client, + bool iap, u16 *csum) +{ + int error; + u8 val[3]; + + error = i2c_smbus_read_block_data(client, + iap ? ETP_SMBUS_FW_CHECKSUM_CMD : + ETP_SMBUS_IAP_CHECKSUM_CMD, + val); + if (error < 0) { + dev_err(&client->dev, "failed to get %s checksum: %d\n", + iap ? "IAP" : "FW", error); + return error; + } + + *csum = be16_to_cpup((__be16 *)val); + return 0; +} + +static int elan_smbus_get_max(struct i2c_client *client, + unsigned int *max_x, unsigned int *max_y) +{ + int error; + u8 val[3]; + + error = i2c_smbus_read_block_data(client, ETP_SMBUS_RANGE_CMD, val); + if (error) { + dev_err(&client->dev, "failed to get dimensions: %d\n", error); + return error; + } + + *max_x = (0x0f & val[0]) << 8 | val[1]; + *max_y = (0xf0 & val[0]) << 4 | val[2]; + + return 0; +} + +static int elan_smbus_get_resolution(struct i2c_client *client, + u8 *hw_res_x, u8 *hw_res_y) +{ + int error; + u8 val[3]; + + error = i2c_smbus_read_block_data(client, + ETP_SMBUS_RESOLUTION_CMD, val); + if (error) { + dev_err(&client->dev, "failed to get resolution: %d\n", error); + return error; + } + + *hw_res_x = val[1] & 0x0F; + *hw_res_y = (val[1] & 0xF0) >> 4; + + return 0; +} + +static int elan_smbus_get_num_traces(struct i2c_client *client, + unsigned int *x_traces, + unsigned int *y_traces) +{ + int error; + u8 val[3]; + + error = i2c_smbus_read_block_data(client, + ETP_SMBUS_XY_TRACENUM_CMD, val); + if (error) { + dev_err(&client->dev, "failed to get trace info: %d\n", error); + return error; + } + + *x_traces = val[1] - 1; + *y_traces = val[2] - 1; + + return 0; +} + +static int elan_smbus_iap_get_mode(struct i2c_client *client, + enum tp_mode *mode) +{ + int error; + u16 constant; + u8 val[3]; + + error = i2c_smbus_read_block_data(client, ETP_SMBUS_IAP_CTRL_CMD, val); + if (error < 0) { + dev_err(&client->dev, "failed to read iap ctrol register: %d\n", + error); + return error; + } + + constant = be16_to_cpup((__be16 *)val); + dev_dbg(&client->dev, "iap control reg: 0x%04x.\n", constant); + + *mode = (constant & ETP_SMBUS_IAP_MODE_ON) ? IAP_MODE : MAIN_MODE; + + return 0; +} + +static int elan_smbus_iap_reset(struct i2c_client *client) +{ + int error; + + error = i2c_smbus_write_byte(client, ETP_SMBUS_IAP_RESET_CMD); + if (error) { + dev_err(&client->dev, "cannot reset IC: %d\n", error); + return error; + } + + return 0; +} + +static int elan_smbus_set_flash_key(struct i2c_client *client) +{ + int error; + u8 cmd[4] = { 0x00, 0x0B, 0x00, 0x5A }; + + error = i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD, + sizeof(cmd), cmd); + if (error) { + dev_err(&client->dev, "cannot set flash key: %d\n", error); + return error; + } + + return 0; +} + +static int elan_smbus_prepare_fw_update(struct i2c_client *client) +{ + struct device *dev = &client->dev; + int len; + int error; + enum tp_mode mode; + u8 val[3]; + u8 cmd[4] = {0x0F, 0x78, 0x00, 0x06}; + u16 password; + + /* Get FW in which mode (IAP_MODE/MAIN_MODE) */ + error = elan_smbus_iap_get_mode(client, &mode); + if (error) + return error; + + if (mode == MAIN_MODE) { + + /* set flash key */ + error = elan_smbus_set_flash_key(client); + if (error) + return error; + + /* write iap password */ + if (i2c_smbus_write_byte(client, + ETP_SMBUS_IAP_PASSWORD_WRITE) < 0) { + dev_err(dev, "cannot write iap password\n"); + return -EIO; + } + + error = i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD, + sizeof(cmd), cmd); + if (error) { + dev_err(dev, "failed to write iap password: %d\n", + error); + return error; + } + + /* + * Read back password to make sure we enabled flash + * successfully. + */ + len = i2c_smbus_read_block_data(client, + ETP_SMBUS_IAP_PASSWORD_READ, + val); + if (len < sizeof(u16)) { + error = len < 0 ? len : -EIO; + dev_err(dev, "failed to read iap password: %d\n", + error); + return error; + } + + password = be16_to_cpup((__be16 *)val); + if (password != ETP_SMBUS_IAP_PASSWORD) { + dev_err(dev, "wrong iap password = 0x%X\n", password); + return -EIO; + } + + /* Wait 30ms for MAIN_MODE change to IAP_MODE */ + msleep(30); + } + + error = elan_smbus_set_flash_key(client); + if (error) + return error; + + /* Reset IC */ + error = elan_smbus_iap_reset(client); + if (error) + return error; + + return 0; +} + + +static int elan_smbus_write_fw_block(struct i2c_client *client, + const u8 *page, u16 checksum, int idx) +{ + struct device *dev = &client->dev; + int error; + u16 result; + u8 val[3]; + + /* + * Due to the limitation of smbus protocol limiting + * transfer to 32 bytes at a time, we must split block + * in 2 transfers. + */ + error = i2c_smbus_write_block_data(client, + ETP_SMBUS_WRITE_FW_BLOCK, + ETP_FW_PAGE_SIZE / 2, + page); + if (error) { + dev_err(dev, "Failed to write page %d (part %d): %d\n", + idx, 1, error); + return error; + } + + error = i2c_smbus_write_block_data(client, + ETP_SMBUS_WRITE_FW_BLOCK, + ETP_FW_PAGE_SIZE / 2, + page + ETP_FW_PAGE_SIZE / 2); + if (error) { + dev_err(dev, "Failed to write page %d (part %d): %d\n", + idx, 2, error); + return error; + } + + + /* Wait for F/W to update one page ROM data. */ + usleep_range(8000, 10000); + + error = i2c_smbus_read_block_data(client, + ETP_SMBUS_IAP_CTRL_CMD, val); + if (error < 0) { + dev_err(dev, "Failed to read IAP write result: %d\n", + error); + return error; + } + + result = be16_to_cpup((__be16 *)val); + if (result & (ETP_FW_IAP_PAGE_ERR | ETP_FW_IAP_INTF_ERR)) { + dev_err(dev, "IAP reports failed write: %04hx\n", + result); + return -EIO; + } + + return 0; +} + +static int elan_smbus_get_report(struct i2c_client *client, u8 *report) +{ + int len; + + len = i2c_smbus_read_block_data(client, + ETP_SMBUS_PACKET_QUERY, + &report[ETP_SMBUS_REPORT_OFFSET]); + if (len < 0) { + dev_err(&client->dev, "failed to read report data: %d\n", len); + return len; + } + + if (len != ETP_SMBUS_REPORT_LEN) { + dev_err(&client->dev, + "wrong report length (%d vs %d expected)\n", + len, ETP_SMBUS_REPORT_LEN); + return -EIO; + } + + return 0; +} + +static int elan_smbus_finish_fw_update(struct i2c_client *client, + struct completion *fw_completion) +{ + /* No special handling unlike I2C transport */ + return 0; +} + +const struct elan_transport_ops elan_smbus_ops = { + .initialize = elan_smbus_initialize, + .sleep_control = elan_smbus_sleep_control, + .power_control = elan_smbus_power_control, + .set_mode = elan_smbus_set_mode, + + .calibrate = elan_smbus_calibrate, + .calibrate_result = elan_smbus_calibrate_result, + + .get_baseline_data = elan_smbus_get_baseline_data, + + .get_version = elan_smbus_get_version, + .get_sm_version = elan_smbus_get_sm_version, + .get_product_id = elan_smbus_get_product_id, + .get_checksum = elan_smbus_get_checksum, + + .get_max = elan_smbus_get_max, + .get_resolution = elan_smbus_get_resolution, + .get_num_traces = elan_smbus_get_num_traces, + + .iap_get_mode = elan_smbus_iap_get_mode, + .iap_reset = elan_smbus_iap_reset, + + .prepare_fw_update = elan_smbus_prepare_fw_update, + .write_fw_block = elan_smbus_write_fw_block, + .finish_fw_update = elan_smbus_finish_fw_update, + + .get_report = elan_smbus_get_report, +}; diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index f2b978026407..77ecf6d32237 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -1520,6 +1520,8 @@ static int elantech_set_properties(struct elantech_data *etd) case 7: case 8: case 9: + case 10: + case 13: etd->hw_version = 4; break; default: diff --git a/drivers/input/mouse/lifebook.h b/drivers/input/mouse/lifebook.h index 4c4326c6f504..0baf02a70a99 100644 --- a/drivers/input/mouse/lifebook.h +++ b/drivers/input/mouse/lifebook.h @@ -16,14 +16,14 @@ void lifebook_module_init(void); int lifebook_detect(struct psmouse *psmouse, bool set_properties); int lifebook_init(struct psmouse *psmouse); #else -inline void lifebook_module_init(void) +static inline void lifebook_module_init(void) { } -inline int lifebook_detect(struct psmouse *psmouse, bool set_properties) +static inline int lifebook_detect(struct psmouse *psmouse, bool set_properties) { return -ENOSYS; } -inline int lifebook_init(struct psmouse *psmouse) +static inline int lifebook_init(struct psmouse *psmouse) { return -ENOSYS; } diff --git a/drivers/input/mouse/navpoint.c b/drivers/input/mouse/navpoint.c index 2a0360f5b5f7..d6e8f58a1de3 100644 --- a/drivers/input/mouse/navpoint.c +++ b/drivers/input/mouse/navpoint.c @@ -318,8 +318,7 @@ static int navpoint_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int navpoint_suspend(struct device *dev) +static int __maybe_unused navpoint_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct navpoint *navpoint = platform_get_drvdata(pdev); @@ -333,7 +332,7 @@ static int navpoint_suspend(struct device *dev) return 0; } -static int navpoint_resume(struct device *dev) +static int __maybe_unused navpoint_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct navpoint *navpoint = platform_get_drvdata(pdev); @@ -346,7 +345,6 @@ static int navpoint_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(navpoint_pm_ops, navpoint_suspend, navpoint_resume); diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c index ad822608f6ee..878f18498f3b 100644 --- a/drivers/input/mouse/synaptics_i2c.c +++ b/drivers/input/mouse/synaptics_i2c.c @@ -614,8 +614,7 @@ static int synaptics_i2c_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int synaptics_i2c_suspend(struct device *dev) +static int __maybe_unused synaptics_i2c_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct synaptics_i2c *touch = i2c_get_clientdata(client); @@ -628,7 +627,7 @@ static int synaptics_i2c_suspend(struct device *dev) return 0; } -static int synaptics_i2c_resume(struct device *dev) +static int __maybe_unused synaptics_i2c_resume(struct device *dev) { int ret; struct i2c_client *client = to_i2c_client(dev); @@ -643,7 +642,6 @@ static int synaptics_i2c_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(synaptics_i2c_pm, synaptics_i2c_suspend, synaptics_i2c_resume); diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index 30c8b6998808..354d47ecd66a 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c @@ -227,6 +227,7 @@ TRACKPOINT_INT_ATTR(thresh, TP_THRESH, TP_DEF_THRESH); TRACKPOINT_INT_ATTR(upthresh, TP_UP_THRESH, TP_DEF_UP_THRESH); TRACKPOINT_INT_ATTR(ztime, TP_Z_TIME, TP_DEF_Z_TIME); TRACKPOINT_INT_ATTR(jenks, TP_JENKS_CURV, TP_DEF_JENKS_CURV); +TRACKPOINT_INT_ATTR(drift_time, TP_DRIFT_TIME, TP_DEF_DRIFT_TIME); TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON, 0, TP_DEF_PTSON); @@ -246,6 +247,7 @@ static struct attribute *trackpoint_attrs[] = { &psmouse_attr_upthresh.dattr.attr, &psmouse_attr_ztime.dattr.attr, &psmouse_attr_jenks.dattr.attr, + &psmouse_attr_drift_time.dattr.attr, &psmouse_attr_press_to_select.dattr.attr, &psmouse_attr_skipback.dattr.attr, &psmouse_attr_ext_dev.dattr.attr, @@ -312,6 +314,7 @@ static int trackpoint_sync(struct psmouse *psmouse, bool in_power_on_state) TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, upthresh); TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, ztime); TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, jenks); + TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, drift_time); /* toggles */ TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, press_to_select); @@ -332,6 +335,7 @@ static void trackpoint_defaults(struct trackpoint_data *tp) TRACKPOINT_SET_POWER_ON_DEFAULT(tp, upthresh); TRACKPOINT_SET_POWER_ON_DEFAULT(tp, ztime); TRACKPOINT_SET_POWER_ON_DEFAULT(tp, jenks); + TRACKPOINT_SET_POWER_ON_DEFAULT(tp, drift_time); TRACKPOINT_SET_POWER_ON_DEFAULT(tp, inertia); /* toggles */ diff --git a/drivers/input/mouse/trackpoint.h b/drivers/input/mouse/trackpoint.h index ecd0547964a5..5617ed3a7d7a 100644 --- a/drivers/input/mouse/trackpoint.h +++ b/drivers/input/mouse/trackpoint.h @@ -70,6 +70,9 @@ #define TP_UP_THRESH 0x5A /* Used to generate a 'click' on Z-axis */ #define TP_Z_TIME 0x5E /* How sharp of a press */ #define TP_JENKS_CURV 0x5D /* Minimum curvature for double click */ +#define TP_DRIFT_TIME 0x5F /* How long a 'hands off' condition */ + /* must last (x*107ms) for drift */ + /* correction to occur */ /* * Toggling Flag bits @@ -120,6 +123,7 @@ #define TP_DEF_UP_THRESH 0xFF #define TP_DEF_Z_TIME 0x26 #define TP_DEF_JENKS_CURV 0x87 +#define TP_DEF_DRIFT_TIME 0x05 /* Toggles */ #define TP_DEF_MB 0x00 @@ -137,6 +141,7 @@ struct trackpoint_data unsigned char draghys, mindrag; unsigned char thresh, upthresh; unsigned char ztime, jenks; + unsigned char drift_time; /* toggles */ unsigned char press_to_select; diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c index 8921c96589be..131d7826dc6b 100644 --- a/drivers/input/serio/altera_ps2.c +++ b/drivers/input/serio/altera_ps2.c @@ -24,9 +24,7 @@ struct ps2if { struct serio *io; - struct resource *iomem_res; void __iomem *base; - unsigned irq; }; /* @@ -83,16 +81,34 @@ static void altera_ps2_close(struct serio *io) static int altera_ps2_probe(struct platform_device *pdev) { struct ps2if *ps2if; + struct resource *res; struct serio *serio; int error, irq; - ps2if = kzalloc(sizeof(struct ps2if), GFP_KERNEL); - serio = kzalloc(sizeof(struct serio), GFP_KERNEL); - if (!ps2if || !serio) { - error = -ENOMEM; - goto err_free_mem; + ps2if = devm_kzalloc(&pdev->dev, sizeof(struct ps2if), GFP_KERNEL); + if (!ps2if) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + ps2if->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(ps2if->base)) + return PTR_ERR(ps2if->base); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return -ENXIO; + + error = devm_request_irq(&pdev->dev, irq, altera_ps2_rxint, 0, + pdev->name, ps2if); + if (error) { + dev_err(&pdev->dev, "could not request IRQ %d\n", irq); + return error; } + serio = kzalloc(sizeof(struct serio), GFP_KERNEL); + if (!serio) + return -ENOMEM; + serio->id.type = SERIO_8042; serio->write = altera_ps2_write; serio->open = altera_ps2_open; @@ -103,56 +119,12 @@ static int altera_ps2_probe(struct platform_device *pdev) serio->dev.parent = &pdev->dev; ps2if->io = serio; - ps2if->iomem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (ps2if->iomem_res == NULL) { - error = -ENOENT; - goto err_free_mem; - } - - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - error = -ENXIO; - goto err_free_mem; - } - ps2if->irq = irq; - - if (!request_mem_region(ps2if->iomem_res->start, - resource_size(ps2if->iomem_res), pdev->name)) { - error = -EBUSY; - goto err_free_mem; - } - - ps2if->base = ioremap(ps2if->iomem_res->start, - resource_size(ps2if->iomem_res)); - if (!ps2if->base) { - error = -ENOMEM; - goto err_free_res; - } - - error = request_irq(ps2if->irq, altera_ps2_rxint, 0, pdev->name, ps2if); - if (error) { - dev_err(&pdev->dev, "could not allocate IRQ %d: %d\n", - ps2if->irq, error); - goto err_unmap; - } - - dev_info(&pdev->dev, "base %p, irq %d\n", ps2if->base, ps2if->irq); + dev_info(&pdev->dev, "base %p, irq %d\n", ps2if->base, irq); serio_register_port(ps2if->io); platform_set_drvdata(pdev, ps2if); return 0; - - err_unmap: - iounmap(ps2if->base); - err_free_res: - release_mem_region(ps2if->iomem_res->start, - resource_size(ps2if->iomem_res)); - err_free_mem: - kfree(ps2if); - kfree(serio); - return error; } /* @@ -163,11 +135,6 @@ static int altera_ps2_remove(struct platform_device *pdev) struct ps2if *ps2if = platform_get_drvdata(pdev); serio_unregister_port(ps2if->io); - free_irq(ps2if->irq, ps2if); - iounmap(ps2if->base); - release_mem_region(ps2if->iomem_res->start, - resource_size(ps2if->iomem_res)); - kfree(ps2if); return 0; } diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index faeeb1372462..764857b4e268 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -415,6 +415,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { }, }, { + /* Acer Aspire 7738 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7738"), + }, + }, + { /* Gericom Bellagio */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Gericom"), @@ -579,6 +586,16 @@ static const struct dmi_system_id __initconst i8042_dmi_nopnp_table[] = { }, }, { + /* + * Intel NUC D54250WYK - does not have i8042 controller but + * declares PS/2 devices in DSDT. + */ + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "D54250WYK"), + DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), + }, + }, + { /* MSI Wind U-100 */ .matches = { DMI_MATCH(DMI_BOARD_NAME, "U-100"), @@ -735,6 +752,35 @@ static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = { { } }; +/* + * Some laptops need keyboard reset before probing for the trackpad to get + * it detected, initialised & finally work. + */ +static const struct dmi_system_id __initconst i8042_dmi_kbdreset_table[] = { + { + /* Gigabyte P35 v2 - Elantech touchpad */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "P35V2"), + }, + }, + { + /* Aorus branded Gigabyte X3 Plus - Elantech touchpad */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "X3"), + }, + }, + { + /* Gigabyte P34 - Elantech touchpad */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "P34"), + }, + }, + { } +}; + #endif /* CONFIG_X86 */ #ifdef CONFIG_PNP @@ -1030,6 +1076,9 @@ static int __init i8042_platform_init(void) if (dmi_check_system(i8042_dmi_dritek_table)) i8042_dritek = true; + if (dmi_check_system(i8042_dmi_kbdreset_table)) + i8042_kbdreset = true; + /* * A20 was already enabled during early kernel init. But some buggy * BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 924e4bf357fb..986a71c614b0 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -67,6 +67,10 @@ static bool i8042_notimeout; module_param_named(notimeout, i8042_notimeout, bool, 0); MODULE_PARM_DESC(notimeout, "Ignore timeouts signalled by i8042"); +static bool i8042_kbdreset; +module_param_named(kbdreset, i8042_kbdreset, bool, 0); +MODULE_PARM_DESC(kbdreset, "Reset device connected to KBD port"); + #ifdef CONFIG_X86 static bool i8042_dritek; module_param_named(dritek, i8042_dritek, bool, 0); @@ -790,6 +794,16 @@ static int __init i8042_check_aux(void) return -1; /* + * Reset keyboard (needed on some laptops to successfully detect + * touchpad, e.g., some Gigabyte laptop models with Elantech + * touchpads). + */ + if (i8042_kbdreset) { + pr_warn("Attempting to reset device connected to KBD port\n"); + i8042_kbd_write(NULL, (unsigned char) 0xff); + } + +/* * Test AUX IRQ delivery to make sure BIOS did not grab the IRQ and * used it for a PCI card or somethig else. */ diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index d399b8b0f000..a05a5179da32 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -514,7 +514,7 @@ static void serio_release_port(struct device *dev) */ static void serio_init_port(struct serio *serio) { - static atomic_t serio_no = ATOMIC_INIT(0); + static atomic_t serio_no = ATOMIC_INIT(-1); __module_get(THIS_MODULE); @@ -525,7 +525,7 @@ static void serio_init_port(struct serio *serio) mutex_init(&serio->drv_mutex); device_initialize(&serio->dev); dev_set_name(&serio->dev, "serio%lu", - (unsigned long)atomic_inc_return(&serio_no) - 1); + (unsigned long)atomic_inc_return(&serio_no)); serio->dev.bus = &serio_bus; serio->dev.release = serio_release_port; serio->dev.groups = serio_device_attr_groups; diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index c9a02fe57576..71ef5d65a0c6 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c @@ -292,7 +292,7 @@ static irqreturn_t serio_raw_interrupt(struct serio *serio, unsigned char data, static int serio_raw_connect(struct serio *serio, struct serio_driver *drv) { - static atomic_t serio_raw_no = ATOMIC_INIT(0); + static atomic_t serio_raw_no = ATOMIC_INIT(-1); struct serio_raw *serio_raw; int err; @@ -303,7 +303,7 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv) } snprintf(serio_raw->name, sizeof(serio_raw->name), - "serio_raw%ld", (long)atomic_inc_return(&serio_raw_no) - 1); + "serio_raw%ld", (long)atomic_inc_return(&serio_raw_no)); kref_init(&serio_raw->kref); INIT_LIST_HEAD(&serio_raw->client_list); init_waitqueue_head(&serio_raw->wait); diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index e1d8003d01f8..58917525126e 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -295,6 +295,19 @@ config TOUCHSCREEN_FUJITSU To compile this driver as a module, choose M here: the module will be called fujitsu-ts. +config TOUCHSCREEN_GOODIX + tristate "Goodix I2C touchscreen" + depends on I2C && ACPI + help + Say Y here if you have the Goodix touchscreen (such as one + installed in Onda v975w tablets) connected to your + system. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called goodix. + config TOUCHSCREEN_ILI210X tristate "Ilitek ILI210X based touchscreen" depends on I2C @@ -334,6 +347,18 @@ config TOUCHSCREEN_GUNZE To compile this driver as a module, choose M here: the module will be called gunze. +config TOUCHSCREEN_ELAN + tristate "Elan eKTH I2C touchscreen" + depends on I2C + help + Say Y here if you have an Elan eKTH I2C touchscreen + connected to your system. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called elants_i2c. + config TOUCHSCREEN_ELO tristate "Elo serial touchscreens" select SERIO diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 090e61cc9171..0242fea2102a 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -31,9 +31,11 @@ obj-$(CONFIG_TOUCHSCREEN_EDT_FT5X06) += edt-ft5x06.o obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o +obj-$(CONFIG_TOUCHSCREEN_ELAN) += elants_i2c.o obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o obj-$(CONFIG_TOUCHSCREEN_EGALAX) += egalax_ts.o obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o +obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix.o obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c index 523865daa1d3..da4e5bb5e045 100644 --- a/drivers/input/touchscreen/ad7877.c +++ b/drivers/input/touchscreen/ad7877.c @@ -820,8 +820,7 @@ static int ad7877_remove(struct spi_device *spi) return 0; } -#ifdef CONFIG_PM_SLEEP -static int ad7877_suspend(struct device *dev) +static int __maybe_unused ad7877_suspend(struct device *dev) { struct ad7877 *ts = dev_get_drvdata(dev); @@ -830,7 +829,7 @@ static int ad7877_suspend(struct device *dev) return 0; } -static int ad7877_resume(struct device *dev) +static int __maybe_unused ad7877_resume(struct device *dev) { struct ad7877 *ts = dev_get_drvdata(dev); @@ -838,7 +837,6 @@ static int ad7877_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(ad7877_pm, ad7877_suspend, ad7877_resume); diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c index 1eb9d3c20886..fec66ad80513 100644 --- a/drivers/input/touchscreen/ad7879.c +++ b/drivers/input/touchscreen/ad7879.c @@ -284,8 +284,7 @@ static void ad7879_close(struct input_dev* input) __ad7879_disable(ts); } -#ifdef CONFIG_PM_SLEEP -static int ad7879_suspend(struct device *dev) +static int __maybe_unused ad7879_suspend(struct device *dev) { struct ad7879 *ts = dev_get_drvdata(dev); @@ -301,7 +300,7 @@ static int ad7879_suspend(struct device *dev) return 0; } -static int ad7879_resume(struct device *dev) +static int __maybe_unused ad7879_resume(struct device *dev) { struct ad7879 *ts = dev_get_drvdata(dev); @@ -316,7 +315,6 @@ static int ad7879_resume(struct device *dev) return 0; } -#endif SIMPLE_DEV_PM_OPS(ad7879_pm_ops, ad7879_suspend, ad7879_resume); EXPORT_SYMBOL(ad7879_pm_ops); diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index e57ba52bf484..e4eb8a6c658f 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -883,8 +883,7 @@ static irqreturn_t ads7846_irq(int irq, void *handle) return IRQ_HANDLED; } -#ifdef CONFIG_PM_SLEEP -static int ads7846_suspend(struct device *dev) +static int __maybe_unused ads7846_suspend(struct device *dev) { struct ads7846 *ts = dev_get_drvdata(dev); @@ -906,7 +905,7 @@ static int ads7846_suspend(struct device *dev) return 0; } -static int ads7846_resume(struct device *dev) +static int __maybe_unused ads7846_resume(struct device *dev) { struct ads7846 *ts = dev_get_drvdata(dev); @@ -927,7 +926,6 @@ static int ads7846_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume); diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index aaacf8bfa61f..95ee92a91bd2 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -99,13 +99,9 @@ #define MXT_T6_STATUS_COMSERR (1 << 2) /* MXT_GEN_POWER_T7 field */ -struct t7_config { - u8 idle; - u8 active; -} __packed; - -#define MXT_POWER_CFG_RUN 0 -#define MXT_POWER_CFG_DEEPSLEEP 1 +#define MXT_POWER_IDLEACQINT 0 +#define MXT_POWER_ACTVACQINT 1 +#define MXT_POWER_ACTV2IDLETO 2 /* MXT_GEN_ACQUIRE_T8 field */ #define MXT_ACQUIRE_CHRGTIME 0 @@ -117,6 +113,7 @@ struct t7_config { #define MXT_ACQUIRE_ATCHCALSTHR 7 /* MXT_TOUCH_MULTI_T9 field */ +#define MXT_TOUCH_CTRL 0 #define MXT_T9_ORIENT 9 #define MXT_T9_RANGE 18 @@ -256,7 +253,6 @@ struct mxt_data { bool update_input; u8 last_message_count; u8 num_touchids; - struct t7_config t7_cfg; /* Cached parameters from object table */ u16 T5_address; @@ -672,6 +668,20 @@ static void mxt_proc_t6_messages(struct mxt_data *data, u8 *msg) data->t6_status = status; } +static int mxt_write_object(struct mxt_data *data, + u8 type, u8 offset, u8 val) +{ + struct mxt_object *object; + u16 reg; + + object = mxt_get_object(data, type); + if (!object || offset >= mxt_obj_size(object)) + return -EINVAL; + + reg = object->start_address; + return mxt_write_reg(data->client, reg + offset, val); +} + static void mxt_input_button(struct mxt_data *data, u8 *message) { struct input_dev *input = data->input_dev; @@ -1742,60 +1752,6 @@ err_free_object_table: return error; } -static int mxt_set_t7_power_cfg(struct mxt_data *data, u8 sleep) -{ - struct device *dev = &data->client->dev; - int error; - struct t7_config *new_config; - struct t7_config deepsleep = { .active = 0, .idle = 0 }; - - if (sleep == MXT_POWER_CFG_DEEPSLEEP) - new_config = &deepsleep; - else - new_config = &data->t7_cfg; - - error = __mxt_write_reg(data->client, data->T7_address, - sizeof(data->t7_cfg), new_config); - if (error) - return error; - - dev_dbg(dev, "Set T7 ACTV:%d IDLE:%d\n", - new_config->active, new_config->idle); - - return 0; -} - -static int mxt_init_t7_power_cfg(struct mxt_data *data) -{ - struct device *dev = &data->client->dev; - int error; - bool retry = false; - -recheck: - error = __mxt_read_reg(data->client, data->T7_address, - sizeof(data->t7_cfg), &data->t7_cfg); - if (error) - return error; - - if (data->t7_cfg.active == 0 || data->t7_cfg.idle == 0) { - if (!retry) { - dev_dbg(dev, "T7 cfg zero, resetting\n"); - mxt_soft_reset(data); - retry = true; - goto recheck; - } else { - dev_dbg(dev, "T7 cfg zero after reset, overriding\n"); - data->t7_cfg.active = 20; - data->t7_cfg.idle = 100; - return mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN); - } - } - - dev_dbg(dev, "Initialized power cfg: ACTV %d, IDLE %d\n", - data->t7_cfg.active, data->t7_cfg.idle); - return 0; -} - static int mxt_configure_objects(struct mxt_data *data, const struct firmware *cfg) { @@ -1809,12 +1765,6 @@ static int mxt_configure_objects(struct mxt_data *data, dev_warn(dev, "Error %d updating config\n", error); } - error = mxt_init_t7_power_cfg(data); - if (error) { - dev_err(dev, "Failed to initialize power cfg\n"); - return error; - } - error = mxt_initialize_t9_input_device(data); if (error) return error; @@ -2093,15 +2043,16 @@ static const struct attribute_group mxt_attr_group = { static void mxt_start(struct mxt_data *data) { - mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN); - - /* Recalibrate since chip has been in deep sleep */ - mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false); + /* Touch enable */ + mxt_write_object(data, + MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0x83); } static void mxt_stop(struct mxt_data *data) { - mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP); + /* Touch disable */ + mxt_write_object(data, + MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0); } static int mxt_input_open(struct input_dev *dev) @@ -2244,8 +2195,7 @@ static int mxt_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int mxt_suspend(struct device *dev) +static int __maybe_unused mxt_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct mxt_data *data = i2c_get_clientdata(client); @@ -2261,12 +2211,14 @@ static int mxt_suspend(struct device *dev) return 0; } -static int mxt_resume(struct device *dev) +static int __maybe_unused mxt_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct mxt_data *data = i2c_get_clientdata(client); struct input_dev *input_dev = data->input_dev; + mxt_soft_reset(data); + mutex_lock(&input_dev->mutex); if (input_dev->users) @@ -2276,7 +2228,6 @@ static int mxt_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume); diff --git a/drivers/input/touchscreen/auo-pixcir-ts.c b/drivers/input/touchscreen/auo-pixcir-ts.c index 7f3c94787787..40e02dd5b2f9 100644 --- a/drivers/input/touchscreen/auo-pixcir-ts.c +++ b/drivers/input/touchscreen/auo-pixcir-ts.c @@ -417,8 +417,7 @@ static void auo_pixcir_input_close(struct input_dev *dev) return; } -#ifdef CONFIG_PM_SLEEP -static int auo_pixcir_suspend(struct device *dev) +static int __maybe_unused auo_pixcir_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct auo_pixcir_ts *ts = i2c_get_clientdata(client); @@ -450,7 +449,7 @@ unlock: return ret; } -static int auo_pixcir_resume(struct device *dev) +static int __maybe_unused auo_pixcir_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct auo_pixcir_ts *ts = i2c_get_clientdata(client); @@ -479,7 +478,6 @@ unlock: return ret; } -#endif static SIMPLE_DEV_PM_OPS(auo_pixcir_pm_ops, auo_pixcir_suspend, auo_pixcir_resume); diff --git a/drivers/input/touchscreen/cy8ctmg110_ts.c b/drivers/input/touchscreen/cy8ctmg110_ts.c index 5bf1aeeea825..f2119ee0e21b 100644 --- a/drivers/input/touchscreen/cy8ctmg110_ts.c +++ b/drivers/input/touchscreen/cy8ctmg110_ts.c @@ -291,8 +291,7 @@ err_free_mem: return err; } -#ifdef CONFIG_PM_SLEEP -static int cy8ctmg110_suspend(struct device *dev) +static int __maybe_unused cy8ctmg110_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct cy8ctmg110 *ts = i2c_get_clientdata(client); @@ -306,7 +305,7 @@ static int cy8ctmg110_suspend(struct device *dev) return 0; } -static int cy8ctmg110_resume(struct device *dev) +static int __maybe_unused cy8ctmg110_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct cy8ctmg110 *ts = i2c_get_clientdata(client); @@ -319,7 +318,6 @@ static int cy8ctmg110_resume(struct device *dev) } return 0; } -#endif static SIMPLE_DEV_PM_OPS(cy8ctmg110_pm, cy8ctmg110_suspend, cy8ctmg110_resume); diff --git a/drivers/input/touchscreen/cyttsp_core.c b/drivers/input/touchscreen/cyttsp_core.c index eee656f77a2e..5b74e8b84e79 100644 --- a/drivers/input/touchscreen/cyttsp_core.c +++ b/drivers/input/touchscreen/cyttsp_core.c @@ -472,8 +472,7 @@ static int cyttsp_disable(struct cyttsp *ts) return 0; } -#ifdef CONFIG_PM_SLEEP -static int cyttsp_suspend(struct device *dev) +static int __maybe_unused cyttsp_suspend(struct device *dev) { struct cyttsp *ts = dev_get_drvdata(dev); int retval = 0; @@ -491,7 +490,7 @@ static int cyttsp_suspend(struct device *dev) return retval; } -static int cyttsp_resume(struct device *dev) +static int __maybe_unused cyttsp_resume(struct device *dev) { struct cyttsp *ts = dev_get_drvdata(dev); @@ -507,8 +506,6 @@ static int cyttsp_resume(struct device *dev) return 0; } -#endif - SIMPLE_DEV_PM_OPS(cyttsp_pm_ops, cyttsp_suspend, cyttsp_resume); EXPORT_SYMBOL_GPL(cyttsp_pm_ops); diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index ee3434f1e949..d4c24fb7704f 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c @@ -850,9 +850,11 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client, } #define EDT_ATTR_CHECKSET(name, reg) \ +do { \ if (pdata->name >= edt_ft5x06_attr_##name.limit_low && \ pdata->name <= edt_ft5x06_attr_##name.limit_high) \ - edt_ft5x06_register_write(tsdata, reg, pdata->name) + edt_ft5x06_register_write(tsdata, reg, pdata->name); \ +} while (0) #define EDT_GET_PROP(name, reg) { \ u32 val; \ @@ -1092,8 +1094,7 @@ static int edt_ft5x06_ts_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int edt_ft5x06_ts_suspend(struct device *dev) +static int __maybe_unused edt_ft5x06_ts_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -1103,7 +1104,7 @@ static int edt_ft5x06_ts_suspend(struct device *dev) return 0; } -static int edt_ft5x06_ts_resume(struct device *dev) +static int __maybe_unused edt_ft5x06_ts_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -1112,7 +1113,6 @@ static int edt_ft5x06_ts_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(edt_ft5x06_ts_pm_ops, edt_ft5x06_ts_suspend, edt_ft5x06_ts_resume); diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c index b1884ddd7a84..09be6ced7151 100644 --- a/drivers/input/touchscreen/eeti_ts.c +++ b/drivers/input/touchscreen/eeti_ts.c @@ -264,8 +264,7 @@ static int eeti_ts_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int eeti_ts_suspend(struct device *dev) +static int __maybe_unused eeti_ts_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct eeti_ts_priv *priv = i2c_get_clientdata(client); @@ -284,7 +283,7 @@ static int eeti_ts_suspend(struct device *dev) return 0; } -static int eeti_ts_resume(struct device *dev) +static int __maybe_unused eeti_ts_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct eeti_ts_priv *priv = i2c_get_clientdata(client); @@ -302,7 +301,6 @@ static int eeti_ts_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(eeti_ts_pm, eeti_ts_suspend, eeti_ts_resume); diff --git a/drivers/input/touchscreen/egalax_ts.c b/drivers/input/touchscreen/egalax_ts.c index c8057847d71d..4c56299284ef 100644 --- a/drivers/input/touchscreen/egalax_ts.c +++ b/drivers/input/touchscreen/egalax_ts.c @@ -239,8 +239,7 @@ static const struct i2c_device_id egalax_ts_id[] = { }; MODULE_DEVICE_TABLE(i2c, egalax_ts_id); -#ifdef CONFIG_PM_SLEEP -static int egalax_ts_suspend(struct device *dev) +static int __maybe_unused egalax_ts_suspend(struct device *dev) { static const u8 suspend_cmd[MAX_I2C_DATA_LEN] = { 0x3, 0x6, 0xa, 0x3, 0x36, 0x3f, 0x2, 0, 0, 0 @@ -252,13 +251,12 @@ static int egalax_ts_suspend(struct device *dev) return ret > 0 ? 0 : ret; } -static int egalax_ts_resume(struct device *dev) +static int __maybe_unused egalax_ts_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); return egalax_wake_up_device(client); } -#endif static SIMPLE_DEV_PM_OPS(egalax_ts_pm_ops, egalax_ts_suspend, egalax_ts_resume); diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c new file mode 100644 index 000000000000..a510f7ef9b66 --- /dev/null +++ b/drivers/input/touchscreen/elants_i2c.c @@ -0,0 +1,1271 @@ +/* + * Elan Microelectronics touch panels with I2C interface + * + * Copyright (C) 2014 Elan Microelectronics Corporation. + * Scott Liu <scott.liu@emc.com.tw> + * + * This code is partly based on hid-multitouch.c: + * + * Copyright (c) 2010-2012 Stephane Chatty <chatty@enac.fr> + * Copyright (c) 2010-2012 Benjamin Tissoires <benjamin.tissoires@gmail.com> + * Copyright (c) 2010-2012 Ecole Nationale de l'Aviation Civile, France + * + * + * This code is partly based on i2c-hid.c: + * + * Copyright (c) 2012 Benjamin Tissoires <benjamin.tissoires@gmail.com> + * Copyright (c) 2012 Ecole Nationale de l'Aviation Civile, France + * Copyright (c) 2012 Red Hat, Inc + */ + +/* + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + */ + +#include <linux/module.h> +#include <linux/input.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <linux/async.h> +#include <linux/i2c.h> +#include <linux/delay.h> +#include <linux/uaccess.h> +#include <linux/buffer_head.h> +#include <linux/version.h> +#include <linux/slab.h> +#include <linux/firmware.h> +#include <linux/version.h> +#include <linux/input/mt.h> +#include <linux/acpi.h> +#include <linux/of.h> +#include <asm/unaligned.h> + +/* Device, Driver information */ +#define DEVICE_NAME "elants_i2c" +#define DRV_VERSION "1.0.9" + +/* Convert from rows or columns into resolution */ +#define ELAN_TS_RESOLUTION(n, m) (((n) - 1) * (m)) + +/* FW header data */ +#define HEADER_SIZE 4 +#define FW_HDR_TYPE 0 +#define FW_HDR_COUNT 1 +#define FW_HDR_LENGTH 2 + +/* Buffer mode Queue Header information */ +#define QUEUE_HEADER_SINGLE 0x62 +#define QUEUE_HEADER_NORMAL 0X63 +#define QUEUE_HEADER_WAIT 0x64 + +/* Command header definition */ +#define CMD_HEADER_WRITE 0x54 +#define CMD_HEADER_READ 0x53 +#define CMD_HEADER_6B_READ 0x5B +#define CMD_HEADER_RESP 0x52 +#define CMD_HEADER_6B_RESP 0x9B +#define CMD_HEADER_HELLO 0x55 +#define CMD_HEADER_REK 0x66 + +/* FW position data */ +#define PACKET_SIZE 55 +#define MAX_CONTACT_NUM 10 +#define FW_POS_HEADER 0 +#define FW_POS_STATE 1 +#define FW_POS_TOTAL 2 +#define FW_POS_XY 3 +#define FW_POS_CHECKSUM 34 +#define FW_POS_WIDTH 35 +#define FW_POS_PRESSURE 45 + +#define HEADER_REPORT_10_FINGER 0x62 + +/* Header (4 bytes) plus 3 fill 10-finger packets */ +#define MAX_PACKET_SIZE 169 + +#define BOOT_TIME_DELAY_MS 50 + +/* FW read command, 0x53 0x?? 0x0, 0x01 */ +#define E_ELAN_INFO_FW_VER 0x00 +#define E_ELAN_INFO_BC_VER 0x10 +#define E_ELAN_INFO_TEST_VER 0xE0 +#define E_ELAN_INFO_FW_ID 0xF0 +#define E_INFO_OSR 0xD6 +#define E_INFO_PHY_SCAN 0xD7 +#define E_INFO_PHY_DRIVER 0xD8 + +#define MAX_RETRIES 3 +#define MAX_FW_UPDATE_RETRIES 30 + +#define ELAN_FW_PAGESIZE 132 +#define ELAN_FW_FILENAME "elants_i2c.bin" + +/* calibration timeout definition */ +#define ELAN_CALI_TIMEOUT_MSEC 10000 + +enum elants_state { + ELAN_STATE_NORMAL, + ELAN_WAIT_QUEUE_HEADER, + ELAN_WAIT_RECALIBRATION, +}; + +enum elants_iap_mode { + ELAN_IAP_OPERATIONAL, + ELAN_IAP_RECOVERY, +}; + +/* struct elants_data - represents state of Elan touchscreen device */ +struct elants_data { + struct i2c_client *client; + struct input_dev *input; + + u16 fw_version; + u8 test_version; + u8 solution_version; + u8 bc_version; + u8 iap_version; + u16 hw_version; + unsigned int x_res; /* resolution in units/mm */ + unsigned int y_res; + unsigned int x_max; + unsigned int y_max; + + enum elants_state state; + enum elants_iap_mode iap_mode; + + /* Guards against concurrent access to the device via sysfs */ + struct mutex sysfs_mutex; + + u8 cmd_resp[HEADER_SIZE]; + struct completion cmd_done; + + u8 buf[MAX_PACKET_SIZE]; + + bool wake_irq_enabled; +}; + +static int elants_i2c_send(struct i2c_client *client, + const void *data, size_t size) +{ + int ret; + + ret = i2c_master_send(client, data, size); + if (ret == size) + return 0; + + if (ret >= 0) + ret = -EIO; + + dev_err(&client->dev, "%s failed (%*ph): %d\n", + __func__, (int)size, data, ret); + + return ret; +} + +static int elants_i2c_read(struct i2c_client *client, void *data, size_t size) +{ + int ret; + + ret = i2c_master_recv(client, data, size); + if (ret == size) + return 0; + + if (ret >= 0) + ret = -EIO; + + dev_err(&client->dev, "%s failed: %d\n", __func__, ret); + + return ret; +} + +static int elants_i2c_execute_command(struct i2c_client *client, + const u8 *cmd, size_t cmd_size, + u8 *resp, size_t resp_size) +{ + struct i2c_msg msgs[2]; + int ret; + u8 expected_response; + + switch (cmd[0]) { + case CMD_HEADER_READ: + expected_response = CMD_HEADER_RESP; + break; + + case CMD_HEADER_6B_READ: + expected_response = CMD_HEADER_6B_RESP; + break; + + default: + dev_err(&client->dev, "%s: invalid command %*ph\n", + __func__, (int)cmd_size, cmd); + return -EINVAL; + } + + msgs[0].addr = client->addr; + msgs[0].flags = client->flags & I2C_M_TEN; + msgs[0].len = cmd_size; + msgs[0].buf = (u8 *)cmd; + + msgs[1].addr = client->addr; + msgs[1].flags = client->flags & I2C_M_TEN; + msgs[1].flags |= I2C_M_RD; + msgs[1].len = resp_size; + msgs[1].buf = resp; + + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + if (ret < 0) + return ret; + + if (ret != ARRAY_SIZE(msgs) || resp[FW_HDR_TYPE] != expected_response) + return -EIO; + + return 0; +} + +static int elants_i2c_calibrate(struct elants_data *ts) +{ + struct i2c_client *client = ts->client; + int ret, error; + static const u8 w_flashkey[] = { 0x54, 0xC0, 0xE1, 0x5A }; + static const u8 rek[] = { 0x54, 0x29, 0x00, 0x01 }; + static const u8 rek_resp[] = { CMD_HEADER_REK, 0x66, 0x66, 0x66 }; + + disable_irq(client->irq); + + ts->state = ELAN_WAIT_RECALIBRATION; + reinit_completion(&ts->cmd_done); + + elants_i2c_send(client, w_flashkey, sizeof(w_flashkey)); + elants_i2c_send(client, rek, sizeof(rek)); + + enable_irq(client->irq); + + ret = wait_for_completion_interruptible_timeout(&ts->cmd_done, + msecs_to_jiffies(ELAN_CALI_TIMEOUT_MSEC)); + + ts->state = ELAN_STATE_NORMAL; + + if (ret <= 0) { + error = ret < 0 ? ret : -ETIMEDOUT; + dev_err(&client->dev, + "error while waiting for calibration to complete: %d\n", + error); + return error; + } + + if (memcmp(rek_resp, ts->cmd_resp, sizeof(rek_resp))) { + dev_err(&client->dev, + "unexpected calibration response: %*ph\n", + (int)sizeof(ts->cmd_resp), ts->cmd_resp); + return -EINVAL; + } + + return 0; +} + +static int elants_i2c_sw_reset(struct i2c_client *client) +{ + const u8 soft_rst_cmd[] = { 0x77, 0x77, 0x77, 0x77 }; + int error; + + error = elants_i2c_send(client, soft_rst_cmd, + sizeof(soft_rst_cmd)); + if (error) { + dev_err(&client->dev, "software reset failed: %d\n", error); + return error; + } + + /* + * We should wait at least 10 msec (but no more than 40) before + * sending fastboot or IAP command to the device. + */ + msleep(30); + + return 0; +} + +static u16 elants_i2c_parse_version(u8 *buf) +{ + return get_unaligned_be32(buf) >> 4; +} + +static int elants_i2c_query_fw_id(struct elants_data *ts) +{ + struct i2c_client *client = ts->client; + int error, retry_cnt; + const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_FW_ID, 0x00, 0x01 }; + u8 resp[HEADER_SIZE]; + + for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) { + error = elants_i2c_execute_command(client, cmd, sizeof(cmd), + resp, sizeof(resp)); + if (!error) { + ts->hw_version = elants_i2c_parse_version(resp); + if (ts->hw_version != 0xffff) + return 0; + } + + dev_dbg(&client->dev, "read fw id error=%d, buf=%*phC\n", + error, (int)sizeof(resp), resp); + } + + dev_err(&client->dev, + "Failed to read fw id or fw id is invalid\n"); + + return -EINVAL; +} + +static int elants_i2c_query_fw_version(struct elants_data *ts) +{ + struct i2c_client *client = ts->client; + int error, retry_cnt; + const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_FW_VER, 0x00, 0x01 }; + u8 resp[HEADER_SIZE]; + + for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) { + error = elants_i2c_execute_command(client, cmd, sizeof(cmd), + resp, sizeof(resp)); + if (!error) { + ts->fw_version = elants_i2c_parse_version(resp); + if (ts->fw_version != 0x0000 && + ts->fw_version != 0xffff) + return 0; + } + + dev_dbg(&client->dev, "read fw version error=%d, buf=%*phC\n", + error, (int)sizeof(resp), resp); + } + + dev_err(&client->dev, + "Failed to read fw version or fw version is invalid\n"); + + return -EINVAL; +} + +static int elants_i2c_query_test_version(struct elants_data *ts) +{ + struct i2c_client *client = ts->client; + int error, retry_cnt; + u16 version; + const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_TEST_VER, 0x00, 0x01 }; + u8 resp[HEADER_SIZE]; + + for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) { + error = elants_i2c_execute_command(client, cmd, sizeof(cmd), + resp, sizeof(resp)); + if (!error) { + version = elants_i2c_parse_version(resp); + ts->test_version = version >> 8; + ts->solution_version = version & 0xff; + + return 0; + } + + dev_dbg(&client->dev, + "read test version error rc=%d, buf=%*phC\n", + error, (int)sizeof(resp), resp); + } + + dev_err(&client->dev, "Failed to read test version\n"); + + return -EINVAL; +} + +static int elants_i2c_query_bc_version(struct elants_data *ts) +{ + struct i2c_client *client = ts->client; + const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_BC_VER, 0x00, 0x01 }; + u8 resp[HEADER_SIZE]; + u16 version; + int error; + + error = elants_i2c_execute_command(client, cmd, sizeof(cmd), + resp, sizeof(resp)); + if (error) { + dev_err(&client->dev, + "read BC version error=%d, buf=%*phC\n", + error, (int)sizeof(resp), resp); + return error; + } + + version = elants_i2c_parse_version(resp); + ts->bc_version = version >> 8; + ts->iap_version = version & 0xff; + + return 0; +} + +static int elants_i2c_query_ts_info(struct elants_data *ts) +{ + struct i2c_client *client = ts->client; + int error; + u8 resp[17]; + u16 phy_x, phy_y, rows, cols, osr; + const u8 get_resolution_cmd[] = { + CMD_HEADER_6B_READ, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + const u8 get_osr_cmd[] = { + CMD_HEADER_READ, E_INFO_OSR, 0x00, 0x01 + }; + const u8 get_physical_scan_cmd[] = { + CMD_HEADER_READ, E_INFO_PHY_SCAN, 0x00, 0x01 + }; + const u8 get_physical_drive_cmd[] = { + CMD_HEADER_READ, E_INFO_PHY_DRIVER, 0x00, 0x01 + }; + + /* Get trace number */ + error = elants_i2c_execute_command(client, + get_resolution_cmd, + sizeof(get_resolution_cmd), + resp, sizeof(resp)); + if (error) { + dev_err(&client->dev, "get resolution command failed: %d\n", + error); + return error; + } + + rows = resp[2] + resp[6] + resp[10]; + cols = resp[3] + resp[7] + resp[11]; + + /* Process mm_to_pixel information */ + error = elants_i2c_execute_command(client, + get_osr_cmd, sizeof(get_osr_cmd), + resp, sizeof(resp)); + if (error) { + dev_err(&client->dev, "get osr command failed: %d\n", + error); + return error; + } + + osr = resp[3]; + + error = elants_i2c_execute_command(client, + get_physical_scan_cmd, + sizeof(get_physical_scan_cmd), + resp, sizeof(resp)); + if (error) { + dev_err(&client->dev, "get physical scan command failed: %d\n", + error); + return error; + } + + phy_x = get_unaligned_be16(&resp[2]); + + error = elants_i2c_execute_command(client, + get_physical_drive_cmd, + sizeof(get_physical_drive_cmd), + resp, sizeof(resp)); + if (error) { + dev_err(&client->dev, "get physical drive command failed: %d\n", + error); + return error; + } + + phy_y = get_unaligned_be16(&resp[2]); + + dev_dbg(&client->dev, "phy_x=%d, phy_y=%d\n", phy_x, phy_y); + + if (rows == 0 || cols == 0 || osr == 0) { + dev_warn(&client->dev, + "invalid trace number data: %d, %d, %d\n", + rows, cols, osr); + } else { + /* translate trace number to TS resolution */ + ts->x_max = ELAN_TS_RESOLUTION(rows, osr); + ts->x_res = DIV_ROUND_CLOSEST(ts->x_max, phy_x); + ts->y_max = ELAN_TS_RESOLUTION(cols, osr); + ts->y_res = DIV_ROUND_CLOSEST(ts->y_max, phy_y); + } + + return 0; +} + +static int elants_i2c_fastboot(struct i2c_client *client) +{ + const u8 boot_cmd[] = { 0x4D, 0x61, 0x69, 0x6E }; + int error; + + error = elants_i2c_send(client, boot_cmd, sizeof(boot_cmd)); + if (error) { + dev_err(&client->dev, "boot failed: %d\n", error); + return error; + } + + dev_dbg(&client->dev, "boot success -- 0x%x\n", client->addr); + return 0; +} + +static int elants_i2c_initialize(struct elants_data *ts) +{ + struct i2c_client *client = ts->client; + int error, retry_cnt; + const u8 hello_packet[] = { 0x55, 0x55, 0x55, 0x55 }; + const u8 recov_packet[] = { 0x55, 0x55, 0x80, 0x80 }; + u8 buf[HEADER_SIZE]; + + for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) { + error = elants_i2c_sw_reset(client); + if (error) { + /* Continue initializing if it's the last try */ + if (retry_cnt < MAX_RETRIES - 1) + continue; + } + + error = elants_i2c_fastboot(client); + if (error) { + /* Continue initializing if it's the last try */ + if (retry_cnt < MAX_RETRIES - 1) + continue; + } + + /* Wait for Hello packet */ + msleep(BOOT_TIME_DELAY_MS); + + error = elants_i2c_read(client, buf, sizeof(buf)); + if (error) { + dev_err(&client->dev, + "failed to read 'hello' packet: %d\n", error); + } else if (!memcmp(buf, hello_packet, sizeof(hello_packet))) { + ts->iap_mode = ELAN_IAP_OPERATIONAL; + break; + } else if (!memcmp(buf, recov_packet, sizeof(recov_packet))) { + /* + * Setting error code will mark device + * in recovery mode below. + */ + error = -EIO; + break; + } else { + error = -EINVAL; + dev_err(&client->dev, + "invalid 'hello' packet: %*ph\n", + (int)sizeof(buf), buf); + } + } + + if (!error) + error = elants_i2c_query_fw_id(ts); + if (!error) + error = elants_i2c_query_fw_version(ts); + + if (error) { + ts->iap_mode = ELAN_IAP_RECOVERY; + } else { + elants_i2c_query_test_version(ts); + elants_i2c_query_bc_version(ts); + elants_i2c_query_ts_info(ts); + } + + return 0; +} + +/* + * Firmware update interface. + */ + +static int elants_i2c_fw_write_page(struct i2c_client *client, + const void *page) +{ + const u8 ack_ok[] = { 0xaa, 0xaa }; + u8 buf[2]; + int retry; + int error; + + for (retry = 0; retry < MAX_FW_UPDATE_RETRIES; retry++) { + error = elants_i2c_send(client, page, ELAN_FW_PAGESIZE); + if (error) { + dev_err(&client->dev, + "IAP Write Page failed: %d\n", error); + continue; + } + + error = elants_i2c_read(client, buf, 2); + if (error) { + dev_err(&client->dev, + "IAP Ack read failed: %d\n", error); + return error; + } + + if (!memcmp(buf, ack_ok, sizeof(ack_ok))) + return 0; + + error = -EIO; + dev_err(&client->dev, + "IAP Get Ack Error [%02x:%02x]\n", + buf[0], buf[1]); + } + + return error; +} + +static int elants_i2c_do_update_firmware(struct i2c_client *client, + const struct firmware *fw, + bool force) +{ + const u8 enter_iap[] = { 0x45, 0x49, 0x41, 0x50 }; + const u8 enter_iap2[] = { 0x54, 0x00, 0x12, 0x34 }; + const u8 iap_ack[] = { 0x55, 0xaa, 0x33, 0xcc }; + u8 buf[HEADER_SIZE]; + u16 send_id; + int page, n_fw_pages; + int error; + + /* Recovery mode detection! */ + if (force) { + dev_dbg(&client->dev, "Recovery mode procedure\n"); + error = elants_i2c_send(client, enter_iap2, sizeof(enter_iap2)); + } else { + /* Start IAP Procedure */ + dev_dbg(&client->dev, "Normal IAP procedure\n"); + elants_i2c_sw_reset(client); + + error = elants_i2c_send(client, enter_iap, sizeof(enter_iap)); + } + + if (error) { + dev_err(&client->dev, "failed to enter IAP mode: %d\n", error); + return error; + } + + msleep(20); + + /* check IAP state */ + error = elants_i2c_read(client, buf, 4); + if (error) { + dev_err(&client->dev, + "failed to read IAP acknowledgement: %d\n", + error); + return error; + } + + if (memcmp(buf, iap_ack, sizeof(iap_ack))) { + dev_err(&client->dev, + "failed to enter IAP: %*ph (expected %*ph)\n", + (int)sizeof(buf), buf, (int)sizeof(iap_ack), iap_ack); + return -EIO; + } + + dev_info(&client->dev, "successfully entered IAP mode"); + + send_id = client->addr; + error = elants_i2c_send(client, &send_id, 1); + if (error) { + dev_err(&client->dev, "sending dummy byte failed: %d\n", + error); + return error; + } + + /* Clear the last page of Master */ + error = elants_i2c_send(client, fw->data, ELAN_FW_PAGESIZE); + if (error) { + dev_err(&client->dev, "clearing of the last page failed: %d\n", + error); + return error; + } + + error = elants_i2c_read(client, buf, 2); + if (error) { + dev_err(&client->dev, + "failed to read ACK for clearing the last page: %d\n", + error); + return error; + } + + n_fw_pages = fw->size / ELAN_FW_PAGESIZE; + dev_dbg(&client->dev, "IAP Pages = %d\n", n_fw_pages); + + for (page = 0; page < n_fw_pages; page++) { + error = elants_i2c_fw_write_page(client, + fw->data + page * ELAN_FW_PAGESIZE); + if (error) { + dev_err(&client->dev, + "failed to write FW page %d: %d\n", + page, error); + return error; + } + } + + /* Old iap needs to wait 200ms for WDT and rest is for hello packets */ + msleep(300); + + dev_info(&client->dev, "firmware update completed\n"); + return 0; +} + +static int elants_i2c_fw_update(struct elants_data *ts) +{ + struct i2c_client *client = ts->client; + const struct firmware *fw; + int error; + + error = request_firmware(&fw, ELAN_FW_FILENAME, &client->dev); + if (error) { + dev_err(&client->dev, "failed to request firmware %s: %d\n", + ELAN_FW_FILENAME, error); + return error; + } + + if (fw->size % ELAN_FW_PAGESIZE) { + dev_err(&client->dev, "invalid firmware length: %zu\n", + fw->size); + error = -EINVAL; + goto out; + } + + disable_irq(client->irq); + + error = elants_i2c_do_update_firmware(client, fw, + ts->iap_mode == ELAN_IAP_RECOVERY); + if (error) { + dev_err(&client->dev, "firmware update failed: %d\n", error); + ts->iap_mode = ELAN_IAP_RECOVERY; + goto out_enable_irq; + } + + error = elants_i2c_initialize(ts); + if (error) { + dev_err(&client->dev, + "failed to initialize device after firmware update: %d\n", + error); + ts->iap_mode = ELAN_IAP_RECOVERY; + goto out_enable_irq; + } + + ts->iap_mode = ELAN_IAP_OPERATIONAL; + +out_enable_irq: + ts->state = ELAN_STATE_NORMAL; + enable_irq(client->irq); + msleep(100); + + if (!error) + elants_i2c_calibrate(ts); +out: + release_firmware(fw); + return error; +} + +/* + * Event reporting. + */ + +static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf) +{ + struct input_dev *input = ts->input; + unsigned int n_fingers; + u16 finger_state; + int i; + + n_fingers = buf[FW_POS_STATE + 1] & 0x0f; + finger_state = ((buf[FW_POS_STATE + 1] & 0x30) << 4) | + buf[FW_POS_STATE]; + + dev_dbg(&ts->client->dev, + "n_fingers: %u, state: %04x\n", n_fingers, finger_state); + + for (i = 0; i < MAX_CONTACT_NUM && n_fingers; i++) { + if (finger_state & 1) { + unsigned int x, y, p, w; + u8 *pos; + + pos = &buf[FW_POS_XY + i * 3]; + x = (((u16)pos[0] & 0xf0) << 4) | pos[1]; + y = (((u16)pos[0] & 0x0f) << 8) | pos[2]; + p = buf[FW_POS_PRESSURE + i]; + w = buf[FW_POS_WIDTH + i]; + + dev_dbg(&ts->client->dev, "i=%d x=%d y=%d p=%d w=%d\n", + i, x, y, p, w); + + input_mt_slot(input, i); + input_mt_report_slot_state(input, MT_TOOL_FINGER, true); + input_event(input, EV_ABS, ABS_MT_POSITION_X, x); + input_event(input, EV_ABS, ABS_MT_POSITION_Y, y); + input_event(input, EV_ABS, ABS_MT_PRESSURE, p); + input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, w); + + n_fingers--; + } + + finger_state >>= 1; + } + + input_mt_sync_frame(input); + input_sync(input); +} + +static u8 elants_i2c_calculate_checksum(u8 *buf) +{ + u8 checksum = 0; + u8 i; + + for (i = 0; i < FW_POS_CHECKSUM; i++) + checksum += buf[i]; + + return checksum; +} + +static void elants_i2c_event(struct elants_data *ts, u8 *buf) +{ + u8 checksum = elants_i2c_calculate_checksum(buf); + + if (unlikely(buf[FW_POS_CHECKSUM] != checksum)) + dev_warn(&ts->client->dev, + "%s: invalid checksum for packet %02x: %02x vs. %02x\n", + __func__, buf[FW_POS_HEADER], + checksum, buf[FW_POS_CHECKSUM]); + else if (unlikely(buf[FW_POS_HEADER] != HEADER_REPORT_10_FINGER)) + dev_warn(&ts->client->dev, + "%s: unknown packet type: %02x\n", + __func__, buf[FW_POS_HEADER]); + else + elants_i2c_mt_event(ts, buf); +} + +static irqreturn_t elants_i2c_irq(int irq, void *_dev) +{ + const u8 wait_packet[] = { 0x64, 0x64, 0x64, 0x64 }; + struct elants_data *ts = _dev; + struct i2c_client *client = ts->client; + int report_count, report_len; + int i; + int len; + + len = i2c_master_recv(client, ts->buf, sizeof(ts->buf)); + if (len < 0) { + dev_err(&client->dev, "%s: failed to read data: %d\n", + __func__, len); + goto out; + } + + dev_dbg(&client->dev, "%s: packet %*ph\n", + __func__, HEADER_SIZE, ts->buf); + + switch (ts->state) { + case ELAN_WAIT_RECALIBRATION: + if (ts->buf[FW_HDR_TYPE] == CMD_HEADER_REK) { + memcpy(ts->cmd_resp, ts->buf, sizeof(ts->cmd_resp)); + complete(&ts->cmd_done); + ts->state = ELAN_STATE_NORMAL; + } + break; + + case ELAN_WAIT_QUEUE_HEADER: + if (ts->buf[FW_HDR_TYPE] != QUEUE_HEADER_NORMAL) + break; + + ts->state = ELAN_STATE_NORMAL; + /* fall through */ + + case ELAN_STATE_NORMAL: + + switch (ts->buf[FW_HDR_TYPE]) { + case CMD_HEADER_HELLO: + case CMD_HEADER_RESP: + case CMD_HEADER_REK: + break; + + case QUEUE_HEADER_WAIT: + if (memcmp(ts->buf, wait_packet, sizeof(wait_packet))) { + dev_err(&client->dev, + "invalid wait packet %*ph\n", + HEADER_SIZE, ts->buf); + } else { + ts->state = ELAN_WAIT_QUEUE_HEADER; + udelay(30); + } + break; + + case QUEUE_HEADER_SINGLE: + elants_i2c_event(ts, &ts->buf[HEADER_SIZE]); + break; + + case QUEUE_HEADER_NORMAL: + report_count = ts->buf[FW_HDR_COUNT]; + if (report_count > 3) { + dev_err(&client->dev, + "too large report count: %*ph\n", + HEADER_SIZE, ts->buf); + break; + } + + report_len = ts->buf[FW_HDR_LENGTH] / report_count; + if (report_len != PACKET_SIZE) { + dev_err(&client->dev, + "mismatching report length: %*ph\n", + HEADER_SIZE, ts->buf); + break; + } + + for (i = 0; i < report_count; i++) { + u8 *buf = ts->buf + HEADER_SIZE + + i * PACKET_SIZE; + elants_i2c_event(ts, buf); + } + break; + + default: + dev_err(&client->dev, "unknown packet %*ph\n", + HEADER_SIZE, ts->buf); + break; + } + break; + } + +out: + return IRQ_HANDLED; +} + +/* + * sysfs interface + */ +static ssize_t calibrate_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elants_data *ts = i2c_get_clientdata(client); + int error; + + error = mutex_lock_interruptible(&ts->sysfs_mutex); + if (error) + return error; + + error = elants_i2c_calibrate(ts); + + mutex_unlock(&ts->sysfs_mutex); + return error ?: count; +} + +static ssize_t write_update_fw(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elants_data *ts = i2c_get_clientdata(client); + int error; + + error = mutex_lock_interruptible(&ts->sysfs_mutex); + if (error) + return error; + + error = elants_i2c_fw_update(ts); + dev_dbg(dev, "firmware update result: %d\n", error); + + mutex_unlock(&ts->sysfs_mutex); + return error ?: count; +} + +static ssize_t show_iap_mode(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elants_data *ts = i2c_get_clientdata(client); + + return sprintf(buf, "%s\n", + ts->iap_mode == ELAN_IAP_OPERATIONAL ? + "Normal" : "Recovery"); +} + +static DEVICE_ATTR(calibrate, S_IWUSR, NULL, calibrate_store); +static DEVICE_ATTR(iap_mode, S_IRUGO, show_iap_mode, NULL); +static DEVICE_ATTR(update_fw, S_IWUSR, NULL, write_update_fw); + +struct elants_version_attribute { + struct device_attribute dattr; + size_t field_offset; + size_t field_size; +}; + +#define __ELANTS_FIELD_SIZE(_field) \ + sizeof(((struct elants_data *)NULL)->_field) +#define __ELANTS_VERIFY_SIZE(_field) \ + (BUILD_BUG_ON_ZERO(__ELANTS_FIELD_SIZE(_field) > 2) + \ + __ELANTS_FIELD_SIZE(_field)) +#define ELANTS_VERSION_ATTR(_field) \ + struct elants_version_attribute elants_ver_attr_##_field = { \ + .dattr = __ATTR(_field, S_IRUGO, \ + elants_version_attribute_show, NULL), \ + .field_offset = offsetof(struct elants_data, _field), \ + .field_size = __ELANTS_VERIFY_SIZE(_field), \ + } + +static ssize_t elants_version_attribute_show(struct device *dev, + struct device_attribute *dattr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elants_data *ts = i2c_get_clientdata(client); + struct elants_version_attribute *attr = + container_of(dattr, struct elants_version_attribute, dattr); + u8 *field = (u8 *)((char *)ts + attr->field_offset); + unsigned int fmt_size; + unsigned int val; + + if (attr->field_size == 1) { + val = *field; + fmt_size = 2; /* 2 HEX digits */ + } else { + val = *(u16 *)field; + fmt_size = 4; /* 4 HEX digits */ + } + + return sprintf(buf, "%0*x\n", fmt_size, val); +} + +static ELANTS_VERSION_ATTR(fw_version); +static ELANTS_VERSION_ATTR(hw_version); +static ELANTS_VERSION_ATTR(test_version); +static ELANTS_VERSION_ATTR(solution_version); +static ELANTS_VERSION_ATTR(bc_version); +static ELANTS_VERSION_ATTR(iap_version); + +static struct attribute *elants_attributes[] = { + &dev_attr_calibrate.attr, + &dev_attr_update_fw.attr, + &dev_attr_iap_mode.attr, + + &elants_ver_attr_fw_version.dattr.attr, + &elants_ver_attr_hw_version.dattr.attr, + &elants_ver_attr_test_version.dattr.attr, + &elants_ver_attr_solution_version.dattr.attr, + &elants_ver_attr_bc_version.dattr.attr, + &elants_ver_attr_iap_version.dattr.attr, + NULL +}; + +static struct attribute_group elants_attribute_group = { + .attrs = elants_attributes, +}; + +static void elants_i2c_remove_sysfs_group(void *_data) +{ + struct elants_data *ts = _data; + + sysfs_remove_group(&ts->client->dev.kobj, &elants_attribute_group); +} + +static int elants_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + union i2c_smbus_data dummy; + struct elants_data *ts; + unsigned long irqflags; + int error; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + dev_err(&client->dev, + "%s: i2c check functionality error\n", DEVICE_NAME); + return -ENXIO; + } + + /* Make sure there is something at this address */ + if (i2c_smbus_xfer(client->adapter, client->addr, 0, + I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &dummy) < 0) { + dev_err(&client->dev, "nothing at this address\n"); + return -ENXIO; + } + + ts = devm_kzalloc(&client->dev, sizeof(struct elants_data), GFP_KERNEL); + if (!ts) + return -ENOMEM; + + mutex_init(&ts->sysfs_mutex); + init_completion(&ts->cmd_done); + + ts->client = client; + i2c_set_clientdata(client, ts); + + error = elants_i2c_initialize(ts); + if (error) { + dev_err(&client->dev, "failed to initialize: %d\n", error); + return error; + } + + ts->input = devm_input_allocate_device(&client->dev); + if (!ts->input) { + dev_err(&client->dev, "Failed to allocate input device\n"); + return -ENOMEM; + } + + ts->input->name = "Elan Touchscreen"; + ts->input->id.bustype = BUS_I2C; + + __set_bit(BTN_TOUCH, ts->input->keybit); + __set_bit(EV_ABS, ts->input->evbit); + __set_bit(EV_KEY, ts->input->evbit); + + /* Single touch input params setup */ + input_set_abs_params(ts->input, ABS_X, 0, ts->x_max, 0, 0); + input_set_abs_params(ts->input, ABS_Y, 0, ts->y_max, 0, 0); + input_set_abs_params(ts->input, ABS_PRESSURE, 0, 255, 0, 0); + input_abs_set_res(ts->input, ABS_X, ts->x_res); + input_abs_set_res(ts->input, ABS_Y, ts->y_res); + + /* Multitouch input params setup */ + error = input_mt_init_slots(ts->input, MAX_CONTACT_NUM, + INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); + if (error) { + dev_err(&client->dev, + "failed to initialize MT slots: %d\n", error); + return error; + } + + input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, ts->x_max, 0, 0); + input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, ts->y_max, 0, 0); + input_set_abs_params(ts->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(ts->input, ABS_MT_PRESSURE, 0, 255, 0, 0); + input_abs_set_res(ts->input, ABS_MT_POSITION_X, ts->x_res); + input_abs_set_res(ts->input, ABS_MT_POSITION_Y, ts->y_res); + + input_set_drvdata(ts->input, ts); + + error = input_register_device(ts->input); + if (error) { + dev_err(&client->dev, + "unable to register input device: %d\n", error); + return error; + } + + /* + * Systems using device tree should set up interrupt via DTS, + * the rest will use the default falling edge interrupts. + */ + irqflags = client->dev.of_node ? 0 : IRQF_TRIGGER_FALLING; + + error = devm_request_threaded_irq(&client->dev, client->irq, + NULL, elants_i2c_irq, + irqflags | IRQF_ONESHOT, + client->name, ts); + if (error) { + dev_err(&client->dev, "Failed to register interrupt\n"); + return error; + } + + /* + * Systems using device tree should set up wakeup via DTS, + * the rest will configure device as wakeup source by default. + */ + if (!client->dev.of_node) + device_init_wakeup(&client->dev, true); + + error = sysfs_create_group(&client->dev.kobj, &elants_attribute_group); + if (error) { + dev_err(&client->dev, "failed to create sysfs attributes: %d\n", + error); + return error; + } + + error = devm_add_action(&client->dev, + elants_i2c_remove_sysfs_group, ts); + if (error) { + elants_i2c_remove_sysfs_group(ts); + dev_err(&client->dev, + "Failed to add sysfs cleanup action: %d\n", + error); + return error; + } + + return 0; +} + +static int __maybe_unused elants_i2c_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elants_data *ts = i2c_get_clientdata(client); + const u8 set_sleep_cmd[] = { 0x54, 0x50, 0x00, 0x01 }; + int retry_cnt; + int error; + + /* Command not support in IAP recovery mode */ + if (ts->iap_mode != ELAN_IAP_OPERATIONAL) + return -EBUSY; + + disable_irq(client->irq); + + for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) { + error = elants_i2c_send(client, set_sleep_cmd, + sizeof(set_sleep_cmd)); + if (!error) + break; + + dev_err(&client->dev, "suspend command failed: %d\n", error); + } + + if (device_may_wakeup(dev)) + ts->wake_irq_enabled = (enable_irq_wake(client->irq) == 0); + + return 0; +} + +static int __maybe_unused elants_i2c_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elants_data *ts = i2c_get_clientdata(client); + const u8 set_active_cmd[] = { 0x54, 0x58, 0x00, 0x01 }; + int retry_cnt; + int error; + + if (device_may_wakeup(dev) && ts->wake_irq_enabled) + disable_irq_wake(client->irq); + + for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) { + error = elants_i2c_send(client, set_active_cmd, + sizeof(set_active_cmd)); + if (!error) + break; + + dev_err(&client->dev, "resume command failed: %d\n", error); + } + + ts->state = ELAN_STATE_NORMAL; + enable_irq(client->irq); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(elants_i2c_pm_ops, + elants_i2c_suspend, elants_i2c_resume); + +static const struct i2c_device_id elants_i2c_id[] = { + { DEVICE_NAME, 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, elants_i2c_id); + +#ifdef CONFIG_ACPI +static const struct acpi_device_id elants_acpi_id[] = { + { "ELAN0001", 0 }, + { } +}; +MODULE_DEVICE_TABLE(acpi, elants_acpi_id); +#endif + +#ifdef CONFIG_OF +static const struct of_device_id elants_of_match[] = { + { .compatible = "elan,ekth3500" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, elants_of_match); +#endif + +static struct i2c_driver elants_i2c_driver = { + .probe = elants_i2c_probe, + .id_table = elants_i2c_id, + .driver = { + .name = DEVICE_NAME, + .owner = THIS_MODULE, + .pm = &elants_i2c_pm_ops, + .acpi_match_table = ACPI_PTR(elants_acpi_id), + .of_match_table = of_match_ptr(elants_of_match), + }, +}; +module_i2c_driver(elants_i2c_driver); + +MODULE_AUTHOR("Scott Liu <scott.liu@emc.com.tw>"); +MODULE_DESCRIPTION("Elan I2c Touchscreen driver"); +MODULE_VERSION(DRV_VERSION); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c new file mode 100644 index 000000000000..ca196689f025 --- /dev/null +++ b/drivers/input/touchscreen/goodix.c @@ -0,0 +1,395 @@ +/* + * Driver for Goodix Touchscreens + * + * Copyright (c) 2014 Red Hat Inc. + * + * This code is based on gt9xx.c authored by andrew@goodix.com: + * + * 2010 - 2012 Goodix Technology. + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; version 2 of the License. + */ + +#include <linux/kernel.h> +#include <linux/i2c.h> +#include <linux/input.h> +#include <linux/input/mt.h> +#include <linux/module.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/interrupt.h> +#include <linux/slab.h> +#include <asm/unaligned.h> + +struct goodix_ts_data { + struct i2c_client *client; + struct input_dev *input_dev; + int abs_x_max; + int abs_y_max; + unsigned int max_touch_num; + unsigned int int_trigger_type; +}; + +#define GOODIX_MAX_HEIGHT 4096 +#define GOODIX_MAX_WIDTH 4096 +#define GOODIX_INT_TRIGGER 1 +#define GOODIX_CONTACT_SIZE 8 +#define GOODIX_MAX_CONTACTS 10 + +#define GOODIX_CONFIG_MAX_LENGTH 240 + +/* Register defines */ +#define GOODIX_READ_COOR_ADDR 0x814E +#define GOODIX_REG_CONFIG_DATA 0x8047 +#define GOODIX_REG_VERSION 0x8140 + +#define RESOLUTION_LOC 1 +#define TRIGGER_LOC 6 + +static const unsigned long goodix_irq_flags[] = { + IRQ_TYPE_EDGE_RISING, + IRQ_TYPE_EDGE_FALLING, + IRQ_TYPE_LEVEL_LOW, + IRQ_TYPE_LEVEL_HIGH, +}; + +/** + * goodix_i2c_read - read data from a register of the i2c slave device. + * + * @client: i2c device. + * @reg: the register to read from. + * @buf: raw write data buffer. + * @len: length of the buffer to write + */ +static int goodix_i2c_read(struct i2c_client *client, + u16 reg, u8 *buf, int len) +{ + struct i2c_msg msgs[2]; + u16 wbuf = cpu_to_be16(reg); + int ret; + + msgs[0].flags = 0; + msgs[0].addr = client->addr; + msgs[0].len = 2; + msgs[0].buf = (u8 *) &wbuf; + + msgs[1].flags = I2C_M_RD; + msgs[1].addr = client->addr; + msgs[1].len = len; + msgs[1].buf = buf; + + ret = i2c_transfer(client->adapter, msgs, 2); + return ret < 0 ? ret : (ret != ARRAY_SIZE(msgs) ? -EIO : 0); +} + +static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data) +{ + int touch_num; + int error; + + error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR, data, + GOODIX_CONTACT_SIZE + 1); + if (error) { + dev_err(&ts->client->dev, "I2C transfer error: %d\n", error); + return error; + } + + touch_num = data[0] & 0x0f; + if (touch_num > GOODIX_MAX_CONTACTS) + return -EPROTO; + + if (touch_num > 1) { + data += 1 + GOODIX_CONTACT_SIZE; + error = goodix_i2c_read(ts->client, + GOODIX_READ_COOR_ADDR + + 1 + GOODIX_CONTACT_SIZE, + data, + GOODIX_CONTACT_SIZE * (touch_num - 1)); + if (error) + return error; + } + + return touch_num; +} + +static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data) +{ + int id = coor_data[0] & 0x0F; + int input_x = get_unaligned_le16(&coor_data[1]); + int input_y = get_unaligned_le16(&coor_data[3]); + int input_w = get_unaligned_le16(&coor_data[5]); + + input_mt_slot(ts->input_dev, id); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_x); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, input_y); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w); + input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w); +} + +/** + * goodix_process_events - Process incoming events + * + * @ts: our goodix_ts_data pointer + * + * Called when the IRQ is triggered. Read the current device state, and push + * the input events to the user space. + */ +static void goodix_process_events(struct goodix_ts_data *ts) +{ + u8 point_data[1 + GOODIX_CONTACT_SIZE * GOODIX_MAX_CONTACTS]; + int touch_num; + int i; + + touch_num = goodix_ts_read_input_report(ts, point_data); + if (touch_num < 0) + return; + + for (i = 0; i < touch_num; i++) + goodix_ts_report_touch(ts, + &point_data[1 + GOODIX_CONTACT_SIZE * i]); + + input_mt_sync_frame(ts->input_dev); + input_sync(ts->input_dev); +} + +/** + * goodix_ts_irq_handler - The IRQ handler + * + * @irq: interrupt number. + * @dev_id: private data pointer. + */ +static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id) +{ + static const u8 end_cmd[] = { + GOODIX_READ_COOR_ADDR >> 8, + GOODIX_READ_COOR_ADDR & 0xff, + 0 + }; + struct goodix_ts_data *ts = dev_id; + + goodix_process_events(ts); + + if (i2c_master_send(ts->client, end_cmd, sizeof(end_cmd)) < 0) + dev_err(&ts->client->dev, "I2C write end_cmd error\n"); + + return IRQ_HANDLED; +} + +/** + * goodix_read_config - Read the embedded configuration of the panel + * + * @ts: our goodix_ts_data pointer + * + * Must be called during probe + */ +static void goodix_read_config(struct goodix_ts_data *ts) +{ + u8 config[GOODIX_CONFIG_MAX_LENGTH]; + int error; + + error = goodix_i2c_read(ts->client, GOODIX_REG_CONFIG_DATA, + config, + GOODIX_CONFIG_MAX_LENGTH); + if (error) { + dev_warn(&ts->client->dev, + "Error reading config (%d), using defaults\n", + error); + ts->abs_x_max = GOODIX_MAX_WIDTH; + ts->abs_y_max = GOODIX_MAX_HEIGHT; + ts->int_trigger_type = GOODIX_INT_TRIGGER; + return; + } + + ts->abs_x_max = get_unaligned_le16(&config[RESOLUTION_LOC]); + ts->abs_y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]); + ts->int_trigger_type = (config[TRIGGER_LOC]) & 0x03; + if (!ts->abs_x_max || !ts->abs_y_max) { + dev_err(&ts->client->dev, + "Invalid config, using defaults\n"); + ts->abs_x_max = GOODIX_MAX_WIDTH; + ts->abs_y_max = GOODIX_MAX_HEIGHT; + } +} + + +/** + * goodix_read_version - Read goodix touchscreen version + * + * @client: the i2c client + * @version: output buffer containing the version on success + */ +static int goodix_read_version(struct i2c_client *client, u16 *version) +{ + int error; + u8 buf[6]; + + error = goodix_i2c_read(client, GOODIX_REG_VERSION, buf, sizeof(buf)); + if (error) { + dev_err(&client->dev, "read version failed: %d\n", error); + return error; + } + + if (version) + *version = get_unaligned_le16(&buf[4]); + + dev_info(&client->dev, "IC VERSION: %6ph\n", buf); + + return 0; +} + +/** + * goodix_i2c_test - I2C test function to check if the device answers. + * + * @client: the i2c client + */ +static int goodix_i2c_test(struct i2c_client *client) +{ + int retry = 0; + int error; + u8 test; + + while (retry++ < 2) { + error = goodix_i2c_read(client, GOODIX_REG_CONFIG_DATA, + &test, 1); + if (!error) + return 0; + + dev_err(&client->dev, "i2c test failed attempt %d: %d\n", + retry, error); + msleep(20); + } + + return error; +} + +/** + * goodix_request_input_dev - Allocate, populate and register the input device + * + * @ts: our goodix_ts_data pointer + * + * Must be called during probe + */ +static int goodix_request_input_dev(struct goodix_ts_data *ts) +{ + int error; + + ts->input_dev = devm_input_allocate_device(&ts->client->dev); + if (!ts->input_dev) { + dev_err(&ts->client->dev, "Failed to allocate input device."); + return -ENOMEM; + } + + ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | + BIT_MASK(EV_KEY) | + BIT_MASK(EV_ABS); + + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, + ts->abs_x_max, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, + ts->abs_y_max, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); + + input_mt_init_slots(ts->input_dev, GOODIX_MAX_CONTACTS, + INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); + + ts->input_dev->name = "Goodix Capacitive TouchScreen"; + ts->input_dev->phys = "input/ts"; + ts->input_dev->id.bustype = BUS_I2C; + ts->input_dev->id.vendor = 0x0416; + ts->input_dev->id.product = 0x1001; + ts->input_dev->id.version = 10427; + + error = input_register_device(ts->input_dev); + if (error) { + dev_err(&ts->client->dev, + "Failed to register input device: %d", error); + return error; + } + + return 0; +} + +static int goodix_ts_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct goodix_ts_data *ts; + unsigned long irq_flags; + int error; + u16 version_info; + + dev_dbg(&client->dev, "I2C Address: 0x%02x\n", client->addr); + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + dev_err(&client->dev, "I2C check functionality failed.\n"); + return -ENXIO; + } + + ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL); + if (!ts) + return -ENOMEM; + + ts->client = client; + i2c_set_clientdata(client, ts); + + error = goodix_i2c_test(client); + if (error) { + dev_err(&client->dev, "I2C communication failure: %d\n", error); + return error; + } + + error = goodix_read_version(client, &version_info); + if (error) { + dev_err(&client->dev, "Read version failed.\n"); + return error; + } + + goodix_read_config(ts); + + error = goodix_request_input_dev(ts); + if (error) + return error; + + irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT; + error = devm_request_threaded_irq(&ts->client->dev, client->irq, + NULL, goodix_ts_irq_handler, + irq_flags, client->name, ts); + if (error) { + dev_err(&client->dev, "request IRQ failed: %d\n", error); + return error; + } + + return 0; +} + +static const struct i2c_device_id goodix_ts_id[] = { + { "GDIX1001:00", 0 }, + { } +}; + +static const struct acpi_device_id goodix_acpi_match[] = { + { "GDIX1001", 0 }, + { } +}; +MODULE_DEVICE_TABLE(acpi, goodix_acpi_match); + +static struct i2c_driver goodix_ts_driver = { + .probe = goodix_ts_probe, + .id_table = goodix_ts_id, + .driver = { + .name = "Goodix-TS", + .owner = THIS_MODULE, + .acpi_match_table = goodix_acpi_match, + }, +}; +module_i2c_driver(goodix_ts_driver); + +MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>"); +MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>"); +MODULE_DESCRIPTION("Goodix touchscreen driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index 2a5089139818..da6dc819c846 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -311,8 +311,7 @@ static int ili210x_i2c_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int ili210x_i2c_suspend(struct device *dev) +static int __maybe_unused ili210x_i2c_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -322,7 +321,7 @@ static int ili210x_i2c_suspend(struct device *dev) return 0; } -static int ili210x_i2c_resume(struct device *dev) +static int __maybe_unused ili210x_i2c_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -331,7 +330,6 @@ static int ili210x_i2c_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(ili210x_i2c_pm, ili210x_i2c_suspend, ili210x_i2c_resume); diff --git a/drivers/input/touchscreen/ipaq-micro-ts.c b/drivers/input/touchscreen/ipaq-micro-ts.c index 62c8976e616f..33c134820ef9 100644 --- a/drivers/input/touchscreen/ipaq-micro-ts.c +++ b/drivers/input/touchscreen/ipaq-micro-ts.c @@ -122,8 +122,7 @@ static int micro_ts_probe(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int micro_ts_suspend(struct device *dev) +static int __maybe_unused micro_ts_suspend(struct device *dev) { struct touchscreen_data *ts = dev_get_drvdata(dev); @@ -132,7 +131,7 @@ static int micro_ts_suspend(struct device *dev) return 0; } -static int micro_ts_resume(struct device *dev) +static int __maybe_unused micro_ts_resume(struct device *dev) { struct touchscreen_data *ts = dev_get_drvdata(dev); struct input_dev *input = ts->input; @@ -146,7 +145,6 @@ static int micro_ts_resume(struct device *dev) return 0; } -#endif static const struct dev_pm_ops micro_ts_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(micro_ts_suspend, micro_ts_resume) diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c index 372bbf7658fe..67c0d31613d8 100644 --- a/drivers/input/touchscreen/mms114.c +++ b/drivers/input/touchscreen/mms114.c @@ -515,8 +515,7 @@ static int mms114_probe(struct i2c_client *client, return 0; } -#ifdef CONFIG_PM_SLEEP -static int mms114_suspend(struct device *dev) +static int __maybe_unused mms114_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct mms114_data *data = i2c_get_clientdata(client); @@ -540,7 +539,7 @@ static int mms114_suspend(struct device *dev) return 0; } -static int mms114_resume(struct device *dev) +static int __maybe_unused mms114_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct mms114_data *data = i2c_get_clientdata(client); @@ -559,7 +558,6 @@ static int mms114_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(mms114_pm_ops, mms114_suspend, mms114_resume); diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c index fc49c75317d1..4fb5537fdd42 100644 --- a/drivers/input/touchscreen/pixcir_i2c_ts.c +++ b/drivers/input/touchscreen/pixcir_i2c_ts.c @@ -347,8 +347,7 @@ static void pixcir_input_close(struct input_dev *dev) pixcir_stop(ts); } -#ifdef CONFIG_PM_SLEEP -static int pixcir_i2c_ts_suspend(struct device *dev) +static int __maybe_unused pixcir_i2c_ts_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client); @@ -377,7 +376,7 @@ unlock: return ret; } -static int pixcir_i2c_ts_resume(struct device *dev) +static int __maybe_unused pixcir_i2c_ts_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client); @@ -405,7 +404,6 @@ unlock: return ret; } -#endif static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops, pixcir_i2c_ts_suspend, pixcir_i2c_ts_resume); diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index 3c0f57efe7b1..697e26e52d54 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c @@ -243,8 +243,7 @@ static int st1232_ts_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int st1232_ts_suspend(struct device *dev) +static int __maybe_unused st1232_ts_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct st1232_ts_data *ts = i2c_get_clientdata(client); @@ -259,7 +258,7 @@ static int st1232_ts_suspend(struct device *dev) return 0; } -static int st1232_ts_resume(struct device *dev) +static int __maybe_unused st1232_ts_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct st1232_ts_data *ts = i2c_get_clientdata(client); @@ -274,8 +273,6 @@ static int st1232_ts_resume(struct device *dev) return 0; } -#endif - static SIMPLE_DEV_PM_OPS(st1232_ts_pm_ops, st1232_ts_suspend, st1232_ts_resume); diff --git a/drivers/input/touchscreen/tsc2005.c b/drivers/input/touchscreen/tsc2005.c index 52380b68ebdf..72657c579430 100644 --- a/drivers/input/touchscreen/tsc2005.c +++ b/drivers/input/touchscreen/tsc2005.c @@ -773,8 +773,7 @@ static int tsc2005_remove(struct spi_device *spi) return 0; } -#ifdef CONFIG_PM_SLEEP -static int tsc2005_suspend(struct device *dev) +static int __maybe_unused tsc2005_suspend(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct tsc2005 *ts = spi_get_drvdata(spi); @@ -791,7 +790,7 @@ static int tsc2005_suspend(struct device *dev) return 0; } -static int tsc2005_resume(struct device *dev) +static int __maybe_unused tsc2005_resume(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct tsc2005 *ts = spi_get_drvdata(spi); @@ -807,7 +806,6 @@ static int tsc2005_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(tsc2005_pm_ops, tsc2005_suspend, tsc2005_resume); diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index 0eca00da584b..c1e23cfc6155 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c @@ -406,8 +406,7 @@ static int ucb1400_ts_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int ucb1400_ts_suspend(struct device *dev) +static int __maybe_unused ucb1400_ts_suspend(struct device *dev) { struct ucb1400_ts *ucb = dev_get_platdata(dev); struct input_dev *idev = ucb->ts_idev; @@ -421,7 +420,7 @@ static int ucb1400_ts_suspend(struct device *dev) return 0; } -static int ucb1400_ts_resume(struct device *dev) +static int __maybe_unused ucb1400_ts_resume(struct device *dev) { struct ucb1400_ts *ucb = dev_get_platdata(dev); struct input_dev *idev = ucb->ts_idev; @@ -434,7 +433,6 @@ static int ucb1400_ts_resume(struct device *dev) mutex_unlock(&idev->mutex); return 0; } -#endif static SIMPLE_DEV_PM_OPS(ucb1400_ts_pm_ops, ucb1400_ts_suspend, ucb1400_ts_resume); diff --git a/drivers/input/touchscreen/wacom_i2c.c b/drivers/input/touchscreen/wacom_i2c.c index 7ccaa1b12b05..32f8ac003936 100644 --- a/drivers/input/touchscreen/wacom_i2c.c +++ b/drivers/input/touchscreen/wacom_i2c.c @@ -242,8 +242,7 @@ static int wacom_i2c_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int wacom_i2c_suspend(struct device *dev) +static int __maybe_unused wacom_i2c_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -252,7 +251,7 @@ static int wacom_i2c_suspend(struct device *dev) return 0; } -static int wacom_i2c_resume(struct device *dev) +static int __maybe_unused wacom_i2c_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -260,7 +259,6 @@ static int wacom_i2c_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(wacom_i2c_pm, wacom_i2c_suspend, wacom_i2c_resume); diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c index 8ba48f5eff7b..19880c7385e3 100644 --- a/drivers/input/touchscreen/zforce_ts.c +++ b/drivers/input/touchscreen/zforce_ts.c @@ -602,8 +602,7 @@ static void zforce_input_close(struct input_dev *dev) return; } -#ifdef CONFIG_PM_SLEEP -static int zforce_suspend(struct device *dev) +static int __maybe_unused zforce_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct zforce_ts *ts = i2c_get_clientdata(client); @@ -648,7 +647,7 @@ unlock: return ret; } -static int zforce_resume(struct device *dev) +static int __maybe_unused zforce_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct zforce_ts *ts = i2c_get_clientdata(client); @@ -685,7 +684,6 @@ unlock: return ret; } -#endif static SIMPLE_DEV_PM_OPS(zforce_pm_ops, zforce_suspend, zforce_resume); diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 30f0e61341c5..325188eef1c1 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -15,7 +15,7 @@ if IOMMU_SUPPORT config OF_IOMMU def_bool y - depends on OF + depends on OF && IOMMU_API config FSL_PAMU bool "Freescale IOMMU support" @@ -187,7 +187,7 @@ config TEGRA_IOMMU_SMMU config EXYNOS_IOMMU bool "Exynos IOMMU Support" - depends on ARCH_EXYNOS + depends on ARCH_EXYNOS && ARM select IOMMU_API select ARM_DMA_USE_IOMMU help diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index b205f76d7129..98024856df07 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -4071,7 +4071,7 @@ static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry, int devid; int ret; - cfg = irq_get_chip_data(irq); + cfg = irq_cfg(irq); if (!cfg) return -EINVAL; @@ -4134,7 +4134,7 @@ static int set_affinity(struct irq_data *data, const struct cpumask *mask, if (!config_enabled(CONFIG_SMP)) return -1; - cfg = data->chip_data; + cfg = irqd_cfg(data); irq = data->irq; irte_info = &cfg->irq_2_irte; @@ -4172,7 +4172,7 @@ static int free_irq(int irq) struct irq_2_irte *irte_info; struct irq_cfg *cfg; - cfg = irq_get_chip_data(irq); + cfg = irq_cfg(irq); if (!cfg) return -EINVAL; @@ -4191,7 +4191,7 @@ static void compose_msi_msg(struct pci_dev *pdev, struct irq_cfg *cfg; union irte irte; - cfg = irq_get_chip_data(irq); + cfg = irq_cfg(irq); if (!cfg) return; @@ -4220,7 +4220,7 @@ static int msi_alloc_irq(struct pci_dev *pdev, int irq, int nvec) if (!pdev) return -EINVAL; - cfg = irq_get_chip_data(irq); + cfg = irq_cfg(irq); if (!cfg) return -EINVAL; @@ -4240,7 +4240,7 @@ static int msi_setup_irq(struct pci_dev *pdev, unsigned int irq, if (!pdev) return -EINVAL; - cfg = irq_get_chip_data(irq); + cfg = irq_cfg(irq); if (!cfg) return -EINVAL; @@ -4263,7 +4263,7 @@ static int alloc_hpet_msi(unsigned int irq, unsigned int id) struct irq_cfg *cfg; int index, devid; - cfg = irq_get_chip_data(irq); + cfg = irq_cfg(irq); if (!cfg) return -EINVAL; diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 1232336b960e..40dfbc0444c0 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -4029,14 +4029,6 @@ static int device_notifier(struct notifier_block *nb, if (action != BUS_NOTIFY_REMOVED_DEVICE) return 0; - /* - * If the device is still attached to a device driver we can't - * tear down the domain yet as DMA mappings may still be in use. - * Wait for the BUS_NOTIFY_UNBOUND_DRIVER event to do that. - */ - if (action == BUS_NOTIFY_DEL_DEVICE && dev->driver != NULL) - return 0; - domain = find_domain(dev); if (!domain) return 0; @@ -4428,6 +4420,10 @@ static int intel_iommu_attach_device(struct iommu_domain *domain, domain_remove_one_dev_info(old_domain, dev); else domain_remove_dev_info(old_domain); + + if (!domain_type_is_vm_or_si(old_domain) && + list_empty(&old_domain->devices)) + domain_exit(old_domain); } } diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 27541d440849..a55b207b9425 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c @@ -54,7 +54,7 @@ static int __init parse_ioapics_under_ir(void); static struct irq_2_iommu *irq_2_iommu(unsigned int irq) { - struct irq_cfg *cfg = irq_get_chip_data(irq); + struct irq_cfg *cfg = irq_cfg(irq); return cfg ? &cfg->irq_2_iommu : NULL; } @@ -85,7 +85,7 @@ static int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) { struct ir_table *table = iommu->ir_table; struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); - struct irq_cfg *cfg = irq_get_chip_data(irq); + struct irq_cfg *cfg = irq_cfg(irq); unsigned int mask = 0; unsigned long flags; int index; @@ -153,7 +153,7 @@ static int map_irq_to_irte_handle(int irq, u16 *sub_handle) static int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) { struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); - struct irq_cfg *cfg = irq_get_chip_data(irq); + struct irq_cfg *cfg = irq_cfg(irq); unsigned long flags; if (!irq_iommu) @@ -1050,7 +1050,7 @@ static int intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) { - struct irq_cfg *cfg = data->chip_data; + struct irq_cfg *cfg = irqd_cfg(data); unsigned int dest, irq = data->irq; struct irte irte; int err; @@ -1105,7 +1105,7 @@ static void intel_compose_msi_msg(struct pci_dev *pdev, u16 sub_handle = 0; int ir_index; - cfg = irq_get_chip_data(irq); + cfg = irq_cfg(irq); ir_index = map_irq_to_irte_handle(irq, &sub_handle); BUG_ON(ir_index == -1); diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 1bd63352ab17..f7718d73e984 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -737,7 +737,7 @@ static int add_iommu_group(struct device *dev, void *data) const struct iommu_ops *ops = cb->ops; if (!ops->add_device) - return -ENODEV; + return 0; WARN_ON(dev->iommu_group); diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index 68dfb0fd5ee9..748693192c20 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c @@ -558,7 +558,7 @@ static pmd_t *ipmmu_alloc_pmd(struct ipmmu_vmsa_device *mmu, pgd_t *pgd, static u64 ipmmu_page_prot(unsigned int prot, u64 type) { - u64 pgprot = ARM_VMSA_PTE_XN | ARM_VMSA_PTE_nG | ARM_VMSA_PTE_AF + u64 pgprot = ARM_VMSA_PTE_nG | ARM_VMSA_PTE_AF | ARM_VMSA_PTE_SH_IS | ARM_VMSA_PTE_AP_UNPRIV | ARM_VMSA_PTE_NS | type; @@ -568,8 +568,8 @@ static u64 ipmmu_page_prot(unsigned int prot, u64 type) if (prot & IOMMU_CACHE) pgprot |= IMMAIR_ATTR_IDX_WBRWA << ARM_VMSA_PTE_ATTRINDX_SHIFT; - if (prot & IOMMU_EXEC) - pgprot &= ~ARM_VMSA_PTE_XN; + if (prot & IOMMU_NOEXEC) + pgprot |= ARM_VMSA_PTE_XN; else if (!(prot & (IOMMU_READ | IOMMU_WRITE))) /* If no access create a faulting entry to avoid TLB fills. */ pgprot &= ~ARM_VMSA_PTE_PAGE; diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c index 2c3f5ad01098..89c4846683be 100644 --- a/drivers/iommu/irq_remapping.c +++ b/drivers/iommu/irq_remapping.c @@ -298,7 +298,7 @@ static int set_remapped_irq_affinity(struct irq_data *data, void free_remapped_irq(int irq) { - struct irq_cfg *cfg = irq_get_chip_data(irq); + struct irq_cfg *cfg = irq_cfg(irq); if (!remap_ops || !remap_ops->free_irq) return; @@ -311,7 +311,7 @@ void compose_remapped_msi_msg(struct pci_dev *pdev, unsigned int irq, unsigned int dest, struct msi_msg *msg, u8 hpet_id) { - struct irq_cfg *cfg = irq_get_chip_data(irq); + struct irq_cfg *cfg = irq_cfg(irq); if (!irq_remapped(cfg)) native_compose_msi_msg(pdev, irq, dest, msg, hpet_id); @@ -364,7 +364,7 @@ static void ir_ack_apic_edge(struct irq_data *data) static void ir_ack_apic_level(struct irq_data *data) { ack_APIC_irq(); - eoi_ioapic_irq(data->irq, data->chip_data); + eoi_ioapic_irq(data->irq, irqd_cfg(data)); } static void ir_print_prefix(struct irq_data *data, struct seq_file *p) diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index e550ccb7634e..af1dc6a1c0a1 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -18,9 +18,14 @@ */ #include <linux/export.h> +#include <linux/iommu.h> #include <linux/limits.h> #include <linux/of.h> #include <linux/of_iommu.h> +#include <linux/slab.h> + +static const struct of_device_id __iommu_of_table_sentinel + __used __section(__iommu_of_table_end); /** * of_get_dma_window - Parse *dma-window property and returns 0 if found. @@ -89,3 +94,87 @@ int of_get_dma_window(struct device_node *dn, const char *prefix, int index, return 0; } EXPORT_SYMBOL_GPL(of_get_dma_window); + +struct of_iommu_node { + struct list_head list; + struct device_node *np; + struct iommu_ops *ops; +}; +static LIST_HEAD(of_iommu_list); +static DEFINE_SPINLOCK(of_iommu_lock); + +void of_iommu_set_ops(struct device_node *np, struct iommu_ops *ops) +{ + struct of_iommu_node *iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); + + if (WARN_ON(!iommu)) + return; + + INIT_LIST_HEAD(&iommu->list); + iommu->np = np; + iommu->ops = ops; + spin_lock(&of_iommu_lock); + list_add_tail(&iommu->list, &of_iommu_list); + spin_unlock(&of_iommu_lock); +} + +struct iommu_ops *of_iommu_get_ops(struct device_node *np) +{ + struct of_iommu_node *node; + struct iommu_ops *ops = NULL; + + spin_lock(&of_iommu_lock); + list_for_each_entry(node, &of_iommu_list, list) + if (node->np == np) { + ops = node->ops; + break; + } + spin_unlock(&of_iommu_lock); + return ops; +} + +struct iommu_ops *of_iommu_configure(struct device *dev) +{ + struct of_phandle_args iommu_spec; + struct device_node *np; + struct iommu_ops *ops = NULL; + int idx = 0; + + /* + * We don't currently walk up the tree looking for a parent IOMMU. + * See the `Notes:' section of + * Documentation/devicetree/bindings/iommu/iommu.txt + */ + while (!of_parse_phandle_with_args(dev->of_node, "iommus", + "#iommu-cells", idx, + &iommu_spec)) { + np = iommu_spec.np; + ops = of_iommu_get_ops(np); + + if (!ops || !ops->of_xlate || ops->of_xlate(dev, &iommu_spec)) + goto err_put_node; + + of_node_put(np); + idx++; + } + + return ops; + +err_put_node: + of_node_put(np); + return NULL; +} + +void __init of_iommu_init(void) +{ + struct device_node *np; + const struct of_device_id *match, *matches = &__iommu_of_table; + + for_each_matching_node_and_match(np, matches, &match) { + const of_iommu_init_fn init_fn = match->data; + + if (init_fn(np)) + pr_err("Failed to initialise IOMMU %s\n", + of_node_full_name(np)); + } +} diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index b2023af384b9..6a8b1ec4a48a 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c @@ -1009,7 +1009,6 @@ static struct platform_driver rk_iommu_driver = { .remove = rk_iommu_remove, .driver = { .name = "rk_iommu", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(rk_iommu_dt_ids), }, }; diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index e12cb23d786c..cc79d2a5a8c2 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -5,8 +5,15 @@ config IRQCHIP config ARM_GIC bool select IRQ_DOMAIN + select IRQ_DOMAIN_HIERARCHY select MULTI_IRQ_HANDLER +config ARM_GIC_V2M + bool + depends on ARM_GIC + depends on PCI && PCI_MSI + select PCI_MSI_IRQ_DOMAIN + config GIC_NON_BANKED bool @@ -14,6 +21,11 @@ config ARM_GIC_V3 bool select IRQ_DOMAIN select MULTI_IRQ_HANDLER + select IRQ_DOMAIN_HIERARCHY + +config ARM_GIC_V3_ITS + bool + select PCI_MSI_IRQ_DOMAIN config ARM_NVIC bool diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 4954a314c31e..9516a324be6d 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -19,7 +19,9 @@ obj-$(CONFIG_ARCH_SUNXI) += irq-sun4i.o obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi-nmi.o obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o obj-$(CONFIG_ARM_GIC) += irq-gic.o irq-gic-common.o +obj-$(CONFIG_ARM_GIC_V2M) += irq-gic-v2m.o obj-$(CONFIG_ARM_GIC_V3) += irq-gic-v3.o irq-gic-common.o +obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o obj-$(CONFIG_ARM_NVIC) += irq-nvic.o obj-$(CONFIG_ARM_VIC) += irq-vic.o obj-$(CONFIG_ATMEL_AIC_IRQ) += irq-atmel-aic-common.o irq-atmel-aic.o @@ -39,3 +41,4 @@ obj-$(CONFIG_BCM7120_L2_IRQ) += irq-bcm7120-l2.o obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o obj-$(CONFIG_MIPS_GIC) += irq-mips-gic.o +obj-$(CONFIG_ARCH_MEDIATEK) += irq-mtk-sysirq.o diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c new file mode 100644 index 000000000000..fdf706555d72 --- /dev/null +++ b/drivers/irqchip/irq-gic-v2m.c @@ -0,0 +1,333 @@ +/* + * ARM GIC v2m MSI(-X) support + * Support for Message Signaled Interrupts for systems that + * implement ARM Generic Interrupt Controller: GICv2m. + * + * Copyright (C) 2014 Advanced Micro Devices, Inc. + * Authors: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> + * Harish Kasiviswanathan <harish.kasiviswanathan@amd.com> + * Brandon Anderson <brandon.anderson@amd.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#define pr_fmt(fmt) "GICv2m: " fmt + +#include <linux/irq.h> +#include <linux/irqdomain.h> +#include <linux/kernel.h> +#include <linux/of_address.h> +#include <linux/of_pci.h> +#include <linux/slab.h> +#include <linux/spinlock.h> + +/* +* MSI_TYPER: +* [31:26] Reserved +* [25:16] lowest SPI assigned to MSI +* [15:10] Reserved +* [9:0] Numer of SPIs assigned to MSI +*/ +#define V2M_MSI_TYPER 0x008 +#define V2M_MSI_TYPER_BASE_SHIFT 16 +#define V2M_MSI_TYPER_BASE_MASK 0x3FF +#define V2M_MSI_TYPER_NUM_MASK 0x3FF +#define V2M_MSI_SETSPI_NS 0x040 +#define V2M_MIN_SPI 32 +#define V2M_MAX_SPI 1019 + +#define V2M_MSI_TYPER_BASE_SPI(x) \ + (((x) >> V2M_MSI_TYPER_BASE_SHIFT) & V2M_MSI_TYPER_BASE_MASK) + +#define V2M_MSI_TYPER_NUM_SPI(x) ((x) & V2M_MSI_TYPER_NUM_MASK) + +struct v2m_data { + spinlock_t msi_cnt_lock; + struct msi_controller mchip; + struct resource res; /* GICv2m resource */ + void __iomem *base; /* GICv2m virt address */ + u32 spi_start; /* The SPI number that MSIs start */ + u32 nr_spis; /* The number of SPIs for MSIs */ + unsigned long *bm; /* MSI vector bitmap */ + struct irq_domain *domain; +}; + +static void gicv2m_mask_msi_irq(struct irq_data *d) +{ + pci_msi_mask_irq(d); + irq_chip_mask_parent(d); +} + +static void gicv2m_unmask_msi_irq(struct irq_data *d) +{ + pci_msi_unmask_irq(d); + irq_chip_unmask_parent(d); +} + +static struct irq_chip gicv2m_msi_irq_chip = { + .name = "MSI", + .irq_mask = gicv2m_mask_msi_irq, + .irq_unmask = gicv2m_unmask_msi_irq, + .irq_eoi = irq_chip_eoi_parent, + .irq_write_msi_msg = pci_msi_domain_write_msg, +}; + +static struct msi_domain_info gicv2m_msi_domain_info = { + .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | + MSI_FLAG_PCI_MSIX), + .chip = &gicv2m_msi_irq_chip, +}; + +static int gicv2m_set_affinity(struct irq_data *irq_data, + const struct cpumask *mask, bool force) +{ + int ret; + + ret = irq_chip_set_affinity_parent(irq_data, mask, force); + if (ret == IRQ_SET_MASK_OK) + ret = IRQ_SET_MASK_OK_DONE; + + return ret; +} + +static void gicv2m_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) +{ + struct v2m_data *v2m = irq_data_get_irq_chip_data(data); + phys_addr_t addr = v2m->res.start + V2M_MSI_SETSPI_NS; + + msg->address_hi = (u32) (addr >> 32); + msg->address_lo = (u32) (addr); + msg->data = data->hwirq; +} + +static struct irq_chip gicv2m_irq_chip = { + .name = "GICv2m", + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, + .irq_eoi = irq_chip_eoi_parent, + .irq_set_affinity = gicv2m_set_affinity, + .irq_compose_msi_msg = gicv2m_compose_msi_msg, +}; + +static int gicv2m_irq_gic_domain_alloc(struct irq_domain *domain, + unsigned int virq, + irq_hw_number_t hwirq) +{ + struct of_phandle_args args; + struct irq_data *d; + int err; + + args.np = domain->parent->of_node; + args.args_count = 3; + args.args[0] = 0; + args.args[1] = hwirq - 32; + args.args[2] = IRQ_TYPE_EDGE_RISING; + + err = irq_domain_alloc_irqs_parent(domain, virq, 1, &args); + if (err) + return err; + + /* Configure the interrupt line to be edge */ + d = irq_domain_get_irq_data(domain->parent, virq); + d->chip->irq_set_type(d, IRQ_TYPE_EDGE_RISING); + return 0; +} + +static void gicv2m_unalloc_msi(struct v2m_data *v2m, unsigned int hwirq) +{ + int pos; + + pos = hwirq - v2m->spi_start; + if (pos < 0 || pos >= v2m->nr_spis) { + pr_err("Failed to teardown msi. Invalid hwirq %d\n", hwirq); + return; + } + + spin_lock(&v2m->msi_cnt_lock); + __clear_bit(pos, v2m->bm); + spin_unlock(&v2m->msi_cnt_lock); +} + +static int gicv2m_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *args) +{ + struct v2m_data *v2m = domain->host_data; + int hwirq, offset, err = 0; + + spin_lock(&v2m->msi_cnt_lock); + offset = find_first_zero_bit(v2m->bm, v2m->nr_spis); + if (offset < v2m->nr_spis) + __set_bit(offset, v2m->bm); + else + err = -ENOSPC; + spin_unlock(&v2m->msi_cnt_lock); + + if (err) + return err; + + hwirq = v2m->spi_start + offset; + + err = gicv2m_irq_gic_domain_alloc(domain, virq, hwirq); + if (err) { + gicv2m_unalloc_msi(v2m, hwirq); + return err; + } + + irq_domain_set_hwirq_and_chip(domain, virq, hwirq, + &gicv2m_irq_chip, v2m); + + return 0; +} + +static void gicv2m_irq_domain_free(struct irq_domain *domain, + unsigned int virq, unsigned int nr_irqs) +{ + struct irq_data *d = irq_domain_get_irq_data(domain, virq); + struct v2m_data *v2m = irq_data_get_irq_chip_data(d); + + BUG_ON(nr_irqs != 1); + gicv2m_unalloc_msi(v2m, d->hwirq); + irq_domain_free_irqs_parent(domain, virq, nr_irqs); +} + +static const struct irq_domain_ops gicv2m_domain_ops = { + .alloc = gicv2m_irq_domain_alloc, + .free = gicv2m_irq_domain_free, +}; + +static bool is_msi_spi_valid(u32 base, u32 num) +{ + if (base < V2M_MIN_SPI) { + pr_err("Invalid MSI base SPI (base:%u)\n", base); + return false; + } + + if ((num == 0) || (base + num > V2M_MAX_SPI)) { + pr_err("Number of SPIs (%u) exceed maximum (%u)\n", + num, V2M_MAX_SPI - V2M_MIN_SPI + 1); + return false; + } + + return true; +} + +static int __init gicv2m_init_one(struct device_node *node, + struct irq_domain *parent) +{ + int ret; + struct v2m_data *v2m; + + v2m = kzalloc(sizeof(struct v2m_data), GFP_KERNEL); + if (!v2m) { + pr_err("Failed to allocate struct v2m_data.\n"); + return -ENOMEM; + } + + ret = of_address_to_resource(node, 0, &v2m->res); + if (ret) { + pr_err("Failed to allocate v2m resource.\n"); + goto err_free_v2m; + } + + v2m->base = ioremap(v2m->res.start, resource_size(&v2m->res)); + if (!v2m->base) { + pr_err("Failed to map GICv2m resource\n"); + ret = -ENOMEM; + goto err_free_v2m; + } + + if (!of_property_read_u32(node, "arm,msi-base-spi", &v2m->spi_start) && + !of_property_read_u32(node, "arm,msi-num-spis", &v2m->nr_spis)) { + pr_info("Overriding V2M MSI_TYPER (base:%u, num:%u)\n", + v2m->spi_start, v2m->nr_spis); + } else { + u32 typer = readl_relaxed(v2m->base + V2M_MSI_TYPER); + + v2m->spi_start = V2M_MSI_TYPER_BASE_SPI(typer); + v2m->nr_spis = V2M_MSI_TYPER_NUM_SPI(typer); + } + + if (!is_msi_spi_valid(v2m->spi_start, v2m->nr_spis)) { + ret = -EINVAL; + goto err_iounmap; + } + + v2m->bm = kzalloc(sizeof(long) * BITS_TO_LONGS(v2m->nr_spis), + GFP_KERNEL); + if (!v2m->bm) { + ret = -ENOMEM; + goto err_iounmap; + } + + v2m->domain = irq_domain_add_tree(NULL, &gicv2m_domain_ops, v2m); + if (!v2m->domain) { + pr_err("Failed to create GICv2m domain\n"); + ret = -ENOMEM; + goto err_free_bm; + } + + v2m->domain->parent = parent; + v2m->mchip.of_node = node; + v2m->mchip.domain = pci_msi_create_irq_domain(node, + &gicv2m_msi_domain_info, + v2m->domain); + if (!v2m->mchip.domain) { + pr_err("Failed to create MSI domain\n"); + ret = -ENOMEM; + goto err_free_domains; + } + + spin_lock_init(&v2m->msi_cnt_lock); + + ret = of_pci_msi_chip_add(&v2m->mchip); + if (ret) { + pr_err("Failed to add msi_chip.\n"); + goto err_free_domains; + } + + pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", node->name, + (unsigned long)v2m->res.start, (unsigned long)v2m->res.end, + v2m->spi_start, (v2m->spi_start + v2m->nr_spis)); + + return 0; + +err_free_domains: + if (v2m->mchip.domain) + irq_domain_remove(v2m->mchip.domain); + if (v2m->domain) + irq_domain_remove(v2m->domain); +err_free_bm: + kfree(v2m->bm); +err_iounmap: + iounmap(v2m->base); +err_free_v2m: + kfree(v2m); + return ret; +} + +static struct of_device_id gicv2m_device_id[] = { + { .compatible = "arm,gic-v2m-frame", }, + {}, +}; + +int __init gicv2m_of_init(struct device_node *node, struct irq_domain *parent) +{ + int ret = 0; + struct device_node *child; + + for (child = of_find_matching_node(node, gicv2m_device_id); child; + child = of_find_matching_node(child, gicv2m_device_id)) { + if (!of_find_property(child, "msi-controller", NULL)) + continue; + + ret = gicv2m_init_one(child, parent); + if (ret) { + of_node_put(node); + break; + } + } + + return ret; +} diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c new file mode 100644 index 000000000000..86e4684adeb1 --- /dev/null +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -0,0 +1,1425 @@ +/* + * Copyright (C) 2013, 2014 ARM Limited, All Rights Reserved. + * Author: Marc Zyngier <marc.zyngier@arm.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/bitmap.h> +#include <linux/cpu.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/log2.h> +#include <linux/mm.h> +#include <linux/msi.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/of_pci.h> +#include <linux/of_platform.h> +#include <linux/percpu.h> +#include <linux/slab.h> + +#include <linux/irqchip/arm-gic-v3.h> + +#include <asm/cacheflush.h> +#include <asm/cputype.h> +#include <asm/exception.h> + +#include "irqchip.h" + +#define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1 << 0) + +#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0) + +/* + * Collection structure - just an ID, and a redistributor address to + * ping. We use one per CPU as a bag of interrupts assigned to this + * CPU. + */ +struct its_collection { + u64 target_address; + u16 col_id; +}; + +/* + * The ITS structure - contains most of the infrastructure, with the + * msi_controller, the command queue, the collections, and the list of + * devices writing to it. + */ +struct its_node { + raw_spinlock_t lock; + struct list_head entry; + struct msi_controller msi_chip; + struct irq_domain *domain; + void __iomem *base; + unsigned long phys_base; + struct its_cmd_block *cmd_base; + struct its_cmd_block *cmd_write; + void *tables[GITS_BASER_NR_REGS]; + struct its_collection *collections; + struct list_head its_device_list; + u64 flags; + u32 ite_size; +}; + +#define ITS_ITT_ALIGN SZ_256 + +/* + * The ITS view of a device - belongs to an ITS, a collection, owns an + * interrupt translation table, and a list of interrupts. + */ +struct its_device { + struct list_head entry; + struct its_node *its; + struct its_collection *collection; + void *itt; + unsigned long *lpi_map; + irq_hw_number_t lpi_base; + int nr_lpis; + u32 nr_ites; + u32 device_id; +}; + +static LIST_HEAD(its_nodes); +static DEFINE_SPINLOCK(its_lock); +static struct device_node *gic_root_node; +static struct rdists *gic_rdists; + +#define gic_data_rdist() (raw_cpu_ptr(gic_rdists->rdist)) +#define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base) + +/* + * ITS command descriptors - parameters to be encoded in a command + * block. + */ +struct its_cmd_desc { + union { + struct { + struct its_device *dev; + u32 event_id; + } its_inv_cmd; + + struct { + struct its_device *dev; + u32 event_id; + } its_int_cmd; + + struct { + struct its_device *dev; + int valid; + } its_mapd_cmd; + + struct { + struct its_collection *col; + int valid; + } its_mapc_cmd; + + struct { + struct its_device *dev; + u32 phys_id; + u32 event_id; + } its_mapvi_cmd; + + struct { + struct its_device *dev; + struct its_collection *col; + u32 id; + } its_movi_cmd; + + struct { + struct its_device *dev; + u32 event_id; + } its_discard_cmd; + + struct { + struct its_collection *col; + } its_invall_cmd; + }; +}; + +/* + * The ITS command block, which is what the ITS actually parses. + */ +struct its_cmd_block { + u64 raw_cmd[4]; +}; + +#define ITS_CMD_QUEUE_SZ SZ_64K +#define ITS_CMD_QUEUE_NR_ENTRIES (ITS_CMD_QUEUE_SZ / sizeof(struct its_cmd_block)) + +typedef struct its_collection *(*its_cmd_builder_t)(struct its_cmd_block *, + struct its_cmd_desc *); + +static void its_encode_cmd(struct its_cmd_block *cmd, u8 cmd_nr) +{ + cmd->raw_cmd[0] &= ~0xffUL; + cmd->raw_cmd[0] |= cmd_nr; +} + +static void its_encode_devid(struct its_cmd_block *cmd, u32 devid) +{ + cmd->raw_cmd[0] &= ~(0xffffUL << 32); + cmd->raw_cmd[0] |= ((u64)devid) << 32; +} + +static void its_encode_event_id(struct its_cmd_block *cmd, u32 id) +{ + cmd->raw_cmd[1] &= ~0xffffffffUL; + cmd->raw_cmd[1] |= id; +} + +static void its_encode_phys_id(struct its_cmd_block *cmd, u32 phys_id) +{ + cmd->raw_cmd[1] &= 0xffffffffUL; + cmd->raw_cmd[1] |= ((u64)phys_id) << 32; +} + +static void its_encode_size(struct its_cmd_block *cmd, u8 size) +{ + cmd->raw_cmd[1] &= ~0x1fUL; + cmd->raw_cmd[1] |= size & 0x1f; +} + +static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr) +{ + cmd->raw_cmd[2] &= ~0xffffffffffffUL; + cmd->raw_cmd[2] |= itt_addr & 0xffffffffff00UL; +} + +static void its_encode_valid(struct its_cmd_block *cmd, int valid) +{ + cmd->raw_cmd[2] &= ~(1UL << 63); + cmd->raw_cmd[2] |= ((u64)!!valid) << 63; +} + +static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr) +{ + cmd->raw_cmd[2] &= ~(0xffffffffUL << 16); + cmd->raw_cmd[2] |= (target_addr & (0xffffffffUL << 16)); +} + +static void its_encode_collection(struct its_cmd_block *cmd, u16 col) +{ + cmd->raw_cmd[2] &= ~0xffffUL; + cmd->raw_cmd[2] |= col; +} + +static inline void its_fixup_cmd(struct its_cmd_block *cmd) +{ + /* Let's fixup BE commands */ + cmd->raw_cmd[0] = cpu_to_le64(cmd->raw_cmd[0]); + cmd->raw_cmd[1] = cpu_to_le64(cmd->raw_cmd[1]); + cmd->raw_cmd[2] = cpu_to_le64(cmd->raw_cmd[2]); + cmd->raw_cmd[3] = cpu_to_le64(cmd->raw_cmd[3]); +} + +static struct its_collection *its_build_mapd_cmd(struct its_cmd_block *cmd, + struct its_cmd_desc *desc) +{ + unsigned long itt_addr; + u8 size = ilog2(desc->its_mapd_cmd.dev->nr_ites); + + itt_addr = virt_to_phys(desc->its_mapd_cmd.dev->itt); + itt_addr = ALIGN(itt_addr, ITS_ITT_ALIGN); + + its_encode_cmd(cmd, GITS_CMD_MAPD); + its_encode_devid(cmd, desc->its_mapd_cmd.dev->device_id); + its_encode_size(cmd, size - 1); + its_encode_itt(cmd, itt_addr); + its_encode_valid(cmd, desc->its_mapd_cmd.valid); + + its_fixup_cmd(cmd); + + return desc->its_mapd_cmd.dev->collection; +} + +static struct its_collection *its_build_mapc_cmd(struct its_cmd_block *cmd, + struct its_cmd_desc *desc) +{ + its_encode_cmd(cmd, GITS_CMD_MAPC); + its_encode_collection(cmd, desc->its_mapc_cmd.col->col_id); + its_encode_target(cmd, desc->its_mapc_cmd.col->target_address); + its_encode_valid(cmd, desc->its_mapc_cmd.valid); + + its_fixup_cmd(cmd); + + return desc->its_mapc_cmd.col; +} + +static struct its_collection *its_build_mapvi_cmd(struct its_cmd_block *cmd, + struct its_cmd_desc *desc) +{ + its_encode_cmd(cmd, GITS_CMD_MAPVI); + its_encode_devid(cmd, desc->its_mapvi_cmd.dev->device_id); + its_encode_event_id(cmd, desc->its_mapvi_cmd.event_id); + its_encode_phys_id(cmd, desc->its_mapvi_cmd.phys_id); + its_encode_collection(cmd, desc->its_mapvi_cmd.dev->collection->col_id); + + its_fixup_cmd(cmd); + + return desc->its_mapvi_cmd.dev->collection; +} + +static struct its_collection *its_build_movi_cmd(struct its_cmd_block *cmd, + struct its_cmd_desc *desc) +{ + its_encode_cmd(cmd, GITS_CMD_MOVI); + its_encode_devid(cmd, desc->its_movi_cmd.dev->device_id); + its_encode_event_id(cmd, desc->its_movi_cmd.id); + its_encode_collection(cmd, desc->its_movi_cmd.col->col_id); + + its_fixup_cmd(cmd); + + return desc->its_movi_cmd.dev->collection; +} + +static struct its_collection *its_build_discard_cmd(struct its_cmd_block *cmd, + struct its_cmd_desc *desc) +{ + its_encode_cmd(cmd, GITS_CMD_DISCARD); + its_encode_devid(cmd, desc->its_discard_cmd.dev->device_id); + its_encode_event_id(cmd, desc->its_discard_cmd.event_id); + + its_fixup_cmd(cmd); + + return desc->its_discard_cmd.dev->collection; +} + +static struct its_collection *its_build_inv_cmd(struct its_cmd_block *cmd, + struct its_cmd_desc *desc) +{ + its_encode_cmd(cmd, GITS_CMD_INV); + its_encode_devid(cmd, desc->its_inv_cmd.dev->device_id); + its_encode_event_id(cmd, desc->its_inv_cmd.event_id); + + its_fixup_cmd(cmd); + + return desc->its_inv_cmd.dev->collection; +} + +static struct its_collection *its_build_invall_cmd(struct its_cmd_block *cmd, + struct its_cmd_desc *desc) +{ + its_encode_cmd(cmd, GITS_CMD_INVALL); + its_encode_collection(cmd, desc->its_mapc_cmd.col->col_id); + + its_fixup_cmd(cmd); + + return NULL; +} + +static u64 its_cmd_ptr_to_offset(struct its_node *its, + struct its_cmd_block *ptr) +{ + return (ptr - its->cmd_base) * sizeof(*ptr); +} + +static int its_queue_full(struct its_node *its) +{ + int widx; + int ridx; + + widx = its->cmd_write - its->cmd_base; + ridx = readl_relaxed(its->base + GITS_CREADR) / sizeof(struct its_cmd_block); + + /* This is incredibly unlikely to happen, unless the ITS locks up. */ + if (((widx + 1) % ITS_CMD_QUEUE_NR_ENTRIES) == ridx) + return 1; + + return 0; +} + +static struct its_cmd_block *its_allocate_entry(struct its_node *its) +{ + struct its_cmd_block *cmd; + u32 count = 1000000; /* 1s! */ + + while (its_queue_full(its)) { + count--; + if (!count) { + pr_err_ratelimited("ITS queue not draining\n"); + return NULL; + } + cpu_relax(); + udelay(1); + } + + cmd = its->cmd_write++; + + /* Handle queue wrapping */ + if (its->cmd_write == (its->cmd_base + ITS_CMD_QUEUE_NR_ENTRIES)) + its->cmd_write = its->cmd_base; + + return cmd; +} + +static struct its_cmd_block *its_post_commands(struct its_node *its) +{ + u64 wr = its_cmd_ptr_to_offset(its, its->cmd_write); + + writel_relaxed(wr, its->base + GITS_CWRITER); + + return its->cmd_write; +} + +static void its_flush_cmd(struct its_node *its, struct its_cmd_block *cmd) +{ + /* + * Make sure the commands written to memory are observable by + * the ITS. + */ + if (its->flags & ITS_FLAGS_CMDQ_NEEDS_FLUSHING) + __flush_dcache_area(cmd, sizeof(*cmd)); + else + dsb(ishst); +} + +static void its_wait_for_range_completion(struct its_node *its, + struct its_cmd_block *from, + struct its_cmd_block *to) +{ + u64 rd_idx, from_idx, to_idx; + u32 count = 1000000; /* 1s! */ + + from_idx = its_cmd_ptr_to_offset(its, from); + to_idx = its_cmd_ptr_to_offset(its, to); + + while (1) { + rd_idx = readl_relaxed(its->base + GITS_CREADR); + if (rd_idx >= to_idx || rd_idx < from_idx) + break; + + count--; + if (!count) { + pr_err_ratelimited("ITS queue timeout\n"); + return; + } + cpu_relax(); + udelay(1); + } +} + +static void its_send_single_command(struct its_node *its, + its_cmd_builder_t builder, + struct its_cmd_desc *desc) +{ + struct its_cmd_block *cmd, *sync_cmd, *next_cmd; + struct its_collection *sync_col; + + raw_spin_lock(&its->lock); + + cmd = its_allocate_entry(its); + if (!cmd) { /* We're soooooo screewed... */ + pr_err_ratelimited("ITS can't allocate, dropping command\n"); + raw_spin_unlock(&its->lock); + return; + } + sync_col = builder(cmd, desc); + its_flush_cmd(its, cmd); + + if (sync_col) { + sync_cmd = its_allocate_entry(its); + if (!sync_cmd) { + pr_err_ratelimited("ITS can't SYNC, skipping\n"); + goto post; + } + its_encode_cmd(sync_cmd, GITS_CMD_SYNC); + its_encode_target(sync_cmd, sync_col->target_address); + its_fixup_cmd(sync_cmd); + its_flush_cmd(its, sync_cmd); + } + +post: + next_cmd = its_post_commands(its); + raw_spin_unlock(&its->lock); + + its_wait_for_range_completion(its, cmd, next_cmd); +} + +static void its_send_inv(struct its_device *dev, u32 event_id) +{ + struct its_cmd_desc desc; + + desc.its_inv_cmd.dev = dev; + desc.its_inv_cmd.event_id = event_id; + + its_send_single_command(dev->its, its_build_inv_cmd, &desc); +} + +static void its_send_mapd(struct its_device *dev, int valid) +{ + struct its_cmd_desc desc; + + desc.its_mapd_cmd.dev = dev; + desc.its_mapd_cmd.valid = !!valid; + + its_send_single_command(dev->its, its_build_mapd_cmd, &desc); +} + +static void its_send_mapc(struct its_node *its, struct its_collection *col, + int valid) +{ + struct its_cmd_desc desc; + + desc.its_mapc_cmd.col = col; + desc.its_mapc_cmd.valid = !!valid; + + its_send_single_command(its, its_build_mapc_cmd, &desc); +} + +static void its_send_mapvi(struct its_device *dev, u32 irq_id, u32 id) +{ + struct its_cmd_desc desc; + + desc.its_mapvi_cmd.dev = dev; + desc.its_mapvi_cmd.phys_id = irq_id; + desc.its_mapvi_cmd.event_id = id; + + its_send_single_command(dev->its, its_build_mapvi_cmd, &desc); +} + +static void its_send_movi(struct its_device *dev, + struct its_collection *col, u32 id) +{ + struct its_cmd_desc desc; + + desc.its_movi_cmd.dev = dev; + desc.its_movi_cmd.col = col; + desc.its_movi_cmd.id = id; + + its_send_single_command(dev->its, its_build_movi_cmd, &desc); +} + +static void its_send_discard(struct its_device *dev, u32 id) +{ + struct its_cmd_desc desc; + + desc.its_discard_cmd.dev = dev; + desc.its_discard_cmd.event_id = id; + + its_send_single_command(dev->its, its_build_discard_cmd, &desc); +} + +static void its_send_invall(struct its_node *its, struct its_collection *col) +{ + struct its_cmd_desc desc; + + desc.its_invall_cmd.col = col; + + its_send_single_command(its, its_build_invall_cmd, &desc); +} + +/* + * irqchip functions - assumes MSI, mostly. + */ + +static inline u32 its_get_event_id(struct irq_data *d) +{ + struct its_device *its_dev = irq_data_get_irq_chip_data(d); + return d->hwirq - its_dev->lpi_base; +} + +static void lpi_set_config(struct irq_data *d, bool enable) +{ + struct its_device *its_dev = irq_data_get_irq_chip_data(d); + irq_hw_number_t hwirq = d->hwirq; + u32 id = its_get_event_id(d); + u8 *cfg = page_address(gic_rdists->prop_page) + hwirq - 8192; + + if (enable) + *cfg |= LPI_PROP_ENABLED; + else + *cfg &= ~LPI_PROP_ENABLED; + + /* + * Make the above write visible to the redistributors. + * And yes, we're flushing exactly: One. Single. Byte. + * Humpf... + */ + if (gic_rdists->flags & RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING) + __flush_dcache_area(cfg, sizeof(*cfg)); + else + dsb(ishst); + its_send_inv(its_dev, id); +} + +static void its_mask_irq(struct irq_data *d) +{ + lpi_set_config(d, false); +} + +static void its_unmask_irq(struct irq_data *d) +{ + lpi_set_config(d, true); +} + +static void its_eoi_irq(struct irq_data *d) +{ + gic_write_eoir(d->hwirq); +} + +static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val, + bool force) +{ + unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask); + struct its_device *its_dev = irq_data_get_irq_chip_data(d); + struct its_collection *target_col; + u32 id = its_get_event_id(d); + + if (cpu >= nr_cpu_ids) + return -EINVAL; + + target_col = &its_dev->its->collections[cpu]; + its_send_movi(its_dev, target_col, id); + its_dev->collection = target_col; + + return IRQ_SET_MASK_OK_DONE; +} + +static void its_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg) +{ + struct its_device *its_dev = irq_data_get_irq_chip_data(d); + struct its_node *its; + u64 addr; + + its = its_dev->its; + addr = its->phys_base + GITS_TRANSLATER; + + msg->address_lo = addr & ((1UL << 32) - 1); + msg->address_hi = addr >> 32; + msg->data = its_get_event_id(d); +} + +static struct irq_chip its_irq_chip = { + .name = "ITS", + .irq_mask = its_mask_irq, + .irq_unmask = its_unmask_irq, + .irq_eoi = its_eoi_irq, + .irq_set_affinity = its_set_affinity, + .irq_compose_msi_msg = its_irq_compose_msi_msg, +}; + +static void its_mask_msi_irq(struct irq_data *d) +{ + pci_msi_mask_irq(d); + irq_chip_mask_parent(d); +} + +static void its_unmask_msi_irq(struct irq_data *d) +{ + pci_msi_unmask_irq(d); + irq_chip_unmask_parent(d); +} + +static struct irq_chip its_msi_irq_chip = { + .name = "ITS-MSI", + .irq_unmask = its_unmask_msi_irq, + .irq_mask = its_mask_msi_irq, + .irq_eoi = irq_chip_eoi_parent, + .irq_write_msi_msg = pci_msi_domain_write_msg, +}; + +/* + * How we allocate LPIs: + * + * The GIC has id_bits bits for interrupt identifiers. From there, we + * must subtract 8192 which are reserved for SGIs/PPIs/SPIs. Then, as + * we allocate LPIs by chunks of 32, we can shift the whole thing by 5 + * bits to the right. + * + * This gives us (((1UL << id_bits) - 8192) >> 5) possible allocations. + */ +#define IRQS_PER_CHUNK_SHIFT 5 +#define IRQS_PER_CHUNK (1 << IRQS_PER_CHUNK_SHIFT) + +static unsigned long *lpi_bitmap; +static u32 lpi_chunks; +static DEFINE_SPINLOCK(lpi_lock); + +static int its_lpi_to_chunk(int lpi) +{ + return (lpi - 8192) >> IRQS_PER_CHUNK_SHIFT; +} + +static int its_chunk_to_lpi(int chunk) +{ + return (chunk << IRQS_PER_CHUNK_SHIFT) + 8192; +} + +static int its_lpi_init(u32 id_bits) +{ + lpi_chunks = its_lpi_to_chunk(1UL << id_bits); + + lpi_bitmap = kzalloc(BITS_TO_LONGS(lpi_chunks) * sizeof(long), + GFP_KERNEL); + if (!lpi_bitmap) { + lpi_chunks = 0; + return -ENOMEM; + } + + pr_info("ITS: Allocated %d chunks for LPIs\n", (int)lpi_chunks); + return 0; +} + +static unsigned long *its_lpi_alloc_chunks(int nr_irqs, int *base, int *nr_ids) +{ + unsigned long *bitmap = NULL; + int chunk_id; + int nr_chunks; + int i; + + nr_chunks = DIV_ROUND_UP(nr_irqs, IRQS_PER_CHUNK); + + spin_lock(&lpi_lock); + + do { + chunk_id = bitmap_find_next_zero_area(lpi_bitmap, lpi_chunks, + 0, nr_chunks, 0); + if (chunk_id < lpi_chunks) + break; + + nr_chunks--; + } while (nr_chunks > 0); + + if (!nr_chunks) + goto out; + + bitmap = kzalloc(BITS_TO_LONGS(nr_chunks * IRQS_PER_CHUNK) * sizeof (long), + GFP_ATOMIC); + if (!bitmap) + goto out; + + for (i = 0; i < nr_chunks; i++) + set_bit(chunk_id + i, lpi_bitmap); + + *base = its_chunk_to_lpi(chunk_id); + *nr_ids = nr_chunks * IRQS_PER_CHUNK; + +out: + spin_unlock(&lpi_lock); + + return bitmap; +} + +static void its_lpi_free(unsigned long *bitmap, int base, int nr_ids) +{ + int lpi; + + spin_lock(&lpi_lock); + + for (lpi = base; lpi < (base + nr_ids); lpi += IRQS_PER_CHUNK) { + int chunk = its_lpi_to_chunk(lpi); + BUG_ON(chunk > lpi_chunks); + if (test_bit(chunk, lpi_bitmap)) { + clear_bit(chunk, lpi_bitmap); + } else { + pr_err("Bad LPI chunk %d\n", chunk); + } + } + + spin_unlock(&lpi_lock); + + kfree(bitmap); +} + +/* + * We allocate 64kB for PROPBASE. That gives us at most 64K LPIs to + * deal with (one configuration byte per interrupt). PENDBASE has to + * be 64kB aligned (one bit per LPI, plus 8192 bits for SPI/PPI/SGI). + */ +#define LPI_PROPBASE_SZ SZ_64K +#define LPI_PENDBASE_SZ (LPI_PROPBASE_SZ / 8 + SZ_1K) + +/* + * This is how many bits of ID we need, including the useless ones. + */ +#define LPI_NRBITS ilog2(LPI_PROPBASE_SZ + SZ_8K) + +#define LPI_PROP_DEFAULT_PRIO 0xa0 + +static int __init its_alloc_lpi_tables(void) +{ + phys_addr_t paddr; + + gic_rdists->prop_page = alloc_pages(GFP_NOWAIT, + get_order(LPI_PROPBASE_SZ)); + if (!gic_rdists->prop_page) { + pr_err("Failed to allocate PROPBASE\n"); + return -ENOMEM; + } + + paddr = page_to_phys(gic_rdists->prop_page); + pr_info("GIC: using LPI property table @%pa\n", &paddr); + + /* Priority 0xa0, Group-1, disabled */ + memset(page_address(gic_rdists->prop_page), + LPI_PROP_DEFAULT_PRIO | LPI_PROP_GROUP1, + LPI_PROPBASE_SZ); + + /* Make sure the GIC will observe the written configuration */ + __flush_dcache_area(page_address(gic_rdists->prop_page), LPI_PROPBASE_SZ); + + return 0; +} + +static const char *its_base_type_string[] = { + [GITS_BASER_TYPE_DEVICE] = "Devices", + [GITS_BASER_TYPE_VCPU] = "Virtual CPUs", + [GITS_BASER_TYPE_CPU] = "Physical CPUs", + [GITS_BASER_TYPE_COLLECTION] = "Interrupt Collections", + [GITS_BASER_TYPE_RESERVED5] = "Reserved (5)", + [GITS_BASER_TYPE_RESERVED6] = "Reserved (6)", + [GITS_BASER_TYPE_RESERVED7] = "Reserved (7)", +}; + +static void its_free_tables(struct its_node *its) +{ + int i; + + for (i = 0; i < GITS_BASER_NR_REGS; i++) { + if (its->tables[i]) { + free_page((unsigned long)its->tables[i]); + its->tables[i] = NULL; + } + } +} + +static int its_alloc_tables(struct its_node *its) +{ + int err; + int i; + int psz = PAGE_SIZE; + u64 shr = GITS_BASER_InnerShareable; + + for (i = 0; i < GITS_BASER_NR_REGS; i++) { + u64 val = readq_relaxed(its->base + GITS_BASER + i * 8); + u64 type = GITS_BASER_TYPE(val); + u64 entry_size = GITS_BASER_ENTRY_SIZE(val); + u64 tmp; + void *base; + + if (type == GITS_BASER_TYPE_NONE) + continue; + + /* We're lazy and only allocate a single page for now */ + base = (void *)get_zeroed_page(GFP_KERNEL); + if (!base) { + err = -ENOMEM; + goto out_free; + } + + its->tables[i] = base; + +retry_baser: + val = (virt_to_phys(base) | + (type << GITS_BASER_TYPE_SHIFT) | + ((entry_size - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) | + GITS_BASER_WaWb | + shr | + GITS_BASER_VALID); + + switch (psz) { + case SZ_4K: + val |= GITS_BASER_PAGE_SIZE_4K; + break; + case SZ_16K: + val |= GITS_BASER_PAGE_SIZE_16K; + break; + case SZ_64K: + val |= GITS_BASER_PAGE_SIZE_64K; + break; + } + + val |= (PAGE_SIZE / psz) - 1; + + writeq_relaxed(val, its->base + GITS_BASER + i * 8); + tmp = readq_relaxed(its->base + GITS_BASER + i * 8); + + if ((val ^ tmp) & GITS_BASER_SHAREABILITY_MASK) { + /* + * Shareability didn't stick. Just use + * whatever the read reported, which is likely + * to be the only thing this redistributor + * supports. + */ + shr = tmp & GITS_BASER_SHAREABILITY_MASK; + goto retry_baser; + } + + if ((val ^ tmp) & GITS_BASER_PAGE_SIZE_MASK) { + /* + * Page size didn't stick. Let's try a smaller + * size and retry. If we reach 4K, then + * something is horribly wrong... + */ + switch (psz) { + case SZ_16K: + psz = SZ_4K; + goto retry_baser; + case SZ_64K: + psz = SZ_16K; + goto retry_baser; + } + } + + if (val != tmp) { + pr_err("ITS: %s: GITS_BASER%d doesn't stick: %lx %lx\n", + its->msi_chip.of_node->full_name, i, + (unsigned long) val, (unsigned long) tmp); + err = -ENXIO; + goto out_free; + } + + pr_info("ITS: allocated %d %s @%lx (psz %dK, shr %d)\n", + (int)(PAGE_SIZE / entry_size), + its_base_type_string[type], + (unsigned long)virt_to_phys(base), + psz / SZ_1K, (int)shr >> GITS_BASER_SHAREABILITY_SHIFT); + } + + return 0; + +out_free: + its_free_tables(its); + + return err; +} + +static int its_alloc_collections(struct its_node *its) +{ + its->collections = kzalloc(nr_cpu_ids * sizeof(*its->collections), + GFP_KERNEL); + if (!its->collections) + return -ENOMEM; + + return 0; +} + +static void its_cpu_init_lpis(void) +{ + void __iomem *rbase = gic_data_rdist_rd_base(); + struct page *pend_page; + u64 val, tmp; + + /* If we didn't allocate the pending table yet, do it now */ + pend_page = gic_data_rdist()->pend_page; + if (!pend_page) { + phys_addr_t paddr; + /* + * The pending pages have to be at least 64kB aligned, + * hence the 'max(LPI_PENDBASE_SZ, SZ_64K)' below. + */ + pend_page = alloc_pages(GFP_NOWAIT | __GFP_ZERO, + get_order(max(LPI_PENDBASE_SZ, SZ_64K))); + if (!pend_page) { + pr_err("Failed to allocate PENDBASE for CPU%d\n", + smp_processor_id()); + return; + } + + /* Make sure the GIC will observe the zero-ed page */ + __flush_dcache_area(page_address(pend_page), LPI_PENDBASE_SZ); + + paddr = page_to_phys(pend_page); + pr_info("CPU%d: using LPI pending table @%pa\n", + smp_processor_id(), &paddr); + gic_data_rdist()->pend_page = pend_page; + } + + /* Disable LPIs */ + val = readl_relaxed(rbase + GICR_CTLR); + val &= ~GICR_CTLR_ENABLE_LPIS; + writel_relaxed(val, rbase + GICR_CTLR); + + /* + * Make sure any change to the table is observable by the GIC. + */ + dsb(sy); + + /* set PROPBASE */ + val = (page_to_phys(gic_rdists->prop_page) | + GICR_PROPBASER_InnerShareable | + GICR_PROPBASER_WaWb | + ((LPI_NRBITS - 1) & GICR_PROPBASER_IDBITS_MASK)); + + writeq_relaxed(val, rbase + GICR_PROPBASER); + tmp = readq_relaxed(rbase + GICR_PROPBASER); + + if ((tmp ^ val) & GICR_PROPBASER_SHAREABILITY_MASK) { + pr_info_once("GIC: using cache flushing for LPI property table\n"); + gic_rdists->flags |= RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING; + } + + /* set PENDBASE */ + val = (page_to_phys(pend_page) | + GICR_PROPBASER_InnerShareable | + GICR_PROPBASER_WaWb); + + writeq_relaxed(val, rbase + GICR_PENDBASER); + + /* Enable LPIs */ + val = readl_relaxed(rbase + GICR_CTLR); + val |= GICR_CTLR_ENABLE_LPIS; + writel_relaxed(val, rbase + GICR_CTLR); + + /* Make sure the GIC has seen the above */ + dsb(sy); +} + +static void its_cpu_init_collection(void) +{ + struct its_node *its; + int cpu; + + spin_lock(&its_lock); + cpu = smp_processor_id(); + + list_for_each_entry(its, &its_nodes, entry) { + u64 target; + + /* + * We now have to bind each collection to its target + * redistributor. + */ + if (readq_relaxed(its->base + GITS_TYPER) & GITS_TYPER_PTA) { + /* + * This ITS wants the physical address of the + * redistributor. + */ + target = gic_data_rdist()->phys_base; + } else { + /* + * This ITS wants a linear CPU number. + */ + target = readq_relaxed(gic_data_rdist_rd_base() + GICR_TYPER); + target = GICR_TYPER_CPU_NUMBER(target); + } + + /* Perform collection mapping */ + its->collections[cpu].target_address = target; + its->collections[cpu].col_id = cpu; + + its_send_mapc(its, &its->collections[cpu], 1); + its_send_invall(its, &its->collections[cpu]); + } + + spin_unlock(&its_lock); +} + +static struct its_device *its_find_device(struct its_node *its, u32 dev_id) +{ + struct its_device *its_dev = NULL, *tmp; + + raw_spin_lock(&its->lock); + + list_for_each_entry(tmp, &its->its_device_list, entry) { + if (tmp->device_id == dev_id) { + its_dev = tmp; + break; + } + } + + raw_spin_unlock(&its->lock); + + return its_dev; +} + +static struct its_device *its_create_device(struct its_node *its, u32 dev_id, + int nvecs) +{ + struct its_device *dev; + unsigned long *lpi_map; + void *itt; + int lpi_base; + int nr_lpis; + int nr_ites; + int cpu; + int sz; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + /* + * At least one bit of EventID is being used, hence a minimum + * of two entries. No, the architecture doesn't let you + * express an ITT with a single entry. + */ + nr_ites = max(2, roundup_pow_of_two(nvecs)); + sz = nr_ites * its->ite_size; + sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; + itt = kmalloc(sz, GFP_KERNEL); + lpi_map = its_lpi_alloc_chunks(nvecs, &lpi_base, &nr_lpis); + + if (!dev || !itt || !lpi_map) { + kfree(dev); + kfree(itt); + kfree(lpi_map); + return NULL; + } + + dev->its = its; + dev->itt = itt; + dev->nr_ites = nr_ites; + dev->lpi_map = lpi_map; + dev->lpi_base = lpi_base; + dev->nr_lpis = nr_lpis; + dev->device_id = dev_id; + INIT_LIST_HEAD(&dev->entry); + + raw_spin_lock(&its->lock); + list_add(&dev->entry, &its->its_device_list); + raw_spin_unlock(&its->lock); + + /* Bind the device to the first possible CPU */ + cpu = cpumask_first(cpu_online_mask); + dev->collection = &its->collections[cpu]; + + /* Map device to its ITT */ + its_send_mapd(dev, 1); + + return dev; +} + +static void its_free_device(struct its_device *its_dev) +{ + raw_spin_lock(&its_dev->its->lock); + list_del(&its_dev->entry); + raw_spin_unlock(&its_dev->its->lock); + kfree(its_dev->itt); + kfree(its_dev); +} + +static int its_alloc_device_irq(struct its_device *dev, irq_hw_number_t *hwirq) +{ + int idx; + + idx = find_first_zero_bit(dev->lpi_map, dev->nr_lpis); + if (idx == dev->nr_lpis) + return -ENOSPC; + + *hwirq = dev->lpi_base + idx; + set_bit(idx, dev->lpi_map); + + return 0; +} + +static int its_msi_prepare(struct irq_domain *domain, struct device *dev, + int nvec, msi_alloc_info_t *info) +{ + struct pci_dev *pdev; + struct its_node *its; + u32 dev_id; + struct its_device *its_dev; + + if (!dev_is_pci(dev)) + return -EINVAL; + + pdev = to_pci_dev(dev); + dev_id = PCI_DEVID(pdev->bus->number, pdev->devfn); + its = domain->parent->host_data; + + its_dev = its_find_device(its, dev_id); + if (WARN_ON(its_dev)) + return -EINVAL; + + its_dev = its_create_device(its, dev_id, nvec); + if (!its_dev) + return -ENOMEM; + + dev_dbg(&pdev->dev, "ITT %d entries, %d bits\n", nvec, ilog2(nvec)); + + info->scratchpad[0].ptr = its_dev; + info->scratchpad[1].ptr = dev; + return 0; +} + +static struct msi_domain_ops its_pci_msi_ops = { + .msi_prepare = its_msi_prepare, +}; + +static struct msi_domain_info its_pci_msi_domain_info = { + .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | + MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX), + .ops = &its_pci_msi_ops, + .chip = &its_msi_irq_chip, +}; + +static int its_irq_gic_domain_alloc(struct irq_domain *domain, + unsigned int virq, + irq_hw_number_t hwirq) +{ + struct of_phandle_args args; + + args.np = domain->parent->of_node; + args.args_count = 3; + args.args[0] = GIC_IRQ_TYPE_LPI; + args.args[1] = hwirq; + args.args[2] = IRQ_TYPE_EDGE_RISING; + + return irq_domain_alloc_irqs_parent(domain, virq, 1, &args); +} + +static int its_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *args) +{ + msi_alloc_info_t *info = args; + struct its_device *its_dev = info->scratchpad[0].ptr; + irq_hw_number_t hwirq; + int err; + int i; + + for (i = 0; i < nr_irqs; i++) { + err = its_alloc_device_irq(its_dev, &hwirq); + if (err) + return err; + + err = its_irq_gic_domain_alloc(domain, virq + i, hwirq); + if (err) + return err; + + irq_domain_set_hwirq_and_chip(domain, virq + i, + hwirq, &its_irq_chip, its_dev); + dev_dbg(info->scratchpad[1].ptr, "ID:%d pID:%d vID:%d\n", + (int)(hwirq - its_dev->lpi_base), (int)hwirq, virq + i); + } + + return 0; +} + +static void its_irq_domain_activate(struct irq_domain *domain, + struct irq_data *d) +{ + struct its_device *its_dev = irq_data_get_irq_chip_data(d); + u32 event = its_get_event_id(d); + + /* Map the GIC IRQ and event to the device */ + its_send_mapvi(its_dev, d->hwirq, event); +} + +static void its_irq_domain_deactivate(struct irq_domain *domain, + struct irq_data *d) +{ + struct its_device *its_dev = irq_data_get_irq_chip_data(d); + u32 event = its_get_event_id(d); + + /* Stop the delivery of interrupts */ + its_send_discard(its_dev, event); +} + +static void its_irq_domain_free(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs) +{ + struct irq_data *d = irq_domain_get_irq_data(domain, virq); + struct its_device *its_dev = irq_data_get_irq_chip_data(d); + int i; + + for (i = 0; i < nr_irqs; i++) { + struct irq_data *data = irq_domain_get_irq_data(domain, + virq + i); + u32 event = its_get_event_id(data); + + /* Mark interrupt index as unused */ + clear_bit(event, its_dev->lpi_map); + + /* Nuke the entry in the domain */ + irq_domain_reset_irq_data(data); + } + + /* If all interrupts have been freed, start mopping the floor */ + if (bitmap_empty(its_dev->lpi_map, its_dev->nr_lpis)) { + its_lpi_free(its_dev->lpi_map, + its_dev->lpi_base, + its_dev->nr_lpis); + + /* Unmap device/itt */ + its_send_mapd(its_dev, 0); + its_free_device(its_dev); + } + + irq_domain_free_irqs_parent(domain, virq, nr_irqs); +} + +static const struct irq_domain_ops its_domain_ops = { + .alloc = its_irq_domain_alloc, + .free = its_irq_domain_free, + .activate = its_irq_domain_activate, + .deactivate = its_irq_domain_deactivate, +}; + +static int its_probe(struct device_node *node, struct irq_domain *parent) +{ + struct resource res; + struct its_node *its; + void __iomem *its_base; + u32 val; + u64 baser, tmp; + int err; + + err = of_address_to_resource(node, 0, &res); + if (err) { + pr_warn("%s: no regs?\n", node->full_name); + return -ENXIO; + } + + its_base = ioremap(res.start, resource_size(&res)); + if (!its_base) { + pr_warn("%s: unable to map registers\n", node->full_name); + return -ENOMEM; + } + + val = readl_relaxed(its_base + GITS_PIDR2) & GIC_PIDR2_ARCH_MASK; + if (val != 0x30 && val != 0x40) { + pr_warn("%s: no ITS detected, giving up\n", node->full_name); + err = -ENODEV; + goto out_unmap; + } + + pr_info("ITS: %s\n", node->full_name); + + its = kzalloc(sizeof(*its), GFP_KERNEL); + if (!its) { + err = -ENOMEM; + goto out_unmap; + } + + raw_spin_lock_init(&its->lock); + INIT_LIST_HEAD(&its->entry); + INIT_LIST_HEAD(&its->its_device_list); + its->base = its_base; + its->phys_base = res.start; + its->msi_chip.of_node = node; + its->ite_size = ((readl_relaxed(its_base + GITS_TYPER) >> 4) & 0xf) + 1; + + its->cmd_base = kzalloc(ITS_CMD_QUEUE_SZ, GFP_KERNEL); + if (!its->cmd_base) { + err = -ENOMEM; + goto out_free_its; + } + its->cmd_write = its->cmd_base; + + err = its_alloc_tables(its); + if (err) + goto out_free_cmd; + + err = its_alloc_collections(its); + if (err) + goto out_free_tables; + + baser = (virt_to_phys(its->cmd_base) | + GITS_CBASER_WaWb | + GITS_CBASER_InnerShareable | + (ITS_CMD_QUEUE_SZ / SZ_4K - 1) | + GITS_CBASER_VALID); + + writeq_relaxed(baser, its->base + GITS_CBASER); + tmp = readq_relaxed(its->base + GITS_CBASER); + writeq_relaxed(0, its->base + GITS_CWRITER); + writel_relaxed(1, its->base + GITS_CTLR); + + if ((tmp ^ baser) & GITS_BASER_SHAREABILITY_MASK) { + pr_info("ITS: using cache flushing for cmd queue\n"); + its->flags |= ITS_FLAGS_CMDQ_NEEDS_FLUSHING; + } + + if (of_property_read_bool(its->msi_chip.of_node, "msi-controller")) { + its->domain = irq_domain_add_tree(NULL, &its_domain_ops, its); + if (!its->domain) { + err = -ENOMEM; + goto out_free_tables; + } + + its->domain->parent = parent; + + its->msi_chip.domain = pci_msi_create_irq_domain(node, + &its_pci_msi_domain_info, + its->domain); + if (!its->msi_chip.domain) { + err = -ENOMEM; + goto out_free_domains; + } + + err = of_pci_msi_chip_add(&its->msi_chip); + if (err) + goto out_free_domains; + } + + spin_lock(&its_lock); + list_add(&its->entry, &its_nodes); + spin_unlock(&its_lock); + + return 0; + +out_free_domains: + if (its->msi_chip.domain) + irq_domain_remove(its->msi_chip.domain); + if (its->domain) + irq_domain_remove(its->domain); +out_free_tables: + its_free_tables(its); +out_free_cmd: + kfree(its->cmd_base); +out_free_its: + kfree(its); +out_unmap: + iounmap(its_base); + pr_err("ITS: failed probing %s (%d)\n", node->full_name, err); + return err; +} + +static bool gic_rdists_supports_plpis(void) +{ + return !!(readl_relaxed(gic_data_rdist_rd_base() + GICR_TYPER) & GICR_TYPER_PLPIS); +} + +int its_cpu_init(void) +{ + if (!gic_rdists_supports_plpis()) { + pr_info("CPU%d: LPIs not supported\n", smp_processor_id()); + return -ENXIO; + } + + if (!list_empty(&its_nodes)) { + its_cpu_init_lpis(); + its_cpu_init_collection(); + } + + return 0; +} + +static struct of_device_id its_device_id[] = { + { .compatible = "arm,gic-v3-its", }, + {}, +}; + +int its_init(struct device_node *node, struct rdists *rdists, + struct irq_domain *parent_domain) +{ + struct device_node *np; + + for (np = of_find_matching_node(node, its_device_id); np; + np = of_find_matching_node(np, its_device_id)) { + its_probe(np, parent_domain); + } + + if (list_empty(&its_nodes)) { + pr_warn("ITS: No ITS available, not enabling LPIs\n"); + return -ENXIO; + } + + gic_rdists = rdists; + gic_root_node = node; + + its_alloc_lpi_tables(); + its_lpi_init(rdists->id_bits); + + return 0; +} diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index aa17ae805a70..1a146ccee701 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -34,20 +34,25 @@ #include "irq-gic-common.h" #include "irqchip.h" +struct redist_region { + void __iomem *redist_base; + phys_addr_t phys_base; +}; + struct gic_chip_data { void __iomem *dist_base; - void __iomem **redist_base; - void __iomem * __percpu *rdist; + struct redist_region *redist_regions; + struct rdists rdists; struct irq_domain *domain; u64 redist_stride; - u32 redist_regions; + u32 nr_redist_regions; unsigned int irq_nr; }; static struct gic_chip_data gic_data __read_mostly; -#define gic_data_rdist() (this_cpu_ptr(gic_data.rdist)) -#define gic_data_rdist_rd_base() (*gic_data_rdist()) +#define gic_data_rdist() (this_cpu_ptr(gic_data.rdists.rdist)) +#define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base) #define gic_data_rdist_sgi_base() (gic_data_rdist_rd_base() + SZ_64K) /* Our default, arbitrary priority value. Linux only uses one anyway. */ @@ -71,9 +76,6 @@ static inline void __iomem *gic_dist_base(struct irq_data *d) if (d->hwirq <= 1023) /* SPI -> dist_base */ return gic_data.dist_base; - if (d->hwirq >= 8192) - BUG(); /* LPI Detected!!! */ - return NULL; } @@ -271,11 +273,11 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs do { irqnr = gic_read_iar(); - if (likely(irqnr > 15 && irqnr < 1020)) { + if (likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192) { int err; err = handle_domain_irq(gic_data.domain, irqnr, regs); if (err) { - WARN_ONCE(true, "Unexpected SPI received!\n"); + WARN_ONCE(true, "Unexpected interrupt received!\n"); gic_write_eoir(irqnr); } continue; @@ -333,8 +335,8 @@ static int gic_populate_rdist(void) MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 | MPIDR_AFFINITY_LEVEL(mpidr, 0)); - for (i = 0; i < gic_data.redist_regions; i++) { - void __iomem *ptr = gic_data.redist_base[i]; + for (i = 0; i < gic_data.nr_redist_regions; i++) { + void __iomem *ptr = gic_data.redist_regions[i].redist_base; u32 reg; reg = readl_relaxed(ptr + GICR_PIDR2) & GIC_PIDR2_ARCH_MASK; @@ -347,10 +349,13 @@ static int gic_populate_rdist(void) do { typer = readq_relaxed(ptr + GICR_TYPER); if ((typer >> 32) == aff) { + u64 offset = ptr - gic_data.redist_regions[i].redist_base; gic_data_rdist_rd_base() = ptr; - pr_info("CPU%d: found redistributor %llx @%p\n", + gic_data_rdist()->phys_base = gic_data.redist_regions[i].phys_base + offset; + pr_info("CPU%d: found redistributor %llx region %d:%pa\n", smp_processor_id(), - (unsigned long long)mpidr, ptr); + (unsigned long long)mpidr, + i, &gic_data_rdist()->phys_base); return 0; } @@ -385,6 +390,11 @@ static void gic_cpu_sys_reg_init(void) gic_write_grpen1(1); } +static int gic_dist_supports_lpis(void) +{ + return !!(readl_relaxed(gic_data.dist_base + GICD_TYPER) & GICD_TYPER_LPIS); +} + static void gic_cpu_init(void) { void __iomem *rbase; @@ -399,6 +409,10 @@ static void gic_cpu_init(void) gic_cpu_config(rbase, gic_redist_wait_for_rwp); + /* Give LPIs a spin */ + if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis()) + its_cpu_init(); + /* initialise system registers */ gic_cpu_sys_reg_init(); } @@ -585,26 +599,43 @@ static struct irq_chip gic_chip = { .irq_set_affinity = gic_set_affinity, }; +#define GIC_ID_NR (1U << gic_data.rdists.id_bits) + static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { /* SGIs are private to the core kernel */ if (hw < 16) return -EPERM; + /* Nothing here */ + if (hw >= gic_data.irq_nr && hw < 8192) + return -EPERM; + /* Off limits */ + if (hw >= GIC_ID_NR) + return -EPERM; + /* PPIs */ if (hw < 32) { irq_set_percpu_devid(irq); - irq_set_chip_and_handler(irq, &gic_chip, - handle_percpu_devid_irq); + irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data, + handle_percpu_devid_irq, NULL, NULL); set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN); } /* SPIs */ if (hw >= 32 && hw < gic_data.irq_nr) { - irq_set_chip_and_handler(irq, &gic_chip, - handle_fasteoi_irq); + irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data, + handle_fasteoi_irq, NULL, NULL); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } - irq_set_chip_data(irq, d->host_data); + /* LPIs */ + if (hw >= 8192 && hw < GIC_ID_NR) { + if (!gic_dist_supports_lpis()) + return -EPERM; + irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data, + handle_fasteoi_irq, NULL, NULL); + set_irq_flags(irq, IRQF_VALID); + } + return 0; } @@ -625,6 +656,9 @@ static int gic_irq_domain_xlate(struct irq_domain *d, case 1: /* PPI */ *out_hwirq = intspec[1] + 16; break; + case GIC_IRQ_TYPE_LPI: /* LPI */ + *out_hwirq = intspec[1]; + break; default: return -EINVAL; } @@ -633,17 +667,50 @@ static int gic_irq_domain_xlate(struct irq_domain *d, return 0; } +static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *arg) +{ + int i, ret; + irq_hw_number_t hwirq; + unsigned int type = IRQ_TYPE_NONE; + struct of_phandle_args *irq_data = arg; + + ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args, + irq_data->args_count, &hwirq, &type); + if (ret) + return ret; + + for (i = 0; i < nr_irqs; i++) + gic_irq_domain_map(domain, virq + i, hwirq + i); + + return 0; +} + +static void gic_irq_domain_free(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs) +{ + int i; + + for (i = 0; i < nr_irqs; i++) { + struct irq_data *d = irq_domain_get_irq_data(domain, virq + i); + irq_set_handler(virq + i, NULL); + irq_domain_reset_irq_data(d); + } +} + static const struct irq_domain_ops gic_irq_domain_ops = { - .map = gic_irq_domain_map, .xlate = gic_irq_domain_xlate, + .alloc = gic_irq_domain_alloc, + .free = gic_irq_domain_free, }; static int __init gic_of_init(struct device_node *node, struct device_node *parent) { void __iomem *dist_base; - void __iomem **redist_base; + struct redist_region *rdist_regs; u64 redist_stride; - u32 redist_regions; + u32 nr_redist_regions; + u32 typer; u32 reg; int gic_irqs; int err; @@ -664,54 +731,63 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare goto out_unmap_dist; } - if (of_property_read_u32(node, "#redistributor-regions", &redist_regions)) - redist_regions = 1; + if (of_property_read_u32(node, "#redistributor-regions", &nr_redist_regions)) + nr_redist_regions = 1; - redist_base = kzalloc(sizeof(*redist_base) * redist_regions, GFP_KERNEL); - if (!redist_base) { + rdist_regs = kzalloc(sizeof(*rdist_regs) * nr_redist_regions, GFP_KERNEL); + if (!rdist_regs) { err = -ENOMEM; goto out_unmap_dist; } - for (i = 0; i < redist_regions; i++) { - redist_base[i] = of_iomap(node, 1 + i); - if (!redist_base[i]) { + for (i = 0; i < nr_redist_regions; i++) { + struct resource res; + int ret; + + ret = of_address_to_resource(node, 1 + i, &res); + rdist_regs[i].redist_base = of_iomap(node, 1 + i); + if (ret || !rdist_regs[i].redist_base) { pr_err("%s: couldn't map region %d\n", node->full_name, i); err = -ENODEV; goto out_unmap_rdist; } + rdist_regs[i].phys_base = res.start; } if (of_property_read_u64(node, "redistributor-stride", &redist_stride)) redist_stride = 0; gic_data.dist_base = dist_base; - gic_data.redist_base = redist_base; - gic_data.redist_regions = redist_regions; + gic_data.redist_regions = rdist_regs; + gic_data.nr_redist_regions = nr_redist_regions; gic_data.redist_stride = redist_stride; /* * Find out how many interrupts are supported. * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI) */ - gic_irqs = readl_relaxed(gic_data.dist_base + GICD_TYPER) & 0x1f; - gic_irqs = (gic_irqs + 1) * 32; + typer = readl_relaxed(gic_data.dist_base + GICD_TYPER); + gic_data.rdists.id_bits = GICD_TYPER_ID_BITS(typer); + gic_irqs = GICD_TYPER_IRQS(typer); if (gic_irqs > 1020) gic_irqs = 1020; gic_data.irq_nr = gic_irqs; gic_data.domain = irq_domain_add_tree(node, &gic_irq_domain_ops, &gic_data); - gic_data.rdist = alloc_percpu(typeof(*gic_data.rdist)); + gic_data.rdists.rdist = alloc_percpu(typeof(*gic_data.rdists.rdist)); - if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdist)) { + if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdists.rdist)) { err = -ENOMEM; goto out_free; } set_handle_irq(gic_handle_irq); + if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis()) + its_init(node, &gic_data.rdists, gic_data.domain); + gic_smp_init(); gic_dist_init(); gic_cpu_init(); @@ -722,12 +798,12 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare out_free: if (gic_data.domain) irq_domain_remove(gic_data.domain); - free_percpu(gic_data.rdist); + free_percpu(gic_data.rdists.rdist); out_unmap_rdist: - for (i = 0; i < redist_regions; i++) - if (redist_base[i]) - iounmap(redist_base[i]); - kfree(redist_base); + for (i = 0; i < nr_redist_regions; i++) + if (rdist_regs[i].redist_base) + iounmap(rdist_regs[i].redist_base); + kfree(rdist_regs); out_unmap_dist: iounmap(dist_base); return err; diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 7f9be0785c6a..d617ee5a3d8a 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -788,17 +788,16 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, { if (hw < 32) { irq_set_percpu_devid(irq); - irq_set_chip_and_handler(irq, &gic_chip, - handle_percpu_devid_irq); + irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data, + handle_percpu_devid_irq, NULL, NULL); set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN); } else { - irq_set_chip_and_handler(irq, &gic_chip, - handle_fasteoi_irq); + irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data, + handle_fasteoi_irq, NULL, NULL); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); gic_routable_irq_domain_ops->map(d, irq, hw); } - irq_set_chip_data(irq, d->host_data); return 0; } @@ -858,6 +857,31 @@ static struct notifier_block gic_cpu_notifier = { }; #endif +static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *arg) +{ + int i, ret; + irq_hw_number_t hwirq; + unsigned int type = IRQ_TYPE_NONE; + struct of_phandle_args *irq_data = arg; + + ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args, + irq_data->args_count, &hwirq, &type); + if (ret) + return ret; + + for (i = 0; i < nr_irqs; i++) + gic_irq_domain_map(domain, virq + i, hwirq + i); + + return 0; +} + +static const struct irq_domain_ops gic_irq_domain_hierarchy_ops = { + .xlate = gic_irq_domain_xlate, + .alloc = gic_irq_domain_alloc, + .free = irq_domain_free_irqs_top, +}; + static const struct irq_domain_ops gic_irq_domain_ops = { .map = gic_irq_domain_map, .unmap = gic_irq_domain_unmap, @@ -948,18 +972,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, gic_cpu_map[i] = 0xff; /* - * For primary GICs, skip over SGIs. - * For secondary GICs, skip over PPIs, too. - */ - if (gic_nr == 0 && (irq_start & 31) > 0) { - hwirq_base = 16; - if (irq_start != -1) - irq_start = (irq_start & ~31) + 16; - } else { - hwirq_base = 32; - } - - /* * Find out how many interrupts are supported. * The GIC only supports up to 1020 interrupt sources. */ @@ -969,10 +981,31 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, gic_irqs = 1020; gic->gic_irqs = gic_irqs; - gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */ + if (node) { /* DT case */ + const struct irq_domain_ops *ops = &gic_irq_domain_hierarchy_ops; + + if (!of_property_read_u32(node, "arm,routable-irqs", + &nr_routable_irqs)) { + ops = &gic_irq_domain_ops; + gic_irqs = nr_routable_irqs; + } + + gic->domain = irq_domain_add_linear(node, gic_irqs, ops, gic); + } else { /* Non-DT case */ + /* + * For primary GICs, skip over SGIs. + * For secondary GICs, skip over PPIs, too. + */ + if (gic_nr == 0 && (irq_start & 31) > 0) { + hwirq_base = 16; + if (irq_start != -1) + irq_start = (irq_start & ~31) + 16; + } else { + hwirq_base = 32; + } + + gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */ - if (of_property_read_u32(node, "arm,routable-irqs", - &nr_routable_irqs)) { irq_base = irq_alloc_descs(irq_start, 16, gic_irqs, numa_node_id()); if (IS_ERR_VALUE(irq_base)) { @@ -983,10 +1016,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, gic->domain = irq_domain_add_legacy(node, gic_irqs, irq_base, hwirq_base, &gic_irq_domain_ops, gic); - } else { - gic->domain = irq_domain_add_linear(node, nr_routable_irqs, - &gic_irq_domain_ops, - gic); } if (WARN_ON(!gic->domain)) @@ -1037,6 +1066,10 @@ gic_of_init(struct device_node *node, struct device_node *parent) irq = irq_of_parse_and_map(node, 0); gic_cascade_irq(gic_cnt, irq); } + + if (IS_ENABLED(CONFIG_ARM_GIC_V2M)) + gicv2m_of_init(node, gic_data[gic_cnt].domain); + gic_cnt++; return 0; } diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c new file mode 100644 index 000000000000..7e342df6a62f --- /dev/null +++ b/drivers/irqchip/irq-mtk-sysirq.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2014 MediaTek Inc. + * Author: Joe.C <yingjoe.chen@mediatek.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/irq.h> +#include <linux/irqdomain.h> +#include <linux/of.h> +#include <linux/of_irq.h> +#include <linux/of_address.h> +#include <linux/io.h> +#include <linux/slab.h> +#include <linux/spinlock.h> + +#include "irqchip.h" + +#define MT6577_SYS_INTPOL_NUM (224) + +struct mtk_sysirq_chip_data { + spinlock_t lock; + void __iomem *intpol_base; +}; + +static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type) +{ + irq_hw_number_t hwirq = data->hwirq; + struct mtk_sysirq_chip_data *chip_data = data->chip_data; + u32 offset, reg_index, value; + unsigned long flags; + int ret; + + offset = hwirq & 0x1f; + reg_index = hwirq >> 5; + + spin_lock_irqsave(&chip_data->lock, flags); + value = readl_relaxed(chip_data->intpol_base + reg_index * 4); + if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING) { + if (type == IRQ_TYPE_LEVEL_LOW) + type = IRQ_TYPE_LEVEL_HIGH; + else + type = IRQ_TYPE_EDGE_RISING; + value |= (1 << offset); + } else { + value &= ~(1 << offset); + } + writel(value, chip_data->intpol_base + reg_index * 4); + + data = data->parent_data; + ret = data->chip->irq_set_type(data, type); + spin_unlock_irqrestore(&chip_data->lock, flags); + return ret; +} + +static struct irq_chip mtk_sysirq_chip = { + .name = "MT_SYSIRQ", + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, + .irq_eoi = irq_chip_eoi_parent, + .irq_set_type = mtk_sysirq_set_type, + .irq_retrigger = irq_chip_retrigger_hierarchy, + .irq_set_affinity = irq_chip_set_affinity_parent, +}; + +static int mtk_sysirq_domain_xlate(struct irq_domain *d, + struct device_node *controller, + const u32 *intspec, unsigned int intsize, + unsigned long *out_hwirq, + unsigned int *out_type) +{ + if (intsize != 3) + return -EINVAL; + + /* sysirq doesn't support PPI */ + if (intspec[0]) + return -EINVAL; + + *out_hwirq = intspec[1]; + *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; + return 0; +} + +static int mtk_sysirq_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *arg) +{ + int i; + irq_hw_number_t hwirq; + struct of_phandle_args *irq_data = arg; + struct of_phandle_args gic_data = *irq_data; + + if (irq_data->args_count != 3) + return -EINVAL; + + /* sysirq doesn't support PPI */ + if (irq_data->args[0]) + return -EINVAL; + + hwirq = irq_data->args[1]; + for (i = 0; i < nr_irqs; i++) + irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, + &mtk_sysirq_chip, + domain->host_data); + + gic_data.np = domain->parent->of_node; + return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data); +} + +static struct irq_domain_ops sysirq_domain_ops = { + .xlate = mtk_sysirq_domain_xlate, + .alloc = mtk_sysirq_domain_alloc, + .free = irq_domain_free_irqs_common, +}; + +static int __init mtk_sysirq_of_init(struct device_node *node, + struct device_node *parent) +{ + struct irq_domain *domain, *domain_parent; + struct mtk_sysirq_chip_data *chip_data; + int ret = 0; + + domain_parent = irq_find_host(parent); + if (!domain_parent) { + pr_err("mtk_sysirq: interrupt-parent not found\n"); + return -EINVAL; + } + + chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL); + if (!chip_data) + return -ENOMEM; + + chip_data->intpol_base = of_io_request_and_map(node, 0, "intpol"); + if (!chip_data->intpol_base) { + pr_err("mtk_sysirq: unable to map sysirq register\n"); + ret = -ENOMEM; + goto out_free; + } + + domain = irq_domain_add_hierarchy(domain_parent, 0, + MT6577_SYS_INTPOL_NUM, node, + &sysirq_domain_ops, chip_data); + if (!domain) { + ret = -ENOMEM; + goto out_unmap; + } + spin_lock_init(&chip_data->lock); + + return 0; + +out_unmap: + iounmap(chip_data->intpol_base); +out_free: + kfree(chip_data); + return ret; +} +IRQCHIP_DECLARE(mtk_sysirq, "mediatek,mt6577-sysirq", mtk_sysirq_of_init); diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c index a82e542ffc21..0b380603a578 100644 --- a/drivers/isdn/hardware/eicon/message.c +++ b/drivers/isdn/hardware/eicon/message.c @@ -4880,7 +4880,7 @@ static void sig_ind(PLCI *plci) byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/ byte CF_Ind[] = "\x09\x02\x00\x06\x00\x00\x00\x00\x00\x00"; byte Interr_Err_Ind[] = "\x0a\x02\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; - byte CONF_Ind[] = "\x09\x16\x00\x06\x00\x00\0x00\0x00\0x00\0x00"; + byte CONF_Ind[] = "\x09\x16\x00\x06\x00\x00\x00\x00\x00\x00"; byte force_mt_info = false; byte dir; dword d; diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index a210338cfeb1..a6c3d2f153f3 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -250,6 +250,17 @@ config LEDS_LP8788 help This option enables support for the Keyboard LEDs on the LP8788 PMIC. +config LEDS_LP8860 + tristate "LED support for the TI LP8860 4 channel LED driver" + depends on LEDS_CLASS && I2C + select REGMAP_I2C + help + If you say yes here you get support for the TI LP8860 4 channel + LED driver. + This option enables support for the display cluster LEDs + on the LP8860 4 channel LED driver using the I2C communication + bus. + config LEDS_CLEVO_MAIL tristate "Mail LED on Clevo notebook" depends on LEDS_CLASS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index a2b164741465..1c65a191d907 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_LEDS_LP5523) += leds-lp5523.o obj-$(CONFIG_LEDS_LP5562) += leds-lp5562.o obj-$(CONFIG_LEDS_LP8501) += leds-lp8501.o obj-$(CONFIG_LEDS_LP8788) += leds-lp8788.o +obj-$(CONFIG_LEDS_LP8860) += leds-lp8860.o obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o obj-$(CONFIG_LEDS_IPAQ_MICRO) += leds-ipaq-micro.o diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 7440c58b8e6f..dbeebac38d31 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -40,17 +40,27 @@ static ssize_t brightness_store(struct device *dev, { struct led_classdev *led_cdev = dev_get_drvdata(dev); unsigned long state; - ssize_t ret = -EINVAL; + ssize_t ret; + + mutex_lock(&led_cdev->led_access); + + if (led_sysfs_is_disabled(led_cdev)) { + ret = -EBUSY; + goto unlock; + } ret = kstrtoul(buf, 10, &state); if (ret) - return ret; + goto unlock; if (state == LED_OFF) led_trigger_remove(led_cdev); - __led_set_brightness(led_cdev, state); + led_set_brightness(led_cdev, state); - return size; + ret = size; +unlock: + mutex_unlock(&led_cdev->led_access); + return ret; } static DEVICE_ATTR_RW(brightness); @@ -99,7 +109,7 @@ static void led_timer_function(unsigned long data) unsigned long delay; if (!led_cdev->blink_delay_on || !led_cdev->blink_delay_off) { - __led_set_brightness(led_cdev, LED_OFF); + led_set_brightness_async(led_cdev, LED_OFF); return; } @@ -122,7 +132,7 @@ static void led_timer_function(unsigned long data) delay = led_cdev->blink_delay_off; } - __led_set_brightness(led_cdev, brightness); + led_set_brightness_async(led_cdev, brightness); /* Return in next iteration if led is in one-shot mode and we are in * the final blink state so that the led is toggled each delay_on + @@ -148,7 +158,7 @@ static void set_brightness_delayed(struct work_struct *ws) led_stop_software_blink(led_cdev); - __led_set_brightness(led_cdev, led_cdev->delayed_set_value); + led_set_brightness_async(led_cdev, led_cdev->delayed_set_value); } /** @@ -214,6 +224,7 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) #ifdef CONFIG_LEDS_TRIGGERS init_rwsem(&led_cdev->trigger_lock); #endif + mutex_init(&led_cdev->led_access); /* add to the list of leds */ down_write(&leds_list_lock); list_add_tail(&led_cdev->node, &leds_list); @@ -222,6 +233,8 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) if (!led_cdev->max_brightness) led_cdev->max_brightness = LED_FULL; + led_cdev->flags |= SET_BRIGHTNESS_ASYNC; + led_update_brightness(led_cdev); INIT_WORK(&led_cdev->set_brightness_work, set_brightness_delayed); @@ -267,6 +280,8 @@ void led_classdev_unregister(struct led_classdev *led_cdev) down_write(&leds_list_lock); list_del(&led_cdev->node); up_write(&leds_list_lock); + + mutex_destroy(&led_cdev->led_access); } EXPORT_SYMBOL_GPL(led_classdev_unregister); diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index aaa8eba9099f..9886dace5ad2 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c @@ -42,13 +42,13 @@ static void led_set_software_blink(struct led_classdev *led_cdev, /* never on - just set to off */ if (!delay_on) { - __led_set_brightness(led_cdev, LED_OFF); + led_set_brightness_async(led_cdev, LED_OFF); return; } /* never off - just set to brightness */ if (!delay_off) { - __led_set_brightness(led_cdev, led_cdev->blink_brightness); + led_set_brightness_async(led_cdev, led_cdev->blink_brightness); return; } @@ -117,6 +117,8 @@ EXPORT_SYMBOL_GPL(led_stop_software_blink); void led_set_brightness(struct led_classdev *led_cdev, enum led_brightness brightness) { + int ret = 0; + /* delay brightness setting if need to stop soft-blink timer */ if (led_cdev->blink_delay_on || led_cdev->blink_delay_off) { led_cdev->delayed_set_value = brightness; @@ -124,7 +126,17 @@ void led_set_brightness(struct led_classdev *led_cdev, return; } - __led_set_brightness(led_cdev, brightness); + if (led_cdev->flags & SET_BRIGHTNESS_ASYNC) { + led_set_brightness_async(led_cdev, brightness); + return; + } else if (led_cdev->flags & SET_BRIGHTNESS_SYNC) + ret = led_set_brightness_sync(led_cdev, brightness); + else + ret = -EINVAL; + + if (ret < 0) + dev_dbg(led_cdev->dev, "Setting LED brightness failed (%d)\n", + ret); } EXPORT_SYMBOL(led_set_brightness); @@ -143,3 +155,21 @@ int led_update_brightness(struct led_classdev *led_cdev) return ret; } EXPORT_SYMBOL(led_update_brightness); + +/* Caller must ensure led_cdev->led_access held */ +void led_sysfs_disable(struct led_classdev *led_cdev) +{ + lockdep_assert_held(&led_cdev->led_access); + + led_cdev->flags |= LED_SYSFS_DISABLE; +} +EXPORT_SYMBOL_GPL(led_sysfs_disable); + +/* Caller must ensure led_cdev->led_access held */ +void led_sysfs_enable(struct led_classdev *led_cdev) +{ + lockdep_assert_held(&led_cdev->led_access); + + led_cdev->flags &= ~LED_SYSFS_DISABLE; +} +EXPORT_SYMBOL_GPL(led_sysfs_enable); diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index c3734f10fdd5..e8b1120f486d 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -37,6 +37,14 @@ ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, char trigger_name[TRIG_NAME_MAX]; struct led_trigger *trig; size_t len; + int ret = count; + + mutex_lock(&led_cdev->led_access); + + if (led_sysfs_is_disabled(led_cdev)) { + ret = -EBUSY; + goto unlock; + } trigger_name[sizeof(trigger_name) - 1] = '\0'; strncpy(trigger_name, buf, sizeof(trigger_name) - 1); @@ -47,7 +55,7 @@ ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, if (!strcmp(trigger_name, "none")) { led_trigger_remove(led_cdev); - return count; + goto unlock; } down_read(&triggers_list_lock); @@ -58,12 +66,14 @@ ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, up_write(&led_cdev->trigger_lock); up_read(&triggers_list_lock); - return count; + goto unlock; } } up_read(&triggers_list_lock); - return -EINVAL; +unlock: + mutex_unlock(&led_cdev->led_access); + return ret; } EXPORT_SYMBOL_GPL(led_trigger_store); diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 8a8ba11c5c14..7ea1ea42c2d2 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -203,7 +203,7 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev) fwnode_property_read_string(child, "linux,default-trigger", &led.default_trigger); - if (!fwnode_property_read_string(child, "linux,default_state", + if (!fwnode_property_read_string(child, "default-state", &state)) { if (!strcmp(state, "keep")) led.default_state = LEDS_GPIO_DEFSTATE_KEEP; diff --git a/drivers/leds/leds-lp8860.c b/drivers/leds/leds-lp8860.c new file mode 100644 index 000000000000..840e93f3ab3e --- /dev/null +++ b/drivers/leds/leds-lp8860.c @@ -0,0 +1,491 @@ +/* + * TI LP8860 4-Channel LED Driver + * + * Copyright (C) 2014 Texas Instruments + * + * Author: Dan Murphy <dmurphy@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + */ + +#include <linux/i2c.h> +#include <linux/init.h> +#include <linux/leds.h> +#include <linux/regmap.h> +#include <linux/regulator/consumer.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/of.h> +#include <linux/of_gpio.h> +#include <linux/gpio/consumer.h> +#include <linux/slab.h> + +#define LP8860_DISP_CL1_BRT_MSB 0x00 +#define LP8860_DISP_CL1_BRT_LSB 0x01 +#define LP8860_DISP_CL1_CURR_MSB 0x02 +#define LP8860_DISP_CL1_CURR_LSB 0x03 +#define LP8860_CL2_BRT_MSB 0x04 +#define LP8860_CL2_BRT_LSB 0x05 +#define LP8860_CL2_CURRENT 0x06 +#define LP8860_CL3_BRT_MSB 0x07 +#define LP8860_CL3_BRT_LSB 0x08 +#define LP8860_CL3_CURRENT 0x09 +#define LP8860_CL4_BRT_MSB 0x0a +#define LP8860_CL4_BRT_LSB 0x0b +#define LP8860_CL4_CURRENT 0x0c +#define LP8860_CONFIG 0x0d +#define LP8860_STATUS 0x0e +#define LP8860_FAULT 0x0f +#define LP8860_LED_FAULT 0x10 +#define LP8860_FAULT_CLEAR 0x11 +#define LP8860_ID 0x12 +#define LP8860_TEMP_MSB 0x13 +#define LP8860_TEMP_LSB 0x14 +#define LP8860_DISP_LED_CURR_MSB 0x15 +#define LP8860_DISP_LED_CURR_LSB 0x16 +#define LP8860_DISP_LED_PWM_MSB 0x17 +#define LP8860_DISP_LED_PWM_LSB 0x18 +#define LP8860_EEPROM_CNTRL 0x19 +#define LP8860_EEPROM_UNLOCK 0x1a + +#define LP8860_EEPROM_REG_0 0x60 +#define LP8860_EEPROM_REG_1 0x61 +#define LP8860_EEPROM_REG_2 0x62 +#define LP8860_EEPROM_REG_3 0x63 +#define LP8860_EEPROM_REG_4 0x64 +#define LP8860_EEPROM_REG_5 0x65 +#define LP8860_EEPROM_REG_6 0x66 +#define LP8860_EEPROM_REG_7 0x67 +#define LP8860_EEPROM_REG_8 0x68 +#define LP8860_EEPROM_REG_9 0x69 +#define LP8860_EEPROM_REG_10 0x6a +#define LP8860_EEPROM_REG_11 0x6b +#define LP8860_EEPROM_REG_12 0x6c +#define LP8860_EEPROM_REG_13 0x6d +#define LP8860_EEPROM_REG_14 0x6e +#define LP8860_EEPROM_REG_15 0x6f +#define LP8860_EEPROM_REG_16 0x70 +#define LP8860_EEPROM_REG_17 0x71 +#define LP8860_EEPROM_REG_18 0x72 +#define LP8860_EEPROM_REG_19 0x73 +#define LP8860_EEPROM_REG_20 0x74 +#define LP8860_EEPROM_REG_21 0x75 +#define LP8860_EEPROM_REG_22 0x76 +#define LP8860_EEPROM_REG_23 0x77 +#define LP8860_EEPROM_REG_24 0x78 + +#define LP8860_LOCK_EEPROM 0x00 +#define LP8860_UNLOCK_EEPROM 0x01 +#define LP8860_PROGRAM_EEPROM 0x02 +#define LP8860_EEPROM_CODE_1 0x08 +#define LP8860_EEPROM_CODE_2 0xba +#define LP8860_EEPROM_CODE_3 0xef + +#define LP8860_CLEAR_FAULTS 0x01 + +#define LP8860_DISP_LED_NAME "display_cluster" + +/** + * struct lp8860_led - + * @lock - Lock for reading/writing the device + * @work - Work item used to off load the brightness register writes + * @client - Pointer to the I2C client + * @led_dev - led class device pointer + * @regmap - Devices register map + * @eeprom_regmap - EEPROM register map + * @enable_gpio - VDDIO/EN gpio to enable communication interface + * @regulator - LED supply regulator pointer + * @brightness - Current brightness value requested + * @label - LED label +**/ +struct lp8860_led { + struct mutex lock; + struct work_struct work; + struct i2c_client *client; + struct led_classdev led_dev; + struct regmap *regmap; + struct regmap *eeprom_regmap; + struct gpio_desc *enable_gpio; + struct regulator *regulator; + enum led_brightness brightness; + const char *label; +}; + +struct lp8860_eeprom_reg { + uint8_t reg; + uint8_t value; +}; + +static struct lp8860_eeprom_reg lp8860_eeprom_disp_regs[] = { + { LP8860_EEPROM_REG_0, 0xed }, + { LP8860_EEPROM_REG_1, 0xdf }, + { LP8860_EEPROM_REG_2, 0xdc }, + { LP8860_EEPROM_REG_3, 0xf0 }, + { LP8860_EEPROM_REG_4, 0xdf }, + { LP8860_EEPROM_REG_5, 0xe5 }, + { LP8860_EEPROM_REG_6, 0xf2 }, + { LP8860_EEPROM_REG_7, 0x77 }, + { LP8860_EEPROM_REG_8, 0x77 }, + { LP8860_EEPROM_REG_9, 0x71 }, + { LP8860_EEPROM_REG_10, 0x3f }, + { LP8860_EEPROM_REG_11, 0xb7 }, + { LP8860_EEPROM_REG_12, 0x17 }, + { LP8860_EEPROM_REG_13, 0xef }, + { LP8860_EEPROM_REG_14, 0xb0 }, + { LP8860_EEPROM_REG_15, 0x87 }, + { LP8860_EEPROM_REG_16, 0xce }, + { LP8860_EEPROM_REG_17, 0x72 }, + { LP8860_EEPROM_REG_18, 0xe5 }, + { LP8860_EEPROM_REG_19, 0xdf }, + { LP8860_EEPROM_REG_20, 0x35 }, + { LP8860_EEPROM_REG_21, 0x06 }, + { LP8860_EEPROM_REG_22, 0xdc }, + { LP8860_EEPROM_REG_23, 0x88 }, + { LP8860_EEPROM_REG_24, 0x3E }, +}; + +static int lp8860_unlock_eeprom(struct lp8860_led *led, int lock) +{ + int ret; + + mutex_lock(&led->lock); + + if (lock == LP8860_UNLOCK_EEPROM) { + ret = regmap_write(led->regmap, + LP8860_EEPROM_UNLOCK, + LP8860_EEPROM_CODE_1); + if (ret) { + dev_err(&led->client->dev, "EEPROM Unlock failed\n"); + goto out; + } + + ret = regmap_write(led->regmap, + LP8860_EEPROM_UNLOCK, + LP8860_EEPROM_CODE_2); + if (ret) { + dev_err(&led->client->dev, "EEPROM Unlock failed\n"); + goto out; + } + ret = regmap_write(led->regmap, + LP8860_EEPROM_UNLOCK, + LP8860_EEPROM_CODE_3); + if (ret) { + dev_err(&led->client->dev, "EEPROM Unlock failed\n"); + goto out; + } + } else { + ret = regmap_write(led->regmap, + LP8860_EEPROM_UNLOCK, + LP8860_LOCK_EEPROM); + } + +out: + mutex_unlock(&led->lock); + return ret; +} + +static int lp8860_fault_check(struct lp8860_led *led) +{ + int ret, fault; + unsigned int read_buf; + + ret = regmap_read(led->regmap, LP8860_LED_FAULT, &read_buf); + if (ret) + goto out; + + fault = read_buf; + + ret = regmap_read(led->regmap, LP8860_FAULT, &read_buf); + if (ret) + goto out; + + fault |= read_buf; + + /* Attempt to clear any faults */ + if (fault) + ret = regmap_write(led->regmap, LP8860_FAULT_CLEAR, + LP8860_CLEAR_FAULTS); +out: + return ret; +} + +static void lp8860_led_brightness_work(struct work_struct *work) +{ + struct lp8860_led *led = container_of(work, struct lp8860_led, work); + int ret; + int disp_brightness = led->brightness * 255; + + mutex_lock(&led->lock); + + ret = lp8860_fault_check(led); + if (ret) { + dev_err(&led->client->dev, "Cannot read/clear faults\n"); + goto out; + } + + ret = regmap_write(led->regmap, LP8860_DISP_CL1_BRT_MSB, + (disp_brightness & 0xff00) >> 8); + if (ret) { + dev_err(&led->client->dev, "Cannot write CL1 MSB\n"); + goto out; + } + + ret = regmap_write(led->regmap, LP8860_DISP_CL1_BRT_LSB, + disp_brightness & 0xff); + if (ret) { + dev_err(&led->client->dev, "Cannot write CL1 LSB\n"); + goto out; + } +out: + mutex_unlock(&led->lock); +} + +static void lp8860_brightness_set(struct led_classdev *led_cdev, + enum led_brightness brt_val) +{ + struct lp8860_led *led = + container_of(led_cdev, struct lp8860_led, led_dev); + + led->brightness = brt_val; + schedule_work(&led->work); +} + +static int lp8860_init(struct lp8860_led *led) +{ + unsigned int read_buf; + int ret, i, reg_count; + + if (led->enable_gpio) + gpiod_direction_output(led->enable_gpio, 1); + + ret = lp8860_fault_check(led); + if (ret) + goto out; + + ret = regmap_read(led->regmap, LP8860_STATUS, &read_buf); + if (ret) + goto out; + + ret = lp8860_unlock_eeprom(led, LP8860_UNLOCK_EEPROM); + if (ret) { + dev_err(&led->client->dev, "Failed unlocking EEPROM\n"); + goto out; + } + + reg_count = ARRAY_SIZE(lp8860_eeprom_disp_regs) / sizeof(lp8860_eeprom_disp_regs[0]); + for (i = 0; i < reg_count; i++) { + ret = regmap_write(led->eeprom_regmap, + lp8860_eeprom_disp_regs[i].reg, + lp8860_eeprom_disp_regs[i].value); + if (ret) { + dev_err(&led->client->dev, "Failed writing EEPROM\n"); + goto out; + } + } + + ret = lp8860_unlock_eeprom(led, LP8860_LOCK_EEPROM); + if (ret) + goto out; + + ret = regmap_write(led->regmap, + LP8860_EEPROM_CNTRL, + LP8860_PROGRAM_EEPROM); + if (ret) + dev_err(&led->client->dev, "Failed programming EEPROM\n"); +out: + if (ret) + if (led->enable_gpio) + gpiod_direction_output(led->enable_gpio, 0); + return ret; +} + +static struct reg_default lp8860_reg_defs[] = { + { LP8860_DISP_CL1_BRT_MSB, 0x00}, + { LP8860_DISP_CL1_BRT_LSB, 0x00}, + { LP8860_DISP_CL1_CURR_MSB, 0x00}, + { LP8860_DISP_CL1_CURR_LSB, 0x00}, + { LP8860_CL2_BRT_MSB, 0x00}, + { LP8860_CL2_BRT_LSB, 0x00}, + { LP8860_CL2_CURRENT, 0x00}, + { LP8860_CL3_BRT_MSB, 0x00}, + { LP8860_CL3_BRT_LSB, 0x00}, + { LP8860_CL3_CURRENT, 0x00}, + { LP8860_CL4_BRT_MSB, 0x00}, + { LP8860_CL4_BRT_LSB, 0x00}, + { LP8860_CL4_CURRENT, 0x00}, + { LP8860_CONFIG, 0x00}, + { LP8860_FAULT_CLEAR, 0x00}, + { LP8860_EEPROM_CNTRL, 0x80}, + { LP8860_EEPROM_UNLOCK, 0x00}, +}; + +static const struct regmap_config lp8860_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = LP8860_EEPROM_UNLOCK, + .reg_defaults = lp8860_reg_defs, + .num_reg_defaults = ARRAY_SIZE(lp8860_reg_defs), + .cache_type = REGCACHE_NONE, +}; + +static struct reg_default lp8860_eeprom_defs[] = { + { LP8860_EEPROM_REG_0, 0x00 }, + { LP8860_EEPROM_REG_1, 0x00 }, + { LP8860_EEPROM_REG_2, 0x00 }, + { LP8860_EEPROM_REG_3, 0x00 }, + { LP8860_EEPROM_REG_4, 0x00 }, + { LP8860_EEPROM_REG_5, 0x00 }, + { LP8860_EEPROM_REG_6, 0x00 }, + { LP8860_EEPROM_REG_7, 0x00 }, + { LP8860_EEPROM_REG_8, 0x00 }, + { LP8860_EEPROM_REG_9, 0x00 }, + { LP8860_EEPROM_REG_10, 0x00 }, + { LP8860_EEPROM_REG_11, 0x00 }, + { LP8860_EEPROM_REG_12, 0x00 }, + { LP8860_EEPROM_REG_13, 0x00 }, + { LP8860_EEPROM_REG_14, 0x00 }, + { LP8860_EEPROM_REG_15, 0x00 }, + { LP8860_EEPROM_REG_16, 0x00 }, + { LP8860_EEPROM_REG_17, 0x00 }, + { LP8860_EEPROM_REG_18, 0x00 }, + { LP8860_EEPROM_REG_19, 0x00 }, + { LP8860_EEPROM_REG_20, 0x00 }, + { LP8860_EEPROM_REG_21, 0x00 }, + { LP8860_EEPROM_REG_22, 0x00 }, + { LP8860_EEPROM_REG_23, 0x00 }, + { LP8860_EEPROM_REG_24, 0x00 }, +}; + +static const struct regmap_config lp8860_eeprom_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = LP8860_EEPROM_REG_24, + .reg_defaults = lp8860_eeprom_defs, + .num_reg_defaults = ARRAY_SIZE(lp8860_eeprom_defs), + .cache_type = REGCACHE_NONE, +}; + +static int lp8860_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret; + struct lp8860_led *led; + struct device_node *np = client->dev.of_node; + + led = devm_kzalloc(&client->dev, sizeof(*led), GFP_KERNEL); + if (!led) + return -ENOMEM; + + led->label = LP8860_DISP_LED_NAME; + + if (client->dev.of_node) { + ret = of_property_read_string(np, "label", &led->label); + if (ret) { + dev_err(&client->dev, "Missing label in dt\n"); + return -EINVAL; + } + } + + led->enable_gpio = devm_gpiod_get(&client->dev, "enable"); + if (IS_ERR(led->enable_gpio)) + led->enable_gpio = NULL; + else + gpiod_direction_output(led->enable_gpio, 0); + + led->regulator = devm_regulator_get(&client->dev, "vled"); + if (IS_ERR(led->regulator)) + led->regulator = NULL; + + led->client = client; + led->led_dev.name = led->label; + led->led_dev.max_brightness = LED_FULL; + led->led_dev.brightness_set = lp8860_brightness_set; + + mutex_init(&led->lock); + INIT_WORK(&led->work, lp8860_led_brightness_work); + + i2c_set_clientdata(client, led); + + led->regmap = devm_regmap_init_i2c(client, &lp8860_regmap_config); + if (IS_ERR(led->regmap)) { + ret = PTR_ERR(led->regmap); + dev_err(&client->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + + led->eeprom_regmap = devm_regmap_init_i2c(client, &lp8860_eeprom_regmap_config); + if (IS_ERR(led->eeprom_regmap)) { + ret = PTR_ERR(led->eeprom_regmap); + dev_err(&client->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + + ret = lp8860_init(led); + if (ret) + return ret; + + ret = led_classdev_register(&client->dev, &led->led_dev); + if (ret) { + dev_err(&client->dev, "led register err: %d\n", ret); + return ret; + } + + return 0; +} + +static int lp8860_remove(struct i2c_client *client) +{ + struct lp8860_led *led = i2c_get_clientdata(client); + int ret; + + led_classdev_unregister(&led->led_dev); + cancel_work_sync(&led->work); + + if (led->enable_gpio) + gpiod_direction_output(led->enable_gpio, 0); + + if (led->regulator) { + ret = regulator_disable(led->regulator); + if (ret) + dev_err(&led->client->dev, + "Failed to disable regulator\n"); + } + + return 0; +} + +static const struct i2c_device_id lp8860_id[] = { + { "lp8860", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, lp8860_id); + +#ifdef CONFIG_OF +static const struct of_device_id of_lp8860_leds_match[] = { + { .compatible = "ti,lp8860", }, + {}, +}; +MODULE_DEVICE_TABLE(of, of_lp8860_leds_match); +#endif + +static struct i2c_driver lp8860_driver = { + .driver = { + .name = "lp8860", + .of_match_table = of_match_ptr(of_lp8860_leds_match), + }, + .probe = lp8860_probe, + .remove = lp8860_remove, + .id_table = lp8860_id, +}; +module_i2c_driver(lp8860_driver); + +MODULE_DESCRIPTION("Texas Instruments LP8860 LED drvier"); +MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c index 26515c27ea8c..25e419752a7b 100644 --- a/drivers/leds/leds-netxbig.c +++ b/drivers/leds/leds-netxbig.c @@ -330,18 +330,18 @@ create_netxbig_led(struct platform_device *pdev, led_dat->sata = 0; led_dat->cdev.brightness = LED_OFF; led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; - /* - * If available, expose the SATA activity blink capability through - * a "sata" sysfs attribute. - */ - if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) - led_dat->cdev.groups = netxbig_led_groups; led_dat->mode_addr = template->mode_addr; led_dat->mode_val = template->mode_val; led_dat->bright_addr = template->bright_addr; led_dat->bright_max = (1 << pdata->gpio_ext->num_data) - 1; led_dat->timer = pdata->timer; led_dat->num_timer = pdata->num_timer; + /* + * If available, expose the SATA activity blink capability through + * a "sata" sysfs attribute. + */ + if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) + led_dat->cdev.groups = netxbig_led_groups; return led_classdev_register(&pdev->dev, &led_dat->cdev); } diff --git a/drivers/leds/leds-regulator.c b/drivers/leds/leds-regulator.c index fa1126f12063..ffc21397a675 100644 --- a/drivers/leds/leds-regulator.c +++ b/drivers/leds/leds-regulator.c @@ -153,24 +153,21 @@ static int regulator_led_probe(struct platform_device *pdev) return -ENODEV; } - vcc = regulator_get_exclusive(&pdev->dev, "vled"); + vcc = devm_regulator_get_exclusive(&pdev->dev, "vled"); if (IS_ERR(vcc)) { dev_err(&pdev->dev, "Cannot get vcc for %s\n", pdata->name); return PTR_ERR(vcc); } led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL); - if (led == NULL) { - ret = -ENOMEM; - goto err_vcc; - } + if (led == NULL) + return -ENOMEM; led->cdev.max_brightness = led_regulator_get_max_brightness(vcc); if (pdata->brightness > led->cdev.max_brightness) { dev_err(&pdev->dev, "Invalid default brightness %d\n", pdata->brightness); - ret = -EINVAL; - goto err_vcc; + return -EINVAL; } led->value = pdata->brightness; @@ -191,7 +188,7 @@ static int regulator_led_probe(struct platform_device *pdev) ret = led_classdev_register(&pdev->dev, &led->cdev); if (ret < 0) { cancel_work_sync(&led->work); - goto err_vcc; + return ret; } /* to expose the default value to userspace */ @@ -201,10 +198,6 @@ static int regulator_led_probe(struct platform_device *pdev) regulator_led_set_value(led); return 0; - -err_vcc: - regulator_put(vcc); - return ret; } static int regulator_led_remove(struct platform_device *pdev) @@ -214,7 +207,6 @@ static int regulator_led_remove(struct platform_device *pdev) led_classdev_unregister(&led->cdev); cancel_work_sync(&led->work); regulator_led_disable(led); - regulator_put(led->vcc); return 0; } diff --git a/drivers/leds/leds-syscon.c b/drivers/leds/leds-syscon.c index 3afec79c43f4..6896e2d9ba58 100644 --- a/drivers/leds/leds-syscon.c +++ b/drivers/leds/leds-syscon.c @@ -18,10 +18,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA - * - * This driver provides system reboot functionality for APM X-Gene SoC. - * For system shutdown, this is board specify. If a board designer - * implements GPIO shutdown, use the gpio-poweroff.c driver. */ #include <linux/io.h> #include <linux/of_device.h> @@ -70,39 +66,13 @@ static void syscon_led_set(struct led_classdev *led_cdev, dev_err(sled->cdev.dev, "error updating LED status\n"); } -static const struct of_device_id syscon_match[] = { - { .compatible = "syscon", }, - {}, -}; - -static int __init syscon_leds_init(void) +static int __init syscon_leds_spawn(struct device_node *np, + struct device *dev, + struct regmap *map) { - const struct of_device_id *devid; - struct device_node *np; struct device_node *child; - struct regmap *map; - struct platform_device *pdev; - struct device *dev; int ret; - np = of_find_matching_node_and_match(NULL, syscon_match, - &devid); - if (!np) - return -ENODEV; - - map = syscon_node_to_regmap(np); - if (IS_ERR(map)) - return PTR_ERR(map); - - /* - * If the map is there, the device should be there, we allocate - * memory on the syscon device's behalf here. - */ - pdev = of_find_device_by_node(np); - if (!pdev) - return -ENODEV; - dev = &pdev->dev; - for_each_available_child_of_node(np, child) { struct syscon_led *sled; const char *state; @@ -150,7 +120,6 @@ static int __init syscon_leds_init(void) if (ret < 0) return ret; } - } sled->cdev.brightness_set = syscon_led_set; @@ -160,7 +129,39 @@ static int __init syscon_leds_init(void) dev_info(dev, "registered LED %s\n", sled->cdev.name); } + return 0; +} + +static int __init syscon_leds_init(void) +{ + struct device_node *np; + + for_each_of_allnodes(np) { + struct platform_device *pdev; + struct regmap *map; + int ret; + + if (!of_device_is_compatible(np, "syscon")) + continue; + + map = syscon_node_to_regmap(np); + if (IS_ERR(map)) { + pr_err("error getting regmap for syscon LEDs\n"); + continue; + } + + /* + * If the map is there, the device should be there, we allocate + * memory on the syscon device's behalf here. + */ + pdev = of_find_device_by_node(np); + if (!pdev) + return -ENODEV; + ret = syscon_leds_spawn(np, &pdev->dev, map); + if (ret) + dev_err(&pdev->dev, "could not spawn syscon LEDs\n"); + } - return 0; + return 0; } device_initcall(syscon_leds_init); diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h index 4c50365344a9..2348dbda5269 100644 --- a/drivers/leds/leds.h +++ b/drivers/leds/leds.h @@ -17,16 +17,28 @@ #include <linux/rwsem.h> #include <linux/leds.h> -static inline void __led_set_brightness(struct led_classdev *led_cdev, +static inline void led_set_brightness_async(struct led_classdev *led_cdev, enum led_brightness value) { - if (value > led_cdev->max_brightness) - value = led_cdev->max_brightness; - led_cdev->brightness = value; + led_cdev->brightness = min(value, led_cdev->max_brightness); + if (!(led_cdev->flags & LED_SUSPENDED)) led_cdev->brightness_set(led_cdev, value); } +static inline int led_set_brightness_sync(struct led_classdev *led_cdev, + enum led_brightness value) +{ + int ret = 0; + + led_cdev->brightness = min(value, led_cdev->max_brightness); + + if (!(led_cdev->flags & LED_SUSPENDED)) + ret = led_cdev->brightness_set_sync(led_cdev, + led_cdev->brightness); + return ret; +} + static inline int led_get_brightness(struct led_classdev *led_cdev) { return led_cdev->brightness; diff --git a/drivers/leds/trigger/ledtrig-backlight.c b/drivers/leds/trigger/ledtrig-backlight.c index 47e55aa9eefa..59eca17d9661 100644 --- a/drivers/leds/trigger/ledtrig-backlight.c +++ b/drivers/leds/trigger/ledtrig-backlight.c @@ -51,9 +51,9 @@ static int fb_notifier_callback(struct notifier_block *p, if ((n->old_status == UNBLANK) ^ n->invert) { n->brightness = led->brightness; - __led_set_brightness(led, LED_OFF); + led_set_brightness_async(led, LED_OFF); } else { - __led_set_brightness(led, n->brightness); + led_set_brightness_async(led, n->brightness); } n->old_status = new_status; @@ -89,9 +89,9 @@ static ssize_t bl_trig_invert_store(struct device *dev, /* After inverting, we need to update the LED. */ if ((n->old_status == BLANK) ^ n->invert) - __led_set_brightness(led, LED_OFF); + led_set_brightness_async(led, LED_OFF); else - __led_set_brightness(led, n->brightness); + led_set_brightness_async(led, n->brightness); return num; } diff --git a/drivers/leds/trigger/ledtrig-default-on.c b/drivers/leds/trigger/ledtrig-default-on.c index 81a91be8e18d..6f38f883aaf1 100644 --- a/drivers/leds/trigger/ledtrig-default-on.c +++ b/drivers/leds/trigger/ledtrig-default-on.c @@ -19,7 +19,7 @@ static void defon_trig_activate(struct led_classdev *led_cdev) { - __led_set_brightness(led_cdev, led_cdev->max_brightness); + led_set_brightness_async(led_cdev, led_cdev->max_brightness); } static struct led_trigger defon_led_trigger = { diff --git a/drivers/leds/trigger/ledtrig-gpio.c b/drivers/leds/trigger/ledtrig-gpio.c index c86c41826476..4cc7040746c6 100644 --- a/drivers/leds/trigger/ledtrig-gpio.c +++ b/drivers/leds/trigger/ledtrig-gpio.c @@ -54,12 +54,12 @@ static void gpio_trig_work(struct work_struct *work) if (tmp) { if (gpio_data->desired_brightness) - __led_set_brightness(gpio_data->led, + led_set_brightness_async(gpio_data->led, gpio_data->desired_brightness); else - __led_set_brightness(gpio_data->led, LED_FULL); + led_set_brightness_async(gpio_data->led, LED_FULL); } else { - __led_set_brightness(gpio_data->led, LED_OFF); + led_set_brightness_async(gpio_data->led, LED_OFF); } } diff --git a/drivers/leds/trigger/ledtrig-heartbeat.c b/drivers/leds/trigger/ledtrig-heartbeat.c index 5c8464a33172..fea6871d2609 100644 --- a/drivers/leds/trigger/ledtrig-heartbeat.c +++ b/drivers/leds/trigger/ledtrig-heartbeat.c @@ -74,7 +74,7 @@ static void led_heartbeat_function(unsigned long data) break; } - __led_set_brightness(led_cdev, brightness); + led_set_brightness_async(led_cdev, brightness); mod_timer(&heartbeat_data->timer, jiffies + delay); } diff --git a/drivers/leds/trigger/ledtrig-oneshot.c b/drivers/leds/trigger/ledtrig-oneshot.c index cb4c7466692a..fbd02cdc3ad7 100644 --- a/drivers/leds/trigger/ledtrig-oneshot.c +++ b/drivers/leds/trigger/ledtrig-oneshot.c @@ -63,9 +63,9 @@ static ssize_t led_invert_store(struct device *dev, oneshot_data->invert = !!state; if (oneshot_data->invert) - __led_set_brightness(led_cdev, LED_FULL); + led_set_brightness_async(led_cdev, LED_FULL); else - __led_set_brightness(led_cdev, LED_OFF); + led_set_brightness_async(led_cdev, LED_OFF); return size; } diff --git a/drivers/leds/trigger/ledtrig-transient.c b/drivers/leds/trigger/ledtrig-transient.c index e5abc00bb00c..3c34de404d18 100644 --- a/drivers/leds/trigger/ledtrig-transient.c +++ b/drivers/leds/trigger/ledtrig-transient.c @@ -41,7 +41,7 @@ static void transient_timer_function(unsigned long data) struct transient_trig_data *transient_data = led_cdev->trigger_data; transient_data->activate = 0; - __led_set_brightness(led_cdev, transient_data->restore_state); + led_set_brightness_async(led_cdev, transient_data->restore_state); } static ssize_t transient_activate_show(struct device *dev, @@ -72,7 +72,8 @@ static ssize_t transient_activate_store(struct device *dev, if (state == 0 && transient_data->activate == 1) { del_timer(&transient_data->timer); transient_data->activate = state; - __led_set_brightness(led_cdev, transient_data->restore_state); + led_set_brightness_async(led_cdev, + transient_data->restore_state); return size; } @@ -80,7 +81,7 @@ static ssize_t transient_activate_store(struct device *dev, if (state == 1 && transient_data->activate == 0 && transient_data->duration != 0) { transient_data->activate = state; - __led_set_brightness(led_cdev, transient_data->state); + led_set_brightness_async(led_cdev, transient_data->state); transient_data->restore_state = (transient_data->state == LED_FULL) ? LED_OFF : LED_FULL; mod_timer(&transient_data->timer, @@ -203,7 +204,8 @@ static void transient_trig_deactivate(struct led_classdev *led_cdev) if (led_cdev->activated) { del_timer_sync(&transient_data->timer); - __led_set_brightness(led_cdev, transient_data->restore_state); + led_set_brightness_async(led_cdev, + transient_data->restore_state); device_remove_file(led_cdev->dev, &dev_attr_activate); device_remove_file(led_cdev->dev, &dev_attr_duration); device_remove_file(led_cdev->dev, &dev_attr_state); diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index 3067d56b11a6..5844b80bd90e 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig @@ -204,16 +204,6 @@ config THERM_ADT746X iBook G4, and the ATI based aluminium PowerBooks, allowing slightly better fan behaviour by default, and some manual control. -config THERM_PM72 - tristate "Support for thermal management on PowerMac G5 (AGP)" - depends on I2C && I2C_POWERMAC && PPC_PMAC64 - default n - help - This driver provides thermostat and fan control for the desktop - G5 machines. - - This is deprecated, use windfarm instead. - config WINDFARM tristate "New PowerMac thermal control infrastructure" depends on PPC diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile index d2f0120bc878..383ba920085b 100644 --- a/drivers/macintosh/Makefile +++ b/drivers/macintosh/Makefile @@ -25,7 +25,6 @@ obj-$(CONFIG_ADB_IOP) += adb-iop.o obj-$(CONFIG_ADB_PMU68K) += via-pmu68k.o obj-$(CONFIG_ADB_MACIO) += macio-adb.o -obj-$(CONFIG_THERM_PM72) += therm_pm72.o obj-$(CONFIG_THERM_WINDTUNNEL) += therm_windtunnel.o obj-$(CONFIG_THERM_ADT746X) += therm_adt746x.o obj-$(CONFIG_WINDFARM) += windfarm_core.o diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c deleted file mode 100644 index 7ed92582d2cf..000000000000 --- a/drivers/macintosh/therm_pm72.c +++ /dev/null @@ -1,2278 +0,0 @@ -/* - * Device driver for the thermostats & fan controller of the - * Apple G5 "PowerMac7,2" desktop machines. - * - * (c) Copyright IBM Corp. 2003-2004 - * - * Maintained by: Benjamin Herrenschmidt - * <benh@kernel.crashing.org> - * - * - * The algorithm used is the PID control algorithm, used the same - * way the published Darwin code does, using the same values that - * are present in the Darwin 7.0 snapshot property lists. - * - * As far as the CPUs control loops are concerned, I use the - * calibration & PID constants provided by the EEPROM, - * I do _not_ embed any value from the property lists, as the ones - * provided by Darwin 7.0 seem to always have an older version that - * what I've seen on the actual computers. - * It would be interesting to verify that though. Darwin has a - * version code of 1.0.0d11 for all control loops it seems, while - * so far, the machines EEPROMs contain a dataset versioned 1.0.0f - * - * Darwin doesn't provide source to all parts, some missing - * bits like the AppleFCU driver or the actual scale of some - * of the values returned by sensors had to be "guessed" some - * way... or based on what Open Firmware does. - * - * I didn't yet figure out how to get the slots power consumption - * out of the FCU, so that part has not been implemented yet and - * the slots fan is set to a fixed 50% PWM, hoping this value is - * safe enough ... - * - * Note: I have observed strange oscillations of the CPU control - * loop on a dual G5 here. When idle, the CPU exhaust fan tend to - * oscillates slowly (over several minutes) between the minimum - * of 300RPMs and approx. 1000 RPMs. I don't know what is causing - * this, it could be some incorrect constant or an error in the - * way I ported the algorithm, or it could be just normal. I - * don't have full understanding on the way Apple tweaked the PID - * algorithm for the CPU control, it is definitely not a standard - * implementation... - * - * TODO: - Check MPU structure version/signature - * - Add things like /sbin/overtemp for non-critical - * overtemp conditions so userland can take some policy - * decisions, like slowing down CPUs - * - Deal with fan and i2c failures in a better way - * - Maybe do a generic PID based on params used for - * U3 and Drives ? Definitely need to factor code a bit - * better... also make sensor detection more robust using - * the device-tree to probe for them - * - Figure out how to get the slots consumption and set the - * slots fan accordingly - * - * History: - * - * Nov. 13, 2003 : 0.5 - * - First release - * - * Nov. 14, 2003 : 0.6 - * - Read fan speed from FCU, low level fan routines now deal - * with errors & check fan status, though higher level don't - * do much. - * - Move a bunch of definitions to .h file - * - * Nov. 18, 2003 : 0.7 - * - Fix build on ppc64 kernel - * - Move back statics definitions to .c file - * - Avoid calling schedule_timeout with a negative number - * - * Dec. 18, 2003 : 0.8 - * - Fix typo when reading back fan speed on 2 CPU machines - * - * Mar. 11, 2004 : 0.9 - * - Rework code accessing the ADC chips, make it more robust and - * closer to the chip spec. Also make sure it is configured properly, - * I've seen yet unexplained cases where on startup, I would have stale - * values in the configuration register - * - Switch back to use of target fan speed for PID, thus lowering - * pressure on i2c - * - * Oct. 20, 2004 : 1.1 - * - Add device-tree lookup for fan IDs, should detect liquid cooling - * pumps when present - * - Enable driver for PowerMac7,3 machines - * - Split the U3/Backside cooling on U3 & U3H versions as Darwin does - * - Add new CPU cooling algorithm for machines with liquid cooling - * - Workaround for some PowerMac7,3 with empty "fan" node in the devtree - * - Fix a signed/unsigned compare issue in some PID loops - * - * Mar. 10, 2005 : 1.2 - * - Add basic support for Xserve G5 - * - Retrieve pumps min/max from EEPROM image in device-tree (broken) - * - Use min/max macros here or there - * - Latest darwin updated U3H min fan speed to 20% PWM - * - * July. 06, 2006 : 1.3 - * - Fix setting of RPM fans on Xserve G5 (they were going too fast) - * - Add missing slots fan control loop for Xserve G5 - * - Lower fixed slots fan speed from 50% to 40% on desktop G5s. We - * still can't properly implement the control loop for these, so let's - * reduce the noise a little bit, it appears that 40% still gives us - * a pretty good air flow - * - Add code to "tickle" the FCU regulary so it doesn't think that - * we are gone while in fact, the machine just didn't need any fan - * speed change lately - * - */ - -#include <linux/types.h> -#include <linux/module.h> -#include <linux/errno.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/sched.h> -#include <linux/init.h> -#include <linux/spinlock.h> -#include <linux/wait.h> -#include <linux/reboot.h> -#include <linux/kmod.h> -#include <linux/i2c.h> -#include <linux/kthread.h> -#include <linux/mutex.h> -#include <linux/of_device.h> -#include <linux/of_platform.h> -#include <asm/prom.h> -#include <asm/machdep.h> -#include <asm/io.h> -#include <asm/sections.h> -#include <asm/macio.h> - -#include "therm_pm72.h" - -#define VERSION "1.3" - -#undef DEBUG - -#ifdef DEBUG -#define DBG(args...) printk(args) -#else -#define DBG(args...) do { } while(0) -#endif - - -/* - * Driver statics - */ - -static struct platform_device * of_dev; -static struct i2c_adapter * u3_0; -static struct i2c_adapter * u3_1; -static struct i2c_adapter * k2; -static struct i2c_client * fcu; -static struct cpu_pid_state processor_state[2]; -static struct basckside_pid_params backside_params; -static struct backside_pid_state backside_state; -static struct drives_pid_state drives_state; -static struct dimm_pid_state dimms_state; -static struct slots_pid_state slots_state; -static int state; -static int cpu_count; -static int cpu_pid_type; -static struct task_struct *ctrl_task; -static struct completion ctrl_complete; -static int critical_state; -static int rackmac; -static s32 dimm_output_clamp; -static int fcu_rpm_shift; -static int fcu_tickle_ticks; -static DEFINE_MUTEX(driver_lock); - -/* - * We have 3 types of CPU PID control. One is "split" old style control - * for intake & exhaust fans, the other is "combined" control for both - * CPUs that also deals with the pumps when present. To be "compatible" - * with OS X at this point, we only use "COMBINED" on the machines that - * are identified as having the pumps (though that identification is at - * least dodgy). Ultimately, we could probably switch completely to this - * algorithm provided we hack it to deal with the UP case - */ -#define CPU_PID_TYPE_SPLIT 0 -#define CPU_PID_TYPE_COMBINED 1 -#define CPU_PID_TYPE_RACKMAC 2 - -/* - * This table describes all fans in the FCU. The "id" and "type" values - * are defaults valid for all earlier machines. Newer machines will - * eventually override the table content based on the device-tree - */ -struct fcu_fan_table -{ - char* loc; /* location code */ - int type; /* 0 = rpm, 1 = pwm, 2 = pump */ - int id; /* id or -1 */ -}; - -#define FCU_FAN_RPM 0 -#define FCU_FAN_PWM 1 - -#define FCU_FAN_ABSENT_ID -1 - -#define FCU_FAN_COUNT ARRAY_SIZE(fcu_fans) - -struct fcu_fan_table fcu_fans[] = { - [BACKSIDE_FAN_PWM_INDEX] = { - .loc = "BACKSIDE,SYS CTRLR FAN", - .type = FCU_FAN_PWM, - .id = BACKSIDE_FAN_PWM_DEFAULT_ID, - }, - [DRIVES_FAN_RPM_INDEX] = { - .loc = "DRIVE BAY", - .type = FCU_FAN_RPM, - .id = DRIVES_FAN_RPM_DEFAULT_ID, - }, - [SLOTS_FAN_PWM_INDEX] = { - .loc = "SLOT,PCI FAN", - .type = FCU_FAN_PWM, - .id = SLOTS_FAN_PWM_DEFAULT_ID, - }, - [CPUA_INTAKE_FAN_RPM_INDEX] = { - .loc = "CPU A INTAKE", - .type = FCU_FAN_RPM, - .id = CPUA_INTAKE_FAN_RPM_DEFAULT_ID, - }, - [CPUA_EXHAUST_FAN_RPM_INDEX] = { - .loc = "CPU A EXHAUST", - .type = FCU_FAN_RPM, - .id = CPUA_EXHAUST_FAN_RPM_DEFAULT_ID, - }, - [CPUB_INTAKE_FAN_RPM_INDEX] = { - .loc = "CPU B INTAKE", - .type = FCU_FAN_RPM, - .id = CPUB_INTAKE_FAN_RPM_DEFAULT_ID, - }, - [CPUB_EXHAUST_FAN_RPM_INDEX] = { - .loc = "CPU B EXHAUST", - .type = FCU_FAN_RPM, - .id = CPUB_EXHAUST_FAN_RPM_DEFAULT_ID, - }, - /* pumps aren't present by default, have to be looked up in the - * device-tree - */ - [CPUA_PUMP_RPM_INDEX] = { - .loc = "CPU A PUMP", - .type = FCU_FAN_RPM, - .id = FCU_FAN_ABSENT_ID, - }, - [CPUB_PUMP_RPM_INDEX] = { - .loc = "CPU B PUMP", - .type = FCU_FAN_RPM, - .id = FCU_FAN_ABSENT_ID, - }, - /* Xserve fans */ - [CPU_A1_FAN_RPM_INDEX] = { - .loc = "CPU A 1", - .type = FCU_FAN_RPM, - .id = FCU_FAN_ABSENT_ID, - }, - [CPU_A2_FAN_RPM_INDEX] = { - .loc = "CPU A 2", - .type = FCU_FAN_RPM, - .id = FCU_FAN_ABSENT_ID, - }, - [CPU_A3_FAN_RPM_INDEX] = { - .loc = "CPU A 3", - .type = FCU_FAN_RPM, - .id = FCU_FAN_ABSENT_ID, - }, - [CPU_B1_FAN_RPM_INDEX] = { - .loc = "CPU B 1", - .type = FCU_FAN_RPM, - .id = FCU_FAN_ABSENT_ID, - }, - [CPU_B2_FAN_RPM_INDEX] = { - .loc = "CPU B 2", - .type = FCU_FAN_RPM, - .id = FCU_FAN_ABSENT_ID, - }, - [CPU_B3_FAN_RPM_INDEX] = { - .loc = "CPU B 3", - .type = FCU_FAN_RPM, - .id = FCU_FAN_ABSENT_ID, - }, -}; - -static struct i2c_driver therm_pm72_driver; - -/* - * Utility function to create an i2c_client structure and - * attach it to one of u3 adapters - */ -static struct i2c_client *attach_i2c_chip(int id, const char *name) -{ - struct i2c_client *clt; - struct i2c_adapter *adap; - struct i2c_board_info info; - - if (id & 0x200) - adap = k2; - else if (id & 0x100) - adap = u3_1; - else - adap = u3_0; - if (adap == NULL) - return NULL; - - memset(&info, 0, sizeof(struct i2c_board_info)); - info.addr = (id >> 1) & 0x7f; - strlcpy(info.type, "therm_pm72", I2C_NAME_SIZE); - clt = i2c_new_device(adap, &info); - if (!clt) { - printk(KERN_ERR "therm_pm72: Failed to attach to i2c ID 0x%x\n", id); - return NULL; - } - - /* - * Let i2c-core delete that device on driver removal. - * This is safe because i2c-core holds the core_lock mutex for us. - */ - list_add_tail(&clt->detected, &therm_pm72_driver.clients); - return clt; -} - -/* - * Here are the i2c chip access wrappers - */ - -static void initialize_adc(struct cpu_pid_state *state) -{ - int rc; - u8 buf[2]; - - /* Read ADC the configuration register and cache it. We - * also make sure Config2 contains proper values, I've seen - * cases where we got stale grabage in there, thus preventing - * proper reading of conv. values - */ - - /* Clear Config2 */ - buf[0] = 5; - buf[1] = 0; - i2c_master_send(state->monitor, buf, 2); - - /* Read & cache Config1 */ - buf[0] = 1; - rc = i2c_master_send(state->monitor, buf, 1); - if (rc > 0) { - rc = i2c_master_recv(state->monitor, buf, 1); - if (rc > 0) { - state->adc_config = buf[0]; - DBG("ADC config reg: %02x\n", state->adc_config); - /* Disable shutdown mode */ - state->adc_config &= 0xfe; - buf[0] = 1; - buf[1] = state->adc_config; - rc = i2c_master_send(state->monitor, buf, 2); - } - } - if (rc <= 0) - printk(KERN_ERR "therm_pm72: Error reading ADC config" - " register !\n"); -} - -static int read_smon_adc(struct cpu_pid_state *state, int chan) -{ - int rc, data, tries = 0; - u8 buf[2]; - - for (;;) { - /* Set channel */ - buf[0] = 1; - buf[1] = (state->adc_config & 0x1f) | (chan << 5); - rc = i2c_master_send(state->monitor, buf, 2); - if (rc <= 0) - goto error; - /* Wait for conversion */ - msleep(1); - /* Switch to data register */ - buf[0] = 4; - rc = i2c_master_send(state->monitor, buf, 1); - if (rc <= 0) - goto error; - /* Read result */ - rc = i2c_master_recv(state->monitor, buf, 2); - if (rc < 0) - goto error; - data = ((u16)buf[0]) << 8 | (u16)buf[1]; - return data >> 6; - error: - DBG("Error reading ADC, retrying...\n"); - if (++tries > 10) { - printk(KERN_ERR "therm_pm72: Error reading ADC !\n"); - return -1; - } - msleep(10); - } -} - -static int read_lm87_reg(struct i2c_client * chip, int reg) -{ - int rc, tries = 0; - u8 buf; - - for (;;) { - /* Set address */ - buf = (u8)reg; - rc = i2c_master_send(chip, &buf, 1); - if (rc <= 0) - goto error; - rc = i2c_master_recv(chip, &buf, 1); - if (rc <= 0) - goto error; - return (int)buf; - error: - DBG("Error reading LM87, retrying...\n"); - if (++tries > 10) { - printk(KERN_ERR "therm_pm72: Error reading LM87 !\n"); - return -1; - } - msleep(10); - } -} - -static int fan_read_reg(int reg, unsigned char *buf, int nb) -{ - int tries, nr, nw; - - buf[0] = reg; - tries = 0; - for (;;) { - nw = i2c_master_send(fcu, buf, 1); - if (nw > 0 || (nw < 0 && nw != -EIO) || tries >= 100) - break; - msleep(10); - ++tries; - } - if (nw <= 0) { - printk(KERN_ERR "Failure writing address to FCU: %d", nw); - return -EIO; - } - tries = 0; - for (;;) { - nr = i2c_master_recv(fcu, buf, nb); - if (nr > 0 || (nr < 0 && nr != -ENODEV) || tries >= 100) - break; - msleep(10); - ++tries; - } - if (nr <= 0) - printk(KERN_ERR "Failure reading data from FCU: %d", nw); - return nr; -} - -static int fan_write_reg(int reg, const unsigned char *ptr, int nb) -{ - int tries, nw; - unsigned char buf[16]; - - buf[0] = reg; - memcpy(buf+1, ptr, nb); - ++nb; - tries = 0; - for (;;) { - nw = i2c_master_send(fcu, buf, nb); - if (nw > 0 || (nw < 0 && nw != -EIO) || tries >= 100) - break; - msleep(10); - ++tries; - } - if (nw < 0) - printk(KERN_ERR "Failure writing to FCU: %d", nw); - return nw; -} - -static int start_fcu(void) -{ - unsigned char buf = 0xff; - int rc; - - rc = fan_write_reg(0xe, &buf, 1); - if (rc < 0) - return -EIO; - rc = fan_write_reg(0x2e, &buf, 1); - if (rc < 0) - return -EIO; - rc = fan_read_reg(0, &buf, 1); - if (rc < 0) - return -EIO; - fcu_rpm_shift = (buf == 1) ? 2 : 3; - printk(KERN_DEBUG "FCU Initialized, RPM fan shift is %d\n", - fcu_rpm_shift); - - return 0; -} - -static int set_rpm_fan(int fan_index, int rpm) -{ - unsigned char buf[2]; - int rc, id, min, max; - - if (fcu_fans[fan_index].type != FCU_FAN_RPM) - return -EINVAL; - id = fcu_fans[fan_index].id; - if (id == FCU_FAN_ABSENT_ID) - return -EINVAL; - - min = 2400 >> fcu_rpm_shift; - max = 56000 >> fcu_rpm_shift; - - if (rpm < min) - rpm = min; - else if (rpm > max) - rpm = max; - buf[0] = rpm >> (8 - fcu_rpm_shift); - buf[1] = rpm << fcu_rpm_shift; - rc = fan_write_reg(0x10 + (id * 2), buf, 2); - if (rc < 0) - return -EIO; - return 0; -} - -static int get_rpm_fan(int fan_index, int programmed) -{ - unsigned char failure; - unsigned char active; - unsigned char buf[2]; - int rc, id, reg_base; - - if (fcu_fans[fan_index].type != FCU_FAN_RPM) - return -EINVAL; - id = fcu_fans[fan_index].id; - if (id == FCU_FAN_ABSENT_ID) - return -EINVAL; - - rc = fan_read_reg(0xb, &failure, 1); - if (rc != 1) - return -EIO; - if ((failure & (1 << id)) != 0) - return -EFAULT; - rc = fan_read_reg(0xd, &active, 1); - if (rc != 1) - return -EIO; - if ((active & (1 << id)) == 0) - return -ENXIO; - - /* Programmed value or real current speed */ - reg_base = programmed ? 0x10 : 0x11; - rc = fan_read_reg(reg_base + (id * 2), buf, 2); - if (rc != 2) - return -EIO; - - return (buf[0] << (8 - fcu_rpm_shift)) | buf[1] >> fcu_rpm_shift; -} - -static int set_pwm_fan(int fan_index, int pwm) -{ - unsigned char buf[2]; - int rc, id; - - if (fcu_fans[fan_index].type != FCU_FAN_PWM) - return -EINVAL; - id = fcu_fans[fan_index].id; - if (id == FCU_FAN_ABSENT_ID) - return -EINVAL; - - if (pwm < 10) - pwm = 10; - else if (pwm > 100) - pwm = 100; - pwm = (pwm * 2559) / 1000; - buf[0] = pwm; - rc = fan_write_reg(0x30 + (id * 2), buf, 1); - if (rc < 0) - return rc; - return 0; -} - -static int get_pwm_fan(int fan_index) -{ - unsigned char failure; - unsigned char active; - unsigned char buf[2]; - int rc, id; - - if (fcu_fans[fan_index].type != FCU_FAN_PWM) - return -EINVAL; - id = fcu_fans[fan_index].id; - if (id == FCU_FAN_ABSENT_ID) - return -EINVAL; - - rc = fan_read_reg(0x2b, &failure, 1); - if (rc != 1) - return -EIO; - if ((failure & (1 << id)) != 0) - return -EFAULT; - rc = fan_read_reg(0x2d, &active, 1); - if (rc != 1) - return -EIO; - if ((active & (1 << id)) == 0) - return -ENXIO; - - /* Programmed value or real current speed */ - rc = fan_read_reg(0x30 + (id * 2), buf, 1); - if (rc != 1) - return -EIO; - - return (buf[0] * 1000) / 2559; -} - -static void tickle_fcu(void) -{ - int pwm; - - pwm = get_pwm_fan(SLOTS_FAN_PWM_INDEX); - - DBG("FCU Tickle, slots fan is: %d\n", pwm); - if (pwm < 0) - pwm = 100; - - if (!rackmac) { - pwm = SLOTS_FAN_DEFAULT_PWM; - } else if (pwm < SLOTS_PID_OUTPUT_MIN) - pwm = SLOTS_PID_OUTPUT_MIN; - - /* That is hopefully enough to make the FCU happy */ - set_pwm_fan(SLOTS_FAN_PWM_INDEX, pwm); -} - - -/* - * Utility routine to read the CPU calibration EEPROM data - * from the device-tree - */ -static int read_eeprom(int cpu, struct mpu_data *out) -{ - struct device_node *np; - char nodename[64]; - const u8 *data; - int len; - - /* prom.c routine for finding a node by path is a bit brain dead - * and requires exact @xxx unit numbers. This is a bit ugly but - * will work for these machines - */ - sprintf(nodename, "/u3@0,f8000000/i2c@f8001000/cpuid@a%d", cpu ? 2 : 0); - np = of_find_node_by_path(nodename); - if (np == NULL) { - printk(KERN_ERR "therm_pm72: Failed to retrieve cpuid node from device-tree\n"); - return -ENODEV; - } - data = of_get_property(np, "cpuid", &len); - if (data == NULL) { - printk(KERN_ERR "therm_pm72: Failed to retrieve cpuid property from device-tree\n"); - of_node_put(np); - return -ENODEV; - } - memcpy(out, data, sizeof(struct mpu_data)); - of_node_put(np); - - return 0; -} - -static void fetch_cpu_pumps_minmax(void) -{ - struct cpu_pid_state *state0 = &processor_state[0]; - struct cpu_pid_state *state1 = &processor_state[1]; - u16 pump_min = 0, pump_max = 0xffff; - u16 tmp[4]; - - /* Try to fetch pumps min/max infos from eeprom */ - - memcpy(&tmp, &state0->mpu.processor_part_num, 8); - if (tmp[0] != 0xffff && tmp[1] != 0xffff) { - pump_min = max(pump_min, tmp[0]); - pump_max = min(pump_max, tmp[1]); - } - if (tmp[2] != 0xffff && tmp[3] != 0xffff) { - pump_min = max(pump_min, tmp[2]); - pump_max = min(pump_max, tmp[3]); - } - - /* Double check the values, this _IS_ needed as the EEPROM on - * some dual 2.5Ghz G5s seem, at least, to have both min & max - * same to the same value ... (grrrr) - */ - if (pump_min == pump_max || pump_min == 0 || pump_max == 0xffff) { - pump_min = CPU_PUMP_OUTPUT_MIN; - pump_max = CPU_PUMP_OUTPUT_MAX; - } - - state0->pump_min = state1->pump_min = pump_min; - state0->pump_max = state1->pump_max = pump_max; -} - -/* - * Now, unfortunately, sysfs doesn't give us a nice void * we could - * pass around to the attribute functions, so we don't really have - * choice but implement a bunch of them... - * - * That sucks a bit, we take the lock because FIX32TOPRINT evaluates - * the input twice... I accept patches :) - */ -#define BUILD_SHOW_FUNC_FIX(name, data) \ -static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \ -{ \ - ssize_t r; \ - mutex_lock(&driver_lock); \ - r = sprintf(buf, "%d.%03d", FIX32TOPRINT(data)); \ - mutex_unlock(&driver_lock); \ - return r; \ -} -#define BUILD_SHOW_FUNC_INT(name, data) \ -static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \ -{ \ - return sprintf(buf, "%d", data); \ -} - -BUILD_SHOW_FUNC_FIX(cpu0_temperature, processor_state[0].last_temp) -BUILD_SHOW_FUNC_FIX(cpu0_voltage, processor_state[0].voltage) -BUILD_SHOW_FUNC_FIX(cpu0_current, processor_state[0].current_a) -BUILD_SHOW_FUNC_INT(cpu0_exhaust_fan_rpm, processor_state[0].rpm) -BUILD_SHOW_FUNC_INT(cpu0_intake_fan_rpm, processor_state[0].intake_rpm) - -BUILD_SHOW_FUNC_FIX(cpu1_temperature, processor_state[1].last_temp) -BUILD_SHOW_FUNC_FIX(cpu1_voltage, processor_state[1].voltage) -BUILD_SHOW_FUNC_FIX(cpu1_current, processor_state[1].current_a) -BUILD_SHOW_FUNC_INT(cpu1_exhaust_fan_rpm, processor_state[1].rpm) -BUILD_SHOW_FUNC_INT(cpu1_intake_fan_rpm, processor_state[1].intake_rpm) - -BUILD_SHOW_FUNC_FIX(backside_temperature, backside_state.last_temp) -BUILD_SHOW_FUNC_INT(backside_fan_pwm, backside_state.pwm) - -BUILD_SHOW_FUNC_FIX(drives_temperature, drives_state.last_temp) -BUILD_SHOW_FUNC_INT(drives_fan_rpm, drives_state.rpm) - -BUILD_SHOW_FUNC_FIX(slots_temperature, slots_state.last_temp) -BUILD_SHOW_FUNC_INT(slots_fan_pwm, slots_state.pwm) - -BUILD_SHOW_FUNC_FIX(dimms_temperature, dimms_state.last_temp) - -static DEVICE_ATTR(cpu0_temperature,S_IRUGO,show_cpu0_temperature,NULL); -static DEVICE_ATTR(cpu0_voltage,S_IRUGO,show_cpu0_voltage,NULL); -static DEVICE_ATTR(cpu0_current,S_IRUGO,show_cpu0_current,NULL); -static DEVICE_ATTR(cpu0_exhaust_fan_rpm,S_IRUGO,show_cpu0_exhaust_fan_rpm,NULL); -static DEVICE_ATTR(cpu0_intake_fan_rpm,S_IRUGO,show_cpu0_intake_fan_rpm,NULL); - -static DEVICE_ATTR(cpu1_temperature,S_IRUGO,show_cpu1_temperature,NULL); -static DEVICE_ATTR(cpu1_voltage,S_IRUGO,show_cpu1_voltage,NULL); -static DEVICE_ATTR(cpu1_current,S_IRUGO,show_cpu1_current,NULL); -static DEVICE_ATTR(cpu1_exhaust_fan_rpm,S_IRUGO,show_cpu1_exhaust_fan_rpm,NULL); -static DEVICE_ATTR(cpu1_intake_fan_rpm,S_IRUGO,show_cpu1_intake_fan_rpm,NULL); - -static DEVICE_ATTR(backside_temperature,S_IRUGO,show_backside_temperature,NULL); -static DEVICE_ATTR(backside_fan_pwm,S_IRUGO,show_backside_fan_pwm,NULL); - -static DEVICE_ATTR(drives_temperature,S_IRUGO,show_drives_temperature,NULL); -static DEVICE_ATTR(drives_fan_rpm,S_IRUGO,show_drives_fan_rpm,NULL); - -static DEVICE_ATTR(slots_temperature,S_IRUGO,show_slots_temperature,NULL); -static DEVICE_ATTR(slots_fan_pwm,S_IRUGO,show_slots_fan_pwm,NULL); - -static DEVICE_ATTR(dimms_temperature,S_IRUGO,show_dimms_temperature,NULL); - -/* - * CPUs fans control loop - */ - -static int do_read_one_cpu_values(struct cpu_pid_state *state, s32 *temp, s32 *power) -{ - s32 ltemp, volts, amps; - int index, rc = 0; - - /* Default (in case of error) */ - *temp = state->cur_temp; - *power = state->cur_power; - - if (cpu_pid_type == CPU_PID_TYPE_RACKMAC) - index = (state->index == 0) ? - CPU_A1_FAN_RPM_INDEX : CPU_B1_FAN_RPM_INDEX; - else - index = (state->index == 0) ? - CPUA_EXHAUST_FAN_RPM_INDEX : CPUB_EXHAUST_FAN_RPM_INDEX; - - /* Read current fan status */ - rc = get_rpm_fan(index, !RPM_PID_USE_ACTUAL_SPEED); - if (rc < 0) { - /* XXX What do we do now ? Nothing for now, keep old value, but - * return error upstream - */ - DBG(" cpu %d, fan reading error !\n", state->index); - } else { - state->rpm = rc; - DBG(" cpu %d, exhaust RPM: %d\n", state->index, state->rpm); - } - - /* Get some sensor readings and scale it */ - ltemp = read_smon_adc(state, 1); - if (ltemp == -1) { - /* XXX What do we do now ? */ - state->overtemp++; - if (rc == 0) - rc = -EIO; - DBG(" cpu %d, temp reading error !\n", state->index); - } else { - /* Fixup temperature according to diode calibration - */ - DBG(" cpu %d, temp raw: %04x, m_diode: %04x, b_diode: %04x\n", - state->index, - ltemp, state->mpu.mdiode, state->mpu.bdiode); - *temp = ((s32)ltemp * (s32)state->mpu.mdiode + ((s32)state->mpu.bdiode << 12)) >> 2; - state->last_temp = *temp; - DBG(" temp: %d.%03d\n", FIX32TOPRINT((*temp))); - } - - /* - * Read voltage & current and calculate power - */ - volts = read_smon_adc(state, 3); - amps = read_smon_adc(state, 4); - - /* Scale voltage and current raw sensor values according to fixed scales - * obtained in Darwin and calculate power from I and V - */ - volts *= ADC_CPU_VOLTAGE_SCALE; - amps *= ADC_CPU_CURRENT_SCALE; - *power = (((u64)volts) * ((u64)amps)) >> 16; - state->voltage = volts; - state->current_a = amps; - state->last_power = *power; - - DBG(" cpu %d, current: %d.%03d, voltage: %d.%03d, power: %d.%03d W\n", - state->index, FIX32TOPRINT(state->current_a), - FIX32TOPRINT(state->voltage), FIX32TOPRINT(*power)); - - return 0; -} - -static void do_cpu_pid(struct cpu_pid_state *state, s32 temp, s32 power) -{ - s32 power_target, integral, derivative, proportional, adj_in_target, sval; - s64 integ_p, deriv_p, prop_p, sum; - int i; - - /* Calculate power target value (could be done once for all) - * and convert to a 16.16 fp number - */ - power_target = ((u32)(state->mpu.pmaxh - state->mpu.padjmax)) << 16; - DBG(" power target: %d.%03d, error: %d.%03d\n", - FIX32TOPRINT(power_target), FIX32TOPRINT(power_target - power)); - - /* Store temperature and power in history array */ - state->cur_temp = (state->cur_temp + 1) % CPU_TEMP_HISTORY_SIZE; - state->temp_history[state->cur_temp] = temp; - state->cur_power = (state->cur_power + 1) % state->count_power; - state->power_history[state->cur_power] = power; - state->error_history[state->cur_power] = power_target - power; - - /* If first loop, fill the history table */ - if (state->first) { - for (i = 0; i < (state->count_power - 1); i++) { - state->cur_power = (state->cur_power + 1) % state->count_power; - state->power_history[state->cur_power] = power; - state->error_history[state->cur_power] = power_target - power; - } - for (i = 0; i < (CPU_TEMP_HISTORY_SIZE - 1); i++) { - state->cur_temp = (state->cur_temp + 1) % CPU_TEMP_HISTORY_SIZE; - state->temp_history[state->cur_temp] = temp; - } - state->first = 0; - } - - /* Calculate the integral term normally based on the "power" values */ - sum = 0; - integral = 0; - for (i = 0; i < state->count_power; i++) - integral += state->error_history[i]; - integral *= CPU_PID_INTERVAL; - DBG(" integral: %08x\n", integral); - - /* Calculate the adjusted input (sense value). - * G_r is 12.20 - * integ is 16.16 - * so the result is 28.36 - * - * input target is mpu.ttarget, input max is mpu.tmax - */ - integ_p = ((s64)state->mpu.pid_gr) * (s64)integral; - DBG(" integ_p: %d\n", (int)(integ_p >> 36)); - sval = (state->mpu.tmax << 16) - ((integ_p >> 20) & 0xffffffff); - adj_in_target = (state->mpu.ttarget << 16); - if (adj_in_target > sval) - adj_in_target = sval; - DBG(" adj_in_target: %d.%03d, ttarget: %d\n", FIX32TOPRINT(adj_in_target), - state->mpu.ttarget); - - /* Calculate the derivative term */ - derivative = state->temp_history[state->cur_temp] - - state->temp_history[(state->cur_temp + CPU_TEMP_HISTORY_SIZE - 1) - % CPU_TEMP_HISTORY_SIZE]; - derivative /= CPU_PID_INTERVAL; - deriv_p = ((s64)state->mpu.pid_gd) * (s64)derivative; - DBG(" deriv_p: %d\n", (int)(deriv_p >> 36)); - sum += deriv_p; - - /* Calculate the proportional term */ - proportional = temp - adj_in_target; - prop_p = ((s64)state->mpu.pid_gp) * (s64)proportional; - DBG(" prop_p: %d\n", (int)(prop_p >> 36)); - sum += prop_p; - - /* Scale sum */ - sum >>= 36; - - DBG(" sum: %d\n", (int)sum); - state->rpm += (s32)sum; -} - -static void do_monitor_cpu_combined(void) -{ - struct cpu_pid_state *state0 = &processor_state[0]; - struct cpu_pid_state *state1 = &processor_state[1]; - s32 temp0, power0, temp1, power1; - s32 temp_combi, power_combi; - int rc, intake, pump; - - rc = do_read_one_cpu_values(state0, &temp0, &power0); - if (rc < 0) { - /* XXX What do we do now ? */ - } - state1->overtemp = 0; - rc = do_read_one_cpu_values(state1, &temp1, &power1); - if (rc < 0) { - /* XXX What do we do now ? */ - } - if (state1->overtemp) - state0->overtemp++; - - temp_combi = max(temp0, temp1); - power_combi = max(power0, power1); - - /* Check tmax, increment overtemp if we are there. At tmax+8, we go - * full blown immediately and try to trigger a shutdown - */ - if (temp_combi >= ((state0->mpu.tmax + 8) << 16)) { - printk(KERN_WARNING "Warning ! Temperature way above maximum (%d) !\n", - temp_combi >> 16); - state0->overtemp += CPU_MAX_OVERTEMP / 4; - } else if (temp_combi > (state0->mpu.tmax << 16)) { - state0->overtemp++; - printk(KERN_WARNING "Temperature %d above max %d. overtemp %d\n", - temp_combi >> 16, state0->mpu.tmax, state0->overtemp); - } else { - if (state0->overtemp) - printk(KERN_WARNING "Temperature back down to %d\n", - temp_combi >> 16); - state0->overtemp = 0; - } - if (state0->overtemp >= CPU_MAX_OVERTEMP) - critical_state = 1; - if (state0->overtemp > 0) { - state0->rpm = state0->mpu.rmaxn_exhaust_fan; - state0->intake_rpm = intake = state0->mpu.rmaxn_intake_fan; - pump = state0->pump_max; - goto do_set_fans; - } - - /* Do the PID */ - do_cpu_pid(state0, temp_combi, power_combi); - - /* Range check */ - state0->rpm = max(state0->rpm, (int)state0->mpu.rminn_exhaust_fan); - state0->rpm = min(state0->rpm, (int)state0->mpu.rmaxn_exhaust_fan); - - /* Calculate intake fan speed */ - intake = (state0->rpm * CPU_INTAKE_SCALE) >> 16; - intake = max(intake, (int)state0->mpu.rminn_intake_fan); - intake = min(intake, (int)state0->mpu.rmaxn_intake_fan); - state0->intake_rpm = intake; - - /* Calculate pump speed */ - pump = (state0->rpm * state0->pump_max) / - state0->mpu.rmaxn_exhaust_fan; - pump = min(pump, state0->pump_max); - pump = max(pump, state0->pump_min); - - do_set_fans: - /* We copy values from state 0 to state 1 for /sysfs */ - state1->rpm = state0->rpm; - state1->intake_rpm = state0->intake_rpm; - - DBG("** CPU %d RPM: %d Ex, %d, Pump: %d, In, overtemp: %d\n", - state1->index, (int)state1->rpm, intake, pump, state1->overtemp); - - /* We should check for errors, shouldn't we ? But then, what - * do we do once the error occurs ? For FCU notified fan - * failures (-EFAULT) we probably want to notify userland - * some way... - */ - set_rpm_fan(CPUA_INTAKE_FAN_RPM_INDEX, intake); - set_rpm_fan(CPUA_EXHAUST_FAN_RPM_INDEX, state0->rpm); - set_rpm_fan(CPUB_INTAKE_FAN_RPM_INDEX, intake); - set_rpm_fan(CPUB_EXHAUST_FAN_RPM_INDEX, state0->rpm); - - if (fcu_fans[CPUA_PUMP_RPM_INDEX].id != FCU_FAN_ABSENT_ID) - set_rpm_fan(CPUA_PUMP_RPM_INDEX, pump); - if (fcu_fans[CPUB_PUMP_RPM_INDEX].id != FCU_FAN_ABSENT_ID) - set_rpm_fan(CPUB_PUMP_RPM_INDEX, pump); -} - -static void do_monitor_cpu_split(struct cpu_pid_state *state) -{ - s32 temp, power; - int rc, intake; - - /* Read current fan status */ - rc = do_read_one_cpu_values(state, &temp, &power); - if (rc < 0) { - /* XXX What do we do now ? */ - } - - /* Check tmax, increment overtemp if we are there. At tmax+8, we go - * full blown immediately and try to trigger a shutdown - */ - if (temp >= ((state->mpu.tmax + 8) << 16)) { - printk(KERN_WARNING "Warning ! CPU %d temperature way above maximum" - " (%d) !\n", - state->index, temp >> 16); - state->overtemp += CPU_MAX_OVERTEMP / 4; - } else if (temp > (state->mpu.tmax << 16)) { - state->overtemp++; - printk(KERN_WARNING "CPU %d temperature %d above max %d. overtemp %d\n", - state->index, temp >> 16, state->mpu.tmax, state->overtemp); - } else { - if (state->overtemp) - printk(KERN_WARNING "CPU %d temperature back down to %d\n", - state->index, temp >> 16); - state->overtemp = 0; - } - if (state->overtemp >= CPU_MAX_OVERTEMP) - critical_state = 1; - if (state->overtemp > 0) { - state->rpm = state->mpu.rmaxn_exhaust_fan; - state->intake_rpm = intake = state->mpu.rmaxn_intake_fan; - goto do_set_fans; - } - - /* Do the PID */ - do_cpu_pid(state, temp, power); - - /* Range check */ - state->rpm = max(state->rpm, (int)state->mpu.rminn_exhaust_fan); - state->rpm = min(state->rpm, (int)state->mpu.rmaxn_exhaust_fan); - - /* Calculate intake fan */ - intake = (state->rpm * CPU_INTAKE_SCALE) >> 16; - intake = max(intake, (int)state->mpu.rminn_intake_fan); - intake = min(intake, (int)state->mpu.rmaxn_intake_fan); - state->intake_rpm = intake; - - do_set_fans: - DBG("** CPU %d RPM: %d Ex, %d In, overtemp: %d\n", - state->index, (int)state->rpm, intake, state->overtemp); - - /* We should check for errors, shouldn't we ? But then, what - * do we do once the error occurs ? For FCU notified fan - * failures (-EFAULT) we probably want to notify userland - * some way... - */ - if (state->index == 0) { - set_rpm_fan(CPUA_INTAKE_FAN_RPM_INDEX, intake); - set_rpm_fan(CPUA_EXHAUST_FAN_RPM_INDEX, state->rpm); - } else { - set_rpm_fan(CPUB_INTAKE_FAN_RPM_INDEX, intake); - set_rpm_fan(CPUB_EXHAUST_FAN_RPM_INDEX, state->rpm); - } -} - -static void do_monitor_cpu_rack(struct cpu_pid_state *state) -{ - s32 temp, power, fan_min; - int rc; - - /* Read current fan status */ - rc = do_read_one_cpu_values(state, &temp, &power); - if (rc < 0) { - /* XXX What do we do now ? */ - } - - /* Check tmax, increment overtemp if we are there. At tmax+8, we go - * full blown immediately and try to trigger a shutdown - */ - if (temp >= ((state->mpu.tmax + 8) << 16)) { - printk(KERN_WARNING "Warning ! CPU %d temperature way above maximum" - " (%d) !\n", - state->index, temp >> 16); - state->overtemp = CPU_MAX_OVERTEMP / 4; - } else if (temp > (state->mpu.tmax << 16)) { - state->overtemp++; - printk(KERN_WARNING "CPU %d temperature %d above max %d. overtemp %d\n", - state->index, temp >> 16, state->mpu.tmax, state->overtemp); - } else { - if (state->overtemp) - printk(KERN_WARNING "CPU %d temperature back down to %d\n", - state->index, temp >> 16); - state->overtemp = 0; - } - if (state->overtemp >= CPU_MAX_OVERTEMP) - critical_state = 1; - if (state->overtemp > 0) { - state->rpm = state->intake_rpm = state->mpu.rmaxn_intake_fan; - goto do_set_fans; - } - - /* Do the PID */ - do_cpu_pid(state, temp, power); - - /* Check clamp from dimms */ - fan_min = dimm_output_clamp; - fan_min = max(fan_min, (int)state->mpu.rminn_intake_fan); - - DBG(" CPU min mpu = %d, min dimm = %d\n", - state->mpu.rminn_intake_fan, dimm_output_clamp); - - state->rpm = max(state->rpm, (int)fan_min); - state->rpm = min(state->rpm, (int)state->mpu.rmaxn_intake_fan); - state->intake_rpm = state->rpm; - - do_set_fans: - DBG("** CPU %d RPM: %d overtemp: %d\n", - state->index, (int)state->rpm, state->overtemp); - - /* We should check for errors, shouldn't we ? But then, what - * do we do once the error occurs ? For FCU notified fan - * failures (-EFAULT) we probably want to notify userland - * some way... - */ - if (state->index == 0) { - set_rpm_fan(CPU_A1_FAN_RPM_INDEX, state->rpm); - set_rpm_fan(CPU_A2_FAN_RPM_INDEX, state->rpm); - set_rpm_fan(CPU_A3_FAN_RPM_INDEX, state->rpm); - } else { - set_rpm_fan(CPU_B1_FAN_RPM_INDEX, state->rpm); - set_rpm_fan(CPU_B2_FAN_RPM_INDEX, state->rpm); - set_rpm_fan(CPU_B3_FAN_RPM_INDEX, state->rpm); - } -} - -/* - * Initialize the state structure for one CPU control loop - */ -static int init_processor_state(struct cpu_pid_state *state, int index) -{ - int err; - - state->index = index; - state->first = 1; - state->rpm = (cpu_pid_type == CPU_PID_TYPE_RACKMAC) ? 4000 : 1000; - state->overtemp = 0; - state->adc_config = 0x00; - - - if (index == 0) - state->monitor = attach_i2c_chip(SUPPLY_MONITOR_ID, "CPU0_monitor"); - else if (index == 1) - state->monitor = attach_i2c_chip(SUPPLY_MONITORB_ID, "CPU1_monitor"); - if (state->monitor == NULL) - goto fail; - - if (read_eeprom(index, &state->mpu)) - goto fail; - - state->count_power = state->mpu.tguardband; - if (state->count_power > CPU_POWER_HISTORY_SIZE) { - printk(KERN_WARNING "Warning ! too many power history slots\n"); - state->count_power = CPU_POWER_HISTORY_SIZE; - } - DBG("CPU %d Using %d power history entries\n", index, state->count_power); - - if (index == 0) { - err = device_create_file(&of_dev->dev, &dev_attr_cpu0_temperature); - err |= device_create_file(&of_dev->dev, &dev_attr_cpu0_voltage); - err |= device_create_file(&of_dev->dev, &dev_attr_cpu0_current); - err |= device_create_file(&of_dev->dev, &dev_attr_cpu0_exhaust_fan_rpm); - err |= device_create_file(&of_dev->dev, &dev_attr_cpu0_intake_fan_rpm); - } else { - err = device_create_file(&of_dev->dev, &dev_attr_cpu1_temperature); - err |= device_create_file(&of_dev->dev, &dev_attr_cpu1_voltage); - err |= device_create_file(&of_dev->dev, &dev_attr_cpu1_current); - err |= device_create_file(&of_dev->dev, &dev_attr_cpu1_exhaust_fan_rpm); - err |= device_create_file(&of_dev->dev, &dev_attr_cpu1_intake_fan_rpm); - } - if (err) - printk(KERN_WARNING "Failed to create some of the attribute" - "files for CPU %d\n", index); - - return 0; - fail: - state->monitor = NULL; - - return -ENODEV; -} - -/* - * Dispose of the state data for one CPU control loop - */ -static void dispose_processor_state(struct cpu_pid_state *state) -{ - if (state->monitor == NULL) - return; - - if (state->index == 0) { - device_remove_file(&of_dev->dev, &dev_attr_cpu0_temperature); - device_remove_file(&of_dev->dev, &dev_attr_cpu0_voltage); - device_remove_file(&of_dev->dev, &dev_attr_cpu0_current); - device_remove_file(&of_dev->dev, &dev_attr_cpu0_exhaust_fan_rpm); - device_remove_file(&of_dev->dev, &dev_attr_cpu0_intake_fan_rpm); - } else { - device_remove_file(&of_dev->dev, &dev_attr_cpu1_temperature); - device_remove_file(&of_dev->dev, &dev_attr_cpu1_voltage); - device_remove_file(&of_dev->dev, &dev_attr_cpu1_current); - device_remove_file(&of_dev->dev, &dev_attr_cpu1_exhaust_fan_rpm); - device_remove_file(&of_dev->dev, &dev_attr_cpu1_intake_fan_rpm); - } - - state->monitor = NULL; -} - -/* - * Motherboard backside & U3 heatsink fan control loop - */ -static void do_monitor_backside(struct backside_pid_state *state) -{ - s32 temp, integral, derivative, fan_min; - s64 integ_p, deriv_p, prop_p, sum; - int i, rc; - - if (--state->ticks != 0) - return; - state->ticks = backside_params.interval; - - DBG("backside:\n"); - - /* Check fan status */ - rc = get_pwm_fan(BACKSIDE_FAN_PWM_INDEX); - if (rc < 0) { - printk(KERN_WARNING "Error %d reading backside fan !\n", rc); - /* XXX What do we do now ? */ - } else - state->pwm = rc; - DBG(" current pwm: %d\n", state->pwm); - - /* Get some sensor readings */ - temp = i2c_smbus_read_byte_data(state->monitor, MAX6690_EXT_TEMP) << 16; - state->last_temp = temp; - DBG(" temp: %d.%03d, target: %d.%03d\n", FIX32TOPRINT(temp), - FIX32TOPRINT(backside_params.input_target)); - - /* Store temperature and error in history array */ - state->cur_sample = (state->cur_sample + 1) % BACKSIDE_PID_HISTORY_SIZE; - state->sample_history[state->cur_sample] = temp; - state->error_history[state->cur_sample] = temp - backside_params.input_target; - - /* If first loop, fill the history table */ - if (state->first) { - for (i = 0; i < (BACKSIDE_PID_HISTORY_SIZE - 1); i++) { - state->cur_sample = (state->cur_sample + 1) % - BACKSIDE_PID_HISTORY_SIZE; - state->sample_history[state->cur_sample] = temp; - state->error_history[state->cur_sample] = - temp - backside_params.input_target; - } - state->first = 0; - } - - /* Calculate the integral term */ - sum = 0; - integral = 0; - for (i = 0; i < BACKSIDE_PID_HISTORY_SIZE; i++) - integral += state->error_history[i]; - integral *= backside_params.interval; - DBG(" integral: %08x\n", integral); - integ_p = ((s64)backside_params.G_r) * (s64)integral; - DBG(" integ_p: %d\n", (int)(integ_p >> 36)); - sum += integ_p; - - /* Calculate the derivative term */ - derivative = state->error_history[state->cur_sample] - - state->error_history[(state->cur_sample + BACKSIDE_PID_HISTORY_SIZE - 1) - % BACKSIDE_PID_HISTORY_SIZE]; - derivative /= backside_params.interval; - deriv_p = ((s64)backside_params.G_d) * (s64)derivative; - DBG(" deriv_p: %d\n", (int)(deriv_p >> 36)); - sum += deriv_p; - - /* Calculate the proportional term */ - prop_p = ((s64)backside_params.G_p) * (s64)(state->error_history[state->cur_sample]); - DBG(" prop_p: %d\n", (int)(prop_p >> 36)); - sum += prop_p; - - /* Scale sum */ - sum >>= 36; - - DBG(" sum: %d\n", (int)sum); - if (backside_params.additive) - state->pwm += (s32)sum; - else - state->pwm = sum; - - /* Check for clamp */ - fan_min = (dimm_output_clamp * 100) / 14000; - fan_min = max(fan_min, backside_params.output_min); - - state->pwm = max(state->pwm, fan_min); - state->pwm = min(state->pwm, backside_params.output_max); - - DBG("** BACKSIDE PWM: %d\n", (int)state->pwm); - set_pwm_fan(BACKSIDE_FAN_PWM_INDEX, state->pwm); -} - -/* - * Initialize the state structure for the backside fan control loop - */ -static int init_backside_state(struct backside_pid_state *state) -{ - struct device_node *u3; - int u3h = 1; /* conservative by default */ - int err; - - /* - * There are different PID params for machines with U3 and machines - * with U3H, pick the right ones now - */ - u3 = of_find_node_by_path("/u3@0,f8000000"); - if (u3 != NULL) { - const u32 *vers = of_get_property(u3, "device-rev", NULL); - if (vers) - if (((*vers) & 0x3f) < 0x34) - u3h = 0; - of_node_put(u3); - } - - if (rackmac) { - backside_params.G_d = BACKSIDE_PID_RACK_G_d; - backside_params.input_target = BACKSIDE_PID_RACK_INPUT_TARGET; - backside_params.output_min = BACKSIDE_PID_U3H_OUTPUT_MIN; - backside_params.interval = BACKSIDE_PID_RACK_INTERVAL; - backside_params.G_p = BACKSIDE_PID_RACK_G_p; - backside_params.G_r = BACKSIDE_PID_G_r; - backside_params.output_max = BACKSIDE_PID_OUTPUT_MAX; - backside_params.additive = 0; - } else if (u3h) { - backside_params.G_d = BACKSIDE_PID_U3H_G_d; - backside_params.input_target = BACKSIDE_PID_U3H_INPUT_TARGET; - backside_params.output_min = BACKSIDE_PID_U3H_OUTPUT_MIN; - backside_params.interval = BACKSIDE_PID_INTERVAL; - backside_params.G_p = BACKSIDE_PID_G_p; - backside_params.G_r = BACKSIDE_PID_G_r; - backside_params.output_max = BACKSIDE_PID_OUTPUT_MAX; - backside_params.additive = 1; - } else { - backside_params.G_d = BACKSIDE_PID_U3_G_d; - backside_params.input_target = BACKSIDE_PID_U3_INPUT_TARGET; - backside_params.output_min = BACKSIDE_PID_U3_OUTPUT_MIN; - backside_params.interval = BACKSIDE_PID_INTERVAL; - backside_params.G_p = BACKSIDE_PID_G_p; - backside_params.G_r = BACKSIDE_PID_G_r; - backside_params.output_max = BACKSIDE_PID_OUTPUT_MAX; - backside_params.additive = 1; - } - - state->ticks = 1; - state->first = 1; - state->pwm = 50; - - state->monitor = attach_i2c_chip(BACKSIDE_MAX_ID, "backside_temp"); - if (state->monitor == NULL) - return -ENODEV; - - err = device_create_file(&of_dev->dev, &dev_attr_backside_temperature); - err |= device_create_file(&of_dev->dev, &dev_attr_backside_fan_pwm); - if (err) - printk(KERN_WARNING "Failed to create attribute file(s)" - " for backside fan\n"); - - return 0; -} - -/* - * Dispose of the state data for the backside control loop - */ -static void dispose_backside_state(struct backside_pid_state *state) -{ - if (state->monitor == NULL) - return; - - device_remove_file(&of_dev->dev, &dev_attr_backside_temperature); - device_remove_file(&of_dev->dev, &dev_attr_backside_fan_pwm); - - state->monitor = NULL; -} - -/* - * Drives bay fan control loop - */ -static void do_monitor_drives(struct drives_pid_state *state) -{ - s32 temp, integral, derivative; - s64 integ_p, deriv_p, prop_p, sum; - int i, rc; - - if (--state->ticks != 0) - return; - state->ticks = DRIVES_PID_INTERVAL; - - DBG("drives:\n"); - - /* Check fan status */ - rc = get_rpm_fan(DRIVES_FAN_RPM_INDEX, !RPM_PID_USE_ACTUAL_SPEED); - if (rc < 0) { - printk(KERN_WARNING "Error %d reading drives fan !\n", rc); - /* XXX What do we do now ? */ - } else - state->rpm = rc; - DBG(" current rpm: %d\n", state->rpm); - - /* Get some sensor readings */ - temp = le16_to_cpu(i2c_smbus_read_word_data(state->monitor, - DS1775_TEMP)) << 8; - state->last_temp = temp; - DBG(" temp: %d.%03d, target: %d.%03d\n", FIX32TOPRINT(temp), - FIX32TOPRINT(DRIVES_PID_INPUT_TARGET)); - - /* Store temperature and error in history array */ - state->cur_sample = (state->cur_sample + 1) % DRIVES_PID_HISTORY_SIZE; - state->sample_history[state->cur_sample] = temp; - state->error_history[state->cur_sample] = temp - DRIVES_PID_INPUT_TARGET; - - /* If first loop, fill the history table */ - if (state->first) { - for (i = 0; i < (DRIVES_PID_HISTORY_SIZE - 1); i++) { - state->cur_sample = (state->cur_sample + 1) % - DRIVES_PID_HISTORY_SIZE; - state->sample_history[state->cur_sample] = temp; - state->error_history[state->cur_sample] = - temp - DRIVES_PID_INPUT_TARGET; - } - state->first = 0; - } - - /* Calculate the integral term */ - sum = 0; - integral = 0; - for (i = 0; i < DRIVES_PID_HISTORY_SIZE; i++) - integral += state->error_history[i]; - integral *= DRIVES_PID_INTERVAL; - DBG(" integral: %08x\n", integral); - integ_p = ((s64)DRIVES_PID_G_r) * (s64)integral; - DBG(" integ_p: %d\n", (int)(integ_p >> 36)); - sum += integ_p; - - /* Calculate the derivative term */ - derivative = state->error_history[state->cur_sample] - - state->error_history[(state->cur_sample + DRIVES_PID_HISTORY_SIZE - 1) - % DRIVES_PID_HISTORY_SIZE]; - derivative /= DRIVES_PID_INTERVAL; - deriv_p = ((s64)DRIVES_PID_G_d) * (s64)derivative; - DBG(" deriv_p: %d\n", (int)(deriv_p >> 36)); - sum += deriv_p; - - /* Calculate the proportional term */ - prop_p = ((s64)DRIVES_PID_G_p) * (s64)(state->error_history[state->cur_sample]); - DBG(" prop_p: %d\n", (int)(prop_p >> 36)); - sum += prop_p; - - /* Scale sum */ - sum >>= 36; - - DBG(" sum: %d\n", (int)sum); - state->rpm += (s32)sum; - - state->rpm = max(state->rpm, DRIVES_PID_OUTPUT_MIN); - state->rpm = min(state->rpm, DRIVES_PID_OUTPUT_MAX); - - DBG("** DRIVES RPM: %d\n", (int)state->rpm); - set_rpm_fan(DRIVES_FAN_RPM_INDEX, state->rpm); -} - -/* - * Initialize the state structure for the drives bay fan control loop - */ -static int init_drives_state(struct drives_pid_state *state) -{ - int err; - - state->ticks = 1; - state->first = 1; - state->rpm = 1000; - - state->monitor = attach_i2c_chip(DRIVES_DALLAS_ID, "drives_temp"); - if (state->monitor == NULL) - return -ENODEV; - - err = device_create_file(&of_dev->dev, &dev_attr_drives_temperature); - err |= device_create_file(&of_dev->dev, &dev_attr_drives_fan_rpm); - if (err) - printk(KERN_WARNING "Failed to create attribute file(s)" - " for drives bay fan\n"); - - return 0; -} - -/* - * Dispose of the state data for the drives control loop - */ -static void dispose_drives_state(struct drives_pid_state *state) -{ - if (state->monitor == NULL) - return; - - device_remove_file(&of_dev->dev, &dev_attr_drives_temperature); - device_remove_file(&of_dev->dev, &dev_attr_drives_fan_rpm); - - state->monitor = NULL; -} - -/* - * DIMMs temp control loop - */ -static void do_monitor_dimms(struct dimm_pid_state *state) -{ - s32 temp, integral, derivative, fan_min; - s64 integ_p, deriv_p, prop_p, sum; - int i; - - if (--state->ticks != 0) - return; - state->ticks = DIMM_PID_INTERVAL; - - DBG("DIMM:\n"); - - DBG(" current value: %d\n", state->output); - - temp = read_lm87_reg(state->monitor, LM87_INT_TEMP); - if (temp < 0) - return; - temp <<= 16; - state->last_temp = temp; - DBG(" temp: %d.%03d, target: %d.%03d\n", FIX32TOPRINT(temp), - FIX32TOPRINT(DIMM_PID_INPUT_TARGET)); - - /* Store temperature and error in history array */ - state->cur_sample = (state->cur_sample + 1) % DIMM_PID_HISTORY_SIZE; - state->sample_history[state->cur_sample] = temp; - state->error_history[state->cur_sample] = temp - DIMM_PID_INPUT_TARGET; - - /* If first loop, fill the history table */ - if (state->first) { - for (i = 0; i < (DIMM_PID_HISTORY_SIZE - 1); i++) { - state->cur_sample = (state->cur_sample + 1) % - DIMM_PID_HISTORY_SIZE; - state->sample_history[state->cur_sample] = temp; - state->error_history[state->cur_sample] = - temp - DIMM_PID_INPUT_TARGET; - } - state->first = 0; - } - - /* Calculate the integral term */ - sum = 0; - integral = 0; - for (i = 0; i < DIMM_PID_HISTORY_SIZE; i++) - integral += state->error_history[i]; - integral *= DIMM_PID_INTERVAL; - DBG(" integral: %08x\n", integral); - integ_p = ((s64)DIMM_PID_G_r) * (s64)integral; - DBG(" integ_p: %d\n", (int)(integ_p >> 36)); - sum += integ_p; - - /* Calculate the derivative term */ - derivative = state->error_history[state->cur_sample] - - state->error_history[(state->cur_sample + DIMM_PID_HISTORY_SIZE - 1) - % DIMM_PID_HISTORY_SIZE]; - derivative /= DIMM_PID_INTERVAL; - deriv_p = ((s64)DIMM_PID_G_d) * (s64)derivative; - DBG(" deriv_p: %d\n", (int)(deriv_p >> 36)); - sum += deriv_p; - - /* Calculate the proportional term */ - prop_p = ((s64)DIMM_PID_G_p) * (s64)(state->error_history[state->cur_sample]); - DBG(" prop_p: %d\n", (int)(prop_p >> 36)); - sum += prop_p; - - /* Scale sum */ - sum >>= 36; - - DBG(" sum: %d\n", (int)sum); - state->output = (s32)sum; - state->output = max(state->output, DIMM_PID_OUTPUT_MIN); - state->output = min(state->output, DIMM_PID_OUTPUT_MAX); - dimm_output_clamp = state->output; - - DBG("** DIMM clamp value: %d\n", (int)state->output); - - /* Backside PID is only every 5 seconds, force backside fan clamping now */ - fan_min = (dimm_output_clamp * 100) / 14000; - fan_min = max(fan_min, backside_params.output_min); - if (backside_state.pwm < fan_min) { - backside_state.pwm = fan_min; - DBG(" -> applying clamp to backside fan now: %d !\n", fan_min); - set_pwm_fan(BACKSIDE_FAN_PWM_INDEX, fan_min); - } -} - -/* - * Initialize the state structure for the DIMM temp control loop - */ -static int init_dimms_state(struct dimm_pid_state *state) -{ - state->ticks = 1; - state->first = 1; - state->output = 4000; - - state->monitor = attach_i2c_chip(XSERVE_DIMMS_LM87, "dimms_temp"); - if (state->monitor == NULL) - return -ENODEV; - - if (device_create_file(&of_dev->dev, &dev_attr_dimms_temperature)) - printk(KERN_WARNING "Failed to create attribute file" - " for DIMM temperature\n"); - - return 0; -} - -/* - * Dispose of the state data for the DIMM control loop - */ -static void dispose_dimms_state(struct dimm_pid_state *state) -{ - if (state->monitor == NULL) - return; - - device_remove_file(&of_dev->dev, &dev_attr_dimms_temperature); - - state->monitor = NULL; -} - -/* - * Slots fan control loop - */ -static void do_monitor_slots(struct slots_pid_state *state) -{ - s32 temp, integral, derivative; - s64 integ_p, deriv_p, prop_p, sum; - int i, rc; - - if (--state->ticks != 0) - return; - state->ticks = SLOTS_PID_INTERVAL; - - DBG("slots:\n"); - - /* Check fan status */ - rc = get_pwm_fan(SLOTS_FAN_PWM_INDEX); - if (rc < 0) { - printk(KERN_WARNING "Error %d reading slots fan !\n", rc); - /* XXX What do we do now ? */ - } else - state->pwm = rc; - DBG(" current pwm: %d\n", state->pwm); - - /* Get some sensor readings */ - temp = le16_to_cpu(i2c_smbus_read_word_data(state->monitor, - DS1775_TEMP)) << 8; - state->last_temp = temp; - DBG(" temp: %d.%03d, target: %d.%03d\n", FIX32TOPRINT(temp), - FIX32TOPRINT(SLOTS_PID_INPUT_TARGET)); - - /* Store temperature and error in history array */ - state->cur_sample = (state->cur_sample + 1) % SLOTS_PID_HISTORY_SIZE; - state->sample_history[state->cur_sample] = temp; - state->error_history[state->cur_sample] = temp - SLOTS_PID_INPUT_TARGET; - - /* If first loop, fill the history table */ - if (state->first) { - for (i = 0; i < (SLOTS_PID_HISTORY_SIZE - 1); i++) { - state->cur_sample = (state->cur_sample + 1) % - SLOTS_PID_HISTORY_SIZE; - state->sample_history[state->cur_sample] = temp; - state->error_history[state->cur_sample] = - temp - SLOTS_PID_INPUT_TARGET; - } - state->first = 0; - } - - /* Calculate the integral term */ - sum = 0; - integral = 0; - for (i = 0; i < SLOTS_PID_HISTORY_SIZE; i++) - integral += state->error_history[i]; - integral *= SLOTS_PID_INTERVAL; - DBG(" integral: %08x\n", integral); - integ_p = ((s64)SLOTS_PID_G_r) * (s64)integral; - DBG(" integ_p: %d\n", (int)(integ_p >> 36)); - sum += integ_p; - - /* Calculate the derivative term */ - derivative = state->error_history[state->cur_sample] - - state->error_history[(state->cur_sample + SLOTS_PID_HISTORY_SIZE - 1) - % SLOTS_PID_HISTORY_SIZE]; - derivative /= SLOTS_PID_INTERVAL; - deriv_p = ((s64)SLOTS_PID_G_d) * (s64)derivative; - DBG(" deriv_p: %d\n", (int)(deriv_p >> 36)); - sum += deriv_p; - - /* Calculate the proportional term */ - prop_p = ((s64)SLOTS_PID_G_p) * (s64)(state->error_history[state->cur_sample]); - DBG(" prop_p: %d\n", (int)(prop_p >> 36)); - sum += prop_p; - - /* Scale sum */ - sum >>= 36; - - DBG(" sum: %d\n", (int)sum); - state->pwm = (s32)sum; - - state->pwm = max(state->pwm, SLOTS_PID_OUTPUT_MIN); - state->pwm = min(state->pwm, SLOTS_PID_OUTPUT_MAX); - - DBG("** DRIVES PWM: %d\n", (int)state->pwm); - set_pwm_fan(SLOTS_FAN_PWM_INDEX, state->pwm); -} - -/* - * Initialize the state structure for the slots bay fan control loop - */ -static int init_slots_state(struct slots_pid_state *state) -{ - int err; - - state->ticks = 1; - state->first = 1; - state->pwm = 50; - - state->monitor = attach_i2c_chip(XSERVE_SLOTS_LM75, "slots_temp"); - if (state->monitor == NULL) - return -ENODEV; - - err = device_create_file(&of_dev->dev, &dev_attr_slots_temperature); - err |= device_create_file(&of_dev->dev, &dev_attr_slots_fan_pwm); - if (err) - printk(KERN_WARNING "Failed to create attribute file(s)" - " for slots bay fan\n"); - - return 0; -} - -/* - * Dispose of the state data for the slots control loop - */ -static void dispose_slots_state(struct slots_pid_state *state) -{ - if (state->monitor == NULL) - return; - - device_remove_file(&of_dev->dev, &dev_attr_slots_temperature); - device_remove_file(&of_dev->dev, &dev_attr_slots_fan_pwm); - - state->monitor = NULL; -} - - -static int call_critical_overtemp(void) -{ - char *argv[] = { critical_overtemp_path, NULL }; - static char *envp[] = { "HOME=/", - "TERM=linux", - "PATH=/sbin:/usr/sbin:/bin:/usr/bin", - NULL }; - - return call_usermodehelper(critical_overtemp_path, - argv, envp, UMH_WAIT_EXEC); -} - - -/* - * Here's the kernel thread that calls the various control loops - */ -static int main_control_loop(void *x) -{ - DBG("main_control_loop started\n"); - - mutex_lock(&driver_lock); - - if (start_fcu() < 0) { - printk(KERN_ERR "kfand: failed to start FCU\n"); - mutex_unlock(&driver_lock); - goto out; - } - - /* Set the PCI fan once for now on non-RackMac */ - if (!rackmac) - set_pwm_fan(SLOTS_FAN_PWM_INDEX, SLOTS_FAN_DEFAULT_PWM); - - /* Initialize ADCs */ - initialize_adc(&processor_state[0]); - if (processor_state[1].monitor != NULL) - initialize_adc(&processor_state[1]); - - fcu_tickle_ticks = FCU_TICKLE_TICKS; - - mutex_unlock(&driver_lock); - - while (state == state_attached) { - unsigned long elapsed, start; - - start = jiffies; - - mutex_lock(&driver_lock); - - /* Tickle the FCU just in case */ - if (--fcu_tickle_ticks < 0) { - fcu_tickle_ticks = FCU_TICKLE_TICKS; - tickle_fcu(); - } - - /* First, we always calculate the new DIMMs state on an Xserve */ - if (rackmac) - do_monitor_dimms(&dimms_state); - - /* Then, the CPUs */ - if (cpu_pid_type == CPU_PID_TYPE_COMBINED) - do_monitor_cpu_combined(); - else if (cpu_pid_type == CPU_PID_TYPE_RACKMAC) { - do_monitor_cpu_rack(&processor_state[0]); - if (processor_state[1].monitor != NULL) - do_monitor_cpu_rack(&processor_state[1]); - // better deal with UP - } else { - do_monitor_cpu_split(&processor_state[0]); - if (processor_state[1].monitor != NULL) - do_monitor_cpu_split(&processor_state[1]); - // better deal with UP - } - /* Then, the rest */ - do_monitor_backside(&backside_state); - if (rackmac) - do_monitor_slots(&slots_state); - else - do_monitor_drives(&drives_state); - mutex_unlock(&driver_lock); - - if (critical_state == 1) { - printk(KERN_WARNING "Temperature control detected a critical condition\n"); - printk(KERN_WARNING "Attempting to shut down...\n"); - if (call_critical_overtemp()) { - printk(KERN_WARNING "Can't call %s, power off now!\n", - critical_overtemp_path); - machine_power_off(); - } - } - if (critical_state > 0) - critical_state++; - if (critical_state > MAX_CRITICAL_STATE) { - printk(KERN_WARNING "Shutdown timed out, power off now !\n"); - machine_power_off(); - } - - // FIXME: Deal with signals - elapsed = jiffies - start; - if (elapsed < HZ) - schedule_timeout_interruptible(HZ - elapsed); - } - - out: - DBG("main_control_loop ended\n"); - - ctrl_task = 0; - complete_and_exit(&ctrl_complete, 0); -} - -/* - * Dispose the control loops when tearing down - */ -static void dispose_control_loops(void) -{ - dispose_processor_state(&processor_state[0]); - dispose_processor_state(&processor_state[1]); - dispose_backside_state(&backside_state); - dispose_drives_state(&drives_state); - dispose_slots_state(&slots_state); - dispose_dimms_state(&dimms_state); -} - -/* - * Create the control loops. U3-0 i2c bus is up, so we can now - * get to the various sensors - */ -static int create_control_loops(void) -{ - struct device_node *np; - - /* Count CPUs from the device-tree, we don't care how many are - * actually used by Linux - */ - cpu_count = 0; - for (np = NULL; NULL != (np = of_find_node_by_type(np, "cpu"));) - cpu_count++; - - DBG("counted %d CPUs in the device-tree\n", cpu_count); - - /* Decide the type of PID algorithm to use based on the presence of - * the pumps, though that may not be the best way, that is good enough - * for now - */ - if (rackmac) - cpu_pid_type = CPU_PID_TYPE_RACKMAC; - else if (of_machine_is_compatible("PowerMac7,3") - && (cpu_count > 1) - && fcu_fans[CPUA_PUMP_RPM_INDEX].id != FCU_FAN_ABSENT_ID - && fcu_fans[CPUB_PUMP_RPM_INDEX].id != FCU_FAN_ABSENT_ID) { - printk(KERN_INFO "Liquid cooling pumps detected, using new algorithm !\n"); - cpu_pid_type = CPU_PID_TYPE_COMBINED; - } else - cpu_pid_type = CPU_PID_TYPE_SPLIT; - - /* Create control loops for everything. If any fail, everything - * fails - */ - if (init_processor_state(&processor_state[0], 0)) - goto fail; - if (cpu_pid_type == CPU_PID_TYPE_COMBINED) - fetch_cpu_pumps_minmax(); - - if (cpu_count > 1 && init_processor_state(&processor_state[1], 1)) - goto fail; - if (init_backside_state(&backside_state)) - goto fail; - if (rackmac && init_dimms_state(&dimms_state)) - goto fail; - if (rackmac && init_slots_state(&slots_state)) - goto fail; - if (!rackmac && init_drives_state(&drives_state)) - goto fail; - - DBG("all control loops up !\n"); - - return 0; - - fail: - DBG("failure creating control loops, disposing\n"); - - dispose_control_loops(); - - return -ENODEV; -} - -/* - * Start the control loops after everything is up, that is create - * the thread that will make them run - */ -static void start_control_loops(void) -{ - init_completion(&ctrl_complete); - - ctrl_task = kthread_run(main_control_loop, NULL, "kfand"); -} - -/* - * Stop the control loops when tearing down - */ -static void stop_control_loops(void) -{ - if (ctrl_task) - wait_for_completion(&ctrl_complete); -} - -/* - * Attach to the i2c FCU after detecting U3-1 bus - */ -static int attach_fcu(void) -{ - fcu = attach_i2c_chip(FAN_CTRLER_ID, "fcu"); - if (fcu == NULL) - return -ENODEV; - - DBG("FCU attached\n"); - - return 0; -} - -/* - * Detach from the i2c FCU when tearing down - */ -static void detach_fcu(void) -{ - fcu = NULL; -} - -/* - * Attach to the i2c controller. We probe the various chips based - * on the device-tree nodes and build everything for the driver to - * run, we then kick the driver monitoring thread - */ -static int therm_pm72_attach(struct i2c_adapter *adapter) -{ - mutex_lock(&driver_lock); - - /* Check state */ - if (state == state_detached) - state = state_attaching; - if (state != state_attaching) { - mutex_unlock(&driver_lock); - return 0; - } - - /* Check if we are looking for one of these */ - if (u3_0 == NULL && !strcmp(adapter->name, "u3 0")) { - u3_0 = adapter; - DBG("found U3-0\n"); - if (k2 || !rackmac) - if (create_control_loops()) - u3_0 = NULL; - } else if (u3_1 == NULL && !strcmp(adapter->name, "u3 1")) { - u3_1 = adapter; - DBG("found U3-1, attaching FCU\n"); - if (attach_fcu()) - u3_1 = NULL; - } else if (k2 == NULL && !strcmp(adapter->name, "mac-io 0")) { - k2 = adapter; - DBG("Found K2\n"); - if (u3_0 && rackmac) - if (create_control_loops()) - k2 = NULL; - } - /* We got all we need, start control loops */ - if (u3_0 != NULL && u3_1 != NULL && (k2 || !rackmac)) { - DBG("everything up, starting control loops\n"); - state = state_attached; - start_control_loops(); - } - mutex_unlock(&driver_lock); - - return 0; -} - -static int therm_pm72_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - /* Always succeed, the real work was done in therm_pm72_attach() */ - return 0; -} - -/* - * Called when any of the devices which participates into thermal management - * is going away. - */ -static int therm_pm72_remove(struct i2c_client *client) -{ - struct i2c_adapter *adapter = client->adapter; - - mutex_lock(&driver_lock); - - if (state != state_detached) - state = state_detaching; - - /* Stop control loops if any */ - DBG("stopping control loops\n"); - mutex_unlock(&driver_lock); - stop_control_loops(); - mutex_lock(&driver_lock); - - if (u3_0 != NULL && !strcmp(adapter->name, "u3 0")) { - DBG("lost U3-0, disposing control loops\n"); - dispose_control_loops(); - u3_0 = NULL; - } - - if (u3_1 != NULL && !strcmp(adapter->name, "u3 1")) { - DBG("lost U3-1, detaching FCU\n"); - detach_fcu(); - u3_1 = NULL; - } - if (u3_0 == NULL && u3_1 == NULL) - state = state_detached; - - mutex_unlock(&driver_lock); - - return 0; -} - -/* - * i2c_driver structure to attach to the host i2c controller - */ - -static const struct i2c_device_id therm_pm72_id[] = { - /* - * Fake device name, thermal management is done by several - * chips but we don't need to differentiate between them at - * this point. - */ - { "therm_pm72", 0 }, - { } -}; - -static struct i2c_driver therm_pm72_driver = { - .driver = { - .name = "therm_pm72", - }, - .attach_adapter = therm_pm72_attach, - .probe = therm_pm72_probe, - .remove = therm_pm72_remove, - .id_table = therm_pm72_id, -}; - -static int fan_check_loc_match(const char *loc, int fan) -{ - char tmp[64]; - char *c, *e; - - strlcpy(tmp, fcu_fans[fan].loc, 64); - - c = tmp; - for (;;) { - e = strchr(c, ','); - if (e) - *e = 0; - if (strcmp(loc, c) == 0) - return 1; - if (e == NULL) - break; - c = e + 1; - } - return 0; -} - -static void fcu_lookup_fans(struct device_node *fcu_node) -{ - struct device_node *np = NULL; - int i; - - /* The table is filled by default with values that are suitable - * for the old machines without device-tree informations. We scan - * the device-tree and override those values with whatever is - * there - */ - - DBG("Looking up FCU controls in device-tree...\n"); - - while ((np = of_get_next_child(fcu_node, np)) != NULL) { - int type = -1; - const char *loc; - const u32 *reg; - - DBG(" control: %s, type: %s\n", np->name, np->type); - - /* Detect control type */ - if (!strcmp(np->type, "fan-rpm-control") || - !strcmp(np->type, "fan-rpm")) - type = FCU_FAN_RPM; - if (!strcmp(np->type, "fan-pwm-control") || - !strcmp(np->type, "fan-pwm")) - type = FCU_FAN_PWM; - /* Only care about fans for now */ - if (type == -1) - continue; - - /* Lookup for a matching location */ - loc = of_get_property(np, "location", NULL); - reg = of_get_property(np, "reg", NULL); - if (loc == NULL || reg == NULL) - continue; - DBG(" matching location: %s, reg: 0x%08x\n", loc, *reg); - - for (i = 0; i < FCU_FAN_COUNT; i++) { - int fan_id; - - if (!fan_check_loc_match(loc, i)) - continue; - DBG(" location match, index: %d\n", i); - fcu_fans[i].id = FCU_FAN_ABSENT_ID; - if (type != fcu_fans[i].type) { - printk(KERN_WARNING "therm_pm72: Fan type mismatch " - "in device-tree for %s\n", np->full_name); - break; - } - if (type == FCU_FAN_RPM) - fan_id = ((*reg) - 0x10) / 2; - else - fan_id = ((*reg) - 0x30) / 2; - if (fan_id > 7) { - printk(KERN_WARNING "therm_pm72: Can't parse " - "fan ID in device-tree for %s\n", np->full_name); - break; - } - DBG(" fan id -> %d, type -> %d\n", fan_id, type); - fcu_fans[i].id = fan_id; - } - } - - /* Now dump the array */ - printk(KERN_INFO "Detected fan controls:\n"); - for (i = 0; i < FCU_FAN_COUNT; i++) { - if (fcu_fans[i].id == FCU_FAN_ABSENT_ID) - continue; - printk(KERN_INFO " %d: %s fan, id %d, location: %s\n", i, - fcu_fans[i].type == FCU_FAN_RPM ? "RPM" : "PWM", - fcu_fans[i].id, fcu_fans[i].loc); - } -} - -static int fcu_of_probe(struct platform_device* dev) -{ - state = state_detached; - of_dev = dev; - - dev_info(&dev->dev, "PowerMac G5 Thermal control driver %s\n", VERSION); - - /* Lookup the fans in the device tree */ - fcu_lookup_fans(dev->dev.of_node); - - /* Add the driver */ - return i2c_add_driver(&therm_pm72_driver); -} - -static int fcu_of_remove(struct platform_device* dev) -{ - i2c_del_driver(&therm_pm72_driver); - - return 0; -} - -static const struct of_device_id fcu_match[] = -{ - { - .type = "fcu", - }, - {}, -}; -MODULE_DEVICE_TABLE(of, fcu_match); - -static struct platform_driver fcu_of_platform_driver = -{ - .driver = { - .name = "temperature", - .of_match_table = fcu_match, - }, - .probe = fcu_of_probe, - .remove = fcu_of_remove -}; - -/* - * Check machine type, attach to i2c controller - */ -static int __init therm_pm72_init(void) -{ - rackmac = of_machine_is_compatible("RackMac3,1"); - - if (!of_machine_is_compatible("PowerMac7,2") && - !of_machine_is_compatible("PowerMac7,3") && - !rackmac) - return -ENODEV; - - return platform_driver_register(&fcu_of_platform_driver); -} - -static void __exit therm_pm72_exit(void) -{ - platform_driver_unregister(&fcu_of_platform_driver); -} - -module_init(therm_pm72_init); -module_exit(therm_pm72_exit); - -MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); -MODULE_DESCRIPTION("Driver for Apple's PowerMac G5 thermal control"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/macintosh/therm_pm72.h b/drivers/macintosh/therm_pm72.h deleted file mode 100644 index df3680e2a22f..000000000000 --- a/drivers/macintosh/therm_pm72.h +++ /dev/null @@ -1,326 +0,0 @@ -#ifndef __THERM_PMAC_7_2_H__ -#define __THERM_PMAC_7_2_H__ - -typedef unsigned short fu16; -typedef int fs32; -typedef short fs16; - -struct mpu_data -{ - u8 signature; /* 0x00 - EEPROM sig. */ - u8 bytes_used; /* 0x01 - Bytes used in eeprom (160 ?) */ - u8 size; /* 0x02 - EEPROM size (256 ?) */ - u8 version; /* 0x03 - EEPROM version */ - u32 data_revision; /* 0x04 - Dataset revision */ - u8 processor_bin_code[3]; /* 0x08 - Processor BIN code */ - u8 bin_code_expansion; /* 0x0b - ??? (padding ?) */ - u8 processor_num; /* 0x0c - Number of CPUs on this MPU */ - u8 input_mul_bus_div; /* 0x0d - Clock input multiplier/bus divider */ - u8 reserved1[2]; /* 0x0e - */ - u32 input_clk_freq_high; /* 0x10 - Input clock frequency high */ - u8 cpu_nb_target_cycles; /* 0x14 - ??? */ - u8 cpu_statlat; /* 0x15 - ??? */ - u8 cpu_snooplat; /* 0x16 - ??? */ - u8 cpu_snoopacc; /* 0x17 - ??? */ - u8 nb_paamwin; /* 0x18 - ??? */ - u8 nb_statlat; /* 0x19 - ??? */ - u8 nb_snooplat; /* 0x1a - ??? */ - u8 nb_snoopwin; /* 0x1b - ??? */ - u8 api_bus_mode; /* 0x1c - ??? */ - u8 reserved2[3]; /* 0x1d - */ - u32 input_clk_freq_low; /* 0x20 - Input clock frequency low */ - u8 processor_card_slot; /* 0x24 - Processor card slot number */ - u8 reserved3[2]; /* 0x25 - */ - u8 padjmax; /* 0x27 - Max power adjustment (Not in OF!) */ - u8 ttarget; /* 0x28 - Target temperature */ - u8 tmax; /* 0x29 - Max temperature */ - u8 pmaxh; /* 0x2a - Max power */ - u8 tguardband; /* 0x2b - Guardband temp ??? Hist. len in OSX */ - fs32 pid_gp; /* 0x2c - PID proportional gain */ - fs32 pid_gr; /* 0x30 - PID reset gain */ - fs32 pid_gd; /* 0x34 - PID derivative gain */ - fu16 voph; /* 0x38 - Vop High */ - fu16 vopl; /* 0x3a - Vop Low */ - fs16 nactual_die; /* 0x3c - nActual Die */ - fs16 nactual_heatsink; /* 0x3e - nActual Heatsink */ - fs16 nactual_system; /* 0x40 - nActual System */ - u16 calibration_flags; /* 0x42 - Calibration flags */ - fu16 mdiode; /* 0x44 - Diode M value (scaling factor) */ - fs16 bdiode; /* 0x46 - Diode B value (offset) */ - fs32 theta_heat_sink; /* 0x48 - Theta heat sink */ - u16 rminn_intake_fan; /* 0x4c - Intake fan min RPM */ - u16 rmaxn_intake_fan; /* 0x4e - Intake fan max RPM */ - u16 rminn_exhaust_fan; /* 0x50 - Exhaust fan min RPM */ - u16 rmaxn_exhaust_fan; /* 0x52 - Exhaust fan max RPM */ - u8 processor_part_num[8]; /* 0x54 - Processor part number XX pumps min/max */ - u32 processor_lot_num; /* 0x5c - Processor lot number */ - u8 orig_card_sernum[0x10]; /* 0x60 - Card original serial number */ - u8 curr_card_sernum[0x10]; /* 0x70 - Card current serial number */ - u8 mlb_sernum[0x18]; /* 0x80 - MLB serial number */ - u32 checksum1; /* 0x98 - */ - u32 checksum2; /* 0x9c - */ -}; /* Total size = 0xa0 */ - -/* Display a 16.16 fixed point value */ -#define FIX32TOPRINT(f) ((f) >> 16),((((f) & 0xffff) * 1000) >> 16) - -/* - * Maximum number of seconds to be in critical state (after a - * normal shutdown attempt). If the machine isn't down after - * this counter elapses, we force an immediate machine power - * off. - */ -#define MAX_CRITICAL_STATE 30 -static char * critical_overtemp_path = "/sbin/critical_overtemp"; - -/* - * This option is "weird" :) Basically, if you define this to 1 - * the control loop for the RPMs fans (not PWMs) will apply the - * correction factor obtained from the PID to the _actual_ RPM - * speed read from the FCU. - * If you define the below constant to 0, then it will be - * applied to the setpoint RPM speed, that is basically the - * speed we proviously "asked" for. - * - * I'm not sure which of these Apple's algorithm is supposed - * to use - */ -#define RPM_PID_USE_ACTUAL_SPEED 0 - -/* - * i2c IDs. Currently, we hard code those and assume that - * the FCU is on U3 bus 1 while all sensors are on U3 bus - * 0. This appear to be safe enough for this first version - * of the driver, though I would accept any clean patch - * doing a better use of the device-tree without turning the - * while i2c registration mechanism into a racy mess - * - * Note: Xserve changed this. We have some bits on the K2 bus, - * which I arbitrarily set to 0x200. Ultimately, we really want - * too lookup these in the device-tree though - */ -#define FAN_CTRLER_ID 0x15e -#define SUPPLY_MONITOR_ID 0x58 -#define SUPPLY_MONITORB_ID 0x5a -#define DRIVES_DALLAS_ID 0x94 -#define BACKSIDE_MAX_ID 0x98 -#define XSERVE_DIMMS_LM87 0x25a -#define XSERVE_SLOTS_LM75 0x290 - -/* - * Some MAX6690, DS1775, LM87 register definitions - */ -#define MAX6690_INT_TEMP 0 -#define MAX6690_EXT_TEMP 1 -#define DS1775_TEMP 0 -#define LM87_INT_TEMP 0x27 - -/* - * Scaling factors for the AD7417 ADC converters (except - * for the CPU diode which is obtained from the EEPROM). - * Those values are obtained from the property list of - * the darwin driver - */ -#define ADC_12V_CURRENT_SCALE 0x0320 /* _AD2 */ -#define ADC_CPU_VOLTAGE_SCALE 0x00a0 /* _AD3 */ -#define ADC_CPU_CURRENT_SCALE 0x1f40 /* _AD4 */ - -/* - * PID factors for the U3/Backside fan control loop. We have 2 sets - * of values here, one set for U3 and one set for U3H - */ -#define BACKSIDE_FAN_PWM_DEFAULT_ID 1 -#define BACKSIDE_FAN_PWM_INDEX 0 -#define BACKSIDE_PID_U3_G_d 0x02800000 -#define BACKSIDE_PID_U3H_G_d 0x01400000 -#define BACKSIDE_PID_RACK_G_d 0x00500000 -#define BACKSIDE_PID_G_p 0x00500000 -#define BACKSIDE_PID_RACK_G_p 0x0004cccc -#define BACKSIDE_PID_G_r 0x00000000 -#define BACKSIDE_PID_U3_INPUT_TARGET 0x00410000 -#define BACKSIDE_PID_U3H_INPUT_TARGET 0x004b0000 -#define BACKSIDE_PID_RACK_INPUT_TARGET 0x00460000 -#define BACKSIDE_PID_INTERVAL 5 -#define BACKSIDE_PID_RACK_INTERVAL 1 -#define BACKSIDE_PID_OUTPUT_MAX 100 -#define BACKSIDE_PID_U3_OUTPUT_MIN 20 -#define BACKSIDE_PID_U3H_OUTPUT_MIN 20 -#define BACKSIDE_PID_HISTORY_SIZE 2 - -struct basckside_pid_params -{ - s32 G_d; - s32 G_p; - s32 G_r; - s32 input_target; - s32 output_min; - s32 output_max; - s32 interval; - int additive; -}; - -struct backside_pid_state -{ - int ticks; - struct i2c_client * monitor; - s32 sample_history[BACKSIDE_PID_HISTORY_SIZE]; - s32 error_history[BACKSIDE_PID_HISTORY_SIZE]; - int cur_sample; - s32 last_temp; - int pwm; - int first; -}; - -/* - * PID factors for the Drive Bay fan control loop - */ -#define DRIVES_FAN_RPM_DEFAULT_ID 2 -#define DRIVES_FAN_RPM_INDEX 1 -#define DRIVES_PID_G_d 0x01e00000 -#define DRIVES_PID_G_p 0x00500000 -#define DRIVES_PID_G_r 0x00000000 -#define DRIVES_PID_INPUT_TARGET 0x00280000 -#define DRIVES_PID_INTERVAL 5 -#define DRIVES_PID_OUTPUT_MAX 4000 -#define DRIVES_PID_OUTPUT_MIN 300 -#define DRIVES_PID_HISTORY_SIZE 2 - -struct drives_pid_state -{ - int ticks; - struct i2c_client * monitor; - s32 sample_history[BACKSIDE_PID_HISTORY_SIZE]; - s32 error_history[BACKSIDE_PID_HISTORY_SIZE]; - int cur_sample; - s32 last_temp; - int rpm; - int first; -}; - -#define SLOTS_FAN_PWM_DEFAULT_ID 2 -#define SLOTS_FAN_PWM_INDEX 2 -#define SLOTS_FAN_DEFAULT_PWM 40 /* Do better here ! */ - - -/* - * PID factors for the Xserve DIMM control loop - */ -#define DIMM_PID_G_d 0 -#define DIMM_PID_G_p 0 -#define DIMM_PID_G_r 0x06553600 -#define DIMM_PID_INPUT_TARGET 3276800 -#define DIMM_PID_INTERVAL 1 -#define DIMM_PID_OUTPUT_MAX 14000 -#define DIMM_PID_OUTPUT_MIN 4000 -#define DIMM_PID_HISTORY_SIZE 20 - -struct dimm_pid_state -{ - int ticks; - struct i2c_client * monitor; - s32 sample_history[DIMM_PID_HISTORY_SIZE]; - s32 error_history[DIMM_PID_HISTORY_SIZE]; - int cur_sample; - s32 last_temp; - int first; - int output; -}; - - -/* - * PID factors for the Xserve Slots control loop - */ -#define SLOTS_PID_G_d 0 -#define SLOTS_PID_G_p 0 -#define SLOTS_PID_G_r 0x00100000 -#define SLOTS_PID_INPUT_TARGET 3200000 -#define SLOTS_PID_INTERVAL 1 -#define SLOTS_PID_OUTPUT_MAX 100 -#define SLOTS_PID_OUTPUT_MIN 20 -#define SLOTS_PID_HISTORY_SIZE 20 - -struct slots_pid_state -{ - int ticks; - struct i2c_client * monitor; - s32 sample_history[SLOTS_PID_HISTORY_SIZE]; - s32 error_history[SLOTS_PID_HISTORY_SIZE]; - int cur_sample; - s32 last_temp; - int first; - int pwm; -}; - - - -/* Desktops */ - -#define CPUA_INTAKE_FAN_RPM_DEFAULT_ID 3 -#define CPUA_EXHAUST_FAN_RPM_DEFAULT_ID 4 -#define CPUB_INTAKE_FAN_RPM_DEFAULT_ID 5 -#define CPUB_EXHAUST_FAN_RPM_DEFAULT_ID 6 - -#define CPUA_INTAKE_FAN_RPM_INDEX 3 -#define CPUA_EXHAUST_FAN_RPM_INDEX 4 -#define CPUB_INTAKE_FAN_RPM_INDEX 5 -#define CPUB_EXHAUST_FAN_RPM_INDEX 6 - -#define CPU_INTAKE_SCALE 0x0000f852 -#define CPU_TEMP_HISTORY_SIZE 2 -#define CPU_POWER_HISTORY_SIZE 10 -#define CPU_PID_INTERVAL 1 -#define CPU_MAX_OVERTEMP 90 - -#define CPUA_PUMP_RPM_INDEX 7 -#define CPUB_PUMP_RPM_INDEX 8 -#define CPU_PUMP_OUTPUT_MAX 3200 -#define CPU_PUMP_OUTPUT_MIN 1250 - -/* Xserve */ -#define CPU_A1_FAN_RPM_INDEX 9 -#define CPU_A2_FAN_RPM_INDEX 10 -#define CPU_A3_FAN_RPM_INDEX 11 -#define CPU_B1_FAN_RPM_INDEX 12 -#define CPU_B2_FAN_RPM_INDEX 13 -#define CPU_B3_FAN_RPM_INDEX 14 - - -struct cpu_pid_state -{ - int index; - struct i2c_client * monitor; - struct mpu_data mpu; - int overtemp; - s32 temp_history[CPU_TEMP_HISTORY_SIZE]; - int cur_temp; - s32 power_history[CPU_POWER_HISTORY_SIZE]; - s32 error_history[CPU_POWER_HISTORY_SIZE]; - int cur_power; - int count_power; - int rpm; - int intake_rpm; - s32 voltage; - s32 current_a; - s32 last_temp; - s32 last_power; - int first; - u8 adc_config; - s32 pump_min; - s32 pump_max; -}; - -/* Tickle FCU every 10 seconds */ -#define FCU_TICKLE_TICKS 10 - -/* - * Driver state - */ -enum { - state_detached, - state_attaching, - state_attached, - state_detaching, -}; - - -#endif /* __THERM_PMAC_7_2_H__ */ diff --git a/drivers/mcb/mcb-internal.h b/drivers/mcb/mcb-internal.h index f956ef26c0ce..fb7493dcfb79 100644 --- a/drivers/mcb/mcb-internal.h +++ b/drivers/mcb/mcb-internal.h @@ -7,6 +7,7 @@ #define PCI_DEVICE_ID_MEN_CHAMELEON 0x4d45 #define CHAMELEON_FILENAME_LEN 12 #define CHAMELEONV2_MAGIC 0xabce +#define CHAM_HEADER_SIZE 0x200 enum chameleon_descriptor_type { CHAMELEON_DTYPE_GENERAL = 0x0, diff --git a/drivers/mcb/mcb-pci.c b/drivers/mcb/mcb-pci.c index b59181965643..5e1bd5db02c8 100644 --- a/drivers/mcb/mcb-pci.c +++ b/drivers/mcb/mcb-pci.c @@ -17,6 +17,7 @@ struct priv { struct mcb_bus *bus; + phys_addr_t mapbase; void __iomem *base; }; @@ -31,8 +32,8 @@ static int mcb_pci_get_irq(struct mcb_device *mdev) static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { + struct resource *res; struct priv *priv; - phys_addr_t mapbase; int ret; int num_cells; unsigned long flags; @@ -47,19 +48,21 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) return -ENODEV; } - mapbase = pci_resource_start(pdev, 0); - if (!mapbase) { + priv->mapbase = pci_resource_start(pdev, 0); + if (!priv->mapbase) { dev_err(&pdev->dev, "No PCI resource\n"); goto err_start; } - ret = pci_request_region(pdev, 0, KBUILD_MODNAME); - if (ret) { - dev_err(&pdev->dev, "Failed to request PCI BARs\n"); + res = request_mem_region(priv->mapbase, CHAM_HEADER_SIZE, + KBUILD_MODNAME); + if (IS_ERR(res)) { + dev_err(&pdev->dev, "Failed to request PCI memory\n"); + ret = PTR_ERR(res); goto err_start; } - priv->base = pci_iomap(pdev, 0, 0); + priv->base = ioremap(priv->mapbase, CHAM_HEADER_SIZE); if (!priv->base) { dev_err(&pdev->dev, "Cannot ioremap\n"); ret = -ENOMEM; @@ -84,7 +87,7 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) priv->bus->get_irq = mcb_pci_get_irq; - ret = chameleon_parse_cells(priv->bus, mapbase, priv->base); + ret = chameleon_parse_cells(priv->bus, priv->mapbase, priv->base); if (ret < 0) goto err_drvdata; num_cells = ret; @@ -93,8 +96,10 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) mcb_bus_add_devices(priv->bus); + return 0; + err_drvdata: - pci_iounmap(pdev, priv->base); + iounmap(priv->base); err_ioremap: pci_release_region(pdev, 0); err_start: @@ -107,6 +112,10 @@ static void mcb_pci_remove(struct pci_dev *pdev) struct priv *priv = pci_get_drvdata(pdev); mcb_release_bus(priv->bus); + + iounmap(priv->base); + release_region(priv->mapbase, CHAM_HEADER_SIZE); + pci_disable_device(pdev); } static const struct pci_device_id mcb_pci_tbl[] = { diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 3c89fcbc621e..49cd30870e0d 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -160,7 +160,6 @@ source "drivers/media/usb/Kconfig" source "drivers/media/pci/Kconfig" source "drivers/media/platform/Kconfig" source "drivers/media/mmc/Kconfig" -source "drivers/media/parport/Kconfig" source "drivers/media/radio/Kconfig" comment "Supported FireWire (IEEE 1394) Adapters" diff --git a/drivers/media/Makefile b/drivers/media/Makefile index 620f275a45c9..e608bbce0c35 100644 --- a/drivers/media/Makefile +++ b/drivers/media/Makefile @@ -28,6 +28,6 @@ obj-y += rc/ # Finally, merge the drivers that require the core # -obj-y += common/ platform/ pci/ usb/ mmc/ firewire/ parport/ +obj-y += common/ platform/ pci/ usb/ mmc/ firewire/ obj-$(CONFIG_VIDEO_DEV) += radio/ diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index f40b4cf6107a..205d71364343 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -284,15 +284,6 @@ config VIDEO_SAA711X To compile this driver as a module, choose M here: the module will be called saa7115. -config VIDEO_SAA7191 - tristate "Philips SAA7191 video decoder" - depends on VIDEO_V4L2 && I2C - ---help--- - Support for the Philips SAA7191 video decoder. - - To compile this driver as a module, choose M here: the - module will be called saa7191. - config VIDEO_TVP514X tristate "Texas Instruments TVP514x video decoder" depends on VIDEO_V4L2 && I2C diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index 01ae9328e582..9858900168bf 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -18,7 +18,6 @@ obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o obj-$(CONFIG_VIDEO_SAA717X) += saa717x.o obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o -obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o obj-$(CONFIG_VIDEO_SAA6752HS) += saa6752hs.o obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c index db99ca2613ba..06931f6fa26c 100644 --- a/drivers/media/pci/cx23885/cx23885-cards.c +++ b/drivers/media/pci/cx23885/cx23885-cards.c @@ -614,7 +614,7 @@ struct cx23885_board cx23885_boards[] = { .portb = CX23885_MPEG_DVB, }, [CX23885_BOARD_HAUPPAUGE_HVR4400] = { - .name = "Hauppauge WinTV-HVR4400", + .name = "Hauppauge WinTV-HVR4400/HVR5500", .porta = CX23885_ANALOG_VIDEO, .portb = CX23885_MPEG_DVB, .portc = CX23885_MPEG_DVB, @@ -622,6 +622,10 @@ struct cx23885_board cx23885_boards[] = { .tuner_addr = 0x60, /* 0xc0 >> 1 */ .tuner_bus = 1, }, + [CX23885_BOARD_HAUPPAUGE_STARBURST] = { + .name = "Hauppauge WinTV Starburst", + .portb = CX23885_MPEG_DVB, + }, [CX23885_BOARD_AVERMEDIA_HC81R] = { .name = "AVerTV Hybrid Express Slim HC81R", .tuner_type = TUNER_XC2028, @@ -936,19 +940,19 @@ struct cx23885_subid cx23885_subids[] = { }, { .subvendor = 0x0070, .subdevice = 0xc108, - .card = CX23885_BOARD_HAUPPAUGE_HVR4400, + .card = CX23885_BOARD_HAUPPAUGE_HVR4400, /* Hauppauge WinTV HVR-4400 (Model 121xxx, Hybrid DVB-T/S2, IR) */ }, { .subvendor = 0x0070, .subdevice = 0xc138, - .card = CX23885_BOARD_HAUPPAUGE_HVR4400, + .card = CX23885_BOARD_HAUPPAUGE_HVR4400, /* Hauppauge WinTV HVR-5500 (Model 121xxx, Hybrid DVB-T/C/S2, IR) */ }, { .subvendor = 0x0070, .subdevice = 0xc12a, - .card = CX23885_BOARD_HAUPPAUGE_HVR4400, + .card = CX23885_BOARD_HAUPPAUGE_STARBURST, /* Hauppauge WinTV Starburst (Model 121x00, DVB-S2, IR) */ }, { .subvendor = 0x0070, .subdevice = 0xc1f8, - .card = CX23885_BOARD_HAUPPAUGE_HVR4400, + .card = CX23885_BOARD_HAUPPAUGE_HVR4400, /* Hauppauge WinTV HVR-5500 (Model 121xxx, Hybrid DVB-T/C/S2, IR) */ }, { .subvendor = 0x1461, .subdevice = 0xd939, @@ -1545,8 +1549,9 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/ break; case CX23885_BOARD_HAUPPAUGE_HVR4400: + case CX23885_BOARD_HAUPPAUGE_STARBURST: /* GPIO-8 tda10071 demod reset */ - /* GPIO-9 si2165 demod reset */ + /* GPIO-9 si2165 demod reset (only HVR4400/HVR5500)*/ /* Put the parts into reset and back */ cx23885_gpio_enable(dev, GPIO_8 | GPIO_9, 1); @@ -1872,6 +1877,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1850: case CX23885_BOARD_HAUPPAUGE_HVR1290: case CX23885_BOARD_HAUPPAUGE_HVR4400: + case CX23885_BOARD_HAUPPAUGE_STARBURST: case CX23885_BOARD_HAUPPAUGE_IMPACTVCBE: if (dev->i2c_bus[0].i2c_rc == 0) hauppauge_eeprom(dev, eeprom+0xc0); @@ -1980,6 +1986,11 @@ void cx23885_card_setup(struct cx23885_dev *dev) ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; break; + case CX23885_BOARD_HAUPPAUGE_STARBURST: + ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ + ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ + ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; + break; case CX23885_BOARD_DVBSKY_T9580: case CX23885_BOARD_DVBSKY_T982: ts1->gen_ctrl_val = 0x5; /* Parallel */ diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c index 1d9d0f86ca8c..1ad49946d7fa 100644 --- a/drivers/media/pci/cx23885/cx23885-core.c +++ b/drivers/media/pci/cx23885/cx23885-core.c @@ -2049,11 +2049,11 @@ static void cx23885_finidev(struct pci_dev *pci_dev) cx23885_shutdown(dev); - pci_disable_device(pci_dev); - /* unregister stuff */ free_irq(pci_dev->irq, dev); + pci_disable_device(pci_dev); + cx23885_dev_unregister(dev); vb2_dma_sg_cleanup_ctx(dev->alloc_ctx); v4l2_ctrl_handler_free(&dev->ctrl_handler); diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index c47d18270cfc..a9c450d4b54e 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -1710,6 +1710,17 @@ static int dvb_register(struct cx23885_tsport *port) break; } break; + case CX23885_BOARD_HAUPPAUGE_STARBURST: + i2c_bus = &dev->i2c_bus[0]; + fe0->dvb.frontend = dvb_attach(tda10071_attach, + &hauppauge_tda10071_config, + &i2c_bus->i2c_adap); + if (fe0->dvb.frontend != NULL) { + dvb_attach(a8293_attach, fe0->dvb.frontend, + &i2c_bus->i2c_adap, + &hauppauge_a8293_config); + } + break; case CX23885_BOARD_DVBSKY_T9580: case CX23885_BOARD_DVBSKY_S950: i2c_bus = &dev->i2c_bus[0]; diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index f55cd12da0fd..36f2f96c40e4 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h @@ -99,6 +99,7 @@ #define CX23885_BOARD_DVBSKY_S950 49 #define CX23885_BOARD_DVBSKY_S952 50 #define CX23885_BOARD_DVBSKY_T982 51 +#define CX23885_BOARD_HAUPPAUGE_STARBURST 52 #define GPIO_0 0x00000001 #define GPIO_1 0x00000002 diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c index 4160ca4e5413..d3c79d964f2c 100644 --- a/drivers/media/pci/cx88/cx88-blackbird.c +++ b/drivers/media/pci/cx88/cx88-blackbird.c @@ -647,6 +647,7 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, dev->ts_packet_size = 188 * 4; dev->ts_packet_count = 32; sizes[0] = dev->ts_packet_size * dev->ts_packet_count; + alloc_ctxs[0] = dev->alloc_ctx; return 0; } @@ -662,14 +663,11 @@ static void buffer_finish(struct vb2_buffer *vb) { struct cx8802_dev *dev = vb->vb2_queue->drv_priv; struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); - struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); struct cx88_riscmem *risc = &buf->risc; if (risc->cpu) pci_free_consistent(dev->pci, risc->size, risc->cpu, risc->dma); memset(risc, 0, sizeof(*risc)); - - dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); } static void buffer_queue(struct vb2_buffer *vb) diff --git a/drivers/media/pci/cx88/cx88-dvb.c b/drivers/media/pci/cx88/cx88-dvb.c index c344bfd0b896..5780e2f013b4 100644 --- a/drivers/media/pci/cx88/cx88-dvb.c +++ b/drivers/media/pci/cx88/cx88-dvb.c @@ -92,6 +92,7 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, dev->ts_packet_size = 188 * 4; dev->ts_packet_count = dvb_buf_tscnt; sizes[0] = dev->ts_packet_size * dev->ts_packet_count; + alloc_ctxs[0] = dev->alloc_ctx; *num_buffers = dvb_buf_tscnt; return 0; } @@ -108,14 +109,11 @@ static void buffer_finish(struct vb2_buffer *vb) { struct cx8802_dev *dev = vb->vb2_queue->drv_priv; struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); - struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); struct cx88_riscmem *risc = &buf->risc; if (risc->cpu) pci_free_consistent(dev->pci, risc->size, risc->cpu, risc->dma); memset(risc, 0, sizeof(*risc)); - - dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); } static void buffer_queue(struct vb2_buffer *vb) diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c index f181a3a10389..1c1f69e6b0b9 100644 --- a/drivers/media/pci/cx88/cx88-mpeg.c +++ b/drivers/media/pci/cx88/cx88-mpeg.c @@ -235,10 +235,6 @@ int cx8802_buf_prepare(struct vb2_queue *q, struct cx8802_dev *dev, return -EINVAL; vb2_set_plane_payload(&buf->vb, 0, size); - rc = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); - if (!rc) - return -EIO; - rc = cx88_risc_databuffer(dev->pci, risc, sgt->sgl, dev->ts_packet_size, dev->ts_packet_count, 0); if (rc) { @@ -733,6 +729,11 @@ static int cx8802_probe(struct pci_dev *pci_dev, if (NULL == dev) goto fail_core; dev->pci = pci_dev; + dev->alloc_ctx = vb2_dma_sg_init_ctx(&pci_dev->dev); + if (IS_ERR(dev->alloc_ctx)) { + err = PTR_ERR(dev->alloc_ctx); + goto fail_core; + } dev->core = core; /* Maintain a reference so cx88-video can query the 8802 device. */ @@ -752,6 +753,7 @@ static int cx8802_probe(struct pci_dev *pci_dev, return 0; fail_free: + vb2_dma_sg_cleanup_ctx(dev->alloc_ctx); kfree(dev); fail_core: core->dvbdev = NULL; @@ -798,6 +800,7 @@ static void cx8802_remove(struct pci_dev *pci_dev) /* common */ cx8802_fini_common(dev); cx88_core_put(dev->core,dev->pci); + vb2_dma_sg_cleanup_ctx(dev->alloc_ctx); kfree(dev); } diff --git a/drivers/media/pci/cx88/cx88-vbi.c b/drivers/media/pci/cx88/cx88-vbi.c index 6ab6e27648f6..32eb7fdb875e 100644 --- a/drivers/media/pci/cx88/cx88-vbi.c +++ b/drivers/media/pci/cx88/cx88-vbi.c @@ -120,6 +120,7 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, sizes[0] = VBI_LINE_NTSC_COUNT * VBI_LINE_LENGTH * 2; else sizes[0] = VBI_LINE_PAL_COUNT * VBI_LINE_LENGTH * 2; + alloc_ctxs[0] = dev->alloc_ctx; return 0; } @@ -131,7 +132,6 @@ static int buffer_prepare(struct vb2_buffer *vb) struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); unsigned int lines; unsigned int size; - int rc; if (dev->core->tvnorm & V4L2_STD_525_60) lines = VBI_LINE_NTSC_COUNT; @@ -142,10 +142,6 @@ static int buffer_prepare(struct vb2_buffer *vb) return -EINVAL; vb2_set_plane_payload(vb, 0, size); - rc = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); - if (!rc) - return -EIO; - cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl, 0, VBI_LINE_LENGTH * lines, VBI_LINE_LENGTH, 0, @@ -157,14 +153,11 @@ static void buffer_finish(struct vb2_buffer *vb) { struct cx8800_dev *dev = vb->vb2_queue->drv_priv; struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); - struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); struct cx88_riscmem *risc = &buf->risc; if (risc->cpu) pci_free_consistent(dev->pci, risc->size, risc->cpu, risc->dma); memset(risc, 0, sizeof(*risc)); - - dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); } static void buffer_queue(struct vb2_buffer *vb) diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index a64ae31ae142..860c98fc72c7 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -440,6 +440,7 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, *num_planes = 1; sizes[0] = (dev->fmt->depth * core->width * core->height) >> 3; + alloc_ctxs[0] = dev->alloc_ctx; return 0; } @@ -449,7 +450,6 @@ static int buffer_prepare(struct vb2_buffer *vb) struct cx88_core *core = dev->core; struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); - int rc; buf->bpl = core->width * dev->fmt->depth >> 3; @@ -457,10 +457,6 @@ static int buffer_prepare(struct vb2_buffer *vb) return -EINVAL; vb2_set_plane_payload(vb, 0, core->height * buf->bpl); - rc = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); - if (!rc) - return -EIO; - switch (core->field) { case V4L2_FIELD_TOP: cx88_risc_buffer(dev->pci, &buf->risc, @@ -505,14 +501,11 @@ static void buffer_finish(struct vb2_buffer *vb) { struct cx8800_dev *dev = vb->vb2_queue->drv_priv; struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); - struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); struct cx88_riscmem *risc = &buf->risc; if (risc->cpu) pci_free_consistent(dev->pci, risc->size, risc->cpu, risc->dma); memset(risc, 0, sizeof(*risc)); - - dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); } static void buffer_queue(struct vb2_buffer *vb) @@ -530,7 +523,6 @@ static void buffer_queue(struct vb2_buffer *vb) if (list_empty(&q->active)) { list_add_tail(&buf->list, &q->active); - start_video_dma(dev, q, buf); buf->count = q->count++; dprintk(2,"[%p/%d] buffer_queue - first active\n", buf, buf->vb.v4l2_buf.index); @@ -1345,6 +1337,12 @@ static int cx8800_initdev(struct pci_dev *pci_dev, err = -EIO; goto fail_core; } + dev->alloc_ctx = vb2_dma_sg_init_ctx(&pci_dev->dev); + if (IS_ERR(dev->alloc_ctx)) { + err = PTR_ERR(dev->alloc_ctx); + goto fail_core; + } + /* initialize driver struct */ spin_lock_init(&dev->slock); @@ -1549,6 +1547,7 @@ fail_unreg: free_irq(pci_dev->irq, dev); mutex_unlock(&core->lock); fail_core: + vb2_dma_sg_cleanup_ctx(dev->alloc_ctx); core->v4ldev = NULL; cx88_core_put(core,dev->pci); fail_free: @@ -1582,6 +1581,7 @@ static void cx8800_finidev(struct pci_dev *pci_dev) /* free memory */ cx88_core_put(core,dev->pci); + vb2_dma_sg_cleanup_ctx(dev->alloc_ctx); kfree(dev); } diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h index 3b0ae754f165..7748ca9abb09 100644 --- a/drivers/media/pci/cx88/cx88.h +++ b/drivers/media/pci/cx88/cx88.h @@ -485,6 +485,7 @@ struct cx8800_dev { /* pci i/o */ struct pci_dev *pci; unsigned char pci_rev,pci_lat; + void *alloc_ctx; const struct cx8800_fmt *fmt; @@ -548,6 +549,7 @@ struct cx8802_dev { /* pci i/o */ struct pci_dev *pci; unsigned char pci_rev,pci_lat; + void *alloc_ctx; /* dma queues */ struct cx88_dmaqueue mpegq; diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 0c61155699f7..765bffb49a72 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -65,14 +65,6 @@ config VIDEO_TIMBERDALE ---help--- Add support for the Video In peripherial of the timberdale FPGA. -config VIDEO_VINO - tristate "SGI Vino Video For Linux" - depends on I2C && SGI_IP22 && VIDEO_V4L2 - select VIDEO_SAA7191 if MEDIA_SUBDRV_AUTOSELECT - help - Say Y here to build in support for the Vino video input system found - on SGI Indy machines. - config VIDEO_M32R_AR tristate "AR devices" depends on VIDEO_V4L2 @@ -112,7 +104,7 @@ config VIDEO_OMAP3_DEBUG config VIDEO_S3C_CAMIF tristate "Samsung S3C24XX/S3C64XX SoC Camera Interface driver" depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API - depends on PM_RUNTIME + depends on PM depends on ARCH_S3C64XX || PLAT_S3C24XX || COMPILE_TEST depends on HAS_DMA select VIDEOBUF2_DMA_CONTIG diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index b818afb4d336..a49936b8ce8a 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -2,9 +2,6 @@ # Makefile for the video capture/playback device drivers. # -obj-$(CONFIG_VIDEO_VINO) += indycam.o -obj-$(CONFIG_VIDEO_VINO) += vino.o - obj-$(CONFIG_VIDEO_TIMBERDALE) += timblogiw.o obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index b463fe172d16..3fe9047ef466 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -602,10 +602,13 @@ isp_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap) strlcpy(cap->card, video->video.name, sizeof(cap->card)); strlcpy(cap->bus_info, "media", sizeof(cap->bus_info)); + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT + | V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS; + if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; else - cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; return 0; } diff --git a/drivers/media/platform/s5p-tv/Kconfig b/drivers/media/platform/s5p-tv/Kconfig index beb180e71ba0..5a1835dd65e8 100644 --- a/drivers/media/platform/s5p-tv/Kconfig +++ b/drivers/media/platform/s5p-tv/Kconfig @@ -8,7 +8,7 @@ config VIDEO_SAMSUNG_S5P_TV bool "Samsung TV driver for S5P platform" - depends on PM_RUNTIME + depends on PM depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST default n ---help--- diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 8efe40337608..6d885239b16a 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -760,8 +760,9 @@ static int isi_camera_querycap(struct soc_camera_host *ici, { strcpy(cap->driver, "atmel-isi"); strcpy(cap->card, "Atmel Image Sensor Interface"); - cap->capabilities = (V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_STREAMING); + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + return 0; } diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c index ce72bd26a6ac..192377f55840 100644 --- a/drivers/media/platform/soc_camera/mx2_camera.c +++ b/drivers/media/platform/soc_camera/mx2_camera.c @@ -1256,7 +1256,8 @@ static int mx2_camera_querycap(struct soc_camera_host *ici, { /* cap->name is set by the friendly caller:-> */ strlcpy(cap->card, MX2_CAM_DRIVER_DESCRIPTION, sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c index a60c3bb0e4cc..0b3299dee05d 100644 --- a/drivers/media/platform/soc_camera/mx3_camera.c +++ b/drivers/media/platform/soc_camera/mx3_camera.c @@ -967,7 +967,8 @@ static int mx3_camera_querycap(struct soc_camera_host *ici, { /* cap->name is set by the firendly caller:-> */ strlcpy(cap->card, "i.MX3x Camera", sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } diff --git a/drivers/media/platform/soc_camera/omap1_camera.c b/drivers/media/platform/soc_camera/omap1_camera.c index e6b93281f246..16f65ecb70a3 100644 --- a/drivers/media/platform/soc_camera/omap1_camera.c +++ b/drivers/media/platform/soc_camera/omap1_camera.c @@ -1427,7 +1427,8 @@ static int omap1_cam_querycap(struct soc_camera_host *ici, { /* cap->name is set by the friendly caller:-> */ strlcpy(cap->card, "OMAP1 Camera", sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c index 951226af0eba..8d6e343fec0f 100644 --- a/drivers/media/platform/soc_camera/pxa_camera.c +++ b/drivers/media/platform/soc_camera/pxa_camera.c @@ -1576,7 +1576,8 @@ static int pxa_camera_querycap(struct soc_camera_host *ici, { /* cap->name is set by the firendly caller:-> */ strlcpy(cap->card, pxa_cam_driver_description, sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index 126ac7c5b6fd..9f1473c0a0cf 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c @@ -64,6 +64,30 @@ #define VNDMR_REG 0x58 /* Video n Data Mode Register */ #define VNDMR2_REG 0x5C /* Video n Data Mode Register 2 */ #define VNUVAOF_REG 0x60 /* Video n UV Address Offset Register */ +#define VNC1A_REG 0x80 /* Video n Coefficient Set C1A Register */ +#define VNC1B_REG 0x84 /* Video n Coefficient Set C1B Register */ +#define VNC1C_REG 0x88 /* Video n Coefficient Set C1C Register */ +#define VNC2A_REG 0x90 /* Video n Coefficient Set C2A Register */ +#define VNC2B_REG 0x94 /* Video n Coefficient Set C2B Register */ +#define VNC2C_REG 0x98 /* Video n Coefficient Set C2C Register */ +#define VNC3A_REG 0xA0 /* Video n Coefficient Set C3A Register */ +#define VNC3B_REG 0xA4 /* Video n Coefficient Set C3B Register */ +#define VNC3C_REG 0xA8 /* Video n Coefficient Set C3C Register */ +#define VNC4A_REG 0xB0 /* Video n Coefficient Set C4A Register */ +#define VNC4B_REG 0xB4 /* Video n Coefficient Set C4B Register */ +#define VNC4C_REG 0xB8 /* Video n Coefficient Set C4C Register */ +#define VNC5A_REG 0xC0 /* Video n Coefficient Set C5A Register */ +#define VNC5B_REG 0xC4 /* Video n Coefficient Set C5B Register */ +#define VNC5C_REG 0xC8 /* Video n Coefficient Set C5C Register */ +#define VNC6A_REG 0xD0 /* Video n Coefficient Set C6A Register */ +#define VNC6B_REG 0xD4 /* Video n Coefficient Set C6B Register */ +#define VNC6C_REG 0xD8 /* Video n Coefficient Set C6C Register */ +#define VNC7A_REG 0xE0 /* Video n Coefficient Set C7A Register */ +#define VNC7B_REG 0xE4 /* Video n Coefficient Set C7B Register */ +#define VNC7C_REG 0xE8 /* Video n Coefficient Set C7C Register */ +#define VNC8A_REG 0xF0 /* Video n Coefficient Set C8A Register */ +#define VNC8B_REG 0xF4 /* Video n Coefficient Set C8B Register */ +#define VNC8C_REG 0xF8 /* Video n Coefficient Set C8C Register */ /* Register bit fields for R-Car VIN */ /* Video n Main Control Register bits */ @@ -106,6 +130,7 @@ #define VNDMR2_VPS (1 << 30) #define VNDMR2_HPS (1 << 29) #define VNDMR2_FTEV (1 << 17) +#define VNDMR2_VLV(n) ((n & 0xf) << 12) #define VIN_MAX_WIDTH 2048 #define VIN_MAX_HEIGHT 2048 @@ -117,6 +142,324 @@ enum chip_id { RCAR_E1, }; +struct vin_coeff { + unsigned short xs_value; + u32 coeff_set[24]; +}; + +static const struct vin_coeff vin_coeff_set[] = { + { 0x0000, { + 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000 }, + }, + { 0x1000, { + 0x000fa400, 0x000fa400, 0x09625902, + 0x000003f8, 0x00000403, 0x3de0d9f0, + 0x001fffed, 0x00000804, 0x3cc1f9c3, + 0x001003de, 0x00000c01, 0x3cb34d7f, + 0x002003d2, 0x00000c00, 0x3d24a92d, + 0x00200bca, 0x00000bff, 0x3df600d2, + 0x002013cc, 0x000007ff, 0x3ed70c7e, + 0x00100fde, 0x00000000, 0x3f87c036 }, + }, + { 0x1200, { + 0x002ffff1, 0x002ffff1, 0x02a0a9c8, + 0x002003e7, 0x001ffffa, 0x000185bc, + 0x002007dc, 0x000003ff, 0x3e52859c, + 0x00200bd4, 0x00000002, 0x3d53996b, + 0x00100fd0, 0x00000403, 0x3d04ad2d, + 0x00000bd5, 0x00000403, 0x3d35ace7, + 0x3ff003e4, 0x00000801, 0x3dc674a1, + 0x3fffe800, 0x00000800, 0x3e76f461 }, + }, + { 0x1400, { + 0x00100be3, 0x00100be3, 0x04d1359a, + 0x00000fdb, 0x002003ed, 0x0211fd93, + 0x00000fd6, 0x002003f4, 0x0002d97b, + 0x000007d6, 0x002ffffb, 0x3e93b956, + 0x3ff003da, 0x001003ff, 0x3db49926, + 0x3fffefe9, 0x00100001, 0x3d655cee, + 0x3fffd400, 0x00000003, 0x3d65f4b6, + 0x000fb421, 0x00000402, 0x3dc6547e }, + }, + { 0x1600, { + 0x00000bdd, 0x00000bdd, 0x06519578, + 0x3ff007da, 0x00000be3, 0x03c24973, + 0x3ff003d9, 0x00000be9, 0x01b30d5f, + 0x3ffff7df, 0x001003f1, 0x0003c542, + 0x000fdfec, 0x001003f7, 0x3ec4711d, + 0x000fc400, 0x002ffffd, 0x3df504f1, + 0x001fa81a, 0x002ffc00, 0x3d957cc2, + 0x002f8c3c, 0x00100000, 0x3db5c891 }, + }, + { 0x1800, { + 0x3ff003dc, 0x3ff003dc, 0x0791e558, + 0x000ff7dd, 0x3ff007de, 0x05328554, + 0x000fe7e3, 0x3ff00be2, 0x03232546, + 0x000fd7ee, 0x000007e9, 0x0143bd30, + 0x001fb800, 0x000007ee, 0x00044511, + 0x002fa015, 0x000007f4, 0x3ef4bcee, + 0x002f8832, 0x001003f9, 0x3e4514c7, + 0x001f7853, 0x001003fd, 0x3de54c9f }, + }, + { 0x1a00, { + 0x000fefe0, 0x000fefe0, 0x08721d3c, + 0x001fdbe7, 0x000ffbde, 0x0652a139, + 0x001fcbf0, 0x000003df, 0x0463292e, + 0x002fb3ff, 0x3ff007e3, 0x0293a91d, + 0x002f9c12, 0x3ff00be7, 0x01241905, + 0x001f8c29, 0x000007ed, 0x3fe470eb, + 0x000f7c46, 0x000007f2, 0x3f04b8ca, + 0x3fef7865, 0x000007f6, 0x3e74e4a8 }, + }, + { 0x1c00, { + 0x001fd3e9, 0x001fd3e9, 0x08f23d26, + 0x002fbff3, 0x001fe3e4, 0x0712ad23, + 0x002fa800, 0x000ff3e0, 0x05631d1b, + 0x001f9810, 0x000ffbe1, 0x03b3890d, + 0x000f8c23, 0x000003e3, 0x0233e8fa, + 0x3fef843b, 0x000003e7, 0x00f430e4, + 0x3fbf8456, 0x3ff00bea, 0x00046cc8, + 0x3f8f8c72, 0x3ff00bef, 0x3f3490ac }, + }, + { 0x1e00, { + 0x001fbbf4, 0x001fbbf4, 0x09425112, + 0x001fa800, 0x002fc7ed, 0x0792b110, + 0x000f980e, 0x001fdbe6, 0x0613110a, + 0x3fff8c20, 0x001fe7e3, 0x04a368fd, + 0x3fcf8c33, 0x000ff7e2, 0x0343b8ed, + 0x3f9f8c4a, 0x000fffe3, 0x0203f8da, + 0x3f5f9c61, 0x000003e6, 0x00e428c5, + 0x3f1fb07b, 0x000003eb, 0x3fe440af }, + }, + { 0x2000, { + 0x000fa400, 0x000fa400, 0x09625902, + 0x3fff980c, 0x001fb7f5, 0x0812b0ff, + 0x3fdf901c, 0x001fc7ed, 0x06b2fcfa, + 0x3faf902d, 0x001fd3e8, 0x055348f1, + 0x3f7f983f, 0x001fe3e5, 0x04038ce3, + 0x3f3fa454, 0x001fefe3, 0x02e3c8d1, + 0x3f0fb86a, 0x001ff7e4, 0x01c3e8c0, + 0x3ecfd880, 0x000fffe6, 0x00c404ac }, + }, + { 0x2200, { + 0x3fdf9c0b, 0x3fdf9c0b, 0x09725cf4, + 0x3fbf9818, 0x3fffa400, 0x0842a8f1, + 0x3f8f9827, 0x000fb3f7, 0x0702f0ec, + 0x3f5fa037, 0x000fc3ef, 0x05d330e4, + 0x3f2fac49, 0x001fcfea, 0x04a364d9, + 0x3effc05c, 0x001fdbe7, 0x038394ca, + 0x3ecfdc6f, 0x001fe7e6, 0x0273b0bb, + 0x3ea00083, 0x001fefe6, 0x0183c0a9 }, + }, + { 0x2400, { + 0x3f9fa014, 0x3f9fa014, 0x098260e6, + 0x3f7f9c23, 0x3fcf9c0a, 0x08629ce5, + 0x3f4fa431, 0x3fefa400, 0x0742d8e1, + 0x3f1fb440, 0x3fffb3f8, 0x062310d9, + 0x3eefc850, 0x000fbbf2, 0x050340d0, + 0x3ecfe062, 0x000fcbec, 0x041364c2, + 0x3ea00073, 0x001fd3ea, 0x03037cb5, + 0x3e902086, 0x001fdfe8, 0x022388a5 }, + }, + { 0x2600, { + 0x3f5fa81e, 0x3f5fa81e, 0x096258da, + 0x3f3fac2b, 0x3f8fa412, 0x088290d8, + 0x3f0fbc38, 0x3fafa408, 0x0772c8d5, + 0x3eefcc47, 0x3fcfa800, 0x0672f4ce, + 0x3ecfe456, 0x3fefaffa, 0x05531cc6, + 0x3eb00066, 0x3fffbbf3, 0x047334bb, + 0x3ea01c77, 0x000fc7ee, 0x039348ae, + 0x3ea04486, 0x000fd3eb, 0x02b350a1 }, + }, + { 0x2800, { + 0x3f2fb426, 0x3f2fb426, 0x094250ce, + 0x3f0fc032, 0x3f4fac1b, 0x086284cd, + 0x3eefd040, 0x3f7fa811, 0x0782acc9, + 0x3ecfe84c, 0x3f9fa807, 0x06a2d8c4, + 0x3eb0005b, 0x3fbfac00, 0x05b2f4bc, + 0x3eb0186a, 0x3fdfb3fa, 0x04c308b4, + 0x3eb04077, 0x3fefbbf4, 0x03f31ca8, + 0x3ec06884, 0x000fbff2, 0x03031c9e }, + }, + { 0x2a00, { + 0x3f0fc42d, 0x3f0fc42d, 0x090240c4, + 0x3eefd439, 0x3f2fb822, 0x08526cc2, + 0x3edfe845, 0x3f4fb018, 0x078294bf, + 0x3ec00051, 0x3f6fac0f, 0x06b2b4bb, + 0x3ec0185f, 0x3f8fac07, 0x05e2ccb4, + 0x3ec0386b, 0x3fafac00, 0x0502e8ac, + 0x3ed05c77, 0x3fcfb3fb, 0x0432f0a3, + 0x3ef08482, 0x3fdfbbf6, 0x0372f898 }, + }, + { 0x2c00, { + 0x3eefdc31, 0x3eefdc31, 0x08e238b8, + 0x3edfec3d, 0x3f0fc828, 0x082258b9, + 0x3ed00049, 0x3f1fc01e, 0x077278b6, + 0x3ed01455, 0x3f3fb815, 0x06c294b2, + 0x3ed03460, 0x3f5fb40d, 0x0602acac, + 0x3ef0506c, 0x3f7fb006, 0x0542c0a4, + 0x3f107476, 0x3f9fb400, 0x0472c89d, + 0x3f309c80, 0x3fbfb7fc, 0x03b2cc94 }, + }, + { 0x2e00, { + 0x3eefec37, 0x3eefec37, 0x088220b0, + 0x3ee00041, 0x3effdc2d, 0x07f244ae, + 0x3ee0144c, 0x3f0fd023, 0x07625cad, + 0x3ef02c57, 0x3f1fc81a, 0x06c274a9, + 0x3f004861, 0x3f3fbc13, 0x060288a6, + 0x3f20686b, 0x3f5fb80c, 0x05529c9e, + 0x3f408c74, 0x3f6fb805, 0x04b2ac96, + 0x3f80ac7e, 0x3f8fb800, 0x0402ac8e }, + }, + { 0x3000, { + 0x3ef0003a, 0x3ef0003a, 0x084210a6, + 0x3ef01045, 0x3effec32, 0x07b228a7, + 0x3f00284e, 0x3f0fdc29, 0x073244a4, + 0x3f104058, 0x3f0fd420, 0x06a258a2, + 0x3f305c62, 0x3f2fc818, 0x0612689d, + 0x3f508069, 0x3f3fc011, 0x05728496, + 0x3f80a072, 0x3f4fc00a, 0x04d28c90, + 0x3fc0c07b, 0x3f6fbc04, 0x04429088 }, + }, + { 0x3200, { + 0x3f00103e, 0x3f00103e, 0x07f1fc9e, + 0x3f102447, 0x3f000035, 0x0782149d, + 0x3f203c4f, 0x3f0ff02c, 0x07122c9c, + 0x3f405458, 0x3f0fe424, 0x06924099, + 0x3f607061, 0x3f1fd41d, 0x06024c97, + 0x3f909068, 0x3f2fcc16, 0x05726490, + 0x3fc0b070, 0x3f3fc80f, 0x04f26c8a, + 0x0000d077, 0x3f4fc409, 0x04627484 }, + }, + { 0x3400, { + 0x3f202040, 0x3f202040, 0x07a1e898, + 0x3f303449, 0x3f100c38, 0x0741fc98, + 0x3f504c50, 0x3f10002f, 0x06e21495, + 0x3f706459, 0x3f1ff028, 0x06722492, + 0x3fa08060, 0x3f1fe421, 0x05f2348f, + 0x3fd09c67, 0x3f1fdc19, 0x05824c89, + 0x0000bc6e, 0x3f2fd014, 0x04f25086, + 0x0040dc74, 0x3f3fcc0d, 0x04825c7f }, + }, + { 0x3600, { + 0x3f403042, 0x3f403042, 0x0761d890, + 0x3f504848, 0x3f301c3b, 0x0701f090, + 0x3f805c50, 0x3f200c33, 0x06a2008f, + 0x3fa07458, 0x3f10002b, 0x06520c8d, + 0x3fd0905e, 0x3f1ff424, 0x05e22089, + 0x0000ac65, 0x3f1fe81d, 0x05823483, + 0x0030cc6a, 0x3f2fdc18, 0x04f23c81, + 0x0080e871, 0x3f2fd412, 0x0482407c }, + }, + { 0x3800, { + 0x3f604043, 0x3f604043, 0x0721c88a, + 0x3f80544a, 0x3f502c3c, 0x06d1d88a, + 0x3fb06851, 0x3f301c35, 0x0681e889, + 0x3fd08456, 0x3f30082f, 0x0611fc88, + 0x00009c5d, 0x3f200027, 0x05d20884, + 0x0030b863, 0x3f2ff421, 0x05621880, + 0x0070d468, 0x3f2fe81b, 0x0502247c, + 0x00c0ec6f, 0x3f2fe015, 0x04a22877 }, + }, + { 0x3a00, { + 0x3f904c44, 0x3f904c44, 0x06e1b884, + 0x3fb0604a, 0x3f70383e, 0x0691c885, + 0x3fe07451, 0x3f502c36, 0x0661d483, + 0x00009055, 0x3f401831, 0x0601ec81, + 0x0030a85b, 0x3f300c2a, 0x05b1f480, + 0x0070c061, 0x3f300024, 0x0562047a, + 0x00b0d867, 0x3f3ff41e, 0x05020c77, + 0x00f0f46b, 0x3f2fec19, 0x04a21474 }, + }, + { 0x3c00, { + 0x3fb05c43, 0x3fb05c43, 0x06c1b07e, + 0x3fe06c4b, 0x3f902c3f, 0x0681c081, + 0x0000844f, 0x3f703838, 0x0631cc7d, + 0x00309855, 0x3f602433, 0x05d1d47e, + 0x0060b459, 0x3f50142e, 0x0581e47b, + 0x00a0c85f, 0x3f400828, 0x0531f078, + 0x00e0e064, 0x3f300021, 0x0501fc73, + 0x00b0fc6a, 0x3f3ff41d, 0x04a20873 }, + }, + { 0x3e00, { + 0x3fe06444, 0x3fe06444, 0x0681a07a, + 0x00007849, 0x3fc0503f, 0x0641b07a, + 0x0020904d, 0x3fa0403a, 0x05f1c07a, + 0x0060a453, 0x3f803034, 0x05c1c878, + 0x0090b858, 0x3f70202f, 0x0571d477, + 0x00d0d05d, 0x3f501829, 0x0531e073, + 0x0110e462, 0x3f500825, 0x04e1e471, + 0x01510065, 0x3f40001f, 0x04a1f06d }, + }, + { 0x4000, { + 0x00007044, 0x00007044, 0x06519476, + 0x00208448, 0x3fe05c3f, 0x0621a476, + 0x0050984d, 0x3fc04c3a, 0x05e1b075, + 0x0080ac52, 0x3fa03c35, 0x05a1b875, + 0x00c0c056, 0x3f803030, 0x0561c473, + 0x0100d45b, 0x3f70202b, 0x0521d46f, + 0x0140e860, 0x3f601427, 0x04d1d46e, + 0x01810064, 0x3f500822, 0x0491dc6b }, + }, + { 0x5000, { + 0x0110a442, 0x0110a442, 0x0551545e, + 0x0140b045, 0x00e0983f, 0x0531585f, + 0x0160c047, 0x00c08c3c, 0x0511645e, + 0x0190cc4a, 0x00908039, 0x04f1685f, + 0x01c0dc4c, 0x00707436, 0x04d1705e, + 0x0200e850, 0x00506833, 0x04b1785b, + 0x0230f453, 0x00305c30, 0x0491805a, + 0x02710056, 0x0010542d, 0x04718059 }, + }, + { 0x6000, { + 0x01c0bc40, 0x01c0bc40, 0x04c13052, + 0x01e0c841, 0x01a0b43d, 0x04c13851, + 0x0210cc44, 0x0180a83c, 0x04a13453, + 0x0230d845, 0x0160a03a, 0x04913c52, + 0x0260e047, 0x01409838, 0x04714052, + 0x0280ec49, 0x01208c37, 0x04514c50, + 0x02b0f44b, 0x01008435, 0x04414c50, + 0x02d1004c, 0x00e07c33, 0x0431544f }, + }, + { 0x7000, { + 0x0230c83e, 0x0230c83e, 0x04711c4c, + 0x0250d03f, 0x0210c43c, 0x0471204b, + 0x0270d840, 0x0200b83c, 0x0451244b, + 0x0290dc42, 0x01e0b43a, 0x0441244c, + 0x02b0e443, 0x01c0b038, 0x0441284b, + 0x02d0ec44, 0x01b0a438, 0x0421304a, + 0x02f0f445, 0x0190a036, 0x04213449, + 0x0310f847, 0x01709c34, 0x04213848 }, + }, + { 0x8000, { + 0x0280d03d, 0x0280d03d, 0x04310c48, + 0x02a0d43e, 0x0270c83c, 0x04311047, + 0x02b0dc3e, 0x0250c83a, 0x04311447, + 0x02d0e040, 0x0240c03a, 0x04211446, + 0x02e0e840, 0x0220bc39, 0x04111847, + 0x0300e842, 0x0210b438, 0x04012445, + 0x0310f043, 0x0200b037, 0x04012045, + 0x0330f444, 0x01e0ac36, 0x03f12445 }, + }, + { 0xefff, { + 0x0340dc3a, 0x0340dc3a, 0x03b0ec40, + 0x0340e03a, 0x0330e039, 0x03c0f03e, + 0x0350e03b, 0x0330dc39, 0x03c0ec3e, + 0x0350e43a, 0x0320dc38, 0x03c0f43e, + 0x0360e43b, 0x0320d839, 0x03b0f03e, + 0x0360e83b, 0x0310d838, 0x03c0fc3b, + 0x0370e83b, 0x0310d439, 0x03a0f83d, + 0x0370e83c, 0x0300d438, 0x03b0fc3c }, + } +}; + enum rcar_vin_state { STOPPED = 0, RUNNING, @@ -161,6 +504,9 @@ struct rcar_vin_cam { /* Client output, as seen by the VIN */ unsigned int width; unsigned int height; + /* User window from S_FMT */ + unsigned int out_width; + unsigned int out_height; /* * User window from S_CROP / G_CROP, produced by client cropping and * scaling, VIN scaling and VIN cropping, mapped back onto the client @@ -332,7 +678,7 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv) vnmc |= VNMC_BPS; /* progressive or interlaced mode */ - interrupts = progressive ? VNIE_FIE | VNIE_EFE : VNIE_EFE; + interrupts = progressive ? VNIE_FIE : VNIE_EFE; /* ack interrupts */ iowrite32(interrupts, priv->base + VNINTS_REG); @@ -667,6 +1013,60 @@ static void rcar_vin_clock_stop(struct soc_camera_host *ici) /* VIN does not have "mclk" */ } +static void set_coeff(struct rcar_vin_priv *priv, unsigned short xs) +{ + int i; + const struct vin_coeff *p_prev_set = NULL; + const struct vin_coeff *p_set = NULL; + + /* Look for suitable coefficient values */ + for (i = 0; i < ARRAY_SIZE(vin_coeff_set); i++) { + p_prev_set = p_set; + p_set = &vin_coeff_set[i]; + + if (xs < p_set->xs_value) + break; + } + + /* Use previous value if its XS value is closer */ + if (p_prev_set && p_set && + xs - p_prev_set->xs_value < p_set->xs_value - xs) + p_set = p_prev_set; + + /* Set coefficient registers */ + iowrite32(p_set->coeff_set[0], priv->base + VNC1A_REG); + iowrite32(p_set->coeff_set[1], priv->base + VNC1B_REG); + iowrite32(p_set->coeff_set[2], priv->base + VNC1C_REG); + + iowrite32(p_set->coeff_set[3], priv->base + VNC2A_REG); + iowrite32(p_set->coeff_set[4], priv->base + VNC2B_REG); + iowrite32(p_set->coeff_set[5], priv->base + VNC2C_REG); + + iowrite32(p_set->coeff_set[6], priv->base + VNC3A_REG); + iowrite32(p_set->coeff_set[7], priv->base + VNC3B_REG); + iowrite32(p_set->coeff_set[8], priv->base + VNC3C_REG); + + iowrite32(p_set->coeff_set[9], priv->base + VNC4A_REG); + iowrite32(p_set->coeff_set[10], priv->base + VNC4B_REG); + iowrite32(p_set->coeff_set[11], priv->base + VNC4C_REG); + + iowrite32(p_set->coeff_set[12], priv->base + VNC5A_REG); + iowrite32(p_set->coeff_set[13], priv->base + VNC5B_REG); + iowrite32(p_set->coeff_set[14], priv->base + VNC5C_REG); + + iowrite32(p_set->coeff_set[15], priv->base + VNC6A_REG); + iowrite32(p_set->coeff_set[16], priv->base + VNC6B_REG); + iowrite32(p_set->coeff_set[17], priv->base + VNC6C_REG); + + iowrite32(p_set->coeff_set[18], priv->base + VNC7A_REG); + iowrite32(p_set->coeff_set[19], priv->base + VNC7B_REG); + iowrite32(p_set->coeff_set[20], priv->base + VNC7C_REG); + + iowrite32(p_set->coeff_set[21], priv->base + VNC8A_REG); + iowrite32(p_set->coeff_set[22], priv->base + VNC8B_REG); + iowrite32(p_set->coeff_set[23], priv->base + VNC8C_REG); +} + /* rect is guaranteed to not exceed the scaled camera rectangle */ static int rcar_vin_set_rect(struct soc_camera_device *icd) { @@ -676,6 +1076,7 @@ static int rcar_vin_set_rect(struct soc_camera_device *icd) unsigned int left_offset, top_offset; unsigned char dsize = 0; struct v4l2_rect *cam_subrect = &cam->subrect; + u32 value; dev_dbg(icd->parent, "Crop %ux%u@%u:%u\n", icd->user_width, icd->user_height, cam->vin_left, cam->vin_top); @@ -695,40 +1096,64 @@ static int rcar_vin_set_rect(struct soc_camera_device *icd) /* Set Start/End Pixel/Line Pre-Clip */ iowrite32(left_offset << dsize, priv->base + VNSPPRC_REG); - iowrite32((left_offset + cam->width - 1) << dsize, + iowrite32((left_offset + cam_subrect->width - 1) << dsize, priv->base + VNEPPRC_REG); switch (priv->field) { case V4L2_FIELD_INTERLACED: case V4L2_FIELD_INTERLACED_TB: case V4L2_FIELD_INTERLACED_BT: iowrite32(top_offset / 2, priv->base + VNSLPRC_REG); - iowrite32((top_offset + cam->height) / 2 - 1, + iowrite32((top_offset + cam_subrect->height) / 2 - 1, priv->base + VNELPRC_REG); break; default: iowrite32(top_offset, priv->base + VNSLPRC_REG); - iowrite32(top_offset + cam->height - 1, + iowrite32(top_offset + cam_subrect->height - 1, priv->base + VNELPRC_REG); break; } + /* Set scaling coefficient */ + value = 0; + if (cam_subrect->height != cam->out_height) + value = (4096 * cam_subrect->height) / cam->out_height; + dev_dbg(icd->parent, "YS Value: %x\n", value); + iowrite32(value, priv->base + VNYS_REG); + + value = 0; + if (cam_subrect->width != cam->out_width) + value = (4096 * cam_subrect->width) / cam->out_width; + + /* Horizontal upscaling is up to double size */ + if (0 < value && value < 2048) + value = 2048; + + dev_dbg(icd->parent, "XS Value: %x\n", value); + iowrite32(value, priv->base + VNXS_REG); + + /* Horizontal upscaling is carried out by scaling down from double size */ + if (value < 4096) + value *= 2; + + set_coeff(priv, value); + /* Set Start/End Pixel/Line Post-Clip */ iowrite32(0, priv->base + VNSPPOC_REG); iowrite32(0, priv->base + VNSLPOC_REG); - iowrite32((cam_subrect->width - 1) << dsize, priv->base + VNEPPOC_REG); + iowrite32((cam->out_width - 1) << dsize, priv->base + VNEPPOC_REG); switch (priv->field) { case V4L2_FIELD_INTERLACED: case V4L2_FIELD_INTERLACED_TB: case V4L2_FIELD_INTERLACED_BT: - iowrite32(cam_subrect->height / 2 - 1, + iowrite32(cam->out_height / 2 - 1, priv->base + VNELPOC_REG); break; default: - iowrite32(cam_subrect->height - 1, priv->base + VNELPOC_REG); + iowrite32(cam->out_height - 1, priv->base + VNELPOC_REG); break; } - iowrite32(ALIGN(cam->width, 0x10), priv->base + VNIS_REG); + iowrite32(ALIGN(cam->out_width, 0x10), priv->base + VNIS_REG); return 0; } @@ -819,7 +1244,7 @@ static int rcar_vin_set_bus_param(struct soc_camera_device *icd) if (ret < 0 && ret != -ENOIOCTLCMD) return ret; - val = priv->field == V4L2_FIELD_NONE ? VNDMR2_FTEV : 0; + val = VNDMR2_FTEV | VNDMR2_VLV(1); if (!(common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) val |= VNDMR2_VPS; if (!(common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) @@ -880,6 +1305,14 @@ static const struct soc_mbus_pixelfmt rcar_vin_formats[] = { .layout = SOC_MBUS_LAYOUT_PLANAR_Y_C, }, { + .fourcc = V4L2_PIX_FMT_YUYV, + .name = "YUYV", + .bits_per_sample = 16, + .packing = SOC_MBUS_PACKING_NONE, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, + { .fourcc = V4L2_PIX_FMT_UYVY, .name = "UYVY", .bits_per_sample = 16, @@ -999,6 +1432,8 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx, cam->subrect = rect; cam->width = mf.width; cam->height = mf.height; + cam->out_width = mf.width; + cam->out_height = mf.height; icd->host_priv = cam; } else { @@ -1259,6 +1694,9 @@ static int rcar_vin_set_fmt(struct soc_camera_device *icd, dev_dbg(dev, "W: %u : %u, H: %u : %u\n", vin_sub_width, pix->width, vin_sub_height, pix->height); + cam->out_width = pix->width; + cam->out_height = pix->height; + icd->current_fmt = xlate; priv->field = field; @@ -1310,8 +1748,12 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd, if (ret < 0) return ret; - pix->width = mf.width; - pix->height = mf.height; + /* Adjust only if VIN cannot scale */ + if (pix->width > mf.width * 2) + pix->width = mf.width * 2; + if (pix->height > mf.height * 3) + pix->height = mf.height * 3; + pix->field = mf.field; pix->colorspace = mf.colorspace; @@ -1357,7 +1799,9 @@ static int rcar_vin_querycap(struct soc_camera_host *ici, struct v4l2_capability *cap) { strlcpy(cap->card, "R_Car_VIN", sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + return 0; } @@ -1395,6 +1839,8 @@ static struct soc_camera_host_ops rcar_vin_host_ops = { #ifdef CONFIG_OF static struct of_device_id rcar_vin_of_table[] = { + { .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 }, + { .compatible = "renesas,vin-r8a7793", .data = (void *)RCAR_GEN2 }, { .compatible = "renesas,vin-r8a7791", .data = (void *)RCAR_GEN2 }, { .compatible = "renesas,vin-r8a7790", .data = (void *)RCAR_GEN2 }, { .compatible = "renesas,vin-r8a7779", .data = (void *)RCAR_H1 }, diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 8b27b3eb2b25..71787702d4a2 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -1652,7 +1652,9 @@ static int sh_mobile_ceu_querycap(struct soc_camera_host *ici, struct v4l2_capability *cap) { strlcpy(cap->card, "SuperH_Mobile_CEU", sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + return 0; } diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c index ee5c3992b276..39ff79f6aa67 100644 --- a/drivers/media/platform/vivid/vivid-vid-out.c +++ b/drivers/media/platform/vivid/vivid-vid-out.c @@ -625,7 +625,7 @@ int vivid_vid_out_g_selection(struct file *file, void *priv, sel->r = dev->fmt_out_rect; break; case V4L2_SEL_TGT_CROP_BOUNDS: - if (!dev->has_compose_out) + if (!dev->has_crop_out) return -EINVAL; sel->r = vivid_max_rect; break; diff --git a/drivers/media/usb/Kconfig b/drivers/media/usb/Kconfig index 056181f2f569..7496f332f3f5 100644 --- a/drivers/media/usb/Kconfig +++ b/drivers/media/usb/Kconfig @@ -24,7 +24,6 @@ if MEDIA_ANALOG_TV_SUPPORT comment "Analog TV USB devices" source "drivers/media/usb/pvrusb2/Kconfig" source "drivers/media/usb/hdpvr/Kconfig" -source "drivers/media/usb/tlg2300/Kconfig" source "drivers/media/usb/usbvision/Kconfig" source "drivers/media/usb/stk1160/Kconfig" source "drivers/media/usb/go7007/Kconfig" diff --git a/drivers/media/usb/Makefile b/drivers/media/usb/Makefile index 6f2eb7c8416c..8874ba774a34 100644 --- a/drivers/media/usb/Makefile +++ b/drivers/media/usb/Makefile @@ -16,7 +16,6 @@ obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ obj-$(CONFIG_VIDEO_AU0828) += au0828/ obj-$(CONFIG_VIDEO_HDPVR) += hdpvr/ obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/ -obj-$(CONFIG_VIDEO_TLG2300) += tlg2300/ obj-$(CONFIG_VIDEO_USBVISION) += usbvision/ obj-$(CONFIG_VIDEO_STK1160) += stk1160/ obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/ diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index 0f345b1f9014..f327c49d7e09 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c @@ -2232,7 +2232,7 @@ static struct dvb_usb_device_properties cxusb_mygica_t230_properties = { { "Mygica T230 DVB-T/T2/C", { NULL }, - { &cxusb_table[22], NULL }, + { &cxusb_table[20], NULL }, }, } }; diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c index 1b158f1167ed..536210b39428 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c @@ -89,16 +89,6 @@ static int vbi_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1}; module_param_array(vbi_nr, int, NULL, 0444); MODULE_PARM_DESC(vbi_nr, "Offset for device's vbi dev minor"); -static struct v4l2_capability pvr_capability ={ - .driver = "pvrusb2", - .card = "Hauppauge WinTV pvr-usb2", - .bus_info = "usb", - .version = LINUX_VERSION_CODE, - .capabilities = (V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | - V4L2_CAP_READWRITE), -}; - static struct v4l2_fmtdesc pvr_fmtdesc [] = { { .index = 0, @@ -160,10 +150,22 @@ static int pvr2_querycap(struct file *file, void *priv, struct v4l2_capability * struct pvr2_v4l2_fh *fh = file->private_data; struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability)); + strlcpy(cap->driver, "pvrusb2", sizeof(cap->driver)); strlcpy(cap->bus_info, pvr2_hdw_get_bus_info(hdw), sizeof(cap->bus_info)); strlcpy(cap->card, pvr2_hdw_get_desc(hdw), sizeof(cap->card)); + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | + V4L2_CAP_AUDIO | V4L2_CAP_RADIO | + V4L2_CAP_READWRITE | V4L2_CAP_DEVICE_CAPS; + switch (fh->pdi->devbase.vfl_type) { + case VFL_TYPE_GRABBER: + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO; + break; + case VFL_TYPE_RADIO: + cap->device_caps = V4L2_CAP_RADIO; + break; + } + cap->device_caps |= V4L2_CAP_TUNER | V4L2_CAP_READWRITE; return 0; } diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 75658717961f..faac2f4e0f3a 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1017,6 +1017,12 @@ static int v4l_querycap(const struct v4l2_ioctl_ops *ops, ret = ops->vidioc_querycap(file, fh, cap); cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT; + /* + * Drivers MUST fill in device_caps, so check for this and + * warn if it was forgotten. + */ + WARN_ON(!(cap->capabilities & V4L2_CAP_DEVICE_CAPS) || + !cap->device_caps); cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT; return ret; diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index d09a8916e940..bc08a829bc13 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -3146,27 +3146,26 @@ static int vb2_thread(void *data) prequeue--; } else { call_void_qop(q, wait_finish, q); - ret = vb2_internal_dqbuf(q, &fileio->b, 0); + if (!threadio->stop) + ret = vb2_internal_dqbuf(q, &fileio->b, 0); call_void_qop(q, wait_prepare, q); dprintk(5, "file io: vb2_dqbuf result: %d\n", ret); } - if (threadio->stop) - break; - if (ret) + if (ret || threadio->stop) break; try_to_freeze(); vb = q->bufs[fileio->b.index]; if (!(fileio->b.flags & V4L2_BUF_FLAG_ERROR)) - ret = threadio->fnc(vb, threadio->priv); - if (ret) - break; + if (threadio->fnc(vb, threadio->priv)) + break; call_void_qop(q, wait_finish, q); if (set_timestamp) v4l2_get_timestamp(&fileio->b.timestamp); - ret = vb2_internal_qbuf(q, &fileio->b); + if (!threadio->stop) + ret = vb2_internal_qbuf(q, &fileio->b); call_void_qop(q, wait_prepare, q); - if (ret) + if (ret || threadio->stop) break; } @@ -3235,11 +3234,11 @@ int vb2_thread_stop(struct vb2_queue *q) threadio->stop = true; vb2_internal_streamoff(q, q->type); call_void_qop(q, wait_prepare, q); + err = kthread_stop(threadio->thread); q->fileio = NULL; fileio->req.count = 0; vb2_reqbufs(q, &fileio->req); kfree(fileio); - err = kthread_stop(threadio->thread); threadio->thread = NULL; kfree(threadio); q->fileio = NULL; diff --git a/drivers/memory/fsl_ifc.c b/drivers/memory/fsl_ifc.c index 3d5d792d5cb2..410c39749872 100644 --- a/drivers/memory/fsl_ifc.c +++ b/drivers/memory/fsl_ifc.c @@ -61,7 +61,7 @@ int fsl_ifc_find(phys_addr_t addr_base) if (!fsl_ifc_ctrl_dev || !fsl_ifc_ctrl_dev->regs) return -ENODEV; - for (i = 0; i < ARRAY_SIZE(fsl_ifc_ctrl_dev->regs->cspr_cs); i++) { + for (i = 0; i < fsl_ifc_ctrl_dev->banks; i++) { u32 cspr = in_be32(&fsl_ifc_ctrl_dev->regs->cspr_cs[i].cspr); if (cspr & CSPR_V && (cspr & CSPR_BA) == convert_ifc_address(addr_base)) @@ -213,7 +213,7 @@ static irqreturn_t fsl_ifc_ctrl_irq(int irqno, void *data) static int fsl_ifc_ctrl_probe(struct platform_device *dev) { int ret = 0; - + int version, banks; dev_info(&dev->dev, "Freescale Integrated Flash Controller\n"); @@ -231,6 +231,15 @@ static int fsl_ifc_ctrl_probe(struct platform_device *dev) goto err; } + version = ioread32be(&fsl_ifc_ctrl_dev->regs->ifc_rev) & + FSL_IFC_VERSION_MASK; + banks = (version == FSL_IFC_VERSION_1_0_0) ? 4 : 8; + dev_info(&dev->dev, "IFC version %d.%d, %d banks\n", + version >> 24, (version >> 16) & 0xf, banks); + + fsl_ifc_ctrl_dev->version = version; + fsl_ifc_ctrl_dev->banks = banks; + /* get the Controller level irq */ fsl_ifc_ctrl_dev->irq = irq_of_parse_and_map(dev->dev.of_node, 0); if (fsl_ifc_ctrl_dev->irq == NO_IRQ) { diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c index 52a0c2f6264f..ae498b53ee40 100644 --- a/drivers/mfd/da9052-core.c +++ b/drivers/mfd/da9052-core.c @@ -554,7 +554,8 @@ int da9052_device_init(struct da9052 *da9052, u8 chip_id) return ret; } - ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info, + ret = mfd_add_devices(da9052->dev, PLATFORM_DEVID_AUTO, + da9052_subdev_info, ARRAY_SIZE(da9052_subdev_info), NULL, 0, NULL); if (ret) { dev_err(da9052->dev, "mfd_add_devices failed: %d\n", ret); diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c index dbdd0faeb6ce..210d1f85679e 100644 --- a/drivers/mfd/rtsx_usb.c +++ b/drivers/mfd/rtsx_usb.c @@ -681,21 +681,9 @@ static void rtsx_usb_disconnect(struct usb_interface *intf) #ifdef CONFIG_PM static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message) { - struct rtsx_ucr *ucr = - (struct rtsx_ucr *)usb_get_intfdata(intf); - dev_dbg(&intf->dev, "%s called with pm message 0x%04x\n", __func__, message.event); - /* - * Call to make sure LED is off during suspend to save more power. - * It is NOT a permanent state and could be turned on anytime later. - * Thus no need to call turn_on when resunming. - */ - mutex_lock(&ucr->dev_mutex); - rtsx_usb_turn_off_led(ucr); - mutex_unlock(&ucr->dev_mutex); - return 0; } diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index e2f9df1c0c36..2d7fae94c861 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c @@ -519,6 +519,7 @@ static const u8 stmpe1601_regs[] = { [STMPE_IDX_GPDR_LSB] = STMPE1601_REG_GPIO_SET_DIR_LSB, [STMPE_IDX_GPRER_LSB] = STMPE1601_REG_GPIO_RE_LSB, [STMPE_IDX_GPFER_LSB] = STMPE1601_REG_GPIO_FE_LSB, + [STMPE_IDX_GPPUR_LSB] = STMPE1601_REG_GPIO_PU_LSB, [STMPE_IDX_GPAFR_U_MSB] = STMPE1601_REG_GPIO_AF_U_MSB, [STMPE_IDX_IEGPIOR_LSB] = STMPE1601_REG_INT_EN_GPIO_MASK_LSB, [STMPE_IDX_ISGPIOR_MSB] = STMPE1601_REG_INT_STA_GPIO_MSB, @@ -667,6 +668,7 @@ static const u8 stmpe1801_regs[] = { [STMPE_IDX_GPDR_LSB] = STMPE1801_REG_GPIO_SET_DIR_LOW, [STMPE_IDX_GPRER_LSB] = STMPE1801_REG_GPIO_RE_LOW, [STMPE_IDX_GPFER_LSB] = STMPE1801_REG_GPIO_FE_LOW, + [STMPE_IDX_GPPUR_LSB] = STMPE1801_REG_GPIO_PULL_UP_LOW, [STMPE_IDX_IEGPIOR_LSB] = STMPE1801_REG_INT_EN_GPIO_MASK_LOW, [STMPE_IDX_ISGPIOR_LSB] = STMPE1801_REG_INT_STA_GPIO_LOW, }; @@ -750,6 +752,8 @@ static const u8 stmpe24xx_regs[] = { [STMPE_IDX_GPDR_LSB] = STMPE24XX_REG_GPDR_LSB, [STMPE_IDX_GPRER_LSB] = STMPE24XX_REG_GPRER_LSB, [STMPE_IDX_GPFER_LSB] = STMPE24XX_REG_GPFER_LSB, + [STMPE_IDX_GPPUR_LSB] = STMPE24XX_REG_GPPUR_LSB, + [STMPE_IDX_GPPDR_LSB] = STMPE24XX_REG_GPPDR_LSB, [STMPE_IDX_GPAFR_U_MSB] = STMPE24XX_REG_GPAFR_U_MSB, [STMPE_IDX_IEGPIOR_LSB] = STMPE24XX_REG_IEGPIOR_LSB, [STMPE_IDX_ISGPIOR_MSB] = STMPE24XX_REG_ISGPIOR_MSB, diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h index bee0abf82040..84adb46b3e2f 100644 --- a/drivers/mfd/stmpe.h +++ b/drivers/mfd/stmpe.h @@ -188,6 +188,7 @@ int stmpe_remove(struct stmpe *stmpe); #define STMPE1601_REG_GPIO_ED_MSB 0x8A #define STMPE1601_REG_GPIO_RE_LSB 0x8D #define STMPE1601_REG_GPIO_FE_LSB 0x8F +#define STMPE1601_REG_GPIO_PU_LSB 0x91 #define STMPE1601_REG_GPIO_AF_U_MSB 0x92 #define STMPE1601_SYS_CTRL_ENABLE_GPIO (1 << 3) @@ -276,6 +277,8 @@ int stmpe_remove(struct stmpe *stmpe); #define STMPE24XX_REG_GPEDR_MSB 0x8C #define STMPE24XX_REG_GPRER_LSB 0x91 #define STMPE24XX_REG_GPFER_LSB 0x94 +#define STMPE24XX_REG_GPPUR_LSB 0x97 +#define STMPE24XX_REG_GPPDR_LSB 0x9a #define STMPE24XX_REG_GPAFR_U_MSB 0x9B #define STMPE24XX_SYS_CTRL_ENABLE_GPIO (1 << 3) diff --git a/drivers/mfd/tps65218.c b/drivers/mfd/tps65218.c index 0d256cb002eb..d6b764349f9d 100644 --- a/drivers/mfd/tps65218.c +++ b/drivers/mfd/tps65218.c @@ -125,10 +125,21 @@ int tps65218_clear_bits(struct tps65218 *tps, unsigned int reg, } EXPORT_SYMBOL_GPL(tps65218_clear_bits); +static const struct regmap_range tps65218_yes_ranges[] = { + regmap_reg_range(TPS65218_REG_INT1, TPS65218_REG_INT2), + regmap_reg_range(TPS65218_REG_STATUS, TPS65218_REG_STATUS), +}; + +static const struct regmap_access_table tps65218_volatile_table = { + .yes_ranges = tps65218_yes_ranges, + .n_yes_ranges = ARRAY_SIZE(tps65218_yes_ranges), +}; + static struct regmap_config tps65218_regmap_config = { .reg_bits = 8, .val_bits = 8, .cache_type = REGCACHE_RBTREE, + .volatile_table = &tps65218_volatile_table, }; static const struct regmap_irq tps65218_irqs[] = { @@ -193,6 +204,7 @@ static struct regmap_irq_chip tps65218_irq_chip = { .num_regs = 2, .mask_base = TPS65218_REG_INT_MASK1, + .status_base = TPS65218_REG_INT1, }; static const struct of_device_id of_tps65218_match_table[] = { diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c index cca472109135..d1b55fe62817 100644 --- a/drivers/misc/cxl/context.c +++ b/drivers/misc/cxl/context.c @@ -34,7 +34,8 @@ struct cxl_context *cxl_context_alloc(void) /* * Initialises a CXL context. */ -int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master) +int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master, + struct address_space *mapping) { int i; @@ -42,6 +43,8 @@ int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master) ctx->afu = afu; ctx->master = master; ctx->pid = NULL; /* Set in start work ioctl */ + mutex_init(&ctx->mapping_lock); + ctx->mapping = mapping; /* * Allocate the segment table before we put it in the IDR so that we @@ -82,12 +85,12 @@ int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master) * Allocating IDR! We better make sure everything's setup that * dereferences from it. */ + mutex_lock(&afu->contexts_lock); idr_preload(GFP_KERNEL); - spin_lock(&afu->contexts_lock); i = idr_alloc(&ctx->afu->contexts_idr, ctx, 0, ctx->afu->num_procs, GFP_NOWAIT); - spin_unlock(&afu->contexts_lock); idr_preload_end(); + mutex_unlock(&afu->contexts_lock); if (i < 0) return i; @@ -97,6 +100,46 @@ int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master) return 0; } +static int cxl_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + struct cxl_context *ctx = vma->vm_file->private_data; + unsigned long address = (unsigned long)vmf->virtual_address; + u64 area, offset; + + offset = vmf->pgoff << PAGE_SHIFT; + + pr_devel("%s: pe: %i address: 0x%lx offset: 0x%llx\n", + __func__, ctx->pe, address, offset); + + if (ctx->afu->current_mode == CXL_MODE_DEDICATED) { + area = ctx->afu->psn_phys; + if (offset > ctx->afu->adapter->ps_size) + return VM_FAULT_SIGBUS; + } else { + area = ctx->psn_phys; + if (offset > ctx->psn_size) + return VM_FAULT_SIGBUS; + } + + mutex_lock(&ctx->status_mutex); + + if (ctx->status != STARTED) { + mutex_unlock(&ctx->status_mutex); + pr_devel("%s: Context not started, failing problem state access\n", __func__); + return VM_FAULT_SIGBUS; + } + + vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT); + + mutex_unlock(&ctx->status_mutex); + + return VM_FAULT_NOPAGE; +} + +static const struct vm_operations_struct cxl_mmap_vmops = { + .fault = cxl_mmap_fault, +}; + /* * Map a per-context mmio space into the given vma. */ @@ -105,26 +148,25 @@ int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma) u64 len = vma->vm_end - vma->vm_start; len = min(len, ctx->psn_size); - if (ctx->afu->current_mode == CXL_MODE_DEDICATED) { - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - return vm_iomap_memory(vma, ctx->afu->psn_phys, ctx->afu->adapter->ps_size); - } + if (ctx->afu->current_mode != CXL_MODE_DEDICATED) { + /* make sure there is a valid per process space for this AFU */ + if ((ctx->master && !ctx->afu->psa) || (!ctx->afu->pp_psa)) { + pr_devel("AFU doesn't support mmio space\n"); + return -EINVAL; + } - /* make sure there is a valid per process space for this AFU */ - if ((ctx->master && !ctx->afu->psa) || (!ctx->afu->pp_psa)) { - pr_devel("AFU doesn't support mmio space\n"); - return -EINVAL; + /* Can't mmap until the AFU is enabled */ + if (!ctx->afu->enabled) + return -EBUSY; } - /* Can't mmap until the AFU is enabled */ - if (!ctx->afu->enabled) - return -EBUSY; - pr_devel("%s: mmio physical: %llx pe: %i master:%i\n", __func__, ctx->psn_phys, ctx->pe , ctx->master); + vma->vm_flags |= VM_IO | VM_PFNMAP; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - return vm_iomap_memory(vma, ctx->psn_phys, len); + vma->vm_ops = &cxl_mmap_vmops; + return 0; } /* @@ -168,21 +210,33 @@ void cxl_context_detach_all(struct cxl_afu *afu) struct cxl_context *ctx; int tmp; - rcu_read_lock(); - idr_for_each_entry(&afu->contexts_idr, ctx, tmp) + mutex_lock(&afu->contexts_lock); + idr_for_each_entry(&afu->contexts_idr, ctx, tmp) { /* * Anything done in here needs to be setup before the IDR is * created and torn down after the IDR removed */ __detach_context(ctx); - rcu_read_unlock(); + + /* + * We are force detaching - remove any active PSA mappings so + * userspace cannot interfere with the card if it comes back. + * Easiest way to exercise this is to unbind and rebind the + * driver via sysfs while it is in use. + */ + mutex_lock(&ctx->mapping_lock); + if (ctx->mapping) + unmap_mapping_range(ctx->mapping, 0, 0, 1); + mutex_unlock(&ctx->mapping_lock); + } + mutex_unlock(&afu->contexts_lock); } void cxl_context_free(struct cxl_context *ctx) { - spin_lock(&ctx->afu->contexts_lock); + mutex_lock(&ctx->afu->contexts_lock); idr_remove(&ctx->afu->contexts_idr, ctx->pe); - spin_unlock(&ctx->afu->contexts_lock); + mutex_unlock(&ctx->afu->contexts_lock); synchronize_rcu(); free_page((u64)ctx->sstp); diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index b5b6bda44a00..28078f8894a5 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h @@ -351,7 +351,7 @@ struct cxl_afu { struct device *chardev_s, *chardev_m, *chardev_d; struct idr contexts_idr; struct dentry *debugfs; - spinlock_t contexts_lock; + struct mutex contexts_lock; struct mutex spa_mutex; spinlock_t afu_cntl_lock; @@ -398,6 +398,10 @@ struct cxl_context { phys_addr_t psn_phys; u64 psn_size; + /* Used to unmap any mmaps when force detaching */ + struct address_space *mapping; + struct mutex mapping_lock; + spinlock_t sste_lock; /* Protects segment table entries */ struct cxl_sste *sstp; u64 sstp0, sstp1; @@ -599,7 +603,8 @@ int cxl_alloc_sst(struct cxl_context *ctx); void init_cxl_native(void); struct cxl_context *cxl_context_alloc(void); -int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master); +int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master, + struct address_space *mapping); void cxl_context_free(struct cxl_context *ctx); int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma); diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c index 378b099e7c0b..b15d8113877c 100644 --- a/drivers/misc/cxl/file.c +++ b/drivers/misc/cxl/file.c @@ -77,7 +77,7 @@ static int __afu_open(struct inode *inode, struct file *file, bool master) goto err_put_afu; } - if ((rc = cxl_context_init(ctx, afu, master))) + if ((rc = cxl_context_init(ctx, afu, master, inode->i_mapping))) goto err_put_afu; pr_devel("afu_open pe: %i\n", ctx->pe); @@ -113,6 +113,10 @@ static int afu_release(struct inode *inode, struct file *file) __func__, ctx->pe); cxl_context_detach(ctx); + mutex_lock(&ctx->mapping_lock); + ctx->mapping = NULL; + mutex_unlock(&ctx->mapping_lock); + put_device(&ctx->afu->dev); /* @@ -136,18 +140,20 @@ static long afu_ioctl_start_work(struct cxl_context *ctx, pr_devel("%s: pe: %i\n", __func__, ctx->pe); - mutex_lock(&ctx->status_mutex); - if (ctx->status != OPENED) { - rc = -EIO; - goto out; - } - + /* Do this outside the status_mutex to avoid a circular dependency with + * the locking in cxl_mmap_fault() */ if (copy_from_user(&work, uwork, sizeof(struct cxl_ioctl_start_work))) { rc = -EFAULT; goto out; } + mutex_lock(&ctx->status_mutex); + if (ctx->status != OPENED) { + rc = -EIO; + goto out; + } + /* * if any of the reserved fields are set or any of the unused * flags are set it's invalid diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c index 9a5a442269a8..f2b37b41a0da 100644 --- a/drivers/misc/cxl/native.c +++ b/drivers/misc/cxl/native.c @@ -277,6 +277,7 @@ static int do_process_element_cmd(struct cxl_context *ctx, u64 cmd, u64 pe_state) { u64 state; + unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT); WARN_ON(!ctx->afu->enabled); @@ -286,6 +287,10 @@ static int do_process_element_cmd(struct cxl_context *ctx, smp_mb(); cxl_p1n_write(ctx->afu, CXL_PSL_LLCMD_An, cmd | ctx->pe); while (1) { + if (time_after_eq(jiffies, timeout)) { + dev_warn(&ctx->afu->dev, "WARNING: Process Element Command timed out!\n"); + return -EBUSY; + } state = be64_to_cpup(ctx->afu->sw_command_status); if (state == ~0ULL) { pr_err("cxl: Error adding process element to AFU\n"); @@ -610,13 +615,6 @@ static inline int detach_process_native_dedicated(struct cxl_context *ctx) return 0; } -/* - * TODO: handle case when this is called inside a rcu_read_lock() which may - * happen when we unbind the driver (ie. cxl_context_detach_all()) . Terminate - * & remove use a mutex lock and schedule which will not good with lock held. - * May need to write do_process_element_cmd() that handles outstanding page - * faults synchronously. - */ static inline int detach_process_native_afu_directed(struct cxl_context *ctx) { if (!ctx->pe_inserted) diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c index 10c98ab7f46e..0f2cc9f8b4db 100644 --- a/drivers/misc/cxl/pci.c +++ b/drivers/misc/cxl/pci.c @@ -502,7 +502,7 @@ static struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice) afu->dev.release = cxl_release_afu; afu->slice = slice; idr_init(&afu->contexts_idr); - spin_lock_init(&afu->contexts_lock); + mutex_init(&afu->contexts_lock); spin_lock_init(&afu->afu_cntl_lock); mutex_init(&afu->spa_mutex); diff --git a/drivers/misc/cxl/sysfs.c b/drivers/misc/cxl/sysfs.c index ce7ec06d87d1..461bdbd5d483 100644 --- a/drivers/misc/cxl/sysfs.c +++ b/drivers/misc/cxl/sysfs.c @@ -121,7 +121,7 @@ static ssize_t reset_store_afu(struct device *device, int rc; /* Not safe to reset if it is currently in use */ - spin_lock(&afu->contexts_lock); + mutex_lock(&afu->contexts_lock); if (!idr_is_empty(&afu->contexts_idr)) { rc = -EBUSY; goto err; @@ -132,7 +132,7 @@ static ssize_t reset_store_afu(struct device *device, rc = count; err: - spin_unlock(&afu->contexts_lock); + mutex_unlock(&afu->contexts_lock); return rc; } @@ -247,7 +247,7 @@ static ssize_t mode_store(struct device *device, struct device_attribute *attr, int rc = -EBUSY; /* can't change this if we have a user */ - spin_lock(&afu->contexts_lock); + mutex_lock(&afu->contexts_lock); if (!idr_is_empty(&afu->contexts_idr)) goto err; @@ -271,7 +271,7 @@ static ssize_t mode_store(struct device *device, struct device_attribute *attr, afu->current_mode = 0; afu->num_procs = 0; - spin_unlock(&afu->contexts_lock); + mutex_unlock(&afu->contexts_lock); if ((rc = _cxl_afu_deactivate_mode(afu, old_mode))) return rc; @@ -280,7 +280,7 @@ static ssize_t mode_store(struct device *device, struct device_attribute *attr, return count; err: - spin_unlock(&afu->contexts_lock); + mutex_unlock(&afu->contexts_lock); return rc; } diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index ff2755062b44..06ff0a2ec960 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -234,6 +234,18 @@ static int mei_me_hw_reset(struct mei_device *dev, bool intr_enable) struct mei_me_hw *hw = to_me_hw(dev); u32 hcsr = mei_hcsr_read(hw); + /* H_RST may be found lit before reset is started, + * for example if preceding reset flow hasn't completed. + * In that case asserting H_RST will be ignored, therefore + * we need to clean H_RST bit to start a successful reset sequence. + */ + if ((hcsr & H_RST) == H_RST) { + dev_warn(dev->dev, "H_RST is set = 0x%08X", hcsr); + hcsr &= ~H_RST; + mei_me_reg_write(hw, H_CSR, hcsr); + hcsr = mei_hcsr_read(hw); + } + hcsr |= H_RST | H_IG | H_IS; if (intr_enable) diff --git a/drivers/misc/mic/host/mic_debugfs.c b/drivers/misc/mic/host/mic_debugfs.c index 028ba5d6fd1c..687e9aacf3bb 100644 --- a/drivers/misc/mic/host/mic_debugfs.c +++ b/drivers/misc/mic/host/mic_debugfs.c @@ -326,21 +326,27 @@ static int mic_vdev_info_show(struct seq_file *s, void *unused) } avail = vrh->vring.avail; seq_printf(s, "avail flags 0x%x idx %d\n", - avail->flags, avail->idx & (num - 1)); + vringh16_to_cpu(vrh, avail->flags), + vringh16_to_cpu(vrh, avail->idx) & (num - 1)); seq_printf(s, "avail flags 0x%x idx %d\n", - avail->flags, avail->idx); + vringh16_to_cpu(vrh, avail->flags), + vringh16_to_cpu(vrh, avail->idx)); for (j = 0; j < num; j++) seq_printf(s, "avail ring[%d] %d\n", j, avail->ring[j]); used = vrh->vring.used; seq_printf(s, "used flags 0x%x idx %d\n", - used->flags, used->idx & (num - 1)); + vringh16_to_cpu(vrh, used->flags), + vringh16_to_cpu(vrh, used->idx) & (num - 1)); seq_printf(s, "used flags 0x%x idx %d\n", - used->flags, used->idx); + vringh16_to_cpu(vrh, used->flags), + vringh16_to_cpu(vrh, used->idx)); for (j = 0; j < num; j++) seq_printf(s, "used ring[%d] id %d len %d\n", - j, used->ring[j].id, - used->ring[j].len); + j, vringh32_to_cpu(vrh, + used->ring[j].id), + vringh32_to_cpu(vrh, + used->ring[j].len)); } } mutex_unlock(&mdev->mic_mutex); diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 02ad79229f65..7466ce098e60 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -886,7 +886,7 @@ static int mmc_select_bus_width(struct mmc_card *card) unsigned idx, bus_width = 0; int err = 0; - if (!mmc_can_ext_csd(card) && + if (!mmc_can_ext_csd(card) || !(host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) return 0; diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 62aba9af19f4..03d7c7521d97 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -2561,7 +2561,7 @@ static int atmci_runtime_resume(struct device *dev) static const struct dev_pm_ops atmci_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) - SET_PM_RUNTIME_PM_OPS(atmci_runtime_suspend, atmci_runtime_resume, NULL) + SET_RUNTIME_PM_OPS(atmci_runtime_suspend, atmci_runtime_resume, NULL) }; static struct platform_driver atmci_driver = { diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index e3e56d35f0ee..970314e0aac8 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c @@ -247,6 +247,7 @@ static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = { { "INT33BB" , "3" , &sdhci_acpi_slot_int_sd }, { "INT33C6" , NULL, &sdhci_acpi_slot_int_sdio }, { "INT3436" , NULL, &sdhci_acpi_slot_int_sdio }, + { "INT344D" , NULL, &sdhci_acpi_slot_int_sdio }, { "PNP0D40" }, { }, }; @@ -257,6 +258,7 @@ static const struct acpi_device_id sdhci_acpi_ids[] = { { "INT33BB" }, { "INT33C6" }, { "INT3436" }, + { "INT344D" }, { "PNP0D40" }, { }, }; diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 03427755b902..4f38554ce679 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -993,6 +993,31 @@ static const struct pci_device_id pci_ids[] = { .subdevice = PCI_ANY_ID, .driver_data = (kernel_ulong_t)&sdhci_intel_mrfl_mmc, }, + + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_SPT_EMMC, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (kernel_ulong_t)&sdhci_intel_byt_emmc, + }, + + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_SPT_SDIO, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sdio, + }, + + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_SPT_SD, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sd, + }, + { .vendor = PCI_VENDOR_ID_O2, .device = PCI_DEVICE_ID_O2_8120, diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h index d57c3d169914..1ec684d06d54 100644 --- a/drivers/mmc/host/sdhci-pci.h +++ b/drivers/mmc/host/sdhci-pci.h @@ -21,6 +21,9 @@ #define PCI_DEVICE_ID_INTEL_CLV_EMMC0 0x08e5 #define PCI_DEVICE_ID_INTEL_CLV_EMMC1 0x08e6 #define PCI_DEVICE_ID_INTEL_QRK_SD 0x08A7 +#define PCI_DEVICE_ID_INTEL_SPT_EMMC 0x9d2b +#define PCI_DEVICE_ID_INTEL_SPT_SDIO 0x9d2c +#define PCI_DEVICE_ID_INTEL_SPT_SD 0x9d2d /* * PCI registers diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index 45238871192d..ca3424e7ef71 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c @@ -300,13 +300,6 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) if (IS_ERR(host)) return PTR_ERR(host); - if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) { - ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info()); - if (ret < 0) - goto err_mbus_win; - } - - pltfm_host = sdhci_priv(host); pltfm_host->priv = pxa; @@ -325,6 +318,12 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) if (!IS_ERR(pxa->clk_core)) clk_prepare_enable(pxa->clk_core); + if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) { + ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info()); + if (ret < 0) + goto err_mbus_win; + } + /* enable 1/8V DDR capable */ host->mmc->caps |= MMC_CAP_1_8V_DDR; @@ -396,11 +395,11 @@ err_add_host: pm_runtime_disable(&pdev->dev); err_of_parse: err_cd_req: +err_mbus_win: clk_disable_unprepare(pxa->clk_io); if (!IS_ERR(pxa->clk_core)) clk_disable_unprepare(pxa->clk_core); err_clk_get: -err_mbus_win: sdhci_pltfm_free(pdev); return ret; } diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index cbb245b58538..f1a488ee432f 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -259,8 +259,6 @@ static void sdhci_reinit(struct sdhci_host *host) del_timer_sync(&host->tuning_timer); host->flags &= ~SDHCI_NEEDS_RETUNING; - host->mmc->max_blk_count = - (host->quirks & SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535; } sdhci_enable_card_detection(host); } @@ -1273,6 +1271,12 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned char mode, spin_unlock_irq(&host->lock); mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); spin_lock_irq(&host->lock); + + if (mode != MMC_POWER_OFF) + sdhci_writeb(host, SDHCI_POWER_ON, SDHCI_POWER_CONTROL); + else + sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); + return; } @@ -1353,6 +1357,8 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) sdhci_runtime_pm_get(host); + present = mmc_gpio_get_cd(host->mmc); + spin_lock_irqsave(&host->lock, flags); WARN_ON(host->mrq != NULL); @@ -1381,7 +1387,6 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) * zero: cd-gpio is used, and card is removed * one: cd-gpio is used, and card is present */ - present = mmc_gpio_get_cd(host->mmc); if (present < 0) { /* If polling, assume that the card is always present. */ if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) @@ -1880,6 +1885,18 @@ static int sdhci_card_busy(struct mmc_host *mmc) return !(present_state & SDHCI_DATA_LVL_MASK); } +static int sdhci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct sdhci_host *host = mmc_priv(mmc); + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + host->flags |= SDHCI_HS400_TUNING; + spin_unlock_irqrestore(&host->lock, flags); + + return 0; +} + static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) { struct sdhci_host *host = mmc_priv(mmc); @@ -1887,10 +1904,18 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) int tuning_loop_counter = MAX_TUNING_LOOP; int err = 0; unsigned long flags; + unsigned int tuning_count = 0; + bool hs400_tuning; sdhci_runtime_pm_get(host); spin_lock_irqsave(&host->lock, flags); + hs400_tuning = host->flags & SDHCI_HS400_TUNING; + host->flags &= ~SDHCI_HS400_TUNING; + + if (host->tuning_mode == SDHCI_TUNING_MODE_1) + tuning_count = host->tuning_count; + /* * The Host Controller needs tuning only in case of SDR104 mode * and for SDR50 mode when Use Tuning for SDR50 is set in the @@ -1899,8 +1924,20 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) * tuning function has to be executed. */ switch (host->timing) { + /* HS400 tuning is done in HS200 mode */ case MMC_TIMING_MMC_HS400: + err = -EINVAL; + goto out_unlock; + case MMC_TIMING_MMC_HS200: + /* + * Periodic re-tuning for HS400 is not expected to be needed, so + * disable it here. + */ + if (hs400_tuning) + tuning_count = 0; + break; + case MMC_TIMING_UHS_SDR104: break; @@ -1911,9 +1948,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) /* FALLTHROUGH */ default: - spin_unlock_irqrestore(&host->lock, flags); - sdhci_runtime_pm_put(host); - return 0; + goto out_unlock; } if (host->ops->platform_execute_tuning) { @@ -2037,24 +2072,11 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) } out: - /* - * If this is the very first time we are here, we start the retuning - * timer. Since only during the first time, SDHCI_NEEDS_RETUNING - * flag won't be set, we check this condition before actually starting - * the timer. - */ - if (!(host->flags & SDHCI_NEEDS_RETUNING) && host->tuning_count && - (host->tuning_mode == SDHCI_TUNING_MODE_1)) { + host->flags &= ~SDHCI_NEEDS_RETUNING; + + if (tuning_count) { host->flags |= SDHCI_USING_RETUNING_TIMER; - mod_timer(&host->tuning_timer, jiffies + - host->tuning_count * HZ); - /* Tuning mode 1 limits the maximum data length to 4MB */ - mmc->max_blk_count = (4 * 1024 * 1024) / mmc->max_blk_size; - } else if (host->flags & SDHCI_USING_RETUNING_TIMER) { - host->flags &= ~SDHCI_NEEDS_RETUNING; - /* Reload the new initial value for timer */ - mod_timer(&host->tuning_timer, jiffies + - host->tuning_count * HZ); + mod_timer(&host->tuning_timer, jiffies + tuning_count * HZ); } /* @@ -2070,6 +2092,7 @@ out: sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); +out_unlock: spin_unlock_irqrestore(&host->lock, flags); sdhci_runtime_pm_put(host); @@ -2110,15 +2133,18 @@ static void sdhci_card_event(struct mmc_host *mmc) { struct sdhci_host *host = mmc_priv(mmc); unsigned long flags; + int present; /* First check if client has provided their own card event */ if (host->ops->card_event) host->ops->card_event(host); + present = sdhci_do_get_cd(host); + spin_lock_irqsave(&host->lock, flags); /* Check host->mrq first in case we are runtime suspended */ - if (host->mrq && !sdhci_do_get_cd(host)) { + if (host->mrq && !present) { pr_err("%s: Card removed during transfer!\n", mmc_hostname(host->mmc)); pr_err("%s: Resetting controller.\n", @@ -2142,6 +2168,7 @@ static const struct mmc_host_ops sdhci_ops = { .hw_reset = sdhci_hw_reset, .enable_sdio_irq = sdhci_enable_sdio_irq, .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, + .prepare_hs400_tuning = sdhci_prepare_hs400_tuning, .execute_tuning = sdhci_execute_tuning, .card_event = sdhci_card_event, .card_busy = sdhci_card_busy, @@ -3260,8 +3287,9 @@ int sdhci_add_host(struct sdhci_host *host) mmc->max_segs = SDHCI_MAX_SEGS; /* - * Maximum number of sectors in one transfer. Limited by DMA boundary - * size (512KiB). + * Maximum number of sectors in one transfer. Limited by SDMA boundary + * size (512KiB). Note some tuning modes impose a 4MiB limit, but this + * is less anyway. */ mmc->max_req_size = 524288; diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 94b821042d9d..71fea895ce38 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -133,7 +133,7 @@ config MTD_OF_PARTS help This provides a partition parsing function which derives the partition map from the children of the flash node, - as described in Documentation/devicetree/booting-without-of.txt. + as described in Documentation/devicetree/bindings/mtd/partition.txt. config MTD_AR7_PARTS tristate "TI AR7 partitioning support" diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c index 8057f52a45b7..cc13ea5ce4d5 100644 --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c @@ -15,8 +15,12 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> -/* 10 parts were found on sflash on Netgear WNDR4500 */ -#define BCM47XXPART_MAX_PARTS 12 +/* + * NAND flash on Netgear R6250 was verified to contain 15 partitions. + * This will result in allocating too big array for some old devices, but the + * memory will be freed soon anyway (see mtd_device_parse_register). + */ +#define BCM47XXPART_MAX_PARTS 20 /* * Amount of bytes we read when analyzing each block of flash memory. @@ -168,18 +172,26 @@ static int bcm47xxpart_parse(struct mtd_info *master, i++; } - bcm47xxpart_add_part(&parts[curr_part++], "linux", - offset + trx->offset[i], 0); - i++; + if (trx->offset[i]) { + bcm47xxpart_add_part(&parts[curr_part++], + "linux", + offset + trx->offset[i], + 0); + i++; + } /* * Pure rootfs size is known and can be calculated as: * trx->length - trx->offset[i]. We don't fill it as * we want to have jffs2 (overlay) in the same mtd. */ - bcm47xxpart_add_part(&parts[curr_part++], "rootfs", - offset + trx->offset[i], 0); - i++; + if (trx->offset[i]) { + bcm47xxpart_add_part(&parts[curr_part++], + "rootfs", + offset + trx->offset[i], + 0); + i++; + } last_trx_part = curr_part - 1; diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 3096f3ded3ad..286b97a304cf 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -2654,8 +2654,7 @@ static void cfi_intelext_destroy(struct mtd_info *mtd) kfree(cfi); for (i = 0; i < mtd->numeraseregions; i++) { region = &mtd->eraseregions[i]; - if (region->lockmap) - kfree(region->lockmap); + kfree(region->lockmap); } kfree(mtd->eraseregions); } diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index 72346048532d..448ce42f951e 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -22,6 +22,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/errno.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/string.h> #include <linux/slab.h> @@ -1655,22 +1656,21 @@ static int dbg_flashctrl_show(struct seq_file *s, void *p) { struct docg3 *docg3 = (struct docg3 *)s->private; - int pos = 0; u8 fctrl; mutex_lock(&docg3->cascade->lock); fctrl = doc_register_readb(docg3, DOC_FLASHCONTROL); mutex_unlock(&docg3->cascade->lock); - pos += seq_printf(s, - "FlashControl : 0x%02x (%s,CE# %s,%s,%s,flash %s)\n", - fctrl, - fctrl & DOC_CTRL_VIOLATION ? "protocol violation" : "-", - fctrl & DOC_CTRL_CE ? "active" : "inactive", - fctrl & DOC_CTRL_PROTECTION_ERROR ? "protection error" : "-", - fctrl & DOC_CTRL_SEQUENCE_ERROR ? "sequence error" : "-", - fctrl & DOC_CTRL_FLASHREADY ? "ready" : "not ready"); - return pos; + seq_printf(s, "FlashControl : 0x%02x (%s,CE# %s,%s,%s,flash %s)\n", + fctrl, + fctrl & DOC_CTRL_VIOLATION ? "protocol violation" : "-", + fctrl & DOC_CTRL_CE ? "active" : "inactive", + fctrl & DOC_CTRL_PROTECTION_ERROR ? "protection error" : "-", + fctrl & DOC_CTRL_SEQUENCE_ERROR ? "sequence error" : "-", + fctrl & DOC_CTRL_FLASHREADY ? "ready" : "not ready"); + + return 0; } DEBUGFS_RO_ATTR(flashcontrol, dbg_flashctrl_show); @@ -1678,58 +1678,56 @@ static int dbg_asicmode_show(struct seq_file *s, void *p) { struct docg3 *docg3 = (struct docg3 *)s->private; - int pos = 0, pctrl, mode; + int pctrl, mode; mutex_lock(&docg3->cascade->lock); pctrl = doc_register_readb(docg3, DOC_ASICMODE); mode = pctrl & 0x03; mutex_unlock(&docg3->cascade->lock); - pos += seq_printf(s, - "%04x : RAM_WE=%d,RSTIN_RESET=%d,BDETCT_RESET=%d,WRITE_ENABLE=%d,POWERDOWN=%d,MODE=%d%d (", - pctrl, - pctrl & DOC_ASICMODE_RAM_WE ? 1 : 0, - pctrl & DOC_ASICMODE_RSTIN_RESET ? 1 : 0, - pctrl & DOC_ASICMODE_BDETCT_RESET ? 1 : 0, - pctrl & DOC_ASICMODE_MDWREN ? 1 : 0, - pctrl & DOC_ASICMODE_POWERDOWN ? 1 : 0, - mode >> 1, mode & 0x1); + seq_printf(s, + "%04x : RAM_WE=%d,RSTIN_RESET=%d,BDETCT_RESET=%d,WRITE_ENABLE=%d,POWERDOWN=%d,MODE=%d%d (", + pctrl, + pctrl & DOC_ASICMODE_RAM_WE ? 1 : 0, + pctrl & DOC_ASICMODE_RSTIN_RESET ? 1 : 0, + pctrl & DOC_ASICMODE_BDETCT_RESET ? 1 : 0, + pctrl & DOC_ASICMODE_MDWREN ? 1 : 0, + pctrl & DOC_ASICMODE_POWERDOWN ? 1 : 0, + mode >> 1, mode & 0x1); switch (mode) { case DOC_ASICMODE_RESET: - pos += seq_puts(s, "reset"); + seq_puts(s, "reset"); break; case DOC_ASICMODE_NORMAL: - pos += seq_puts(s, "normal"); + seq_puts(s, "normal"); break; case DOC_ASICMODE_POWERDOWN: - pos += seq_puts(s, "powerdown"); + seq_puts(s, "powerdown"); break; } - pos += seq_puts(s, ")\n"); - return pos; + seq_puts(s, ")\n"); + return 0; } DEBUGFS_RO_ATTR(asic_mode, dbg_asicmode_show); static int dbg_device_id_show(struct seq_file *s, void *p) { struct docg3 *docg3 = (struct docg3 *)s->private; - int pos = 0; int id; mutex_lock(&docg3->cascade->lock); id = doc_register_readb(docg3, DOC_DEVICESELECT); mutex_unlock(&docg3->cascade->lock); - pos += seq_printf(s, "DeviceId = %d\n", id); - return pos; + seq_printf(s, "DeviceId = %d\n", id); + return 0; } DEBUGFS_RO_ATTR(device_id, dbg_device_id_show); static int dbg_protection_show(struct seq_file *s, void *p) { struct docg3 *docg3 = (struct docg3 *)s->private; - int pos = 0; int protect, dps0, dps0_low, dps0_high, dps1, dps1_low, dps1_high; mutex_lock(&docg3->cascade->lock); @@ -1742,45 +1740,40 @@ static int dbg_protection_show(struct seq_file *s, void *p) dps1_high = doc_register_readw(docg3, DOC_DPS1_ADDRHIGH); mutex_unlock(&docg3->cascade->lock); - pos += seq_printf(s, "Protection = 0x%02x (", - protect); + seq_printf(s, "Protection = 0x%02x (", protect); if (protect & DOC_PROTECT_FOUNDRY_OTP_LOCK) - pos += seq_puts(s, "FOUNDRY_OTP_LOCK,"); + seq_puts(s, "FOUNDRY_OTP_LOCK,"); if (protect & DOC_PROTECT_CUSTOMER_OTP_LOCK) - pos += seq_puts(s, "CUSTOMER_OTP_LOCK,"); + seq_puts(s, "CUSTOMER_OTP_LOCK,"); if (protect & DOC_PROTECT_LOCK_INPUT) - pos += seq_puts(s, "LOCK_INPUT,"); + seq_puts(s, "LOCK_INPUT,"); if (protect & DOC_PROTECT_STICKY_LOCK) - pos += seq_puts(s, "STICKY_LOCK,"); + seq_puts(s, "STICKY_LOCK,"); if (protect & DOC_PROTECT_PROTECTION_ENABLED) - pos += seq_puts(s, "PROTECTION ON,"); + seq_puts(s, "PROTECTION ON,"); if (protect & DOC_PROTECT_IPL_DOWNLOAD_LOCK) - pos += seq_puts(s, "IPL_DOWNLOAD_LOCK,"); + seq_puts(s, "IPL_DOWNLOAD_LOCK,"); if (protect & DOC_PROTECT_PROTECTION_ERROR) - pos += seq_puts(s, "PROTECT_ERR,"); + seq_puts(s, "PROTECT_ERR,"); else - pos += seq_puts(s, "NO_PROTECT_ERR"); - pos += seq_puts(s, ")\n"); - - pos += seq_printf(s, "DPS0 = 0x%02x : " - "Protected area [0x%x - 0x%x] : OTP=%d, READ=%d, " - "WRITE=%d, HW_LOCK=%d, KEY_OK=%d\n", - dps0, dps0_low, dps0_high, - !!(dps0 & DOC_DPS_OTP_PROTECTED), - !!(dps0 & DOC_DPS_READ_PROTECTED), - !!(dps0 & DOC_DPS_WRITE_PROTECTED), - !!(dps0 & DOC_DPS_HW_LOCK_ENABLED), - !!(dps0 & DOC_DPS_KEY_OK)); - pos += seq_printf(s, "DPS1 = 0x%02x : " - "Protected area [0x%x - 0x%x] : OTP=%d, READ=%d, " - "WRITE=%d, HW_LOCK=%d, KEY_OK=%d\n", - dps1, dps1_low, dps1_high, - !!(dps1 & DOC_DPS_OTP_PROTECTED), - !!(dps1 & DOC_DPS_READ_PROTECTED), - !!(dps1 & DOC_DPS_WRITE_PROTECTED), - !!(dps1 & DOC_DPS_HW_LOCK_ENABLED), - !!(dps1 & DOC_DPS_KEY_OK)); - return pos; + seq_puts(s, "NO_PROTECT_ERR"); + seq_puts(s, ")\n"); + + seq_printf(s, "DPS0 = 0x%02x : Protected area [0x%x - 0x%x] : OTP=%d, READ=%d, WRITE=%d, HW_LOCK=%d, KEY_OK=%d\n", + dps0, dps0_low, dps0_high, + !!(dps0 & DOC_DPS_OTP_PROTECTED), + !!(dps0 & DOC_DPS_READ_PROTECTED), + !!(dps0 & DOC_DPS_WRITE_PROTECTED), + !!(dps0 & DOC_DPS_HW_LOCK_ENABLED), + !!(dps0 & DOC_DPS_KEY_OK)); + seq_printf(s, "DPS1 = 0x%02x : Protected area [0x%x - 0x%x] : OTP=%d, READ=%d, WRITE=%d, HW_LOCK=%d, KEY_OK=%d\n", + dps1, dps1_low, dps1_high, + !!(dps1 & DOC_DPS_OTP_PROTECTED), + !!(dps1 & DOC_DPS_READ_PROTECTED), + !!(dps1 & DOC_DPS_WRITE_PROTECTED), + !!(dps1 & DOC_DPS_HW_LOCK_ENABLED), + !!(dps1 & DOC_DPS_KEY_OK)); + return 0; } DEBUGFS_RO_ATTR(protection, dbg_protection_show); @@ -2126,9 +2119,18 @@ static int __exit docg3_release(struct platform_device *pdev) return 0; } +#ifdef CONFIG_OF +static struct of_device_id docg3_dt_ids[] = { + { .compatible = "m-systems,diskonchip-g3" }, + {} +}; +MODULE_DEVICE_TABLE(of, docg3_dt_ids); +#endif + static struct platform_driver g3_driver = { .driver = { .name = "docg3", + .of_match_table = of_match_ptr(docg3_dt_ids), }, .suspend = docg3_suspend, .resume = docg3_resume, diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index ed827cf894e4..85e35467fba6 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -128,13 +128,10 @@ static int m25p80_read(struct spi_nor *nor, loff_t from, size_t len, struct spi_device *spi = flash->spi; struct spi_transfer t[2]; struct spi_message m; - int dummy = nor->read_dummy; - int ret; + unsigned int dummy = nor->read_dummy; - /* Wait till previous write/erase is done. */ - ret = nor->wait_till_ready(nor); - if (ret) - return ret; + /* convert the dummy cycles to the number of bytes */ + dummy /= 8; spi_message_init(&m); memset(t, 0, (sizeof t)); @@ -160,21 +157,10 @@ static int m25p80_read(struct spi_nor *nor, loff_t from, size_t len, static int m25p80_erase(struct spi_nor *nor, loff_t offset) { struct m25p *flash = nor->priv; - int ret; dev_dbg(nor->dev, "%dKiB at 0x%08x\n", flash->mtd.erasesize / 1024, (u32)offset); - /* Wait until finished previous write command. */ - ret = nor->wait_till_ready(nor); - if (ret) - return ret; - - /* Send write enable, then erase commands. */ - ret = nor->write_reg(nor, SPINOR_OP_WREN, NULL, 0, 0); - if (ret) - return ret; - /* Set up command buffer. */ flash->command[0] = nor->erase_opcode; m25p_addr2cmd(nor, offset, flash->command); @@ -260,7 +246,6 @@ static int m25p_remove(struct spi_device *spi) return mtd_device_unregister(&flash->mtd); } - /* * XXX This needs to be kept in sync with spi_nor_ids. We can't share * it with spi-nor, because if this is built as a module then modpost @@ -287,7 +272,7 @@ static const struct spi_device_id m25p_ids[] = { {"s25fl512s"}, {"s70fl01gs"}, {"s25sl12800"}, {"s25sl12801"}, {"s25fl129p0"}, {"s25fl129p1"}, {"s25sl004a"}, {"s25sl008a"}, {"s25sl016a"}, {"s25sl032a"}, {"s25sl064a"}, {"s25fl008k"}, - {"s25fl016k"}, {"s25fl064k"}, + {"s25fl016k"}, {"s25fl064k"}, {"s25fl132k"}, {"sst25vf040b"},{"sst25vf080b"},{"sst25vf016b"},{"sst25vf032b"}, {"sst25vf064c"},{"sst25wf512"}, {"sst25wf010"}, {"sst25wf020"}, {"sst25wf040"}, @@ -300,17 +285,16 @@ static const struct spi_device_id m25p_ids[] = { {"m45pe10"}, {"m45pe80"}, {"m45pe16"}, {"m25pe20"}, {"m25pe80"}, {"m25pe16"}, {"m25px16"}, {"m25px32"}, {"m25px32-s0"}, {"m25px32-s1"}, - {"m25px64"}, + {"m25px64"}, {"m25px80"}, {"w25x10"}, {"w25x20"}, {"w25x40"}, {"w25x80"}, {"w25x16"}, {"w25x32"}, {"w25q32"}, {"w25q32dw"}, - {"w25x64"}, {"w25q64"}, {"w25q128"}, {"w25q80"}, - {"w25q80bl"}, {"w25q128"}, {"w25q256"}, {"cat25c11"}, + {"w25x64"}, {"w25q64"}, {"w25q80"}, {"w25q80bl"}, + {"w25q128"}, {"w25q256"}, {"cat25c11"}, {"cat25c03"}, {"cat25c09"}, {"cat25c17"}, {"cat25128"}, { }, }; MODULE_DEVICE_TABLE(spi, m25p_ids); - static struct spi_driver m25p80_driver = { .driver = { .name = "m25p80", diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index dd22ce2cc9ad..0099aba72a8b 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c @@ -149,7 +149,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr) { struct dataflash *priv = mtd->priv; struct spi_device *spi = priv->spi; - struct spi_transfer x = { .tx_dma = 0, }; + struct spi_transfer x = { }; struct spi_message msg; unsigned blocksize = priv->page_size << 3; uint8_t *command; @@ -235,7 +235,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { struct dataflash *priv = mtd->priv; - struct spi_transfer x[2] = { { .tx_dma = 0, }, }; + struct spi_transfer x[2] = { }; struct spi_message msg; unsigned int addr; uint8_t *command; @@ -301,7 +301,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, { struct dataflash *priv = mtd->priv; struct spi_device *spi = priv->spi; - struct spi_transfer x[2] = { { .tx_dma = 0, }, }; + struct spi_transfer x[2] = { }; struct spi_message msg; unsigned int pageaddr, addr, offset, writelen; size_t remaining = len; diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index effd9a4ef7ee..8b66e52ca3cc 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c @@ -17,7 +17,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include <asm/io.h> +#include <linux/io.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/list.h> diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c index f02603e1bfeb..708b7e8c8b18 100644 --- a/drivers/mtd/devices/pmc551.c +++ b/drivers/mtd/devices/pmc551.c @@ -812,8 +812,7 @@ static int __init init_pmc551(void) } /* Exited early, reference left over */ - if (PCI_Device) - pci_dev_put(PCI_Device); + pci_dev_put(PCI_Device); if (!pmc551list) { printk(KERN_NOTICE "pmc551: not detected\n"); diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c index 487e64f411a5..1388c8d7f309 100644 --- a/drivers/mtd/inftlmount.c +++ b/drivers/mtd/inftlmount.c @@ -518,7 +518,7 @@ void INFTL_dumpVUchains(struct INFTLrecord *s) pr_debug("INFTL Virtual Unit Chains:\n"); for (logical = 0; logical < s->nb_blocks; logical++) { block = s->VUtable[logical]; - if (block > s->nb_blocks) + if (block >= s->nb_blocks) continue; pr_debug(" LOGICAL %d --> %d ", logical, block); for (i = 0; i < s->nb_blocks; i++) { diff --git a/drivers/mtd/maps/bfin-async-flash.c b/drivers/mtd/maps/bfin-async-flash.c index 6ea51e549045..41730feeace8 100644 --- a/drivers/mtd/maps/bfin-async-flash.c +++ b/drivers/mtd/maps/bfin-async-flash.c @@ -126,7 +126,6 @@ static const char * const part_probe_types[] = { static int bfin_flash_probe(struct platform_device *pdev) { - int ret; struct physmap_flash_data *pdata = dev_get_platdata(&pdev->dev); struct resource *memory = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct resource *flash_ambctl = platform_get_resource(pdev, IORESOURCE_MEM, 1); diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index 991d0cb871f0..f35cd2081314 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -47,14 +47,12 @@ static int of_flash_remove(struct platform_device *dev) return 0; dev_set_drvdata(&dev->dev, NULL); - if (info->cmtd != info->list[0].mtd) { + if (info->cmtd) { mtd_device_unregister(info->cmtd); - mtd_concat_destroy(info->cmtd); + if (info->cmtd != info->list[0].mtd) + mtd_concat_destroy(info->cmtd); } - if (info->cmtd) - mtd_device_unregister(info->cmtd); - for (i = 0; i < info->list_size; i++) { if (info->list[i].mtd) map_destroy(info->list[i].mtd); diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index dd10646982ae..7d0150d20432 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -75,10 +75,12 @@ config MTD_NAND_DENALI_SCRATCH_REG_ADDR boards, the scratch register is at 0xFF108018. config MTD_NAND_GPIO - tristate "GPIO NAND Flash driver" + tristate "GPIO assisted NAND Flash driver" depends on GPIOLIB help - This enables a GPIO based NAND flash driver. + This enables a NAND flash driver where control signals are + connected to GPIO pins, and commands and data are communicated + via a memory mapped interface. config MTD_NAND_AMS_DELTA tristate "NAND Flash device on Amstrad E3" @@ -516,4 +518,10 @@ config MTD_NAND_XWAY Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached to the External Bus Unit (EBU). +config MTD_NAND_SUNXI + tristate "Support for NAND on Allwinner SoCs" + depends on ARCH_SUNXI + help + Enables support for NAND Flash chips on Allwinner SoCs. + endif # MTD_NAND diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 9c847e469ca7..bd38f21d2e28 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -50,5 +50,6 @@ obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/ obj-$(CONFIG_MTD_NAND_XWAY) += xway_nand.o obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash/ +obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_nand.o nand-objs := nand_base.o nand_bbt.o nand_timings.o diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 84c38f3c65b0..a345e7b2463a 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -92,7 +92,7 @@ static struct nand_ecclayout atmel_oobinfo_small = { struct atmel_nfc { void __iomem *base_cmd_regs; void __iomem *hsmc_regs; - void __iomem *sram_bank0; + void *sram_bank0; dma_addr_t sram_bank0_phys; bool use_nfc_sram; bool write_by_sram; @@ -105,7 +105,7 @@ struct atmel_nfc { struct completion comp_xfer_done; /* Point to the sram bank which include readed data via NFC */ - void __iomem *data_in_sram; + void *data_in_sram; bool will_write_sram; }; static struct atmel_nfc nand_nfc; @@ -127,6 +127,7 @@ struct atmel_nand_host { bool has_pmecc; u8 pmecc_corr_cap; u16 pmecc_sector_size; + bool has_no_lookup_table; u32 pmecc_lookup_table_offset; u32 pmecc_lookup_table_offset_512; u32 pmecc_lookup_table_offset_1024; @@ -256,26 +257,6 @@ static int atmel_nand_set_enable_ready_pins(struct mtd_info *mtd) return res; } -static void memcpy32_fromio(void *trg, const void __iomem *src, size_t size) -{ - int i; - u32 *t = trg; - const __iomem u32 *s = src; - - for (i = 0; i < (size >> 2); i++) - *t++ = readl_relaxed(s++); -} - -static void memcpy32_toio(void __iomem *trg, const void *src, int size) -{ - int i; - u32 __iomem *t = trg; - const u32 *s = src; - - for (i = 0; i < (size >> 2); i++) - writel_relaxed(*s++, t++); -} - /* * Minimal-overhead PIO for data access. */ @@ -285,7 +266,7 @@ static void atmel_read_buf8(struct mtd_info *mtd, u8 *buf, int len) struct atmel_nand_host *host = nand_chip->priv; if (host->nfc && host->nfc->use_nfc_sram && host->nfc->data_in_sram) { - memcpy32_fromio(buf, host->nfc->data_in_sram, len); + memcpy(buf, host->nfc->data_in_sram, len); host->nfc->data_in_sram += len; } else { __raw_readsb(nand_chip->IO_ADDR_R, buf, len); @@ -298,7 +279,7 @@ static void atmel_read_buf16(struct mtd_info *mtd, u8 *buf, int len) struct atmel_nand_host *host = nand_chip->priv; if (host->nfc && host->nfc->use_nfc_sram && host->nfc->data_in_sram) { - memcpy32_fromio(buf, host->nfc->data_in_sram, len); + memcpy(buf, host->nfc->data_in_sram, len); host->nfc->data_in_sram += len; } else { __raw_readsw(nand_chip->IO_ADDR_R, buf, len / 2); @@ -1112,12 +1093,66 @@ static int pmecc_choose_ecc(struct atmel_nand_host *host, return 0; } +static inline int deg(unsigned int poly) +{ + /* polynomial degree is the most-significant bit index */ + return fls(poly) - 1; +} + +static int build_gf_tables(int mm, unsigned int poly, + int16_t *index_of, int16_t *alpha_to) +{ + unsigned int i, x = 1; + const unsigned int k = 1 << deg(poly); + unsigned int nn = (1 << mm) - 1; + + /* primitive polynomial must be of degree m */ + if (k != (1u << mm)) + return -EINVAL; + + for (i = 0; i < nn; i++) { + alpha_to[i] = x; + index_of[x] = i; + if (i && (x == 1)) + /* polynomial is not primitive (a^i=1 with 0<i<2^m-1) */ + return -EINVAL; + x <<= 1; + if (x & k) + x ^= poly; + } + alpha_to[nn] = 1; + index_of[0] = 0; + + return 0; +} + +static uint16_t *create_lookup_table(struct device *dev, int sector_size) +{ + int degree = (sector_size == 512) ? + PMECC_GF_DIMENSION_13 : + PMECC_GF_DIMENSION_14; + unsigned int poly = (sector_size == 512) ? + PMECC_GF_13_PRIMITIVE_POLY : + PMECC_GF_14_PRIMITIVE_POLY; + int table_size = (sector_size == 512) ? + PMECC_LOOKUP_TABLE_SIZE_512 : + PMECC_LOOKUP_TABLE_SIZE_1024; + + int16_t *addr = devm_kzalloc(dev, 2 * table_size * sizeof(uint16_t), + GFP_KERNEL); + if (addr && build_gf_tables(degree, poly, addr, addr + table_size)) + return NULL; + + return addr; +} + static int atmel_pmecc_nand_init_params(struct platform_device *pdev, struct atmel_nand_host *host) { struct mtd_info *mtd = &host->mtd; struct nand_chip *nand_chip = &host->nand_chip; struct resource *regs, *regs_pmerr, *regs_rom; + uint16_t *galois_table; int cap, sector_size, err_no; err_no = pmecc_choose_ecc(host, &cap, §or_size); @@ -1163,8 +1198,24 @@ static int atmel_pmecc_nand_init_params(struct platform_device *pdev, regs_rom = platform_get_resource(pdev, IORESOURCE_MEM, 3); host->pmecc_rom_base = devm_ioremap_resource(&pdev->dev, regs_rom); if (IS_ERR(host->pmecc_rom_base)) { - err_no = PTR_ERR(host->pmecc_rom_base); - goto err; + if (!host->has_no_lookup_table) + /* Don't display the information again */ + dev_err(host->dev, "Can not get I/O resource for ROM, will build a lookup table in runtime!\n"); + + host->has_no_lookup_table = true; + } + + if (host->has_no_lookup_table) { + /* Build the look-up table in runtime */ + galois_table = create_lookup_table(host->dev, sector_size); + if (!galois_table) { + dev_err(host->dev, "Failed to build a lookup table in runtime!\n"); + err_no = -EINVAL; + goto err; + } + + host->pmecc_rom_base = (void __iomem *)galois_table; + host->pmecc_lookup_table_offset = 0; } nand_chip->ecc.size = sector_size; @@ -1501,8 +1552,10 @@ static int atmel_of_init_port(struct atmel_nand_host *host, if (of_property_read_u32_array(np, "atmel,pmecc-lookup-table-offset", offset, 2) != 0) { - dev_err(host->dev, "Cannot get PMECC lookup table offset\n"); - return -EINVAL; + dev_err(host->dev, "Cannot get PMECC lookup table offset, will build a lookup table in runtime.\n"); + host->has_no_lookup_table = true; + /* Will build a lookup table and initialize the offset later */ + return 0; } if (!offset[0] && !offset[1]) { dev_err(host->dev, "Invalid PMECC lookup table offset\n"); @@ -1899,7 +1952,7 @@ static int nfc_sram_write_page(struct mtd_info *mtd, struct nand_chip *chip, int cfg, len; int status = 0; struct atmel_nand_host *host = chip->priv; - void __iomem *sram = host->nfc->sram_bank0 + nfc_get_sram_off(host); + void *sram = host->nfc->sram_bank0 + nfc_get_sram_off(host); /* Subpage write is not supported */ if (offset || (data_len < mtd->writesize)) @@ -1910,14 +1963,14 @@ static int nfc_sram_write_page(struct mtd_info *mtd, struct nand_chip *chip, if (use_dma) { if (atmel_nand_dma_op(mtd, (void *)buf, len, 0) != 0) /* Fall back to use cpu copy */ - memcpy32_toio(sram, buf, len); + memcpy(sram, buf, len); } else { - memcpy32_toio(sram, buf, len); + memcpy(sram, buf, len); } cfg = nfc_readl(host->nfc->hsmc_regs, CFG); if (unlikely(raw) && oob_required) { - memcpy32_toio(sram + len, chip->oob_poi, mtd->oobsize); + memcpy(sram + len, chip->oob_poi, mtd->oobsize); len += mtd->oobsize; nfc_writel(host->nfc->hsmc_regs, CFG, cfg | NFC_CFG_WSPARE); } else { @@ -2260,7 +2313,8 @@ static int atmel_nand_nfc_probe(struct platform_device *pdev) nfc_sram = platform_get_resource(pdev, IORESOURCE_MEM, 2); if (nfc_sram) { - nfc->sram_bank0 = devm_ioremap_resource(&pdev->dev, nfc_sram); + nfc->sram_bank0 = (void * __force) + devm_ioremap_resource(&pdev->dev, nfc_sram); if (IS_ERR(nfc->sram_bank0)) { dev_warn(&pdev->dev, "Fail to ioremap the NFC sram with error: %ld. So disable NFC sram.\n", PTR_ERR(nfc->sram_bank0)); diff --git a/drivers/mtd/nand/atmel_nand_ecc.h b/drivers/mtd/nand/atmel_nand_ecc.h index 8a1e9a686759..d4035e335ad8 100644 --- a/drivers/mtd/nand/atmel_nand_ecc.h +++ b/drivers/mtd/nand/atmel_nand_ecc.h @@ -142,6 +142,10 @@ #define PMECC_GF_DIMENSION_13 13 #define PMECC_GF_DIMENSION_14 14 +/* Primitive Polynomial used by PMECC */ +#define PMECC_GF_13_PRIMITIVE_POLY 0x201b +#define PMECC_GF_14_PRIMITIVE_POLY 0x4443 + #define PMECC_LOOKUP_TABLE_SIZE_512 0x2000 #define PMECC_LOOKUP_TABLE_SIZE_1024 0x4000 diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index 4e66726da9aa..9a0f45f1d932 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c @@ -529,50 +529,6 @@ static int cafe_nand_write_page_lowlevel(struct mtd_info *mtd, return 0; } -static int cafe_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, - uint32_t offset, int data_len, const uint8_t *buf, - int oob_required, int page, int cached, int raw) -{ - int status; - - chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); - - if (unlikely(raw)) - status = chip->ecc.write_page_raw(mtd, chip, buf, oob_required); - else - status = chip->ecc.write_page(mtd, chip, buf, oob_required); - - if (status < 0) - return status; - - /* - * Cached progamming disabled for now, Not sure if its worth the - * trouble. The speed gain is not very impressive. (2.3->2.6Mib/s) - */ - cached = 0; - - if (!cached || !(chip->options & NAND_CACHEPRG)) { - - chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); - status = chip->waitfunc(mtd, chip); - /* - * See if operation failed and additional status checks are - * available - */ - if ((status & NAND_STATUS_FAIL) && (chip->errstat)) - status = chip->errstat(mtd, chip, FL_WRITING, status, - page); - - if (status & NAND_STATUS_FAIL) - return -EIO; - } else { - chip->cmdfunc(mtd, NAND_CMD_CACHEDPROG, -1, -1); - status = chip->waitfunc(mtd, chip); - } - - return 0; -} - static int cafe_nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) { return 0; @@ -800,7 +756,6 @@ static int cafe_nand_probe(struct pci_dev *pdev, cafe->nand.ecc.hwctl = (void *)cafe_nand_bug; cafe->nand.ecc.calculate = (void *)cafe_nand_bug; cafe->nand.ecc.correct = (void *)cafe_nand_bug; - cafe->nand.write_page = cafe_nand_write_page; cafe->nand.ecc.write_page = cafe_nand_write_page_lowlevel; cafe->nand.ecc.write_oob = cafe_nand_write_oob; cafe->nand.ecc.read_page = cafe_nand_read_page; diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index b9ef7a6bba42..4c05f4f6a5c6 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -31,7 +31,6 @@ #include <linux/mtd/nand_ecc.h> #include <linux/fsl_ifc.h> -#define FSL_IFC_V1_1_0 0x01010000 #define ERR_BYTE 0xFF /* Value returned for read bytes when read failed */ #define IFC_TIMEOUT_MSECS 500 /* Maximum number of mSecs to wait @@ -877,7 +876,7 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv) struct fsl_ifc_regs __iomem *ifc = ctrl->regs; struct nand_chip *chip = &priv->chip; struct nand_ecclayout *layout; - u32 csor, ver; + u32 csor; /* Fill in fsl_ifc_mtd structure */ priv->mtd.priv = chip; @@ -984,8 +983,7 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv) chip->ecc.mode = NAND_ECC_SOFT; } - ver = ioread32be(&ifc->ifc_rev); - if (ver == FSL_IFC_V1_1_0) + if (ctrl->version == FSL_IFC_VERSION_1_1_0) fsl_ifc_sram_init(priv); return 0; @@ -1045,12 +1043,12 @@ static int fsl_ifc_nand_probe(struct platform_device *dev) } /* find which chip select it is connected to */ - for (bank = 0; bank < FSL_IFC_BANK_COUNT; bank++) { + for (bank = 0; bank < fsl_ifc_ctrl_dev->banks; bank++) { if (match_bank(ifc, bank, res.start)) break; } - if (bank >= FSL_IFC_BANK_COUNT) { + if (bank >= fsl_ifc_ctrl_dev->banks) { dev_err(&dev->dev, "%s: address did not match any chip selects\n", __func__); return -ENODEV; diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/gpio.c index 918283999a4b..73c4048c3a56 100644 --- a/drivers/mtd/nand/gpio.c +++ b/drivers/mtd/nand/gpio.c @@ -8,7 +8,9 @@ * * © 2004 Simtec Electronics * - * Device driver for NAND connected via GPIO + * Device driver for NAND flash that uses a memory mapped interface to + * read/write the NAND commands and data, and GPIO pins for control signals + * (the DT binding refers to this as "GPIO assisted NAND flash") * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c index 87e658ce23ef..27f272ed502a 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c @@ -1353,3 +1353,156 @@ int gpmi_read_page(struct gpmi_nand_data *this, set_dma_type(this, DMA_FOR_READ_ECC_PAGE); return start_dma_with_bch_irq(this, desc); } + +/** + * gpmi_copy_bits - copy bits from one memory region to another + * @dst: destination buffer + * @dst_bit_off: bit offset we're starting to write at + * @src: source buffer + * @src_bit_off: bit offset we're starting to read from + * @nbits: number of bits to copy + * + * This functions copies bits from one memory region to another, and is used by + * the GPMI driver to copy ECC sections which are not guaranteed to be byte + * aligned. + * + * src and dst should not overlap. + * + */ +void gpmi_copy_bits(u8 *dst, size_t dst_bit_off, + const u8 *src, size_t src_bit_off, + size_t nbits) +{ + size_t i; + size_t nbytes; + u32 src_buffer = 0; + size_t bits_in_src_buffer = 0; + + if (!nbits) + return; + + /* + * Move src and dst pointers to the closest byte pointer and store bit + * offsets within a byte. + */ + src += src_bit_off / 8; + src_bit_off %= 8; + + dst += dst_bit_off / 8; + dst_bit_off %= 8; + + /* + * Initialize the src_buffer value with bits available in the first + * byte of data so that we end up with a byte aligned src pointer. + */ + if (src_bit_off) { + src_buffer = src[0] >> src_bit_off; + if (nbits >= (8 - src_bit_off)) { + bits_in_src_buffer += 8 - src_bit_off; + } else { + src_buffer &= GENMASK(nbits - 1, 0); + bits_in_src_buffer += nbits; + } + nbits -= bits_in_src_buffer; + src++; + } + + /* Calculate the number of bytes that can be copied from src to dst. */ + nbytes = nbits / 8; + + /* Try to align dst to a byte boundary. */ + if (dst_bit_off) { + if (bits_in_src_buffer < (8 - dst_bit_off) && nbytes) { + src_buffer |= src[0] << bits_in_src_buffer; + bits_in_src_buffer += 8; + src++; + nbytes--; + } + + if (bits_in_src_buffer >= (8 - dst_bit_off)) { + dst[0] &= GENMASK(dst_bit_off - 1, 0); + dst[0] |= src_buffer << dst_bit_off; + src_buffer >>= (8 - dst_bit_off); + bits_in_src_buffer -= (8 - dst_bit_off); + dst_bit_off = 0; + dst++; + if (bits_in_src_buffer > 7) { + bits_in_src_buffer -= 8; + dst[0] = src_buffer; + dst++; + src_buffer >>= 8; + } + } + } + + if (!bits_in_src_buffer && !dst_bit_off) { + /* + * Both src and dst pointers are byte aligned, thus we can + * just use the optimized memcpy function. + */ + if (nbytes) + memcpy(dst, src, nbytes); + } else { + /* + * src buffer is not byte aligned, hence we have to copy each + * src byte to the src_buffer variable before extracting a byte + * to store in dst. + */ + for (i = 0; i < nbytes; i++) { + src_buffer |= src[i] << bits_in_src_buffer; + dst[i] = src_buffer; + src_buffer >>= 8; + } + } + /* Update dst and src pointers */ + dst += nbytes; + src += nbytes; + + /* + * nbits is the number of remaining bits. It should not exceed 8 as + * we've already copied as much bytes as possible. + */ + nbits %= 8; + + /* + * If there's no more bits to copy to the destination and src buffer + * was already byte aligned, then we're done. + */ + if (!nbits && !bits_in_src_buffer) + return; + + /* Copy the remaining bits to src_buffer */ + if (nbits) + src_buffer |= (*src & GENMASK(nbits - 1, 0)) << + bits_in_src_buffer; + bits_in_src_buffer += nbits; + + /* + * In case there were not enough bits to get a byte aligned dst buffer + * prepare the src_buffer variable to match the dst organization (shift + * src_buffer by dst_bit_off and retrieve the least significant bits + * from dst). + */ + if (dst_bit_off) + src_buffer = (src_buffer << dst_bit_off) | + (*dst & GENMASK(dst_bit_off - 1, 0)); + bits_in_src_buffer += dst_bit_off; + + /* + * Keep most significant bits from dst if we end up with an unaligned + * number of bits. + */ + nbytes = bits_in_src_buffer / 8; + if (bits_in_src_buffer % 8) { + src_buffer |= (dst[nbytes] & + GENMASK(7, bits_in_src_buffer % 8)) << + (nbytes * 8); + nbytes++; + } + + /* Copy the remaining bytes to dst */ + for (i = 0; i < nbytes; i++) { + dst[i] = src_buffer; + src_buffer >>= 8; + } +} diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 959cb9b70310..4f3851a24bb2 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -791,6 +791,7 @@ static void gpmi_free_dma_buffer(struct gpmi_nand_data *this) this->page_buffer_phys); kfree(this->cmd_buffer); kfree(this->data_buffer_dma); + kfree(this->raw_buffer); this->cmd_buffer = NULL; this->data_buffer_dma = NULL; @@ -837,6 +838,9 @@ static int gpmi_alloc_dma_buffer(struct gpmi_nand_data *this) if (!this->page_buffer_virt) goto error_alloc; + this->raw_buffer = kzalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL); + if (!this->raw_buffer) + goto error_alloc; /* Slice up the page buffer. */ this->payload_virt = this->page_buffer_virt; @@ -1347,6 +1351,199 @@ gpmi_ecc_write_oob(struct mtd_info *mtd, struct nand_chip *chip, int page) return status & NAND_STATUS_FAIL ? -EIO : 0; } +/* + * This function reads a NAND page without involving the ECC engine (no HW + * ECC correction). + * The tricky part in the GPMI/BCH controller is that it stores ECC bits + * inline (interleaved with payload DATA), and do not align data chunk on + * byte boundaries. + * We thus need to take care moving the payload data and ECC bits stored in the + * page into the provided buffers, which is why we're using gpmi_copy_bits. + * + * See set_geometry_by_ecc_info inline comments to have a full description + * of the layout used by the GPMI controller. + */ +static int gpmi_ecc_read_page_raw(struct mtd_info *mtd, + struct nand_chip *chip, uint8_t *buf, + int oob_required, int page) +{ + struct gpmi_nand_data *this = chip->priv; + struct bch_geometry *nfc_geo = &this->bch_geometry; + int eccsize = nfc_geo->ecc_chunk_size; + int eccbits = nfc_geo->ecc_strength * nfc_geo->gf_len; + u8 *tmp_buf = this->raw_buffer; + size_t src_bit_off; + size_t oob_bit_off; + size_t oob_byte_off; + uint8_t *oob = chip->oob_poi; + int step; + + chip->read_buf(mtd, tmp_buf, + mtd->writesize + mtd->oobsize); + + /* + * If required, swap the bad block marker and the data stored in the + * metadata section, so that we don't wrongly consider a block as bad. + * + * See the layout description for a detailed explanation on why this + * is needed. + */ + if (this->swap_block_mark) { + u8 swap = tmp_buf[0]; + + tmp_buf[0] = tmp_buf[mtd->writesize]; + tmp_buf[mtd->writesize] = swap; + } + + /* + * Copy the metadata section into the oob buffer (this section is + * guaranteed to be aligned on a byte boundary). + */ + if (oob_required) + memcpy(oob, tmp_buf, nfc_geo->metadata_size); + + oob_bit_off = nfc_geo->metadata_size * 8; + src_bit_off = oob_bit_off; + + /* Extract interleaved payload data and ECC bits */ + for (step = 0; step < nfc_geo->ecc_chunk_count; step++) { + if (buf) + gpmi_copy_bits(buf, step * eccsize * 8, + tmp_buf, src_bit_off, + eccsize * 8); + src_bit_off += eccsize * 8; + + /* Align last ECC block to align a byte boundary */ + if (step == nfc_geo->ecc_chunk_count - 1 && + (oob_bit_off + eccbits) % 8) + eccbits += 8 - ((oob_bit_off + eccbits) % 8); + + if (oob_required) + gpmi_copy_bits(oob, oob_bit_off, + tmp_buf, src_bit_off, + eccbits); + + src_bit_off += eccbits; + oob_bit_off += eccbits; + } + + if (oob_required) { + oob_byte_off = oob_bit_off / 8; + + if (oob_byte_off < mtd->oobsize) + memcpy(oob + oob_byte_off, + tmp_buf + mtd->writesize + oob_byte_off, + mtd->oobsize - oob_byte_off); + } + + return 0; +} + +/* + * This function writes a NAND page without involving the ECC engine (no HW + * ECC generation). + * The tricky part in the GPMI/BCH controller is that it stores ECC bits + * inline (interleaved with payload DATA), and do not align data chunk on + * byte boundaries. + * We thus need to take care moving the OOB area at the right place in the + * final page, which is why we're using gpmi_copy_bits. + * + * See set_geometry_by_ecc_info inline comments to have a full description + * of the layout used by the GPMI controller. + */ +static int gpmi_ecc_write_page_raw(struct mtd_info *mtd, + struct nand_chip *chip, + const uint8_t *buf, + int oob_required) +{ + struct gpmi_nand_data *this = chip->priv; + struct bch_geometry *nfc_geo = &this->bch_geometry; + int eccsize = nfc_geo->ecc_chunk_size; + int eccbits = nfc_geo->ecc_strength * nfc_geo->gf_len; + u8 *tmp_buf = this->raw_buffer; + uint8_t *oob = chip->oob_poi; + size_t dst_bit_off; + size_t oob_bit_off; + size_t oob_byte_off; + int step; + + /* + * Initialize all bits to 1 in case we don't have a buffer for the + * payload or oob data in order to leave unspecified bits of data + * to their initial state. + */ + if (!buf || !oob_required) + memset(tmp_buf, 0xff, mtd->writesize + mtd->oobsize); + + /* + * First copy the metadata section (stored in oob buffer) at the + * beginning of the page, as imposed by the GPMI layout. + */ + memcpy(tmp_buf, oob, nfc_geo->metadata_size); + oob_bit_off = nfc_geo->metadata_size * 8; + dst_bit_off = oob_bit_off; + + /* Interleave payload data and ECC bits */ + for (step = 0; step < nfc_geo->ecc_chunk_count; step++) { + if (buf) + gpmi_copy_bits(tmp_buf, dst_bit_off, + buf, step * eccsize * 8, eccsize * 8); + dst_bit_off += eccsize * 8; + + /* Align last ECC block to align a byte boundary */ + if (step == nfc_geo->ecc_chunk_count - 1 && + (oob_bit_off + eccbits) % 8) + eccbits += 8 - ((oob_bit_off + eccbits) % 8); + + if (oob_required) + gpmi_copy_bits(tmp_buf, dst_bit_off, + oob, oob_bit_off, eccbits); + + dst_bit_off += eccbits; + oob_bit_off += eccbits; + } + + oob_byte_off = oob_bit_off / 8; + + if (oob_required && oob_byte_off < mtd->oobsize) + memcpy(tmp_buf + mtd->writesize + oob_byte_off, + oob + oob_byte_off, mtd->oobsize - oob_byte_off); + + /* + * If required, swap the bad block marker and the first byte of the + * metadata section, so that we don't modify the bad block marker. + * + * See the layout description for a detailed explanation on why this + * is needed. + */ + if (this->swap_block_mark) { + u8 swap = tmp_buf[0]; + + tmp_buf[0] = tmp_buf[mtd->writesize]; + tmp_buf[mtd->writesize] = swap; + } + + chip->write_buf(mtd, tmp_buf, mtd->writesize + mtd->oobsize); + + return 0; +} + +static int gpmi_ecc_read_oob_raw(struct mtd_info *mtd, struct nand_chip *chip, + int page) +{ + chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page); + + return gpmi_ecc_read_page_raw(mtd, chip, NULL, 1, page); +} + +static int gpmi_ecc_write_oob_raw(struct mtd_info *mtd, struct nand_chip *chip, + int page) +{ + chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0, page); + + return gpmi_ecc_write_page_raw(mtd, chip, NULL, 1); +} + static int gpmi_block_markbad(struct mtd_info *mtd, loff_t ofs) { struct nand_chip *chip = mtd->priv; @@ -1664,6 +1861,10 @@ static int gpmi_init_last(struct gpmi_nand_data *this) ecc->write_page = gpmi_ecc_write_page; ecc->read_oob = gpmi_ecc_read_oob; ecc->write_oob = gpmi_ecc_write_oob; + ecc->read_page_raw = gpmi_ecc_read_page_raw; + ecc->write_page_raw = gpmi_ecc_write_page_raw; + ecc->read_oob_raw = gpmi_ecc_read_oob_raw; + ecc->write_oob_raw = gpmi_ecc_write_oob_raw; ecc->mode = NAND_ECC_HW; ecc->size = bch_geo->ecc_chunk_size; ecc->strength = bch_geo->ecc_strength; diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h index 32c6ba49f986..544062f65020 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h @@ -189,6 +189,8 @@ struct gpmi_nand_data { void *auxiliary_virt; dma_addr_t auxiliary_phys; + void *raw_buffer; + /* DMA channels */ #define DMA_CHANS 8 struct dma_chan *dma_chans[DMA_CHANS]; @@ -290,6 +292,10 @@ extern int gpmi_send_page(struct gpmi_nand_data *, extern int gpmi_read_page(struct gpmi_nand_data *, dma_addr_t payload, dma_addr_t auxiliary); +void gpmi_copy_bits(u8 *dst, size_t dst_bit_off, + const u8 *src, size_t src_bit_off, + size_t nbits); + /* BCH : Status Block Completion Codes */ #define STATUS_GOOD 0x00 #define STATUS_ERASED 0xff diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index e1d56beeca79..a8f550fec35e 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -280,14 +280,10 @@ static void memcpy32_fromio(void *trg, const void __iomem *src, size_t size) *t++ = __raw_readl(s++); } -static void memcpy32_toio(void __iomem *trg, const void *src, int size) +static inline void memcpy32_toio(void __iomem *trg, const void *src, int size) { - int i; - u32 __iomem *t = trg; - const u32 *s = src; - - for (i = 0; i < (size >> 2); i++) - __raw_writel(*s++, t++); + /* __iowrite32_copy use 32bit size values so divide by 4 */ + __iowrite32_copy(trg, src, size / 4); } static int check_int_v3(struct mxc_nand_host *host) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 5b5c62712814..41585dfb206f 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -485,11 +485,11 @@ static int nand_check_wp(struct mtd_info *mtd) } /** - * nand_block_checkbad - [GENERIC] Check if a block is marked bad + * nand_block_isreserved - [GENERIC] Check if a block is marked reserved. * @mtd: MTD device structure * @ofs: offset from device start * - * Check if the block is mark as reserved. + * Check if the block is marked as reserved. */ static int nand_block_isreserved(struct mtd_info *mtd, loff_t ofs) { @@ -720,7 +720,7 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command, /* * Program and erase have their own busy handlers status, sequential - * in, and deplete1 need no delay. + * in and status need no delay. */ switch (command) { @@ -3765,9 +3765,9 @@ ident_done: pr_info("%s %s\n", nand_manuf_ids[maf_idx].name, type->name); - pr_info("%dMiB, %s, page size: %d, OOB size: %d\n", + pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n", (int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC", - mtd->writesize, mtd->oobsize); + mtd->erasesize >> 10, mtd->writesize, mtd->oobsize); return type; } @@ -4035,7 +4035,7 @@ int nand_scan_tail(struct mtd_info *mtd) */ if (!ecc->size && (mtd->oobsize >= 64)) { ecc->size = 512; - ecc->bytes = 7; + ecc->bytes = DIV_ROUND_UP(13 * ecc->strength, 8); } ecc->priv = nand_bch_init(mtd, ecc->size, ecc->bytes, &ecc->layout); diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c index fbde89105245..dd620c19c619 100644 --- a/drivers/mtd/nand/nand_ids.c +++ b/drivers/mtd/nand/nand_ids.c @@ -178,6 +178,7 @@ struct nand_manufacturers nand_manuf_ids[] = { {NAND_MFR_EON, "Eon"}, {NAND_MFR_SANDISK, "SanDisk"}, {NAND_MFR_INTEL, "Intel"}, + {NAND_MFR_ATO, "ATO"}, {0x0, "Unknown"} }; diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index 7dc1dd28d896..ab5bbf567439 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -87,10 +87,6 @@ #define CONFIG_NANDSIM_MAX_PARTS 32 #endif -static uint first_id_byte = CONFIG_NANDSIM_FIRST_ID_BYTE; -static uint second_id_byte = CONFIG_NANDSIM_SECOND_ID_BYTE; -static uint third_id_byte = CONFIG_NANDSIM_THIRD_ID_BYTE; -static uint fourth_id_byte = CONFIG_NANDSIM_FOURTH_ID_BYTE; static uint access_delay = CONFIG_NANDSIM_ACCESS_DELAY; static uint programm_delay = CONFIG_NANDSIM_PROGRAMM_DELAY; static uint erase_delay = CONFIG_NANDSIM_ERASE_DELAY; @@ -111,11 +107,19 @@ static unsigned int overridesize = 0; static char *cache_file = NULL; static unsigned int bbt; static unsigned int bch; +static u_char id_bytes[8] = { + [0] = CONFIG_NANDSIM_FIRST_ID_BYTE, + [1] = CONFIG_NANDSIM_SECOND_ID_BYTE, + [2] = CONFIG_NANDSIM_THIRD_ID_BYTE, + [3] = CONFIG_NANDSIM_FOURTH_ID_BYTE, + [4 ... 7] = 0xFF, +}; -module_param(first_id_byte, uint, 0400); -module_param(second_id_byte, uint, 0400); -module_param(third_id_byte, uint, 0400); -module_param(fourth_id_byte, uint, 0400); +module_param_array(id_bytes, byte, NULL, 0400); +module_param_named(first_id_byte, id_bytes[0], byte, 0400); +module_param_named(second_id_byte, id_bytes[1], byte, 0400); +module_param_named(third_id_byte, id_bytes[2], byte, 0400); +module_param_named(fourth_id_byte, id_bytes[3], byte, 0400); module_param(access_delay, uint, 0400); module_param(programm_delay, uint, 0400); module_param(erase_delay, uint, 0400); @@ -136,10 +140,11 @@ module_param(cache_file, charp, 0400); module_param(bbt, uint, 0400); module_param(bch, uint, 0400); -MODULE_PARM_DESC(first_id_byte, "The first byte returned by NAND Flash 'read ID' command (manufacturer ID)"); -MODULE_PARM_DESC(second_id_byte, "The second byte returned by NAND Flash 'read ID' command (chip ID)"); -MODULE_PARM_DESC(third_id_byte, "The third byte returned by NAND Flash 'read ID' command"); -MODULE_PARM_DESC(fourth_id_byte, "The fourth byte returned by NAND Flash 'read ID' command"); +MODULE_PARM_DESC(id_bytes, "The ID bytes returned by NAND Flash 'read ID' command"); +MODULE_PARM_DESC(first_id_byte, "The first byte returned by NAND Flash 'read ID' command (manufacturer ID) (obsolete)"); +MODULE_PARM_DESC(second_id_byte, "The second byte returned by NAND Flash 'read ID' command (chip ID) (obsolete)"); +MODULE_PARM_DESC(third_id_byte, "The third byte returned by NAND Flash 'read ID' command (obsolete)"); +MODULE_PARM_DESC(fourth_id_byte, "The fourth byte returned by NAND Flash 'read ID' command (obsolete)"); MODULE_PARM_DESC(access_delay, "Initial page access delay (microseconds)"); MODULE_PARM_DESC(programm_delay, "Page programm delay (microseconds"); MODULE_PARM_DESC(erase_delay, "Sector erase delay (milliseconds)"); @@ -304,7 +309,7 @@ struct nandsim { unsigned int nbparts; uint busw; /* flash chip bus width (8 or 16) */ - u_char ids[4]; /* chip's ID bytes */ + u_char ids[8]; /* chip's ID bytes */ uint32_t options; /* chip's characteristic bits */ uint32_t state; /* current chip state */ uint32_t nxstate; /* next expected state */ @@ -2279,17 +2284,18 @@ static int __init ns_init_module(void) * Perform minimum nandsim structure initialization to handle * the initial ID read command correctly */ - if (third_id_byte != 0xFF || fourth_id_byte != 0xFF) + if (id_bytes[6] != 0xFF || id_bytes[7] != 0xFF) + nand->geom.idbytes = 8; + else if (id_bytes[4] != 0xFF || id_bytes[5] != 0xFF) + nand->geom.idbytes = 6; + else if (id_bytes[2] != 0xFF || id_bytes[3] != 0xFF) nand->geom.idbytes = 4; else nand->geom.idbytes = 2; nand->regs.status = NS_STATUS_OK(nand); nand->nxstate = STATE_UNKNOWN; nand->options |= OPT_PAGE512; /* temporary value */ - nand->ids[0] = first_id_byte; - nand->ids[1] = second_id_byte; - nand->ids[2] = third_id_byte; - nand->ids[3] = fourth_id_byte; + memcpy(nand->ids, id_bytes, sizeof(nand->ids)); if (bus_width == 16) { nand->busw = 16; chip->options |= NAND_BUSWIDTH_16; diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 6d74b56dd9f6..63f858e6bf39 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -144,11 +144,13 @@ static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc, 0xac, 0x6b, 0xff, 0x99, 0x7b}; static u_char bch4_vector[] = {0x00, 0x6b, 0x31, 0xdd, 0x41, 0xbc, 0x10}; -/* oob info generated runtime depending on ecc algorithm and layout selected */ -static struct nand_ecclayout omap_oobinfo; +/* Shared among all NAND instances to synchronize access to the ECC Engine */ +static struct nand_hw_control omap_gpmc_controller = { + .lock = __SPIN_LOCK_UNLOCKED(omap_gpmc_controller.lock), + .wq = __WAIT_QUEUE_HEAD_INITIALIZER(omap_gpmc_controller.wq), +}; struct omap_nand_info { - struct nand_hw_control controller; struct omap_nand_platform_data *pdata; struct mtd_info mtd; struct nand_chip nand; @@ -168,6 +170,8 @@ struct omap_nand_info { u_char *buf; int buf_len; struct gpmc_nand_regs reg; + /* generated at runtime depending on ECC algorithm and layout selected */ + struct nand_ecclayout oobinfo; /* fields specific for BCHx_HW ECC scheme */ struct device *elm_dev; struct device_node *of_node; @@ -1686,9 +1690,6 @@ static int omap_nand_probe(struct platform_device *pdev) platform_set_drvdata(pdev, info); - spin_lock_init(&info->controller.lock); - init_waitqueue_head(&info->controller.wq); - info->pdev = pdev; info->gpmc_cs = pdata->cs; info->reg = pdata->reg; @@ -1708,7 +1709,7 @@ static int omap_nand_probe(struct platform_device *pdev) info->phys_base = res->start; - nand_chip->controller = &info->controller; + nand_chip->controller = &omap_gpmc_controller; nand_chip->IO_ADDR_W = nand_chip->IO_ADDR_R; nand_chip->cmd_ctrl = omap_hwcontrol; @@ -1741,13 +1742,6 @@ static int omap_nand_probe(struct platform_device *pdev) goto return_error; } - /* check for small page devices */ - if ((mtd->oobsize < 64) && (pdata->ecc_opt != OMAP_ECC_HAM1_CODE_HW)) { - dev_err(&info->pdev->dev, "small page devices are not supported\n"); - err = -EINVAL; - goto return_error; - } - /* re-populate low-level callbacks based on xfer modes */ switch (pdata->xfer_type) { case NAND_OMAP_PREFETCH_POLLED: @@ -1840,7 +1834,7 @@ static int omap_nand_probe(struct platform_device *pdev) } /* populate MTD interface based on ECC scheme */ - ecclayout = &omap_oobinfo; + ecclayout = &info->oobinfo; switch (info->ecc_opt) { case OMAP_ECC_HAM1_CODE_SW: nand_chip->ecc.mode = NAND_ECC_SOFT; diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index c53e36956bff..c3c6d305caa7 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c @@ -19,7 +19,7 @@ #include <linux/mtd/partitions.h> #include <linux/clk.h> #include <linux/err.h> -#include <asm/io.h> +#include <linux/io.h> #include <asm/sizes.h> #include <linux/platform_data/mtd-orion_nand.h> @@ -85,33 +85,24 @@ static int __init orion_nand_probe(struct platform_device *pdev) int ret = 0; u32 val = 0; - nc = kzalloc(sizeof(struct nand_chip) + sizeof(struct mtd_info), GFP_KERNEL); - if (!nc) { - ret = -ENOMEM; - goto no_res; - } + nc = devm_kzalloc(&pdev->dev, + sizeof(struct nand_chip) + sizeof(struct mtd_info), + GFP_KERNEL); + if (!nc) + return -ENOMEM; mtd = (struct mtd_info *)(nc + 1); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - ret = -ENODEV; - goto no_res; - } + io_base = devm_ioremap_resource(&pdev->dev, res); - io_base = ioremap(res->start, resource_size(res)); - if (!io_base) { - dev_err(&pdev->dev, "ioremap failed\n"); - ret = -EIO; - goto no_res; - } + if (IS_ERR(io_base)) + return PTR_ERR(io_base); if (pdev->dev.of_node) { board = devm_kzalloc(&pdev->dev, sizeof(struct orion_nand_data), GFP_KERNEL); - if (!board) { - ret = -ENOMEM; - goto no_res; - } + if (!board) + return -ENOMEM; if (!of_property_read_u32(pdev->dev.of_node, "cle", &val)) board->cle = (u8)val; else @@ -185,9 +176,6 @@ no_dev: clk_disable_unprepare(clk); clk_put(clk); } - iounmap(io_base); -no_res: - kfree(nc); return ret; } @@ -195,15 +183,10 @@ no_res: static int orion_nand_remove(struct platform_device *pdev) { struct mtd_info *mtd = platform_get_drvdata(pdev); - struct nand_chip *nc = mtd->priv; struct clk *clk; nand_release(mtd); - iounmap(nc->IO_ADDR_W); - - kfree(nc); - clk = clk_get(&pdev->dev, NULL); if (!IS_ERR(clk)) { clk_disable_unprepare(clk); diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c new file mode 100644 index 000000000000..ccaa8e283388 --- /dev/null +++ b/drivers/mtd/nand/sunxi_nand.c @@ -0,0 +1,1432 @@ +/* + * Copyright (C) 2013 Boris BREZILLON <b.brezillon.dev@gmail.com> + * + * Derived from: + * https://github.com/yuq/sunxi-nfc-mtd + * Copyright (C) 2013 Qiang Yu <yuq825@gmail.com> + * + * https://github.com/hno/Allwinner-Info + * Copyright (C) 2013 Henrik Nordström <Henrik Nordström> + * + * Copyright (C) 2013 Dmitriy B. <rzk333@gmail.com> + * Copyright (C) 2013 Sergey Lapin <slapin@ossfans.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/dma-mapping.h> +#include <linux/slab.h> +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/platform_device.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/of_gpio.h> +#include <linux/of_mtd.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/nand.h> +#include <linux/mtd/partitions.h> +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/dmaengine.h> +#include <linux/gpio.h> +#include <linux/interrupt.h> +#include <linux/io.h> + +#define NFC_REG_CTL 0x0000 +#define NFC_REG_ST 0x0004 +#define NFC_REG_INT 0x0008 +#define NFC_REG_TIMING_CTL 0x000C +#define NFC_REG_TIMING_CFG 0x0010 +#define NFC_REG_ADDR_LOW 0x0014 +#define NFC_REG_ADDR_HIGH 0x0018 +#define NFC_REG_SECTOR_NUM 0x001C +#define NFC_REG_CNT 0x0020 +#define NFC_REG_CMD 0x0024 +#define NFC_REG_RCMD_SET 0x0028 +#define NFC_REG_WCMD_SET 0x002C +#define NFC_REG_IO_DATA 0x0030 +#define NFC_REG_ECC_CTL 0x0034 +#define NFC_REG_ECC_ST 0x0038 +#define NFC_REG_DEBUG 0x003C +#define NFC_REG_ECC_CNT0 0x0040 +#define NFC_REG_ECC_CNT1 0x0044 +#define NFC_REG_ECC_CNT2 0x0048 +#define NFC_REG_ECC_CNT3 0x004c +#define NFC_REG_USER_DATA_BASE 0x0050 +#define NFC_REG_SPARE_AREA 0x00A0 +#define NFC_RAM0_BASE 0x0400 +#define NFC_RAM1_BASE 0x0800 + +/* define bit use in NFC_CTL */ +#define NFC_EN BIT(0) +#define NFC_RESET BIT(1) +#define NFC_BUS_WIDYH BIT(2) +#define NFC_RB_SEL BIT(3) +#define NFC_CE_SEL GENMASK(26, 24) +#define NFC_CE_CTL BIT(6) +#define NFC_CE_CTL1 BIT(7) +#define NFC_PAGE_SIZE GENMASK(11, 8) +#define NFC_SAM BIT(12) +#define NFC_RAM_METHOD BIT(14) +#define NFC_DEBUG_CTL BIT(31) + +/* define bit use in NFC_ST */ +#define NFC_RB_B2R BIT(0) +#define NFC_CMD_INT_FLAG BIT(1) +#define NFC_DMA_INT_FLAG BIT(2) +#define NFC_CMD_FIFO_STATUS BIT(3) +#define NFC_STA BIT(4) +#define NFC_NATCH_INT_FLAG BIT(5) +#define NFC_RB_STATE0 BIT(8) +#define NFC_RB_STATE1 BIT(9) +#define NFC_RB_STATE2 BIT(10) +#define NFC_RB_STATE3 BIT(11) + +/* define bit use in NFC_INT */ +#define NFC_B2R_INT_ENABLE BIT(0) +#define NFC_CMD_INT_ENABLE BIT(1) +#define NFC_DMA_INT_ENABLE BIT(2) +#define NFC_INT_MASK (NFC_B2R_INT_ENABLE | \ + NFC_CMD_INT_ENABLE | \ + NFC_DMA_INT_ENABLE) + +/* define bit use in NFC_CMD */ +#define NFC_CMD_LOW_BYTE GENMASK(7, 0) +#define NFC_CMD_HIGH_BYTE GENMASK(15, 8) +#define NFC_ADR_NUM GENMASK(18, 16) +#define NFC_SEND_ADR BIT(19) +#define NFC_ACCESS_DIR BIT(20) +#define NFC_DATA_TRANS BIT(21) +#define NFC_SEND_CMD1 BIT(22) +#define NFC_WAIT_FLAG BIT(23) +#define NFC_SEND_CMD2 BIT(24) +#define NFC_SEQ BIT(25) +#define NFC_DATA_SWAP_METHOD BIT(26) +#define NFC_ROW_AUTO_INC BIT(27) +#define NFC_SEND_CMD3 BIT(28) +#define NFC_SEND_CMD4 BIT(29) +#define NFC_CMD_TYPE GENMASK(31, 30) + +/* define bit use in NFC_RCMD_SET */ +#define NFC_READ_CMD GENMASK(7, 0) +#define NFC_RANDOM_READ_CMD0 GENMASK(15, 8) +#define NFC_RANDOM_READ_CMD1 GENMASK(23, 16) + +/* define bit use in NFC_WCMD_SET */ +#define NFC_PROGRAM_CMD GENMASK(7, 0) +#define NFC_RANDOM_WRITE_CMD GENMASK(15, 8) +#define NFC_READ_CMD0 GENMASK(23, 16) +#define NFC_READ_CMD1 GENMASK(31, 24) + +/* define bit use in NFC_ECC_CTL */ +#define NFC_ECC_EN BIT(0) +#define NFC_ECC_PIPELINE BIT(3) +#define NFC_ECC_EXCEPTION BIT(4) +#define NFC_ECC_BLOCK_SIZE BIT(5) +#define NFC_RANDOM_EN BIT(9) +#define NFC_RANDOM_DIRECTION BIT(10) +#define NFC_ECC_MODE_SHIFT 12 +#define NFC_ECC_MODE GENMASK(15, 12) +#define NFC_RANDOM_SEED GENMASK(30, 16) + +#define NFC_DEFAULT_TIMEOUT_MS 1000 + +#define NFC_SRAM_SIZE 1024 + +#define NFC_MAX_CS 7 + +/* + * Ready/Busy detection type: describes the Ready/Busy detection modes + * + * @RB_NONE: no external detection available, rely on STATUS command + * and software timeouts + * @RB_NATIVE: use sunxi NAND controller Ready/Busy support. The Ready/Busy + * pin of the NAND flash chip must be connected to one of the + * native NAND R/B pins (those which can be muxed to the NAND + * Controller) + * @RB_GPIO: use a simple GPIO to handle Ready/Busy status. The Ready/Busy + * pin of the NAND flash chip must be connected to a GPIO capable + * pin. + */ +enum sunxi_nand_rb_type { + RB_NONE, + RB_NATIVE, + RB_GPIO, +}; + +/* + * Ready/Busy structure: stores information related to Ready/Busy detection + * + * @type: the Ready/Busy detection mode + * @info: information related to the R/B detection mode. Either a gpio + * id or a native R/B id (those supported by the NAND controller). + */ +struct sunxi_nand_rb { + enum sunxi_nand_rb_type type; + union { + int gpio; + int nativeid; + } info; +}; + +/* + * Chip Select structure: stores information related to NAND Chip Select + * + * @cs: the NAND CS id used to communicate with a NAND Chip + * @rb: the Ready/Busy description + */ +struct sunxi_nand_chip_sel { + u8 cs; + struct sunxi_nand_rb rb; +}; + +/* + * sunxi HW ECC infos: stores information related to HW ECC support + * + * @mode: the sunxi ECC mode field deduced from ECC requirements + * @layout: the OOB layout depending on the ECC requirements and the + * selected ECC mode + */ +struct sunxi_nand_hw_ecc { + int mode; + struct nand_ecclayout layout; +}; + +/* + * NAND chip structure: stores NAND chip device related information + * + * @node: used to store NAND chips into a list + * @nand: base NAND chip structure + * @mtd: base MTD structure + * @clk_rate: clk_rate required for this NAND chip + * @selected: current active CS + * @nsels: number of CS lines required by the NAND chip + * @sels: array of CS lines descriptions + */ +struct sunxi_nand_chip { + struct list_head node; + struct nand_chip nand; + struct mtd_info mtd; + unsigned long clk_rate; + int selected; + int nsels; + struct sunxi_nand_chip_sel sels[0]; +}; + +static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand) +{ + return container_of(nand, struct sunxi_nand_chip, nand); +} + +/* + * NAND Controller structure: stores sunxi NAND controller information + * + * @controller: base controller structure + * @dev: parent device (used to print error messages) + * @regs: NAND controller registers + * @ahb_clk: NAND Controller AHB clock + * @mod_clk: NAND Controller mod clock + * @assigned_cs: bitmask describing already assigned CS lines + * @clk_rate: NAND controller current clock rate + * @chips: a list containing all the NAND chips attached to + * this NAND controller + * @complete: a completion object used to wait for NAND + * controller events + */ +struct sunxi_nfc { + struct nand_hw_control controller; + struct device *dev; + void __iomem *regs; + struct clk *ahb_clk; + struct clk *mod_clk; + unsigned long assigned_cs; + unsigned long clk_rate; + struct list_head chips; + struct completion complete; +}; + +static inline struct sunxi_nfc *to_sunxi_nfc(struct nand_hw_control *ctrl) +{ + return container_of(ctrl, struct sunxi_nfc, controller); +} + +static irqreturn_t sunxi_nfc_interrupt(int irq, void *dev_id) +{ + struct sunxi_nfc *nfc = dev_id; + u32 st = readl(nfc->regs + NFC_REG_ST); + u32 ien = readl(nfc->regs + NFC_REG_INT); + + if (!(ien & st)) + return IRQ_NONE; + + if ((ien & st) == ien) + complete(&nfc->complete); + + writel(st & NFC_INT_MASK, nfc->regs + NFC_REG_ST); + writel(~st & ien & NFC_INT_MASK, nfc->regs + NFC_REG_INT); + + return IRQ_HANDLED; +} + +static int sunxi_nfc_wait_int(struct sunxi_nfc *nfc, u32 flags, + unsigned int timeout_ms) +{ + init_completion(&nfc->complete); + + writel(flags, nfc->regs + NFC_REG_INT); + + if (!timeout_ms) + timeout_ms = NFC_DEFAULT_TIMEOUT_MS; + + if (!wait_for_completion_timeout(&nfc->complete, + msecs_to_jiffies(timeout_ms))) { + dev_err(nfc->dev, "wait interrupt timedout\n"); + return -ETIMEDOUT; + } + + return 0; +} + +static int sunxi_nfc_wait_cmd_fifo_empty(struct sunxi_nfc *nfc) +{ + unsigned long timeout = jiffies + + msecs_to_jiffies(NFC_DEFAULT_TIMEOUT_MS); + + do { + if (!(readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS)) + return 0; + } while (time_before(jiffies, timeout)); + + dev_err(nfc->dev, "wait for empty cmd FIFO timedout\n"); + return -ETIMEDOUT; +} + +static int sunxi_nfc_rst(struct sunxi_nfc *nfc) +{ + unsigned long timeout = jiffies + + msecs_to_jiffies(NFC_DEFAULT_TIMEOUT_MS); + + writel(0, nfc->regs + NFC_REG_ECC_CTL); + writel(NFC_RESET, nfc->regs + NFC_REG_CTL); + + do { + if (!(readl(nfc->regs + NFC_REG_CTL) & NFC_RESET)) + return 0; + } while (time_before(jiffies, timeout)); + + dev_err(nfc->dev, "wait for NAND controller reset timedout\n"); + return -ETIMEDOUT; +} + +static int sunxi_nfc_dev_ready(struct mtd_info *mtd) +{ + struct nand_chip *nand = mtd->priv; + struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); + struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); + struct sunxi_nand_rb *rb; + unsigned long timeo = (sunxi_nand->nand.state == FL_ERASING ? 400 : 20); + int ret; + + if (sunxi_nand->selected < 0) + return 0; + + rb = &sunxi_nand->sels[sunxi_nand->selected].rb; + + switch (rb->type) { + case RB_NATIVE: + ret = !!(readl(nfc->regs + NFC_REG_ST) & + (NFC_RB_STATE0 << rb->info.nativeid)); + if (ret) + break; + + sunxi_nfc_wait_int(nfc, NFC_RB_B2R, timeo); + ret = !!(readl(nfc->regs + NFC_REG_ST) & + (NFC_RB_STATE0 << rb->info.nativeid)); + break; + case RB_GPIO: + ret = gpio_get_value(rb->info.gpio); + break; + case RB_NONE: + default: + ret = 0; + dev_err(nfc->dev, "cannot check R/B NAND status!\n"); + break; + } + + return ret; +} + +static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip) +{ + struct nand_chip *nand = mtd->priv; + struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); + struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); + struct sunxi_nand_chip_sel *sel; + u32 ctl; + + if (chip > 0 && chip >= sunxi_nand->nsels) + return; + + if (chip == sunxi_nand->selected) + return; + + ctl = readl(nfc->regs + NFC_REG_CTL) & + ~(NFC_CE_SEL | NFC_RB_SEL | NFC_EN); + + if (chip >= 0) { + sel = &sunxi_nand->sels[chip]; + + ctl |= (sel->cs << 24) | NFC_EN | + (((nand->page_shift - 10) & 0xf) << 8); + if (sel->rb.type == RB_NONE) { + nand->dev_ready = NULL; + } else { + nand->dev_ready = sunxi_nfc_dev_ready; + if (sel->rb.type == RB_NATIVE) + ctl |= (sel->rb.info.nativeid << 3); + } + + writel(mtd->writesize, nfc->regs + NFC_REG_SPARE_AREA); + + if (nfc->clk_rate != sunxi_nand->clk_rate) { + clk_set_rate(nfc->mod_clk, sunxi_nand->clk_rate); + nfc->clk_rate = sunxi_nand->clk_rate; + } + } + + writel(ctl, nfc->regs + NFC_REG_CTL); + + sunxi_nand->selected = chip; +} + +static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) +{ + struct nand_chip *nand = mtd->priv; + struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); + struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); + int ret; + int cnt; + int offs = 0; + u32 tmp; + + while (len > offs) { + cnt = min(len - offs, NFC_SRAM_SIZE); + + ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); + if (ret) + break; + + writel(cnt, nfc->regs + NFC_REG_CNT); + tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD; + writel(tmp, nfc->regs + NFC_REG_CMD); + + ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); + if (ret) + break; + + if (buf) + memcpy_fromio(buf + offs, nfc->regs + NFC_RAM0_BASE, + cnt); + offs += cnt; + } +} + +static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, + int len) +{ + struct nand_chip *nand = mtd->priv; + struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); + struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); + int ret; + int cnt; + int offs = 0; + u32 tmp; + + while (len > offs) { + cnt = min(len - offs, NFC_SRAM_SIZE); + + ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); + if (ret) + break; + + writel(cnt, nfc->regs + NFC_REG_CNT); + memcpy_toio(nfc->regs + NFC_RAM0_BASE, buf + offs, cnt); + tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | + NFC_ACCESS_DIR; + writel(tmp, nfc->regs + NFC_REG_CMD); + + ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); + if (ret) + break; + + offs += cnt; + } +} + +static uint8_t sunxi_nfc_read_byte(struct mtd_info *mtd) +{ + uint8_t ret; + + sunxi_nfc_read_buf(mtd, &ret, 1); + + return ret; +} + +static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat, + unsigned int ctrl) +{ + struct nand_chip *nand = mtd->priv; + struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); + struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); + int ret; + u32 tmp; + + ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); + if (ret) + return; + + if (ctrl & NAND_CTRL_CHANGE) { + tmp = readl(nfc->regs + NFC_REG_CTL); + if (ctrl & NAND_NCE) + tmp |= NFC_CE_CTL; + else + tmp &= ~NFC_CE_CTL; + writel(tmp, nfc->regs + NFC_REG_CTL); + } + + if (dat == NAND_CMD_NONE) + return; + + if (ctrl & NAND_CLE) { + writel(NFC_SEND_CMD1 | dat, nfc->regs + NFC_REG_CMD); + } else { + writel(dat, nfc->regs + NFC_REG_ADDR_LOW); + writel(NFC_SEND_ADR, nfc->regs + NFC_REG_CMD); + } + + sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); +} + +static int sunxi_nfc_hw_ecc_read_page(struct mtd_info *mtd, + struct nand_chip *chip, uint8_t *buf, + int oob_required, int page) +{ + struct sunxi_nfc *nfc = to_sunxi_nfc(chip->controller); + struct nand_ecc_ctrl *ecc = &chip->ecc; + struct nand_ecclayout *layout = ecc->layout; + struct sunxi_nand_hw_ecc *data = ecc->priv; + unsigned int max_bitflips = 0; + int offset; + int ret; + u32 tmp; + int i; + int cnt; + + tmp = readl(nfc->regs + NFC_REG_ECC_CTL); + tmp &= ~(NFC_ECC_MODE | NFC_ECC_PIPELINE | NFC_ECC_BLOCK_SIZE); + tmp |= NFC_ECC_EN | (data->mode << NFC_ECC_MODE_SHIFT) | + NFC_ECC_EXCEPTION; + + writel(tmp, nfc->regs + NFC_REG_ECC_CTL); + + for (i = 0; i < ecc->steps; i++) { + if (i) + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, i * ecc->size, -1); + + offset = mtd->writesize + layout->eccpos[i * ecc->bytes] - 4; + + chip->read_buf(mtd, NULL, ecc->size); + + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, offset, -1); + + ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); + if (ret) + return ret; + + tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | (1 << 30); + writel(tmp, nfc->regs + NFC_REG_CMD); + + ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); + if (ret) + return ret; + + memcpy_fromio(buf + (i * ecc->size), + nfc->regs + NFC_RAM0_BASE, ecc->size); + + if (readl(nfc->regs + NFC_REG_ECC_ST) & 0x1) { + mtd->ecc_stats.failed++; + } else { + tmp = readl(nfc->regs + NFC_REG_ECC_CNT0) & 0xff; + mtd->ecc_stats.corrected += tmp; + max_bitflips = max_t(unsigned int, max_bitflips, tmp); + } + + if (oob_required) { + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, offset, -1); + + ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); + if (ret) + return ret; + + offset -= mtd->writesize; + chip->read_buf(mtd, chip->oob_poi + offset, + ecc->bytes + 4); + } + } + + if (oob_required) { + cnt = ecc->layout->oobfree[ecc->steps].length; + if (cnt > 0) { + offset = mtd->writesize + + ecc->layout->oobfree[ecc->steps].offset; + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, offset, -1); + offset -= mtd->writesize; + chip->read_buf(mtd, chip->oob_poi + offset, cnt); + } + } + + tmp = readl(nfc->regs + NFC_REG_ECC_CTL); + tmp &= ~NFC_ECC_EN; + + writel(tmp, nfc->regs + NFC_REG_ECC_CTL); + + return max_bitflips; +} + +static int sunxi_nfc_hw_ecc_write_page(struct mtd_info *mtd, + struct nand_chip *chip, + const uint8_t *buf, int oob_required) +{ + struct sunxi_nfc *nfc = to_sunxi_nfc(chip->controller); + struct nand_ecc_ctrl *ecc = &chip->ecc; + struct nand_ecclayout *layout = ecc->layout; + struct sunxi_nand_hw_ecc *data = ecc->priv; + int offset; + int ret; + u32 tmp; + int i; + int cnt; + + tmp = readl(nfc->regs + NFC_REG_ECC_CTL); + tmp &= ~(NFC_ECC_MODE | NFC_ECC_PIPELINE | NFC_ECC_BLOCK_SIZE); + tmp |= NFC_ECC_EN | (data->mode << NFC_ECC_MODE_SHIFT) | + NFC_ECC_EXCEPTION; + + writel(tmp, nfc->regs + NFC_REG_ECC_CTL); + + for (i = 0; i < ecc->steps; i++) { + if (i) + chip->cmdfunc(mtd, NAND_CMD_RNDIN, i * ecc->size, -1); + + chip->write_buf(mtd, buf + (i * ecc->size), ecc->size); + + offset = layout->eccpos[i * ecc->bytes] - 4 + mtd->writesize; + + /* Fill OOB data in */ + if (oob_required) { + tmp = 0xffffffff; + memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, &tmp, + 4); + } else { + memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, + chip->oob_poi + offset - mtd->writesize, + 4); + } + + chip->cmdfunc(mtd, NAND_CMD_RNDIN, offset, -1); + + ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); + if (ret) + return ret; + + tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ACCESS_DIR | + (1 << 30); + writel(tmp, nfc->regs + NFC_REG_CMD); + ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); + if (ret) + return ret; + } + + if (oob_required) { + cnt = ecc->layout->oobfree[i].length; + if (cnt > 0) { + offset = mtd->writesize + + ecc->layout->oobfree[i].offset; + chip->cmdfunc(mtd, NAND_CMD_RNDIN, offset, -1); + offset -= mtd->writesize; + chip->write_buf(mtd, chip->oob_poi + offset, cnt); + } + } + + tmp = readl(nfc->regs + NFC_REG_ECC_CTL); + tmp &= ~NFC_ECC_EN; + + writel(tmp, nfc->regs + NFC_REG_ECC_CTL); + + return 0; +} + +static int sunxi_nfc_hw_syndrome_ecc_read_page(struct mtd_info *mtd, + struct nand_chip *chip, + uint8_t *buf, int oob_required, + int page) +{ + struct sunxi_nfc *nfc = to_sunxi_nfc(chip->controller); + struct nand_ecc_ctrl *ecc = &chip->ecc; + struct sunxi_nand_hw_ecc *data = ecc->priv; + unsigned int max_bitflips = 0; + uint8_t *oob = chip->oob_poi; + int offset = 0; + int ret; + int cnt; + u32 tmp; + int i; + + tmp = readl(nfc->regs + NFC_REG_ECC_CTL); + tmp &= ~(NFC_ECC_MODE | NFC_ECC_PIPELINE | NFC_ECC_BLOCK_SIZE); + tmp |= NFC_ECC_EN | (data->mode << NFC_ECC_MODE_SHIFT) | + NFC_ECC_EXCEPTION; + + writel(tmp, nfc->regs + NFC_REG_ECC_CTL); + + for (i = 0; i < ecc->steps; i++) { + chip->read_buf(mtd, NULL, ecc->size); + + tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | (1 << 30); + writel(tmp, nfc->regs + NFC_REG_CMD); + + ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); + if (ret) + return ret; + + memcpy_fromio(buf, nfc->regs + NFC_RAM0_BASE, ecc->size); + buf += ecc->size; + offset += ecc->size; + + if (readl(nfc->regs + NFC_REG_ECC_ST) & 0x1) { + mtd->ecc_stats.failed++; + } else { + tmp = readl(nfc->regs + NFC_REG_ECC_CNT0) & 0xff; + mtd->ecc_stats.corrected += tmp; + max_bitflips = max_t(unsigned int, max_bitflips, tmp); + } + + if (oob_required) { + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, offset, -1); + chip->read_buf(mtd, oob, ecc->bytes + ecc->prepad); + oob += ecc->bytes + ecc->prepad; + } + + offset += ecc->bytes + ecc->prepad; + } + + if (oob_required) { + cnt = mtd->oobsize - (oob - chip->oob_poi); + if (cnt > 0) { + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, offset, -1); + chip->read_buf(mtd, oob, cnt); + } + } + + writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_ECC_EN, + nfc->regs + NFC_REG_ECC_CTL); + + return max_bitflips; +} + +static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd, + struct nand_chip *chip, + const uint8_t *buf, + int oob_required) +{ + struct sunxi_nfc *nfc = to_sunxi_nfc(chip->controller); + struct nand_ecc_ctrl *ecc = &chip->ecc; + struct sunxi_nand_hw_ecc *data = ecc->priv; + uint8_t *oob = chip->oob_poi; + int offset = 0; + int ret; + int cnt; + u32 tmp; + int i; + + tmp = readl(nfc->regs + NFC_REG_ECC_CTL); + tmp &= ~(NFC_ECC_MODE | NFC_ECC_PIPELINE | NFC_ECC_BLOCK_SIZE); + tmp |= NFC_ECC_EN | (data->mode << NFC_ECC_MODE_SHIFT) | + NFC_ECC_EXCEPTION; + + writel(tmp, nfc->regs + NFC_REG_ECC_CTL); + + for (i = 0; i < ecc->steps; i++) { + chip->write_buf(mtd, buf + (i * ecc->size), ecc->size); + offset += ecc->size; + + /* Fill OOB data in */ + if (oob_required) { + tmp = 0xffffffff; + memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, &tmp, + 4); + } else { + memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, oob, + 4); + } + + tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ACCESS_DIR | + (1 << 30); + writel(tmp, nfc->regs + NFC_REG_CMD); + + ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); + if (ret) + return ret; + + offset += ecc->bytes + ecc->prepad; + oob += ecc->bytes + ecc->prepad; + } + + if (oob_required) { + cnt = mtd->oobsize - (oob - chip->oob_poi); + if (cnt > 0) { + chip->cmdfunc(mtd, NAND_CMD_RNDIN, offset, -1); + chip->write_buf(mtd, oob, cnt); + } + } + + tmp = readl(nfc->regs + NFC_REG_ECC_CTL); + tmp &= ~NFC_ECC_EN; + + writel(tmp, nfc->regs + NFC_REG_ECC_CTL); + + return 0; +} + +static int sunxi_nand_chip_set_timings(struct sunxi_nand_chip *chip, + const struct nand_sdr_timings *timings) +{ + u32 min_clk_period = 0; + + /* T1 <=> tCLS */ + if (timings->tCLS_min > min_clk_period) + min_clk_period = timings->tCLS_min; + + /* T2 <=> tCLH */ + if (timings->tCLH_min > min_clk_period) + min_clk_period = timings->tCLH_min; + + /* T3 <=> tCS */ + if (timings->tCS_min > min_clk_period) + min_clk_period = timings->tCS_min; + + /* T4 <=> tCH */ + if (timings->tCH_min > min_clk_period) + min_clk_period = timings->tCH_min; + + /* T5 <=> tWP */ + if (timings->tWP_min > min_clk_period) + min_clk_period = timings->tWP_min; + + /* T6 <=> tWH */ + if (timings->tWH_min > min_clk_period) + min_clk_period = timings->tWH_min; + + /* T7 <=> tALS */ + if (timings->tALS_min > min_clk_period) + min_clk_period = timings->tALS_min; + + /* T8 <=> tDS */ + if (timings->tDS_min > min_clk_period) + min_clk_period = timings->tDS_min; + + /* T9 <=> tDH */ + if (timings->tDH_min > min_clk_period) + min_clk_period = timings->tDH_min; + + /* T10 <=> tRR */ + if (timings->tRR_min > (min_clk_period * 3)) + min_clk_period = DIV_ROUND_UP(timings->tRR_min, 3); + + /* T11 <=> tALH */ + if (timings->tALH_min > min_clk_period) + min_clk_period = timings->tALH_min; + + /* T12 <=> tRP */ + if (timings->tRP_min > min_clk_period) + min_clk_period = timings->tRP_min; + + /* T13 <=> tREH */ + if (timings->tREH_min > min_clk_period) + min_clk_period = timings->tREH_min; + + /* T14 <=> tRC */ + if (timings->tRC_min > (min_clk_period * 2)) + min_clk_period = DIV_ROUND_UP(timings->tRC_min, 2); + + /* T15 <=> tWC */ + if (timings->tWC_min > (min_clk_period * 2)) + min_clk_period = DIV_ROUND_UP(timings->tWC_min, 2); + + + /* Convert min_clk_period from picoseconds to nanoseconds */ + min_clk_period = DIV_ROUND_UP(min_clk_period, 1000); + + /* + * Convert min_clk_period into a clk frequency, then get the + * appropriate rate for the NAND controller IP given this formula + * (specified in the datasheet): + * nand clk_rate = 2 * min_clk_rate + */ + chip->clk_rate = (2 * NSEC_PER_SEC) / min_clk_period; + + /* TODO: configure T16-T19 */ + + return 0; +} + +static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip, + struct device_node *np) +{ + const struct nand_sdr_timings *timings; + int ret; + int mode; + + mode = onfi_get_async_timing_mode(&chip->nand); + if (mode == ONFI_TIMING_MODE_UNKNOWN) { + mode = chip->nand.onfi_timing_mode_default; + } else { + uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {}; + + mode = fls(mode) - 1; + if (mode < 0) + mode = 0; + + feature[0] = mode; + ret = chip->nand.onfi_set_features(&chip->mtd, &chip->nand, + ONFI_FEATURE_ADDR_TIMING_MODE, + feature); + if (ret) + return ret; + } + + timings = onfi_async_timing_mode_to_sdr_timings(mode); + if (IS_ERR(timings)) + return PTR_ERR(timings); + + return sunxi_nand_chip_set_timings(chip, timings); +} + +static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd, + struct nand_ecc_ctrl *ecc, + struct device_node *np) +{ + static const u8 strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 }; + struct nand_chip *nand = mtd->priv; + struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); + struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); + struct sunxi_nand_hw_ecc *data; + struct nand_ecclayout *layout; + int nsectors; + int ret; + int i; + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + /* Add ECC info retrieval from DT */ + for (i = 0; i < ARRAY_SIZE(strengths); i++) { + if (ecc->strength <= strengths[i]) + break; + } + + if (i >= ARRAY_SIZE(strengths)) { + dev_err(nfc->dev, "unsupported strength\n"); + ret = -ENOTSUPP; + goto err; + } + + data->mode = i; + + /* HW ECC always request ECC bytes for 1024 bytes blocks */ + ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * 1024), 8); + + /* HW ECC always work with even numbers of ECC bytes */ + ecc->bytes = ALIGN(ecc->bytes, 2); + + layout = &data->layout; + nsectors = mtd->writesize / ecc->size; + + if (mtd->oobsize < ((ecc->bytes + 4) * nsectors)) { + ret = -EINVAL; + goto err; + } + + layout->eccbytes = (ecc->bytes * nsectors); + + ecc->layout = layout; + ecc->priv = data; + + return 0; + +err: + kfree(data); + + return ret; +} + +static void sunxi_nand_hw_common_ecc_ctrl_cleanup(struct nand_ecc_ctrl *ecc) +{ + kfree(ecc->priv); +} + +static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info *mtd, + struct nand_ecc_ctrl *ecc, + struct device_node *np) +{ + struct nand_ecclayout *layout; + int nsectors; + int i, j; + int ret; + + ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np); + if (ret) + return ret; + + ecc->read_page = sunxi_nfc_hw_ecc_read_page; + ecc->write_page = sunxi_nfc_hw_ecc_write_page; + layout = ecc->layout; + nsectors = mtd->writesize / ecc->size; + + for (i = 0; i < nsectors; i++) { + if (i) { + layout->oobfree[i].offset = + layout->oobfree[i - 1].offset + + layout->oobfree[i - 1].length + + ecc->bytes; + layout->oobfree[i].length = 4; + } else { + /* + * The first 2 bytes are used for BB markers, hence we + * only have 2 bytes available in the first user data + * section. + */ + layout->oobfree[i].length = 2; + layout->oobfree[i].offset = 2; + } + + for (j = 0; j < ecc->bytes; j++) + layout->eccpos[(ecc->bytes * i) + j] = + layout->oobfree[i].offset + + layout->oobfree[i].length + j; + } + + if (mtd->oobsize > (ecc->bytes + 4) * nsectors) { + layout->oobfree[nsectors].offset = + layout->oobfree[nsectors - 1].offset + + layout->oobfree[nsectors - 1].length + + ecc->bytes; + layout->oobfree[nsectors].length = mtd->oobsize - + ((ecc->bytes + 4) * nsectors); + } + + return 0; +} + +static int sunxi_nand_hw_syndrome_ecc_ctrl_init(struct mtd_info *mtd, + struct nand_ecc_ctrl *ecc, + struct device_node *np) +{ + struct nand_ecclayout *layout; + int nsectors; + int i; + int ret; + + ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np); + if (ret) + return ret; + + ecc->prepad = 4; + ecc->read_page = sunxi_nfc_hw_syndrome_ecc_read_page; + ecc->write_page = sunxi_nfc_hw_syndrome_ecc_write_page; + + layout = ecc->layout; + nsectors = mtd->writesize / ecc->size; + + for (i = 0; i < (ecc->bytes * nsectors); i++) + layout->eccpos[i] = i; + + layout->oobfree[0].length = mtd->oobsize - i; + layout->oobfree[0].offset = i; + + return 0; +} + +static void sunxi_nand_ecc_cleanup(struct nand_ecc_ctrl *ecc) +{ + switch (ecc->mode) { + case NAND_ECC_HW: + case NAND_ECC_HW_SYNDROME: + sunxi_nand_hw_common_ecc_ctrl_cleanup(ecc); + break; + case NAND_ECC_NONE: + kfree(ecc->layout); + default: + break; + } +} + +static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc, + struct device_node *np) +{ + struct nand_chip *nand = mtd->priv; + int strength; + int blk_size; + int ret; + + blk_size = of_get_nand_ecc_step_size(np); + strength = of_get_nand_ecc_strength(np); + if (blk_size > 0 && strength > 0) { + ecc->size = blk_size; + ecc->strength = strength; + } else { + ecc->size = nand->ecc_step_ds; + ecc->strength = nand->ecc_strength_ds; + } + + if (!ecc->size || !ecc->strength) + return -EINVAL; + + ecc->mode = NAND_ECC_HW; + + ret = of_get_nand_ecc_mode(np); + if (ret >= 0) + ecc->mode = ret; + + switch (ecc->mode) { + case NAND_ECC_SOFT_BCH: + ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * ecc->size), + 8); + break; + case NAND_ECC_HW: + ret = sunxi_nand_hw_ecc_ctrl_init(mtd, ecc, np); + if (ret) + return ret; + break; + case NAND_ECC_HW_SYNDROME: + ret = sunxi_nand_hw_syndrome_ecc_ctrl_init(mtd, ecc, np); + if (ret) + return ret; + break; + case NAND_ECC_NONE: + ecc->layout = kzalloc(sizeof(*ecc->layout), GFP_KERNEL); + if (!ecc->layout) + return -ENOMEM; + ecc->layout->oobfree[0].length = mtd->oobsize; + case NAND_ECC_SOFT: + break; + default: + return -EINVAL; + } + + return 0; +} + +static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc, + struct device_node *np) +{ + const struct nand_sdr_timings *timings; + struct sunxi_nand_chip *chip; + struct mtd_part_parser_data ppdata; + struct mtd_info *mtd; + struct nand_chip *nand; + int nsels; + int ret; + int i; + u32 tmp; + + if (!of_get_property(np, "reg", &nsels)) + return -EINVAL; + + nsels /= sizeof(u32); + if (!nsels) { + dev_err(dev, "invalid reg property size\n"); + return -EINVAL; + } + + chip = devm_kzalloc(dev, + sizeof(*chip) + + (nsels * sizeof(struct sunxi_nand_chip_sel)), + GFP_KERNEL); + if (!chip) { + dev_err(dev, "could not allocate chip\n"); + return -ENOMEM; + } + + chip->nsels = nsels; + chip->selected = -1; + + for (i = 0; i < nsels; i++) { + ret = of_property_read_u32_index(np, "reg", i, &tmp); + if (ret) { + dev_err(dev, "could not retrieve reg property: %d\n", + ret); + return ret; + } + + if (tmp > NFC_MAX_CS) { + dev_err(dev, + "invalid reg value: %u (max CS = 7)\n", + tmp); + return -EINVAL; + } + + if (test_and_set_bit(tmp, &nfc->assigned_cs)) { + dev_err(dev, "CS %d already assigned\n", tmp); + return -EINVAL; + } + + chip->sels[i].cs = tmp; + + if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) && + tmp < 2) { + chip->sels[i].rb.type = RB_NATIVE; + chip->sels[i].rb.info.nativeid = tmp; + } else { + ret = of_get_named_gpio(np, "rb-gpios", i); + if (ret >= 0) { + tmp = ret; + chip->sels[i].rb.type = RB_GPIO; + chip->sels[i].rb.info.gpio = tmp; + ret = devm_gpio_request(dev, tmp, "nand-rb"); + if (ret) + return ret; + + ret = gpio_direction_input(tmp); + if (ret) + return ret; + } else { + chip->sels[i].rb.type = RB_NONE; + } + } + } + + timings = onfi_async_timing_mode_to_sdr_timings(0); + if (IS_ERR(timings)) { + ret = PTR_ERR(timings); + dev_err(dev, + "could not retrieve timings for ONFI mode 0: %d\n", + ret); + return ret; + } + + ret = sunxi_nand_chip_set_timings(chip, timings); + if (ret) { + dev_err(dev, "could not configure chip timings: %d\n", ret); + return ret; + } + + nand = &chip->nand; + /* Default tR value specified in the ONFI spec (chapter 4.15.1) */ + nand->chip_delay = 200; + nand->controller = &nfc->controller; + nand->select_chip = sunxi_nfc_select_chip; + nand->cmd_ctrl = sunxi_nfc_cmd_ctrl; + nand->read_buf = sunxi_nfc_read_buf; + nand->write_buf = sunxi_nfc_write_buf; + nand->read_byte = sunxi_nfc_read_byte; + + if (of_get_nand_on_flash_bbt(np)) + nand->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB; + + mtd = &chip->mtd; + mtd->dev.parent = dev; + mtd->priv = nand; + mtd->owner = THIS_MODULE; + + ret = nand_scan_ident(mtd, nsels, NULL); + if (ret) + return ret; + + ret = sunxi_nand_chip_init_timings(chip, np); + if (ret) { + dev_err(dev, "could not configure chip timings: %d\n", ret); + return ret; + } + + ret = sunxi_nand_ecc_init(mtd, &nand->ecc, np); + if (ret) { + dev_err(dev, "ECC init failed: %d\n", ret); + return ret; + } + + ret = nand_scan_tail(mtd); + if (ret) { + dev_err(dev, "nand_scan_tail failed: %d\n", ret); + return ret; + } + + ppdata.of_node = np; + ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); + if (ret) { + dev_err(dev, "failed to register mtd device: %d\n", ret); + nand_release(mtd); + return ret; + } + + list_add_tail(&chip->node, &nfc->chips); + + return 0; +} + +static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc) +{ + struct device_node *np = dev->of_node; + struct device_node *nand_np; + int nchips = of_get_child_count(np); + int ret; + + if (nchips > 8) { + dev_err(dev, "too many NAND chips: %d (max = 8)\n", nchips); + return -EINVAL; + } + + for_each_child_of_node(np, nand_np) { + ret = sunxi_nand_chip_init(dev, nfc, nand_np); + if (ret) + return ret; + } + + return 0; +} + +static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc) +{ + struct sunxi_nand_chip *chip; + + while (!list_empty(&nfc->chips)) { + chip = list_first_entry(&nfc->chips, struct sunxi_nand_chip, + node); + nand_release(&chip->mtd); + sunxi_nand_ecc_cleanup(&chip->nand.ecc); + } +} + +static int sunxi_nfc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct resource *r; + struct sunxi_nfc *nfc; + int irq; + int ret; + + nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL); + if (!nfc) + return -ENOMEM; + + nfc->dev = dev; + spin_lock_init(&nfc->controller.lock); + init_waitqueue_head(&nfc->controller.wq); + INIT_LIST_HEAD(&nfc->chips); + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + nfc->regs = devm_ioremap_resource(dev, r); + if (IS_ERR(nfc->regs)) + return PTR_ERR(nfc->regs); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(dev, "failed to retrieve irq\n"); + return irq; + } + + nfc->ahb_clk = devm_clk_get(dev, "ahb"); + if (IS_ERR(nfc->ahb_clk)) { + dev_err(dev, "failed to retrieve ahb clk\n"); + return PTR_ERR(nfc->ahb_clk); + } + + ret = clk_prepare_enable(nfc->ahb_clk); + if (ret) + return ret; + + nfc->mod_clk = devm_clk_get(dev, "mod"); + if (IS_ERR(nfc->mod_clk)) { + dev_err(dev, "failed to retrieve mod clk\n"); + ret = PTR_ERR(nfc->mod_clk); + goto out_ahb_clk_unprepare; + } + + ret = clk_prepare_enable(nfc->mod_clk); + if (ret) + goto out_ahb_clk_unprepare; + + ret = sunxi_nfc_rst(nfc); + if (ret) + goto out_mod_clk_unprepare; + + writel(0, nfc->regs + NFC_REG_INT); + ret = devm_request_irq(dev, irq, sunxi_nfc_interrupt, + 0, "sunxi-nand", nfc); + if (ret) + goto out_mod_clk_unprepare; + + platform_set_drvdata(pdev, nfc); + + /* + * TODO: replace these magic values with proper flags as soon as we + * know what they are encoding. + */ + writel(0x100, nfc->regs + NFC_REG_TIMING_CTL); + writel(0x7ff, nfc->regs + NFC_REG_TIMING_CFG); + + ret = sunxi_nand_chips_init(dev, nfc); + if (ret) { + dev_err(dev, "failed to init nand chips\n"); + goto out_mod_clk_unprepare; + } + + return 0; + +out_mod_clk_unprepare: + clk_disable_unprepare(nfc->mod_clk); +out_ahb_clk_unprepare: + clk_disable_unprepare(nfc->ahb_clk); + + return ret; +} + +static int sunxi_nfc_remove(struct platform_device *pdev) +{ + struct sunxi_nfc *nfc = platform_get_drvdata(pdev); + + sunxi_nand_chips_cleanup(nfc); + + return 0; +} + +static const struct of_device_id sunxi_nfc_ids[] = { + { .compatible = "allwinner,sun4i-a10-nand" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, sunxi_nfc_ids); + +static struct platform_driver sunxi_nfc_driver = { + .driver = { + .name = "sunxi_nand", + .of_match_table = sunxi_nfc_ids, + }, + .probe = sunxi_nfc_probe, + .remove = sunxi_nfc_remove, +}; +module_platform_driver(sunxi_nfc_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Boris BREZILLON"); +MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver"); +MODULE_ALIAS("platform:sunxi_nand"); diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c index 2fb07eced2ba..39763b94f67d 100644 --- a/drivers/mtd/spi-nor/fsl-quadspi.c +++ b/drivers/mtd/spi-nor/fsl-quadspi.c @@ -719,16 +719,10 @@ static int fsl_qspi_read(struct spi_nor *nor, loff_t from, { struct fsl_qspi *q = nor->priv; u8 cmd = nor->read_opcode; - int ret; dev_dbg(q->dev, "cmd [%x],read from (0x%p, 0x%.8x, 0x%.8x),len:%d\n", cmd, q->ahb_base, q->chip_base_addr, (unsigned int)from, len); - /* Wait until the previous command is finished. */ - ret = nor->wait_till_ready(nor); - if (ret) - return ret; - /* Read out the data directly from the AHB buffer.*/ memcpy(buf, q->ahb_base + q->chip_base_addr + from, len); @@ -744,16 +738,6 @@ static int fsl_qspi_erase(struct spi_nor *nor, loff_t offs) dev_dbg(nor->dev, "%dKiB at 0x%08x:0x%08x\n", nor->mtd->erasesize / 1024, q->chip_base_addr, (u32)offs); - /* Wait until finished previous write command. */ - ret = nor->wait_till_ready(nor); - if (ret) - return ret; - - /* Send write enable, then erase commands. */ - ret = nor->write_reg(nor, SPINOR_OP_WREN, NULL, 0, 0); - if (ret) - return ret; - ret = fsl_qspi_runcmd(q, nor->erase_opcode, offs, 0); if (ret) return ret; @@ -849,9 +833,8 @@ static int fsl_qspi_probe(struct platform_device *pdev) ret = clk_prepare_enable(q->clk); if (ret) { - clk_disable_unprepare(q->clk_en); dev_err(dev, "can not enable the qspi clock\n"); - goto map_failed; + goto clk_failed; } /* find the irq */ @@ -905,7 +888,8 @@ static int fsl_qspi_probe(struct platform_device *pdev) nor->prepare = fsl_qspi_prep; nor->unprepare = fsl_qspi_unprep; - if (of_modalias_node(np, modalias, sizeof(modalias)) < 0) + ret = of_modalias_node(np, modalias, sizeof(modalias)); + if (ret < 0) goto map_failed; ret = of_property_read_u32(np, "spi-max-frequency", @@ -964,6 +948,7 @@ last_init_failed: irq_failed: clk_disable_unprepare(q->clk); +clk_failed: clk_disable_unprepare(q->clk_en); map_failed: dev_err(dev, "Freescale QuadSPI probe failed\n"); diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index c51ee52386a7..0f8ec3c2d015 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -26,7 +26,38 @@ /* Define max times to check status register before we give up. */ #define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */ -#define JEDEC_MFR(_jedec_id) ((_jedec_id) >> 16) +#define SPI_NOR_MAX_ID_LEN 6 + +struct flash_info { + /* + * This array stores the ID bytes. + * The first three bytes are the JEDIC ID. + * JEDEC ID zero means "no ID" (mostly older chips). + */ + u8 id[SPI_NOR_MAX_ID_LEN]; + u8 id_len; + + /* The size listed here is what works with SPINOR_OP_SE, which isn't + * necessarily called a "sector" by the vendor. + */ + unsigned sector_size; + u16 n_sectors; + + u16 page_size; + u16 addr_width; + + u16 flags; +#define SECT_4K 0x01 /* SPINOR_OP_BE_4K works uniformly */ +#define SPI_NOR_NO_ERASE 0x02 /* No erase command needed */ +#define SST_WRITE 0x04 /* use SST byte programming */ +#define SPI_NOR_NO_FR 0x08 /* Can't do fastread */ +#define SECT_4K_PMC 0x10 /* SPINOR_OP_BE_4K_PMC works uniformly */ +#define SPI_NOR_DUAL_READ 0x20 /* Flash supports Dual Read */ +#define SPI_NOR_QUAD_READ 0x40 /* Flash supports Quad Read */ +#define USE_FSR 0x80 /* use flag status register */ +}; + +#define JEDEC_MFR(info) ((info)->id[0]) static const struct spi_device_id *spi_nor_match_id(const char *name); @@ -98,7 +129,7 @@ static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor) case SPI_NOR_FAST: case SPI_NOR_DUAL: case SPI_NOR_QUAD: - return 1; + return 8; case SPI_NOR_NORMAL: return 0; } @@ -138,13 +169,14 @@ static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd) } /* Enable/disable 4-byte addressing mode. */ -static inline int set_4byte(struct spi_nor *nor, u32 jedec_id, int enable) +static inline int set_4byte(struct spi_nor *nor, struct flash_info *info, + int enable) { int status; bool need_wren = false; u8 cmd; - switch (JEDEC_MFR(jedec_id)) { + switch (JEDEC_MFR(info)) { case CFI_MFR_ST: /* Micron, actually */ /* Some Micron need WREN command; all will accept it */ need_wren = true; @@ -165,81 +197,74 @@ static inline int set_4byte(struct spi_nor *nor, u32 jedec_id, int enable) return nor->write_reg(nor, SPINOR_OP_BRWR, nor->cmd_buf, 1, 0); } } - -static int spi_nor_wait_till_ready(struct spi_nor *nor) +static inline int spi_nor_sr_ready(struct spi_nor *nor) { - unsigned long deadline; - int sr; - - deadline = jiffies + MAX_READY_WAIT_JIFFIES; - - do { - cond_resched(); + int sr = read_sr(nor); + if (sr < 0) + return sr; + else + return !(sr & SR_WIP); +} - sr = read_sr(nor); - if (sr < 0) - break; - else if (!(sr & SR_WIP)) - return 0; - } while (!time_after_eq(jiffies, deadline)); +static inline int spi_nor_fsr_ready(struct spi_nor *nor) +{ + int fsr = read_fsr(nor); + if (fsr < 0) + return fsr; + else + return fsr & FSR_READY; +} - return -ETIMEDOUT; +static int spi_nor_ready(struct spi_nor *nor) +{ + int sr, fsr; + sr = spi_nor_sr_ready(nor); + if (sr < 0) + return sr; + fsr = nor->flags & SNOR_F_USE_FSR ? spi_nor_fsr_ready(nor) : 1; + if (fsr < 0) + return fsr; + return sr && fsr; } -static int spi_nor_wait_till_fsr_ready(struct spi_nor *nor) +/* + * Service routine to read status register until ready, or timeout occurs. + * Returns non-zero if error. + */ +static int spi_nor_wait_till_ready(struct spi_nor *nor) { unsigned long deadline; - int sr; - int fsr; + int timeout = 0, ret; deadline = jiffies + MAX_READY_WAIT_JIFFIES; - do { + while (!timeout) { + if (time_after_eq(jiffies, deadline)) + timeout = 1; + + ret = spi_nor_ready(nor); + if (ret < 0) + return ret; + if (ret) + return 0; + cond_resched(); + } - sr = read_sr(nor); - if (sr < 0) { - break; - } else if (!(sr & SR_WIP)) { - fsr = read_fsr(nor); - if (fsr < 0) - break; - if (fsr & FSR_READY) - return 0; - } - } while (!time_after_eq(jiffies, deadline)); + dev_err(nor->dev, "flash operation timed out\n"); return -ETIMEDOUT; } /* - * Service routine to read status register until ready, or timeout occurs. - * Returns non-zero if error. - */ -static int wait_till_ready(struct spi_nor *nor) -{ - return nor->wait_till_ready(nor); -} - -/* * Erase the whole flash memory * * Returns 0 if successful, non-zero otherwise. */ static int erase_chip(struct spi_nor *nor) { - int ret; - dev_dbg(nor->dev, " %lldKiB\n", (long long)(nor->mtd->size >> 10)); - /* Wait until finished previous write command. */ - ret = wait_till_ready(nor); - if (ret) - return ret; - - /* Send write enable, then erase commands. */ - write_enable(nor); - return nor->write_reg(nor, SPINOR_OP_CHIP_ERASE, NULL, 0, 0); } @@ -294,11 +319,17 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) /* whole-chip erase? */ if (len == mtd->size) { + write_enable(nor); + if (erase_chip(nor)) { ret = -EIO; goto erase_err; } + ret = spi_nor_wait_till_ready(nor); + if (ret) + goto erase_err; + /* REVISIT in some cases we could speed up erasing large regions * by using SPINOR_OP_SE instead of SPINOR_OP_BE_4K. We may have set up * to use "small sector erase", but that's not always optimal. @@ -307,6 +338,8 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) /* "sector"-at-a-time erase */ } else { while (len) { + write_enable(nor); + if (nor->erase(nor, addr)) { ret = -EIO; goto erase_err; @@ -314,9 +347,15 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) addr += mtd->erasesize; len -= mtd->erasesize; + + ret = spi_nor_wait_till_ready(nor); + if (ret) + goto erase_err; } } + write_disable(nor); + spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE); instr->state = MTD_ERASE_DONE; @@ -341,11 +380,6 @@ static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) if (ret) return ret; - /* Wait until finished previous command */ - ret = wait_till_ready(nor); - if (ret) - goto err; - status_old = read_sr(nor); if (offset < mtd->size - (mtd->size / 2)) @@ -388,11 +422,6 @@ static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) if (ret) return ret; - /* Wait until finished previous command */ - ret = wait_till_ready(nor); - if (ret) - goto err; - status_old = read_sr(nor); if (offset+len > mtd->size - (mtd->size / 64)) @@ -424,38 +453,34 @@ err: return ret; } -struct flash_info { - /* JEDEC id zero means "no ID" (most older chips); otherwise it has - * a high byte of zero plus three data bytes: the manufacturer id, - * then a two byte device id. - */ - u32 jedec_id; - u16 ext_id; - - /* The size listed here is what works with SPINOR_OP_SE, which isn't - * necessarily called a "sector" by the vendor. - */ - unsigned sector_size; - u16 n_sectors; - - u16 page_size; - u16 addr_width; - - u16 flags; -#define SECT_4K 0x01 /* SPINOR_OP_BE_4K works uniformly */ -#define SPI_NOR_NO_ERASE 0x02 /* No erase command needed */ -#define SST_WRITE 0x04 /* use SST byte programming */ -#define SPI_NOR_NO_FR 0x08 /* Can't do fastread */ -#define SECT_4K_PMC 0x10 /* SPINOR_OP_BE_4K_PMC works uniformly */ -#define SPI_NOR_DUAL_READ 0x20 /* Flash supports Dual Read */ -#define SPI_NOR_QUAD_READ 0x40 /* Flash supports Quad Read */ -#define USE_FSR 0x80 /* use flag status register */ -}; - +/* Used when the "_ext_id" is two bytes at most */ #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ ((kernel_ulong_t)&(struct flash_info) { \ - .jedec_id = (_jedec_id), \ - .ext_id = (_ext_id), \ + .id = { \ + ((_jedec_id) >> 16) & 0xff, \ + ((_jedec_id) >> 8) & 0xff, \ + (_jedec_id) & 0xff, \ + ((_ext_id) >> 8) & 0xff, \ + (_ext_id) & 0xff, \ + }, \ + .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))), \ + .sector_size = (_sector_size), \ + .n_sectors = (_n_sectors), \ + .page_size = 256, \ + .flags = (_flags), \ + }) + +#define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ + ((kernel_ulong_t)&(struct flash_info) { \ + .id = { \ + ((_jedec_id) >> 16) & 0xff, \ + ((_jedec_id) >> 8) & 0xff, \ + (_jedec_id) & 0xff, \ + ((_ext_id) >> 16) & 0xff, \ + ((_ext_id) >> 8) & 0xff, \ + (_ext_id) & 0xff, \ + }, \ + .id_len = 6, \ .sector_size = (_sector_size), \ .n_sectors = (_n_sectors), \ .page_size = 256, \ @@ -507,6 +532,9 @@ static const struct spi_device_id spi_nor_ids[] = { { "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, { "mr25h10", CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, + /* Fujitsu */ + { "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) }, + /* GigaDevice */ { "gd25q32", INFO(0xc84016, 0, 64 * 1024, 64, SECT_4K) }, { "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, SECT_4K) }, @@ -532,6 +560,7 @@ static const struct spi_device_id spi_nor_ids[] = { { "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) }, /* Micron */ + { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64, 0) }, { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, 0) }, { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, 0) }, { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, 0) }, @@ -556,6 +585,7 @@ static const struct spi_device_id spi_nor_ids[] = { { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, + { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_QUAD_READ) }, { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, 0) }, { "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, 0) }, { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) }, @@ -566,6 +596,7 @@ static const struct spi_device_id spi_nor_ids[] = { { "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, { "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32, SECT_4K) }, { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, + { "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64, 0) }, /* SST -- large erase sizes are "overlays", "sectors" are 4K */ { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, @@ -577,6 +608,7 @@ static const struct spi_device_id spi_nor_ids[] = { { "sst25wf010", INFO(0xbf2502, 0, 64 * 1024, 2, SECT_4K | SST_WRITE) }, { "sst25wf020", INFO(0xbf2503, 0, 64 * 1024, 4, SECT_4K | SST_WRITE) }, { "sst25wf040", INFO(0xbf2504, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, + { "sst25wf080", INFO(0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, /* ST Microelectronics -- newer production may have feature updates */ { "m25p05", INFO(0x202010, 0, 32 * 1024, 2, 0) }, @@ -588,7 +620,6 @@ static const struct spi_device_id spi_nor_ids[] = { { "m25p32", INFO(0x202016, 0, 64 * 1024, 64, 0) }, { "m25p64", INFO(0x202017, 0, 64 * 1024, 128, 0) }, { "m25p128", INFO(0x202018, 0, 256 * 1024, 64, 0) }, - { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64, 0) }, { "m25p05-nonjedec", INFO(0, 0, 32 * 1024, 2, 0) }, { "m25p10-nonjedec", INFO(0, 0, 32 * 1024, 4, 0) }, @@ -643,32 +674,24 @@ static const struct spi_device_id spi_nor_ids[] = { static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor) { int tmp; - u8 id[5]; - u32 jedec; - u16 ext_jedec; + u8 id[SPI_NOR_MAX_ID_LEN]; struct flash_info *info; - tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, 5); + tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN); if (tmp < 0) { dev_dbg(nor->dev, " error %d reading JEDEC ID\n", tmp); return ERR_PTR(tmp); } - jedec = id[0]; - jedec = jedec << 8; - jedec |= id[1]; - jedec = jedec << 8; - jedec |= id[2]; - - ext_jedec = id[3] << 8 | id[4]; for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) { info = (void *)spi_nor_ids[tmp].driver_data; - if (info->jedec_id == jedec) { - if (info->ext_id == 0 || info->ext_id == ext_jedec) + if (info->id_len) { + if (!memcmp(info->id, id, info->id_len)) return &spi_nor_ids[tmp]; } } - dev_err(nor->dev, "unrecognized JEDEC id %06x\n", jedec); + dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %2x, %2x\n", + id[0], id[1], id[2]); return ERR_PTR(-ENODEV); } @@ -703,11 +726,6 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, if (ret) return ret; - /* Wait until finished previous write command. */ - ret = wait_till_ready(nor); - if (ret) - goto time_out; - write_enable(nor); nor->sst_write_second = false; @@ -719,7 +737,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, /* write one byte. */ nor->write(nor, to, 1, retlen, buf); - ret = wait_till_ready(nor); + ret = spi_nor_wait_till_ready(nor); if (ret) goto time_out; } @@ -731,7 +749,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, /* write two bytes. */ nor->write(nor, to, 2, retlen, buf + actual); - ret = wait_till_ready(nor); + ret = spi_nor_wait_till_ready(nor); if (ret) goto time_out; to += 2; @@ -740,7 +758,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, nor->sst_write_second = false; write_disable(nor); - ret = wait_till_ready(nor); + ret = spi_nor_wait_till_ready(nor); if (ret) goto time_out; @@ -751,7 +769,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, nor->program_opcode = SPINOR_OP_BP; nor->write(nor, to, 1, retlen, buf + actual); - ret = wait_till_ready(nor); + ret = spi_nor_wait_till_ready(nor); if (ret) goto time_out; write_disable(nor); @@ -779,11 +797,6 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, if (ret) return ret; - /* Wait until finished previous write command. */ - ret = wait_till_ready(nor); - if (ret) - goto write_err; - write_enable(nor); page_offset = to & (nor->page_size - 1); @@ -802,16 +815,20 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, if (page_size > nor->page_size) page_size = nor->page_size; - wait_till_ready(nor); + ret = spi_nor_wait_till_ready(nor); + if (ret) + goto write_err; + write_enable(nor); nor->write(nor, to + i, page_size, retlen, buf + i); } } + ret = spi_nor_wait_till_ready(nor); write_err: spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE); - return 0; + return ret; } static int macronix_quad_enable(struct spi_nor *nor) @@ -824,7 +841,7 @@ static int macronix_quad_enable(struct spi_nor *nor) nor->cmd_buf[0] = val | SR_QUAD_EN_MX; nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 1, 0); - if (wait_till_ready(nor)) + if (spi_nor_wait_till_ready(nor)) return 1; ret = read_sr(nor); @@ -874,11 +891,11 @@ static int spansion_quad_enable(struct spi_nor *nor) return 0; } -static int set_quad_mode(struct spi_nor *nor, u32 jedec_id) +static int set_quad_mode(struct spi_nor *nor, struct flash_info *info) { int status; - switch (JEDEC_MFR(jedec_id)) { + switch (JEDEC_MFR(info)) { case CFI_MFR_MACRONIX: status = macronix_quad_enable(nor); if (status) { @@ -904,11 +921,6 @@ static int spi_nor_check(struct spi_nor *nor) return -EINVAL; } - if (!nor->read_id) - nor->read_id = spi_nor_read_id; - if (!nor->wait_till_ready) - nor->wait_till_ready = spi_nor_wait_till_ready; - return 0; } @@ -926,16 +938,24 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) if (ret) return ret; - id = spi_nor_match_id(name); - if (!id) + /* Try to auto-detect if chip name wasn't specified */ + if (!name) + id = spi_nor_read_id(nor); + else + id = spi_nor_match_id(name); + if (IS_ERR_OR_NULL(id)) return -ENOENT; info = (void *)id->driver_data; - if (info->jedec_id) { + /* + * If caller has specified name of flash model that can normally be + * detected using JEDEC, let's verify it. + */ + if (name && info->id_len) { const struct spi_device_id *jid; - jid = nor->read_id(nor); + jid = spi_nor_read_id(nor); if (IS_ERR(jid)) { return PTR_ERR(jid); } else if (jid != id) { @@ -960,9 +980,9 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) * up with the software protection bits set */ - if (JEDEC_MFR(info->jedec_id) == CFI_MFR_ATMEL || - JEDEC_MFR(info->jedec_id) == CFI_MFR_INTEL || - JEDEC_MFR(info->jedec_id) == CFI_MFR_SST) { + if (JEDEC_MFR(info) == CFI_MFR_ATMEL || + JEDEC_MFR(info) == CFI_MFR_INTEL || + JEDEC_MFR(info) == CFI_MFR_SST) { write_enable(nor); write_sr(nor, 0); } @@ -977,7 +997,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) mtd->_read = spi_nor_read; /* nor protection support for STmicro chips */ - if (JEDEC_MFR(info->jedec_id) == CFI_MFR_ST) { + if (JEDEC_MFR(info) == CFI_MFR_ST) { mtd->_lock = spi_nor_lock; mtd->_unlock = spi_nor_unlock; } @@ -988,9 +1008,8 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) else mtd->_write = spi_nor_write; - if ((info->flags & USE_FSR) && - nor->wait_till_ready == spi_nor_wait_till_ready) - nor->wait_till_ready = spi_nor_wait_till_fsr_ready; + if (info->flags & USE_FSR) + nor->flags |= SNOR_F_USE_FSR; #ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS /* prefer "small sector" erase if possible */ @@ -1031,7 +1050,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) /* Quad/Dual-read mode takes precedence over fast/normal */ if (mode == SPI_NOR_QUAD && info->flags & SPI_NOR_QUAD_READ) { - ret = set_quad_mode(nor, info->jedec_id); + ret = set_quad_mode(nor, info); if (ret) { dev_err(dev, "quad mode not supported\n"); return ret; @@ -1067,7 +1086,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) else if (mtd->size > 0x1000000) { /* enable 4-byte addressing if the device exceeds 16MiB */ nor->addr_width = 4; - if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) { + if (JEDEC_MFR(info) == CFI_MFR_AMD) { /* Dedicated 4-byte command set */ switch (nor->flash_read) { case SPI_NOR_QUAD: @@ -1088,7 +1107,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) nor->erase_opcode = SPINOR_OP_SE_4B; mtd->erasesize = info->sector_size; } else - set_4byte(nor, info->jedec_id, 1); + set_4byte(nor, info, 1); } else { nor->addr_width = 3; } diff --git a/drivers/mtd/tests/oobtest.c b/drivers/mtd/tests/oobtest.c index dc4f9602b97e..5e061186eab1 100644 --- a/drivers/mtd/tests/oobtest.c +++ b/drivers/mtd/tests/oobtest.c @@ -34,8 +34,11 @@ #include "mtd_test.h" static int dev = -EINVAL; +static int bitflip_limit; module_param(dev, int, S_IRUGO); MODULE_PARM_DESC(dev, "MTD device number to use"); +module_param(bitflip_limit, int, S_IRUGO); +MODULE_PARM_DESC(bitflip_limit, "Max. allowed bitflips per page"); static struct mtd_info *mtd; static unsigned char *readbuf; @@ -115,12 +118,36 @@ static int write_whole_device(void) return 0; } +/* + * Display the address, offset and data bytes at comparison failure. + * Return number of bitflips encountered. + */ +static size_t memcmpshow(loff_t addr, const void *cs, const void *ct, size_t count) +{ + const unsigned char *su1, *su2; + int res; + size_t i = 0; + size_t bitflips = 0; + + for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--, i++) { + res = *su1 ^ *su2; + if (res) { + pr_info("error @addr[0x%lx:0x%zx] 0x%x -> 0x%x diff 0x%x\n", + (unsigned long)addr, i, *su1, *su2, res); + bitflips += hweight8(res); + } + } + + return bitflips; +} + static int verify_eraseblock(int ebnum) { int i; struct mtd_oob_ops ops; int err = 0; loff_t addr = (loff_t)ebnum * mtd->erasesize; + size_t bitflips; prandom_bytes_state(&rnd_state, writebuf, use_len_max * pgcnt); for (i = 0; i < pgcnt; ++i, addr += mtd->writesize) { @@ -139,8 +166,11 @@ static int verify_eraseblock(int ebnum) errcnt += 1; return err ? err : -1; } - if (memcmp(readbuf, writebuf + (use_len_max * i) + use_offset, - use_len)) { + + bitflips = memcmpshow(addr, readbuf, + writebuf + (use_len_max * i) + use_offset, + use_len); + if (bitflips > bitflip_limit) { pr_err("error: verify failed at %#llx\n", (long long)addr); errcnt += 1; @@ -148,7 +178,10 @@ static int verify_eraseblock(int ebnum) pr_err("error: too many errors\n"); return -1; } + } else if (bitflips) { + pr_info("ignoring error as within bitflip_limit\n"); } + if (use_offset != 0 || use_len < mtd->ecclayout->oobavail) { int k; @@ -167,9 +200,10 @@ static int verify_eraseblock(int ebnum) errcnt += 1; return err ? err : -1; } - if (memcmp(readbuf + use_offset, - writebuf + (use_len_max * i) + use_offset, - use_len)) { + bitflips = memcmpshow(addr, readbuf + use_offset, + writebuf + (use_len_max * i) + use_offset, + use_len); + if (bitflips > bitflip_limit) { pr_err("error: verify failed at %#llx\n", (long long)addr); errcnt += 1; @@ -177,7 +211,10 @@ static int verify_eraseblock(int ebnum) pr_err("error: too many errors\n"); return -1; } + } else if (bitflips) { + pr_info("ignoring error as within bitflip_limit\n"); } + for (k = 0; k < use_offset; ++k) if (readbuf[k] != 0xff) { pr_err("error: verify 0xff " @@ -216,6 +253,9 @@ static int verify_eraseblock_in_one_go(int ebnum) int err = 0; loff_t addr = (loff_t)ebnum * mtd->erasesize; size_t len = mtd->ecclayout->oobavail * pgcnt; + size_t oobavail = mtd->ecclayout->oobavail; + size_t bitflips; + int i; prandom_bytes_state(&rnd_state, writebuf, len); ops.mode = MTD_OPS_AUTO_OOB; @@ -226,6 +266,8 @@ static int verify_eraseblock_in_one_go(int ebnum) ops.ooboffs = 0; ops.datbuf = NULL; ops.oobbuf = readbuf; + + /* read entire block's OOB at one go */ err = mtd_read_oob(mtd, addr, &ops); if (err || ops.oobretlen != len) { pr_err("error: readoob failed at %#llx\n", @@ -233,13 +275,21 @@ static int verify_eraseblock_in_one_go(int ebnum) errcnt += 1; return err ? err : -1; } - if (memcmp(readbuf, writebuf, len)) { - pr_err("error: verify failed at %#llx\n", - (long long)addr); - errcnt += 1; - if (errcnt > 1000) { - pr_err("error: too many errors\n"); - return -1; + + /* verify one page OOB at a time for bitflip per page limit check */ + for (i = 0; i < pgcnt; ++i, addr += mtd->writesize) { + bitflips = memcmpshow(addr, readbuf + (i * oobavail), + writebuf + (i * oobavail), oobavail); + if (bitflips > bitflip_limit) { + pr_err("error: verify failed at %#llx\n", + (long long)addr); + errcnt += 1; + if (errcnt > 1000) { + pr_err("error: too many errors\n"); + return -1; + } + } else if (bitflips) { + pr_info("ignoring error as within bitflip_limit\n"); } } @@ -610,7 +660,8 @@ static int __init mtd_oobtest_init(void) err = mtd_read_oob(mtd, addr, &ops); if (err) goto out; - if (memcmp(readbuf, writebuf, mtd->ecclayout->oobavail * 2)) { + if (memcmpshow(addr, readbuf, writebuf, + mtd->ecclayout->oobavail * 2)) { pr_err("error: verify failed at %#llx\n", (long long)addr); errcnt += 1; diff --git a/drivers/mtd/tests/torturetest.c b/drivers/mtd/tests/torturetest.c index eeab96973cf0..b55bc52a1340 100644 --- a/drivers/mtd/tests/torturetest.c +++ b/drivers/mtd/tests/torturetest.c @@ -264,7 +264,9 @@ static int __init tort_init(void) int i; void *patt; - mtdtest_erase_good_eraseblocks(mtd, bad_ebs, eb, ebcnt); + err = mtdtest_erase_good_eraseblocks(mtd, bad_ebs, eb, ebcnt); + if (err) + goto out; /* Check if the eraseblocks contain only 0xFF bytes */ if (check) { diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 184c434ae305..0dceba1a2ba1 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1648,7 +1648,7 @@ static int __bond_release_one(struct net_device *bond_dev, /* slave is not a slave or master is not master of this slave */ if (!(slave_dev->flags & IFF_SLAVE) || !netdev_has_upper_dev(slave_dev, bond_dev)) { - netdev_err(bond_dev, "cannot release %s\n", + netdev_dbg(bond_dev, "cannot release %s\n", slave_dev->name); return -EINVAL; } diff --git a/drivers/net/caif/caif_virtio.c b/drivers/net/caif/caif_virtio.c index a5fefb9059c5..b306210b02b7 100644 --- a/drivers/net/caif/caif_virtio.c +++ b/drivers/net/caif/caif_virtio.c @@ -257,7 +257,6 @@ static int cfv_rx_poll(struct napi_struct *napi, int quota) struct vringh_kiov *riov = &cfv->ctx.riov; unsigned int skb_len; -again: do { skb = NULL; @@ -322,7 +321,6 @@ exit: napi_schedule_prep(napi)) { vringh_notify_disable_kern(cfv->vr_rx); __napi_schedule(napi); - goto again; } break; diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index f363972cd77d..e36d10520e24 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c @@ -103,27 +103,34 @@ static void c_can_hw_raminit_syscon(const struct c_can_priv *priv, bool enable) mask = 1 << raminit->bits.start | 1 << raminit->bits.done; regmap_read(raminit->syscon, raminit->reg, &ctrl); - /* We clear the done and start bit first. The start bit is + /* We clear the start bit first. The start bit is * looking at the 0 -> transition, but is not self clearing; - * And we clear the init done bit as well. * NOTE: DONE must be written with 1 to clear it. + * We can't clear the DONE bit here using regmap_update_bits() + * as it will bypass the write if initial condition is START:0 DONE:1 + * e.g. on DRA7 which needs START pulse. */ - ctrl &= ~(1 << raminit->bits.start); - ctrl |= 1 << raminit->bits.done; - regmap_write(raminit->syscon, raminit->reg, ctrl); + ctrl &= ~mask; /* START = 0, DONE = 0 */ + regmap_update_bits(raminit->syscon, raminit->reg, mask, ctrl); - ctrl &= ~(1 << raminit->bits.done); - c_can_hw_raminit_wait_syscon(priv, mask, ctrl); + /* check if START bit is 0. Ignore DONE bit for now + * as it can be either 0 or 1. + */ + c_can_hw_raminit_wait_syscon(priv, 1 << raminit->bits.start, ctrl); if (enable) { - /* Set start bit and wait for the done bit. */ + /* Clear DONE bit & set START bit. */ ctrl |= 1 << raminit->bits.start; - regmap_write(raminit->syscon, raminit->reg, ctrl); - + /* DONE must be written with 1 to clear it */ + ctrl |= 1 << raminit->bits.done; + regmap_update_bits(raminit->syscon, raminit->reg, mask, ctrl); + /* prevent further clearing of DONE bit */ + ctrl &= ~(1 << raminit->bits.done); /* clear START bit if start pulse is needed */ if (raminit->needs_pulse) { ctrl &= ~(1 << raminit->bits.start); - regmap_write(raminit->syscon, raminit->reg, ctrl); + regmap_update_bits(raminit->syscon, raminit->reg, + mask, ctrl); } ctrl |= 1 << raminit->bits.done; diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 3ec8f6f25e5f..847c1f813261 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -807,10 +807,14 @@ static int can_changelink(struct net_device *dev, if (dev->flags & IFF_UP) return -EBUSY; cm = nla_data(data[IFLA_CAN_CTRLMODE]); - if (cm->flags & ~priv->ctrlmode_supported) + + /* check whether changed bits are allowed to be modified */ + if (cm->mask & ~priv->ctrlmode_supported) return -EOPNOTSUPP; + + /* clear bits to be modified and copy the flag values */ priv->ctrlmode &= ~cm->mask; - priv->ctrlmode |= cm->flags; + priv->ctrlmode |= (cm->flags & cm->mask); /* CAN_CTRLMODE_FD can only be set when driver supports FD */ if (priv->ctrlmode & CAN_CTRLMODE_FD) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index d7bc462aafdc..244529881be9 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -955,6 +955,11 @@ static struct net_device *alloc_m_can_dev(void) priv->can.data_bittiming_const = &m_can_data_bittiming_const; priv->can.do_set_mode = m_can_set_mode; priv->can.do_get_berr_counter = m_can_get_berr_counter; + + /* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.0.1 */ + priv->can.ctrlmode = CAN_CTRLMODE_FD_NON_ISO; + + /* CAN_CTRLMODE_FD_NON_ISO can not be changed with M_CAN IP v3.0.1 */ priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_BERR_REPORTING | diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 541fb7a05625..c32cd61073bc 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -520,10 +520,10 @@ static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev, skb = alloc_can_err_skb(priv->netdev, &cf); if (skb) { cf->can_id |= CAN_ERR_RESTARTED; - netif_rx(skb); stats->rx_packets++; stats->rx_bytes += cf->can_dlc; + netif_rx(skb); } else { netdev_err(priv->netdev, "No memory left for err_skb\n"); @@ -770,10 +770,9 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, priv->can.state = new_state; - netif_rx(skb); - stats->rx_packets++; stats->rx_bytes += cf->can_dlc; + netif_rx(skb); } static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv, @@ -805,10 +804,9 @@ static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv, stats->rx_over_errors++; stats->rx_errors++; - netif_rx(skb); - stats->rx_packets++; stats->rx_bytes += cf->can_dlc; + netif_rx(skb); } } @@ -887,10 +885,9 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev, cf->can_dlc); } - netif_rx(skb); - stats->rx_packets++; stats->rx_bytes += cf->can_dlc; + netif_rx(skb); } static void kvaser_usb_start_chip_reply(const struct kvaser_usb *dev, @@ -1246,6 +1243,9 @@ static int kvaser_usb_close(struct net_device *netdev) if (err) netdev_warn(netdev, "Cannot stop device, error %d\n", err); + /* reset tx contexts */ + kvaser_usb_unlink_tx_urbs(priv); + priv->can.state = CAN_STATE_STOPPED; close_candev(priv->netdev); @@ -1294,12 +1294,14 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, if (!urb) { netdev_err(netdev, "No memory left for URBs\n"); stats->tx_dropped++; - goto nourbmem; + dev_kfree_skb(skb); + return NETDEV_TX_OK; } buf = kmalloc(sizeof(struct kvaser_msg), GFP_ATOMIC); if (!buf) { stats->tx_dropped++; + dev_kfree_skb(skb); goto nobufmem; } @@ -1334,6 +1336,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, } } + /* This should never happen; it implies a flow control bug */ if (!context) { netdev_warn(netdev, "cannot find free context\n"); ret = NETDEV_TX_BUSY; @@ -1364,9 +1367,6 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, if (unlikely(err)) { can_free_echo_skb(netdev, context->echo_index); - skb = NULL; /* set to NULL to avoid double free in - * dev_kfree_skb(skb) */ - atomic_dec(&priv->active_tx_urbs); usb_unanchor_urb(urb); @@ -1388,8 +1388,6 @@ releasebuf: kfree(buf); nobufmem: usb_free_urb(urb); -nourbmem: - dev_kfree_skb(skb); return ret; } @@ -1502,6 +1500,10 @@ static int kvaser_usb_init_one(struct usb_interface *intf, struct kvaser_usb_net_priv *priv; int i, err; + err = kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, channel); + if (err) + return err; + netdev = alloc_candev(sizeof(*priv), MAX_TX_URBS); if (!netdev) { dev_err(&intf->dev, "Cannot alloc candev\n"); @@ -1606,9 +1608,6 @@ static int kvaser_usb_probe(struct usb_interface *intf, usb_set_intfdata(intf, dev); - for (i = 0; i < MAX_NET_DEVICES; i++) - kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, i); - err = kvaser_usb_get_software_info(dev); if (err) { dev_err(&intf->dev, diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig index 7cf8f4ac281f..48e62a34f7f2 100644 --- a/drivers/net/dsa/Kconfig +++ b/drivers/net/dsa/Kconfig @@ -59,7 +59,7 @@ config NET_DSA_BCM_SF2 depends on HAS_IOMEM select NET_DSA select NET_DSA_TAG_BRCM - select FIXED_PHY if NET_DSA_BCM_SF2=y + select FIXED_PHY select BCM7XXX_PHY select MDIO_BCM_UNIMAC ---help--- diff --git a/drivers/net/ethernet/8390/ne2k-pci.c b/drivers/net/ethernet/8390/ne2k-pci.c index 89c8d9fc97de..57e97910c728 100644 --- a/drivers/net/ethernet/8390/ne2k-pci.c +++ b/drivers/net/ethernet/8390/ne2k-pci.c @@ -246,13 +246,13 @@ static int ne2k_pci_init_one(struct pci_dev *pdev, if (!ioaddr || ((pci_resource_flags (pdev, 0) & IORESOURCE_IO) == 0)) { dev_err(&pdev->dev, "no I/O resource at PCI BAR #0\n"); - return -ENODEV; + goto err_out; } if (request_region (ioaddr, NE_IO_EXTENT, DRV_NAME) == NULL) { dev_err(&pdev->dev, "I/O resource 0x%x @ 0x%lx busy\n", NE_IO_EXTENT, ioaddr); - return -EBUSY; + goto err_out; } reg0 = inb(ioaddr); @@ -392,6 +392,8 @@ err_out_free_netdev: free_netdev (dev); err_out_free_res: release_region (ioaddr, NE_IO_EXTENT); +err_out: + pci_disable_device(pdev); return -ENODEV; } diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig index df76050d0a9d..eadcb053807e 100644 --- a/drivers/net/ethernet/Kconfig +++ b/drivers/net/ethernet/Kconfig @@ -156,18 +156,6 @@ source "drivers/net/ethernet/realtek/Kconfig" source "drivers/net/ethernet/renesas/Kconfig" source "drivers/net/ethernet/rdc/Kconfig" source "drivers/net/ethernet/rocker/Kconfig" - -config S6GMAC - tristate "S6105 GMAC ethernet support" - depends on XTENSA_VARIANT_S6000 - select PHYLIB - ---help--- - This driver supports the on chip ethernet device on the - S6105 xtensa processor. - - To compile this driver as a module, choose M here. The module - will be called s6gmac. - source "drivers/net/ethernet/samsung/Kconfig" source "drivers/net/ethernet/seeq/Kconfig" source "drivers/net/ethernet/silan/Kconfig" diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile index bf56f8b36e90..1367afcd0a8b 100644 --- a/drivers/net/ethernet/Makefile +++ b/drivers/net/ethernet/Makefile @@ -66,7 +66,6 @@ obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/ obj-$(CONFIG_SH_ETH) += renesas/ obj-$(CONFIG_NET_VENDOR_RDC) += rdc/ obj-$(CONFIG_NET_VENDOR_ROCKER) += rocker/ -obj-$(CONFIG_S6GMAC) += s6gmac.o obj-$(CONFIG_NET_VENDOR_SAMSUNG) += samsung/ obj-$(CONFIG_NET_VENDOR_SEEQ) += seeq/ obj-$(CONFIG_NET_VENDOR_SILAN) += silan/ diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c index 1fcd5568a352..f3470d96837a 100644 --- a/drivers/net/ethernet/allwinner/sun4i-emac.c +++ b/drivers/net/ethernet/allwinner/sun4i-emac.c @@ -850,8 +850,10 @@ static int emac_probe(struct platform_device *pdev) } db->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(db->clk)) + if (IS_ERR(db->clk)) { + ret = PTR_ERR(db->clk); goto out; + } clk_prepare_enable(db->clk); diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c index 3498760dc22a..760c72c6e2ac 100644 --- a/drivers/net/ethernet/altera/altera_tse_main.c +++ b/drivers/net/ethernet/altera/altera_tse_main.c @@ -1170,10 +1170,6 @@ tx_request_irq_error: init_error: free_skbufs(dev); alloc_skbuf_error: - if (priv->phydev) { - phy_disconnect(priv->phydev); - priv->phydev = NULL; - } phy_error: return ret; } @@ -1186,12 +1182,9 @@ static int tse_shutdown(struct net_device *dev) int ret; unsigned long int flags; - /* Stop and disconnect the PHY */ - if (priv->phydev) { + /* Stop the PHY */ + if (priv->phydev) phy_stop(priv->phydev); - phy_disconnect(priv->phydev); - priv->phydev = NULL; - } netif_stop_queue(dev); napi_disable(&priv->napi); @@ -1525,6 +1518,10 @@ err_free_netdev: static int altera_tse_remove(struct platform_device *pdev) { struct net_device *ndev = platform_get_drvdata(pdev); + struct altera_tse_private *priv = netdev_priv(ndev); + + if (priv->phydev) + phy_disconnect(priv->phydev); platform_set_drvdata(pdev, NULL); altera_tse_mdio_destroy(ndev); diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c index e398eda07298..c8af3ce3ea38 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c @@ -184,15 +184,16 @@ static void alx_schedule_reset(struct alx_priv *alx) schedule_work(&alx->reset_wk); } -static bool alx_clean_rx_irq(struct alx_priv *alx, int budget) +static int alx_clean_rx_irq(struct alx_priv *alx, int budget) { struct alx_rx_queue *rxq = &alx->rxq; struct alx_rrd *rrd; struct alx_buffer *rxb; struct sk_buff *skb; u16 length, rfd_cleaned = 0; + int work = 0; - while (budget > 0) { + while (work < budget) { rrd = &rxq->rrd[rxq->rrd_read_idx]; if (!(rrd->word3 & cpu_to_le32(1 << RRD_UPDATED_SHIFT))) break; @@ -203,7 +204,7 @@ static bool alx_clean_rx_irq(struct alx_priv *alx, int budget) ALX_GET_FIELD(le32_to_cpu(rrd->word0), RRD_NOR) != 1) { alx_schedule_reset(alx); - return 0; + return work; } rxb = &rxq->bufs[rxq->read_idx]; @@ -243,7 +244,7 @@ static bool alx_clean_rx_irq(struct alx_priv *alx, int budget) } napi_gro_receive(&alx->napi, skb); - budget--; + work++; next_pkt: if (++rxq->read_idx == alx->rx_ringsz) @@ -258,21 +259,22 @@ next_pkt: if (rfd_cleaned) alx_refill_rx_ring(alx, GFP_ATOMIC); - return budget > 0; + return work; } static int alx_poll(struct napi_struct *napi, int budget) { struct alx_priv *alx = container_of(napi, struct alx_priv, napi); struct alx_hw *hw = &alx->hw; - bool complete = true; unsigned long flags; + bool tx_complete; + int work; - complete = alx_clean_tx_irq(alx) && - alx_clean_rx_irq(alx, budget); + tx_complete = alx_clean_tx_irq(alx); + work = alx_clean_rx_irq(alx, budget); - if (!complete) - return 1; + if (!tx_complete || work == budget) + return budget; napi_complete(&alx->napi); @@ -284,7 +286,7 @@ static int alx_poll(struct napi_struct *napi, int budget) alx_post_write(hw); - return 0; + return work; } static irqreturn_t alx_intr_handle(struct alx_priv *alx, u32 intr) diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig index 888247ad9068..41a3c9804427 100644 --- a/drivers/net/ethernet/broadcom/Kconfig +++ b/drivers/net/ethernet/broadcom/Kconfig @@ -64,7 +64,7 @@ config BCMGENET tristate "Broadcom GENET internal MAC support" select MII select PHYLIB - select FIXED_PHY if BCMGENET=y + select FIXED_PHY select BCM7XXX_PHY help This driver supports the built-in Ethernet MACs found in the @@ -155,7 +155,7 @@ config SYSTEMPORT depends on OF select MII select PHYLIB - select FIXED_PHY if SYSTEMPORT=y + select FIXED_PHY help This driver supports the built-in Ethernet MACs found in the Broadcom BCM7xxx Set Top Box family chipset using an internal diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 05c6af6c418f..3007d95fbb9f 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1167,10 +1167,10 @@ static int bgmac_poll(struct napi_struct *napi, int weight) bgmac->int_status = 0; } - if (handled < weight) + if (handled < weight) { napi_complete(napi); - - bgmac_chip_intrs_on(bgmac); + bgmac_chip_intrs_on(bgmac); + } return handled; } @@ -1515,6 +1515,8 @@ static int bgmac_probe(struct bcma_device *core) if (core->bus->sprom.boardflags_lo & BGMAC_BFL_ENETADM) bgmac_warn(bgmac, "Support for ADMtek ethernet switch not implemented\n"); + netif_napi_add(net_dev, &bgmac->napi, bgmac_poll, BGMAC_WEIGHT); + err = bgmac_mii_register(bgmac); if (err) { bgmac_err(bgmac, "Cannot register MDIO\n"); @@ -1529,8 +1531,6 @@ static int bgmac_probe(struct bcma_device *core) netif_carrier_off(net_dev); - netif_napi_add(net_dev, &bgmac->napi, bgmac_poll, BGMAC_WEIGHT); - return 0; err_mii_unregister: @@ -1549,9 +1549,9 @@ static void bgmac_remove(struct bcma_device *core) { struct bgmac *bgmac = bcma_get_drvdata(core); - netif_napi_del(&bgmac->napi); unregister_netdev(bgmac->net_dev); bgmac_mii_unregister(bgmac); + netif_napi_del(&bgmac->napi); bgmac_dma_free(bgmac); bcma_set_drvdata(core, NULL); free_netdev(bgmac->net_dev); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 691f0bf09ee1..72eef9fc883e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -12553,9 +12553,11 @@ static int bnx2x_get_phys_port_id(struct net_device *netdev, return 0; } -static bool bnx2x_gso_check(struct sk_buff *skb, struct net_device *dev) +static netdev_features_t bnx2x_features_check(struct sk_buff *skb, + struct net_device *dev, + netdev_features_t features) { - return vxlan_gso_check(skb); + return vxlan_features_check(skb, features); } static const struct net_device_ops bnx2x_netdev_ops = { @@ -12589,7 +12591,7 @@ static const struct net_device_ops bnx2x_netdev_ops = { #endif .ndo_get_phys_port_id = bnx2x_get_phys_port_id, .ndo_set_vf_link_state = bnx2x_set_vf_link_state, - .ndo_gso_check = bnx2x_gso_check, + .ndo_features_check = bnx2x_features_check, }; static int bnx2x_set_coherency_mask(struct bnx2x *bp) @@ -13256,7 +13258,7 @@ static int bnx2x_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) return -EFAULT; } - DP(BNX2X_MSG_PTP, "Configrued val = %d, period = %d\n", best_val, + DP(BNX2X_MSG_PTP, "Configured val = %d, period = %d\n", best_val, best_period); return 0; @@ -14784,7 +14786,7 @@ static int bnx2x_hwtstamp_ioctl(struct bnx2x *bp, struct ifreq *ifr) -EFAULT : 0; } -/* Configrues HW for PTP */ +/* Configures HW for PTP */ static int bnx2x_configure_ptp(struct bnx2x *bp) { int rc, port = BP_PORT(bp); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index b0779d773343..6fe547c93e74 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h @@ -7549,7 +7549,7 @@ Theotherbitsarereservedandshouldbezero*/ #define IGU_REG_SISR_MDPC_WOMASK_UPPER 0x05a6 #define IGU_REG_RESERVED_UPPER 0x05ff -/* Fields of IGU PF CONFIGRATION REGISTER */ +/* Fields of IGU PF CONFIGURATION REGISTER */ #define IGU_PF_CONF_FUNC_EN (0x1<<0) /* function enable */ #define IGU_PF_CONF_MSI_MSIX_EN (0x1<<1) /* MSI/MSIX enable */ #define IGU_PF_CONF_INT_LINE_EN (0x1<<2) /* INT enable */ @@ -7557,7 +7557,7 @@ Theotherbitsarereservedandshouldbezero*/ #define IGU_PF_CONF_SINGLE_ISR_EN (0x1<<4) /* single ISR mode enable */ #define IGU_PF_CONF_SIMD_MODE (0x1<<5) /* simd all ones mode */ -/* Fields of IGU VF CONFIGRATION REGISTER */ +/* Fields of IGU VF CONFIGURATION REGISTER */ #define IGU_VF_CONF_FUNC_EN (0x1<<0) /* function enable */ #define IGU_VF_CONF_MSI_MSIX_EN (0x1<<1) /* MSI/MSIX enable */ #define IGU_VF_CONF_PARENT_MASK (0x3<<2) /* Parent PF */ diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index bb48a610b72a..96bf01ba32dd 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -7413,6 +7413,8 @@ static inline void tg3_netif_start(struct tg3 *tp) } static void tg3_irq_quiesce(struct tg3 *tp) + __releases(tp->lock) + __acquires(tp->lock) { int i; @@ -7421,8 +7423,12 @@ static void tg3_irq_quiesce(struct tg3 *tp) tp->irq_sync = 1; smp_mb(); + spin_unlock_bh(&tp->lock); + for (i = 0; i < tp->irq_cnt; i++) synchronize_irq(tp->napi[i].irq_vec); + + spin_lock_bh(&tp->lock); } /* Fully shutdown all tg3 driver activity elsewhere in the system. @@ -9018,6 +9024,8 @@ static void tg3_restore_clk(struct tg3 *tp) /* tp->lock is held. */ static int tg3_chip_reset(struct tg3 *tp) + __releases(tp->lock) + __acquires(tp->lock) { u32 val; void (*write_op)(struct tg3 *, u32, u32); @@ -9073,9 +9081,13 @@ static int tg3_chip_reset(struct tg3 *tp) } smp_mb(); + tg3_full_unlock(tp); + for (i = 0; i < tp->irq_cnt; i++) synchronize_irq(tp->napi[i].irq_vec); + tg3_full_lock(tp, 0); + if (tg3_asic_rev(tp) == ASIC_REV_57780) { val = tr32(TG3_PCIE_LNKCTL) & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN; tw32(TG3_PCIE_LNKCTL, val | TG3_PCIE_LNKCTL_L1_PLL_PD_DIS); @@ -10903,11 +10915,13 @@ static void tg3_timer(unsigned long __opaque) { struct tg3 *tp = (struct tg3 *) __opaque; - if (tp->irq_sync || tg3_flag(tp, RESET_TASK_PENDING)) - goto restart_timer; - spin_lock(&tp->lock); + if (tp->irq_sync || tg3_flag(tp, RESET_TASK_PENDING)) { + spin_unlock(&tp->lock); + goto restart_timer; + } + if (tg3_asic_rev(tp) == ASIC_REV_5717 || tg3_flag(tp, 57765_CLASS)) tg3_chk_missed_msi(tp); @@ -11101,11 +11115,13 @@ static void tg3_reset_task(struct work_struct *work) struct tg3 *tp = container_of(work, struct tg3, reset_task); int err; + rtnl_lock(); tg3_full_lock(tp, 0); if (!netif_running(tp->dev)) { tg3_flag_clear(tp, RESET_TASK_PENDING); tg3_full_unlock(tp); + rtnl_unlock(); return; } @@ -11138,6 +11154,7 @@ out: tg3_phy_start(tp); tg3_flag_clear(tp, RESET_TASK_PENDING); + rtnl_unlock(); } static int tg3_request_irq(struct tg3 *tp, int irq_num) @@ -17800,23 +17817,6 @@ static int tg3_init_one(struct pci_dev *pdev, goto err_out_apeunmap; } - /* - * Reset chip in case UNDI or EFI driver did not shutdown - * DMA self test will enable WDMAC and we'll see (spurious) - * pending DMA on the PCI bus at that point. - */ - if ((tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE) || - (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { - tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); - tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); - } - - err = tg3_test_dma(tp); - if (err) { - dev_err(&pdev->dev, "DMA engine test failed, aborting\n"); - goto err_out_apeunmap; - } - intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW; rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW; sndmbx = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW; @@ -17861,6 +17861,23 @@ static int tg3_init_one(struct pci_dev *pdev, sndmbx += 0xc; } + /* + * Reset chip in case UNDI or EFI driver did not shutdown + * DMA self test will enable WDMAC and we'll see (spurious) + * pending DMA on the PCI bus at that point. + */ + if ((tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE) || + (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { + tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); + tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); + } + + err = tg3_test_dma(tp); + if (err) { + dev_err(&pdev->dev, "DMA engine test failed, aborting\n"); + goto err_out_apeunmap; + } + tg3_init_coal(tp); pci_set_drvdata(pdev, dev); diff --git a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c index 7d6aa8c87df8..619083a860a4 100644 --- a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c +++ b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c @@ -172,7 +172,7 @@ bnad_get_debug_drvinfo(struct bnad *bnad, void *buffer, u32 len) /* Retrieve flash partition info */ fcomp.comp_status = 0; - init_completion(&fcomp.comp); + reinit_completion(&fcomp.comp); spin_lock_irqsave(&bnad->bna_lock, flags); ret = bfa_nw_flash_get_attr(&bnad->bna.flash, &drvinfo->flash_attr, bnad_cb_completion, &fcomp); diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c index 55eb7f2af2b4..7ef55f5fa664 100644 --- a/drivers/net/ethernet/cadence/at91_ether.c +++ b/drivers/net/ethernet/cadence/at91_ether.c @@ -340,7 +340,7 @@ static int __init at91ether_probe(struct platform_device *pdev) res = PTR_ERR(lp->pclk); goto err_free_dev; } - clk_enable(lp->pclk); + clk_prepare_enable(lp->pclk); lp->hclk = ERR_PTR(-ENOENT); lp->tx_clk = ERR_PTR(-ENOENT); @@ -406,7 +406,7 @@ static int __init at91ether_probe(struct platform_device *pdev) err_out_unregister_netdev: unregister_netdev(dev); err_disable_clock: - clk_disable(lp->pclk); + clk_disable_unprepare(lp->pclk); err_free_dev: free_netdev(dev); return res; @@ -424,7 +424,7 @@ static int at91ether_remove(struct platform_device *pdev) kfree(lp->mii_bus->irq); mdiobus_free(lp->mii_bus); unregister_netdev(dev); - clk_disable(lp->pclk); + clk_disable_unprepare(lp->pclk); free_netdev(dev); return 0; @@ -440,7 +440,7 @@ static int at91ether_suspend(struct platform_device *pdev, pm_message_t mesg) netif_stop_queue(net_dev); netif_device_detach(net_dev); - clk_disable(lp->pclk); + clk_disable_unprepare(lp->pclk); } return 0; } @@ -451,7 +451,7 @@ static int at91ether_resume(struct platform_device *pdev) struct macb *lp = netdev_priv(net_dev); if (netif_running(net_dev)) { - clk_enable(lp->pclk); + clk_prepare_enable(lp->pclk); netif_device_attach(net_dev); netif_start_queue(net_dev); diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 06dea3dd463c..3767271c7667 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -2160,7 +2160,7 @@ static int __init macb_probe(struct platform_device *pdev) int err = -ENXIO; const char *mac; void __iomem *mem; - unsigned int hw_q, queue_mask, q, num_queues, q_irq = 0; + unsigned int hw_q, queue_mask, q, num_queues; struct clk *pclk, *hclk, *tx_clk; regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -2235,11 +2235,11 @@ static int __init macb_probe(struct platform_device *pdev) * register mapping but we don't want to test the queue index then * compute the corresponding register offset at run time. */ - for (hw_q = 0; hw_q < MACB_MAX_QUEUES; ++hw_q) { + for (hw_q = 0, q = 0; hw_q < MACB_MAX_QUEUES; ++hw_q) { if (!(queue_mask & (1 << hw_q))) continue; - queue = &bp->queues[q_irq]; + queue = &bp->queues[q]; queue->bp = bp; if (hw_q) { queue->ISR = GEM_ISR(hw_q - 1); @@ -2261,18 +2261,18 @@ static int __init macb_probe(struct platform_device *pdev) * must remove the optional gaps that could exist in the * hardware queue mask. */ - queue->irq = platform_get_irq(pdev, q_irq); + queue->irq = platform_get_irq(pdev, q); err = devm_request_irq(&pdev->dev, queue->irq, macb_interrupt, 0, dev->name, queue); if (err) { dev_err(&pdev->dev, "Unable to request IRQ %d (error %d)\n", queue->irq, err); - goto err_out_free_irq; + goto err_out_free_netdev; } INIT_WORK(&queue->tx_error_task, macb_tx_error_task); - q_irq++; + q++; } dev->irq = bp->queues[0].irq; @@ -2350,7 +2350,7 @@ static int __init macb_probe(struct platform_device *pdev) err = register_netdev(dev); if (err) { dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); - goto err_out_free_irq; + goto err_out_free_netdev; } err = macb_mii_init(bp); @@ -2373,9 +2373,7 @@ static int __init macb_probe(struct platform_device *pdev) err_out_unregister_netdev: unregister_netdev(dev); -err_out_free_irq: - for (q = 0, queue = bp->queues; q < q_irq; ++q, ++queue) - devm_free_irq(&pdev->dev, queue->irq, queue); +err_out_free_netdev: free_netdev(dev); err_out_disable_clocks: if (!IS_ERR(tx_clk)) @@ -2392,8 +2390,6 @@ static int __exit macb_remove(struct platform_device *pdev) { struct net_device *dev; struct macb *bp; - struct macb_queue *queue; - unsigned int q; dev = platform_get_drvdata(pdev); @@ -2405,14 +2401,11 @@ static int __exit macb_remove(struct platform_device *pdev) kfree(bp->mii_bus->irq); mdiobus_free(bp->mii_bus); unregister_netdev(dev); - queue = bp->queues; - for (q = 0; q < bp->num_queues; ++q, ++queue) - devm_free_irq(&pdev->dev, queue->irq, queue); - free_netdev(dev); if (!IS_ERR(bp->tx_clk)) clk_disable_unprepare(bp->tx_clk); clk_disable_unprepare(bp->hclk); clk_disable_unprepare(bp->pclk); + free_netdev(dev); } return 0; diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 28d04153f999..c132d9030729 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -2376,7 +2376,7 @@ const char *t4_get_port_type_description(enum fw_port_type port_type) "KR/KX", "KR/KX/KX4", "R QSFP_10G", - "", + "R QSA", "R QSFP", "R BP40_BA", }; diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h index 291b6f219708..7c0aec85137a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h @@ -2470,8 +2470,8 @@ enum fw_port_type { FW_PORT_TYPE_BP_AP, FW_PORT_TYPE_BP4_AP, FW_PORT_TYPE_QSFP_10G, - FW_PORT_TYPE_QSFP, FW_PORT_TYPE_QSA, + FW_PORT_TYPE_QSFP, FW_PORT_TYPE_BP40_BA, FW_PORT_TYPE_NONE = FW_PORT_CMD_PTYPE_M diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h index d00a751f0588..6049f70e110c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h +++ b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h @@ -96,6 +96,9 @@ struct port_info { s16 xact_addr_filt; /* index of our MAC address filter */ u16 rss_size; /* size of VI's RSS table slice */ u8 pidx; /* index into adapter port[] */ + s8 mdio_addr; + u8 port_type; /* firmware port type */ + u8 mod_type; /* firmware module type */ u8 port_id; /* physical port ID */ u8 nqsets; /* # of "Queue Sets" */ u8 first_qset; /* index of first "Queue Set" */ @@ -522,6 +525,7 @@ static inline struct adapter *netdev2adap(const struct net_device *dev) * is "contracted" to provide for the common code. */ void t4vf_os_link_changed(struct adapter *, int, int); +void t4vf_os_portmod_changed(struct adapter *, int); /* * SGE function prototype declarations. diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index aa74ec34a467..a936ee8958c7 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -44,6 +44,7 @@ #include <linux/etherdevice.h> #include <linux/debugfs.h> #include <linux/ethtool.h> +#include <linux/mdio.h> #include "t4vf_common.h" #include "t4vf_defs.h" @@ -210,6 +211,38 @@ void t4vf_os_link_changed(struct adapter *adapter, int pidx, int link_ok) } /* + * THe port module type has changed on the indicated "port" (Virtual + * Interface). + */ +void t4vf_os_portmod_changed(struct adapter *adapter, int pidx) +{ + static const char * const mod_str[] = { + NULL, "LR", "SR", "ER", "passive DA", "active DA", "LRM" + }; + const struct net_device *dev = adapter->port[pidx]; + const struct port_info *pi = netdev_priv(dev); + + if (pi->mod_type == FW_PORT_MOD_TYPE_NONE) + dev_info(adapter->pdev_dev, "%s: port module unplugged\n", + dev->name); + else if (pi->mod_type < ARRAY_SIZE(mod_str)) + dev_info(adapter->pdev_dev, "%s: %s port module inserted\n", + dev->name, mod_str[pi->mod_type]); + else if (pi->mod_type == FW_PORT_MOD_TYPE_NOTSUPPORTED) + dev_info(adapter->pdev_dev, "%s: unsupported optical port " + "module inserted\n", dev->name); + else if (pi->mod_type == FW_PORT_MOD_TYPE_UNKNOWN) + dev_info(adapter->pdev_dev, "%s: unknown port module inserted," + "forcing TWINAX\n", dev->name); + else if (pi->mod_type == FW_PORT_MOD_TYPE_ERROR) + dev_info(adapter->pdev_dev, "%s: transceiver module error\n", + dev->name); + else + dev_info(adapter->pdev_dev, "%s: unknown module type %d " + "inserted\n", dev->name, pi->mod_type); +} + +/* * Net device operations. * ====================== */ @@ -1193,24 +1226,103 @@ static void cxgb4vf_poll_controller(struct net_device *dev) * state of the port to which we're linked. */ -/* - * Return current port link settings. - */ -static int cxgb4vf_get_settings(struct net_device *dev, - struct ethtool_cmd *cmd) -{ - const struct port_info *pi = netdev_priv(dev); +static unsigned int t4vf_from_fw_linkcaps(enum fw_port_type type, + unsigned int caps) +{ + unsigned int v = 0; + + if (type == FW_PORT_TYPE_BT_SGMII || type == FW_PORT_TYPE_BT_XFI || + type == FW_PORT_TYPE_BT_XAUI) { + v |= SUPPORTED_TP; + if (caps & FW_PORT_CAP_SPEED_100M) + v |= SUPPORTED_100baseT_Full; + if (caps & FW_PORT_CAP_SPEED_1G) + v |= SUPPORTED_1000baseT_Full; + if (caps & FW_PORT_CAP_SPEED_10G) + v |= SUPPORTED_10000baseT_Full; + } else if (type == FW_PORT_TYPE_KX4 || type == FW_PORT_TYPE_KX) { + v |= SUPPORTED_Backplane; + if (caps & FW_PORT_CAP_SPEED_1G) + v |= SUPPORTED_1000baseKX_Full; + if (caps & FW_PORT_CAP_SPEED_10G) + v |= SUPPORTED_10000baseKX4_Full; + } else if (type == FW_PORT_TYPE_KR) + v |= SUPPORTED_Backplane | SUPPORTED_10000baseKR_Full; + else if (type == FW_PORT_TYPE_BP_AP) + v |= SUPPORTED_Backplane | SUPPORTED_10000baseR_FEC | + SUPPORTED_10000baseKR_Full | SUPPORTED_1000baseKX_Full; + else if (type == FW_PORT_TYPE_BP4_AP) + v |= SUPPORTED_Backplane | SUPPORTED_10000baseR_FEC | + SUPPORTED_10000baseKR_Full | SUPPORTED_1000baseKX_Full | + SUPPORTED_10000baseKX4_Full; + else if (type == FW_PORT_TYPE_FIBER_XFI || + type == FW_PORT_TYPE_FIBER_XAUI || + type == FW_PORT_TYPE_SFP || + type == FW_PORT_TYPE_QSFP_10G || + type == FW_PORT_TYPE_QSA) { + v |= SUPPORTED_FIBRE; + if (caps & FW_PORT_CAP_SPEED_1G) + v |= SUPPORTED_1000baseT_Full; + if (caps & FW_PORT_CAP_SPEED_10G) + v |= SUPPORTED_10000baseT_Full; + } else if (type == FW_PORT_TYPE_BP40_BA || + type == FW_PORT_TYPE_QSFP) { + v |= SUPPORTED_40000baseSR4_Full; + v |= SUPPORTED_FIBRE; + } + + if (caps & FW_PORT_CAP_ANEG) + v |= SUPPORTED_Autoneg; + return v; +} + +static int cxgb4vf_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + const struct port_info *p = netdev_priv(dev); + + if (p->port_type == FW_PORT_TYPE_BT_SGMII || + p->port_type == FW_PORT_TYPE_BT_XFI || + p->port_type == FW_PORT_TYPE_BT_XAUI) + cmd->port = PORT_TP; + else if (p->port_type == FW_PORT_TYPE_FIBER_XFI || + p->port_type == FW_PORT_TYPE_FIBER_XAUI) + cmd->port = PORT_FIBRE; + else if (p->port_type == FW_PORT_TYPE_SFP || + p->port_type == FW_PORT_TYPE_QSFP_10G || + p->port_type == FW_PORT_TYPE_QSA || + p->port_type == FW_PORT_TYPE_QSFP) { + if (p->mod_type == FW_PORT_MOD_TYPE_LR || + p->mod_type == FW_PORT_MOD_TYPE_SR || + p->mod_type == FW_PORT_MOD_TYPE_ER || + p->mod_type == FW_PORT_MOD_TYPE_LRM) + cmd->port = PORT_FIBRE; + else if (p->mod_type == FW_PORT_MOD_TYPE_TWINAX_PASSIVE || + p->mod_type == FW_PORT_MOD_TYPE_TWINAX_ACTIVE) + cmd->port = PORT_DA; + else + cmd->port = PORT_OTHER; + } else + cmd->port = PORT_OTHER; - cmd->supported = pi->link_cfg.supported; - cmd->advertising = pi->link_cfg.advertising; + if (p->mdio_addr >= 0) { + cmd->phy_address = p->mdio_addr; + cmd->transceiver = XCVR_EXTERNAL; + cmd->mdio_support = p->port_type == FW_PORT_TYPE_BT_SGMII ? + MDIO_SUPPORTS_C22 : MDIO_SUPPORTS_C45; + } else { + cmd->phy_address = 0; /* not really, but no better option */ + cmd->transceiver = XCVR_INTERNAL; + cmd->mdio_support = 0; + } + + cmd->supported = t4vf_from_fw_linkcaps(p->port_type, + p->link_cfg.supported); + cmd->advertising = t4vf_from_fw_linkcaps(p->port_type, + p->link_cfg.advertising); ethtool_cmd_speed_set(cmd, - netif_carrier_ok(dev) ? pi->link_cfg.speed : -1); + netif_carrier_ok(dev) ? p->link_cfg.speed : 0); cmd->duplex = DUPLEX_FULL; - - cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE; - cmd->phy_address = pi->port_id; - cmd->transceiver = XCVR_EXTERNAL; - cmd->autoneg = pi->link_cfg.autoneg; + cmd->autoneg = p->link_cfg.autoneg; cmd->maxtxpkt = 0; cmd->maxrxpkt = 0; return 0; @@ -2318,7 +2430,7 @@ static void cfg_queues(struct adapter *adapter) */ n10g = 0; for_each_port(adapter, pidx) - n10g += is_10g_port(&adap2pinfo(adapter, pidx)->link_cfg); + n10g += is_x_10g_port(&adap2pinfo(adapter, pidx)->link_cfg); /* * We default to 1 queue per non-10G port and up to # of cores queues diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h index 8d3237f5e364..b9debb4f29a3 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h @@ -230,7 +230,7 @@ struct adapter_params { static inline bool is_10g_port(const struct link_config *lc) { - return (lc->supported & SUPPORTED_10000baseT_Full) != 0; + return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0; } static inline bool is_x_10g_port(const struct link_config *lc) diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c index 02e8833b7797..60426cf890a7 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c @@ -245,6 +245,10 @@ static int hash_mac_addr(const u8 *addr) return a & 0x3f; } +#define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\ + FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_40G | \ + FW_PORT_CAP_SPEED_100G | FW_PORT_CAP_ANEG) + /** * init_link_config - initialize a link's SW state * @lc: structure holding the link state @@ -259,8 +263,8 @@ static void init_link_config(struct link_config *lc, unsigned int caps) lc->requested_speed = 0; lc->speed = 0; lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX; - if (lc->supported & SUPPORTED_Autoneg) { - lc->advertising = lc->supported; + if (lc->supported & FW_PORT_CAP_ANEG) { + lc->advertising = lc->supported & ADVERT_MASK; lc->autoneg = AUTONEG_ENABLE; lc->requested_fc |= PAUSE_AUTONEG; } else { @@ -280,7 +284,6 @@ int t4vf_port_init(struct adapter *adapter, int pidx) struct fw_vi_cmd vi_cmd, vi_rpl; struct fw_port_cmd port_cmd, port_rpl; int v; - u32 word; /* * Execute a VI Read command to get our Virtual Interface information @@ -319,19 +322,13 @@ int t4vf_port_init(struct adapter *adapter, int pidx) if (v) return v; - v = 0; - word = be16_to_cpu(port_rpl.u.info.pcap); - if (word & FW_PORT_CAP_SPEED_100M) - v |= SUPPORTED_100baseT_Full; - if (word & FW_PORT_CAP_SPEED_1G) - v |= SUPPORTED_1000baseT_Full; - if (word & FW_PORT_CAP_SPEED_10G) - v |= SUPPORTED_10000baseT_Full; - if (word & FW_PORT_CAP_SPEED_40G) - v |= SUPPORTED_40000baseSR4_Full; - if (word & FW_PORT_CAP_ANEG) - v |= SUPPORTED_Autoneg; - init_link_config(&pi->link_cfg, v); + v = be32_to_cpu(port_rpl.u.info.lstatus_to_modtype); + pi->mdio_addr = (v & FW_PORT_CMD_MDIOCAP_F) ? + FW_PORT_CMD_MDIOADDR_G(v) : -1; + pi->port_type = FW_PORT_CMD_PTYPE_G(v); + pi->mod_type = FW_PORT_MOD_TYPE_NA; + + init_link_config(&pi->link_cfg, be16_to_cpu(port_rpl.u.info.pcap)); return 0; } @@ -1491,7 +1488,7 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl) */ const struct fw_port_cmd *port_cmd = (const struct fw_port_cmd *)rpl; - u32 word; + u32 stat, mod; int action, port_id, link_ok, speed, fc, pidx; /* @@ -1509,21 +1506,21 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl) port_id = FW_PORT_CMD_PORTID_G( be32_to_cpu(port_cmd->op_to_portid)); - word = be32_to_cpu(port_cmd->u.info.lstatus_to_modtype); - link_ok = (word & FW_PORT_CMD_LSTATUS_F) != 0; + stat = be32_to_cpu(port_cmd->u.info.lstatus_to_modtype); + link_ok = (stat & FW_PORT_CMD_LSTATUS_F) != 0; speed = 0; fc = 0; - if (word & FW_PORT_CMD_RXPAUSE_F) + if (stat & FW_PORT_CMD_RXPAUSE_F) fc |= PAUSE_RX; - if (word & FW_PORT_CMD_TXPAUSE_F) + if (stat & FW_PORT_CMD_TXPAUSE_F) fc |= PAUSE_TX; - if (word & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M)) + if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M)) speed = 100; - else if (word & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G)) + else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G)) speed = 1000; - else if (word & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G)) + else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G)) speed = 10000; - else if (word & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G)) + else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G)) speed = 40000; /* @@ -1540,12 +1537,21 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl) continue; lc = &pi->link_cfg; + + mod = FW_PORT_CMD_MODTYPE_G(stat); + if (mod != pi->mod_type) { + pi->mod_type = mod; + t4vf_os_portmod_changed(adapter, pidx); + } + if (link_ok != lc->link_ok || speed != lc->speed || fc != lc->fc) { /* something changed */ lc->link_ok = link_ok; lc->speed = speed; lc->fc = fc; + lc->supported = + be16_to_cpu(port_cmd->u.info.pcap); t4vf_os_link_changed(adapter, pidx, link_ok); } } diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c index b2427928eb11..d1c025fd9726 100644 --- a/drivers/net/ethernet/cirrus/cs89x0.c +++ b/drivers/net/ethernet/cirrus/cs89x0.c @@ -60,6 +60,7 @@ #include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/in.h> +#include <linux/jiffies.h> #include <linux/skbuff.h> #include <linux/spinlock.h> #include <linux/string.h> @@ -238,13 +239,13 @@ writereg(struct net_device *dev, u16 regno, u16 value) static int __init wait_eeprom_ready(struct net_device *dev) { - int timeout = jiffies; + unsigned long timeout = jiffies; /* check to see if the EEPROM is ready, * a timeout is used just in case EEPROM is ready when * SI_BUSY in the PP_SelfST is clear */ while (readreg(dev, PP_SelfST) & SI_BUSY) - if (jiffies - timeout >= 40) + if (time_after_eq(jiffies, timeout + 40)) return -1; return 0; } @@ -485,7 +486,7 @@ control_dc_dc(struct net_device *dev, int on_not_off) { struct net_local *lp = netdev_priv(dev); unsigned int selfcontrol; - int timenow = jiffies; + unsigned long timenow = jiffies; /* control the DC to DC convertor in the SelfControl register. * Note: This is hooked up to a general purpose pin, might not * always be a DC to DC convertor. @@ -499,7 +500,7 @@ control_dc_dc(struct net_device *dev, int on_not_off) writereg(dev, PP_SelfCTL, selfcontrol); /* Wait for the DC/DC converter to power up - 500ms */ - while (jiffies - timenow < HZ) + while (time_before(jiffies, timenow + HZ)) ; } @@ -514,7 +515,7 @@ send_test_pkt(struct net_device *dev) 0, 0, /* DSAP=0 & SSAP=0 fields */ 0xf3, 0 /* Control (Test Req + P bit set) */ }; - long timenow = jiffies; + unsigned long timenow = jiffies; writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_TX_ON); @@ -525,10 +526,10 @@ send_test_pkt(struct net_device *dev) iowrite16(ETH_ZLEN, lp->virt_addr + TX_LEN_PORT); /* Test to see if the chip has allocated memory for the packet */ - while (jiffies - timenow < 5) + while (time_before(jiffies, timenow + 5)) if (readreg(dev, PP_BusST) & READY_FOR_TX_NOW) break; - if (jiffies - timenow >= 5) + if (time_after_eq(jiffies, timenow + 5)) return 0; /* this shouldn't happen */ /* Write the contents of the packet */ @@ -536,7 +537,7 @@ send_test_pkt(struct net_device *dev) cs89_dbg(1, debug, "Sending test packet "); /* wait a couple of jiffies for packet to be received */ - for (timenow = jiffies; jiffies - timenow < 3;) + for (timenow = jiffies; time_before(jiffies, timenow + 3);) ; if ((readreg(dev, PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK) { cs89_dbg(1, cont, "succeeded\n"); @@ -556,7 +557,7 @@ static int detect_tp(struct net_device *dev) { struct net_local *lp = netdev_priv(dev); - int timenow = jiffies; + unsigned long timenow = jiffies; int fdx; cs89_dbg(1, debug, "%s: Attempting TP\n", dev->name); @@ -574,7 +575,7 @@ detect_tp(struct net_device *dev) /* Delay for the hardware to work out if the TP cable is present * - 150ms */ - for (timenow = jiffies; jiffies - timenow < 15;) + for (timenow = jiffies; time_before(jiffies, timenow + 15);) ; if ((readreg(dev, PP_LineST) & LINK_OK) == 0) return DETECTED_NONE; @@ -618,7 +619,7 @@ detect_tp(struct net_device *dev) if ((lp->auto_neg_cnf & AUTO_NEG_BITS) == AUTO_NEG_ENABLE) { pr_info("%s: negotiating duplex...\n", dev->name); while (readreg(dev, PP_AutoNegST) & AUTO_NEG_BUSY) { - if (jiffies - timenow > 4000) { + if (time_after(jiffies, timenow + 4000)) { pr_err("**** Full / half duplex auto-negotiation timed out ****\n"); break; } @@ -1271,7 +1272,7 @@ static void __init reset_chip(struct net_device *dev) { #if !defined(CONFIG_MACH_MX31ADS) struct net_local *lp = netdev_priv(dev); - int reset_start_time; + unsigned long reset_start_time; writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET); @@ -1294,7 +1295,7 @@ static void __init reset_chip(struct net_device *dev) /* Wait until the chip is reset */ reset_start_time = jiffies; while ((readreg(dev, PP_SelfST) & INIT_DONE) == 0 && - jiffies - reset_start_time < 2) + time_before(jiffies, reset_start_time + 2)) ; #endif /* !CONFIG_MACH_MX31ADS */ } diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 868d0f605d60..b29e027c476e 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -1060,10 +1060,14 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3); } - if ((netdev->features & NETIF_F_RXCSUM) && !csum_not_calc) { - skb->csum = htons(checksum); - skb->ip_summed = CHECKSUM_COMPLETE; - } + /* Hardware does not provide whole packet checksum. It only + * provides pseudo checksum. Since hw validates the packet + * checksum but not provide us the checksum value. use + * CHECSUM_UNNECESSARY. + */ + if ((netdev->features & NETIF_F_RXCSUM) && tcp_udp_csum_ok && + ipv4_csum_ok) + skb->ip_summed = CHECKSUM_UNNECESSARY; if (vlan_stripped) __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tci); @@ -1612,7 +1616,7 @@ static int enic_open(struct net_device *netdev) if (vnic_rq_desc_used(&enic->rq[i]) == 0) { netdev_err(netdev, "Unable to alloc receive buffers\n"); err = -ENOMEM; - goto err_out_notify_unset; + goto err_out_free_rq; } } @@ -1645,7 +1649,9 @@ static int enic_open(struct net_device *netdev) return 0; -err_out_notify_unset: +err_out_free_rq: + for (i = 0; i < enic->rq_count; i++) + vnic_rq_clean(&enic->rq[i], enic_free_rq_buf); enic_dev_notify_unset(enic); err_out_free_intr: enic_free_intr(enic); diff --git a/drivers/net/ethernet/dnet.c b/drivers/net/ethernet/dnet.c index a379c3e4b57f..13d00a38a5bd 100644 --- a/drivers/net/ethernet/dnet.c +++ b/drivers/net/ethernet/dnet.c @@ -398,13 +398,8 @@ static int dnet_poll(struct napi_struct *napi, int budget) * break out of while loop if there are no more * packets waiting */ - if (!(dnet_readl(bp, RX_FIFO_WCNT) >> 16)) { - napi_complete(napi); - int_enable = dnet_readl(bp, INTR_ENB); - int_enable |= DNET_INTR_SRC_RX_CMDFIFOAF; - dnet_writel(bp, int_enable, INTR_ENB); - return 0; - } + if (!(dnet_readl(bp, RX_FIFO_WCNT) >> 16)) + break; cmd_word = dnet_readl(bp, RX_LEN_FIFO); pkt_len = cmd_word & 0xFFFF; @@ -433,20 +428,17 @@ static int dnet_poll(struct napi_struct *napi, int budget) "size %u.\n", dev->name, pkt_len); } - budget -= npackets; - if (npackets < budget) { /* We processed all packets available. Tell NAPI it can - * stop polling then re-enable rx interrupts */ + * stop polling then re-enable rx interrupts. + */ napi_complete(napi); int_enable = dnet_readl(bp, INTR_ENB); int_enable |= DNET_INTR_SRC_RX_CMDFIFOAF; dnet_writel(bp, int_enable, INTR_ENB); - return 0; } - /* There are still packets waiting */ - return 1; + return npackets; } static irqreturn_t dnet_interrupt(int irq, void *dev_id) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 2aacd4731051..d48806b5cd88 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -3138,6 +3138,7 @@ static void be_disable_vxlan_offloads(struct be_adapter *adapter) netdev->hw_enc_features = 0; netdev->hw_features &= ~(NETIF_F_GSO_UDP_TUNNEL); + netdev->features &= ~(NETIF_F_GSO_UDP_TUNNEL); } #endif @@ -4382,8 +4383,9 @@ static int be_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, * distinguish various types of transports (VxLAN, GRE, NVGRE ..). So, offload * is expected to work across all types of IP tunnels once exported. Skyhawk * supports offloads for either VxLAN or NVGRE, exclusively. So we export VxLAN - * offloads in hw_enc_features only when a VxLAN port is added. Note this only - * ensures that other tunnels work fine while VxLAN offloads are not enabled. + * offloads in hw_enc_features only when a VxLAN port is added. If other (non + * VxLAN) tunnels are configured while VxLAN offloads are enabled, offloads for + * those other tunnels are unexported on the fly through ndo_features_check(). * * Skyhawk supports VxLAN offloads only for one UDP dport. So, if the stack * adds more than one port, disable offloads and don't re-enable them again @@ -4429,6 +4431,7 @@ static void be_add_vxlan_port(struct net_device *netdev, sa_family_t sa_family, NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_UDP_TUNNEL; netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL; + netdev->features |= NETIF_F_GSO_UDP_TUNNEL; dev_info(dev, "Enabled VxLAN offloads for UDP port %d\n", be16_to_cpu(port)); @@ -4457,9 +4460,45 @@ done: adapter->vxlan_port_count--; } -static bool be_gso_check(struct sk_buff *skb, struct net_device *dev) +static netdev_features_t be_features_check(struct sk_buff *skb, + struct net_device *dev, + netdev_features_t features) { - return vxlan_gso_check(skb); + struct be_adapter *adapter = netdev_priv(dev); + u8 l4_hdr = 0; + + /* The code below restricts offload features for some tunneled packets. + * Offload features for normal (non tunnel) packets are unchanged. + */ + if (!skb->encapsulation || + !(adapter->flags & BE_FLAGS_VXLAN_OFFLOADS)) + return features; + + /* It's an encapsulated packet and VxLAN offloads are enabled. We + * should disable tunnel offload features if it's not a VxLAN packet, + * as tunnel offloads have been enabled only for VxLAN. This is done to + * allow other tunneled traffic like GRE work fine while VxLAN + * offloads are configured in Skyhawk-R. + */ + switch (vlan_get_protocol(skb)) { + case htons(ETH_P_IP): + l4_hdr = ip_hdr(skb)->protocol; + break; + case htons(ETH_P_IPV6): + l4_hdr = ipv6_hdr(skb)->nexthdr; + break; + default: + return features; + } + + if (l4_hdr != IPPROTO_UDP || + skb->inner_protocol_type != ENCAP_TYPE_ETHER || + skb->inner_protocol != htons(ETH_P_TEB) || + skb_inner_mac_header(skb) - skb_transport_header(skb) != + sizeof(struct udphdr) + sizeof(struct vxlanhdr)) + return features & ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK); + + return features; } #endif @@ -4490,7 +4529,7 @@ static const struct net_device_ops be_netdev_ops = { #ifdef CONFIG_BE2NET_VXLAN .ndo_add_vxlan_port = be_add_vxlan_port, .ndo_del_vxlan_port = be_del_vxlan_port, - .ndo_gso_check = be_gso_check, + .ndo_features_check = be_features_check, #endif }; diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 469691ad4a1e..40132929daf7 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -424,6 +424,8 @@ struct bufdesc_ex { * (40ns * 6). */ #define FEC_QUIRK_BUG_CAPTURE (1 << 10) +/* Controller has only one MDIO bus */ +#define FEC_QUIRK_SINGLE_MDIO (1 << 11) struct fec_enet_priv_tx_q { int index; diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index ebf76c496e7a..bba87775419d 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -91,7 +91,8 @@ static struct platform_device_id fec_devtype[] = { .driver_data = 0, }, { .name = "imx28-fec", - .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME, + .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME | + FEC_QUIRK_SINGLE_MDIO, }, { .name = "imx6q-fec", .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT | @@ -1558,20 +1559,21 @@ fec_enet_interrupt(int irq, void *dev_id) { struct net_device *ndev = dev_id; struct fec_enet_private *fep = netdev_priv(ndev); - const unsigned napi_mask = FEC_ENET_RXF | FEC_ENET_TXF; uint int_events; irqreturn_t ret = IRQ_NONE; int_events = readl(fep->hwp + FEC_IEVENT); - writel(int_events & ~napi_mask, fep->hwp + FEC_IEVENT); + writel(int_events, fep->hwp + FEC_IEVENT); fec_enet_collect_events(fep, int_events); - if (int_events & napi_mask) { + if (fep->work_tx || fep->work_rx) { ret = IRQ_HANDLED; - /* Disable the NAPI interrupts */ - writel(FEC_ENET_MII, fep->hwp + FEC_IMASK); - napi_schedule(&fep->napi); + if (napi_schedule_prep(&fep->napi)) { + /* Disable the NAPI interrupts */ + writel(FEC_ENET_MII, fep->hwp + FEC_IMASK); + __napi_schedule(&fep->napi); + } } if (int_events & FEC_ENET_MII) { @@ -1591,12 +1593,6 @@ static int fec_enet_rx_napi(struct napi_struct *napi, int budget) struct fec_enet_private *fep = netdev_priv(ndev); int pkts; - /* - * Clear any pending transmit or receive interrupts before - * processing the rings to avoid racing with the hardware. - */ - writel(FEC_ENET_RXF | FEC_ENET_TXF, fep->hwp + FEC_IEVENT); - pkts = fec_enet_rx(ndev, budget); fec_enet_tx(ndev); @@ -1942,7 +1938,7 @@ static int fec_enet_mii_init(struct platform_device *pdev) int err = -ENXIO, i; /* - * The dual fec interfaces are not equivalent with enet-mac. + * The i.MX28 dual fec interfaces are not equal. * Here are the differences: * * - fec0 supports MII & RMII modes while fec1 only supports RMII @@ -1957,7 +1953,7 @@ static int fec_enet_mii_init(struct platform_device *pdev) * mdio interface in board design, and need to be configured by * fec0 mii_bus. */ - if ((fep->quirks & FEC_QUIRK_ENET_MAC) && fep->dev_id > 0) { + if ((fep->quirks & FEC_QUIRK_SINGLE_MDIO) && fep->dev_id > 0) { /* fec1 uses fec0 mii_bus */ if (mii_cnt && fec0_mii_bus) { fep->mii_bus = fec0_mii_bus; @@ -2020,7 +2016,7 @@ static int fec_enet_mii_init(struct platform_device *pdev) mii_cnt++; /* save fec0 mii_bus */ - if (fep->quirks & FEC_QUIRK_ENET_MAC) + if (fep->quirks & FEC_QUIRK_SINGLE_MDIO) fec0_mii_bus = fep->mii_bus; return 0; @@ -3134,6 +3130,7 @@ fec_probe(struct platform_device *pdev) pdev->id_entry = of_id->data; fep->quirks = pdev->id_entry->driver_data; + fep->netdev = ndev; fep->num_rx_queues = num_rx_qs; fep->num_tx_queues = num_tx_qs; diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index 5b8300a32bf5..4d61ef50b465 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig @@ -281,6 +281,17 @@ config I40E_DCB If unsure, say N. +config I40E_FCOE + bool "Fibre Channel over Ethernet (FCoE)" + default n + depends on I40E && DCB && FCOE + ---help--- + Say Y here if you want to use Fibre Channel over Ethernet (FCoE) + in the driver. This will create new netdev for exclusive FCoE + use with XL710 FCoE offloads enabled. + + If unsure, say N. + config I40EVF tristate "Intel(R) XL710 X710 Virtual Function Ethernet support" depends on PCI_MSI diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c index 781065eb5431..e9c3a87e5b11 100644 --- a/drivers/net/ethernet/intel/e100.c +++ b/drivers/net/ethernet/intel/e100.c @@ -1543,7 +1543,7 @@ static int e100_phy_init(struct nic *nic) mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr); } else if ((nic->mac >= mac_82550_D102) || ((nic->flags & ich) && (mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000) && - !(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) { + (nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) { /* enable/disable MDI/MDI-X auto-switching. */ mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG, nic->mii.force_media ? 0 : NCONFIG_AUTO_SWITCH); diff --git a/drivers/net/ethernet/intel/i40e/Makefile b/drivers/net/ethernet/intel/i40e/Makefile index 4b94ddb29c24..c40581999121 100644 --- a/drivers/net/ethernet/intel/i40e/Makefile +++ b/drivers/net/ethernet/intel/i40e/Makefile @@ -44,4 +44,4 @@ i40e-objs := i40e_main.o \ i40e_virtchnl_pf.o i40e-$(CONFIG_I40E_DCB) += i40e_dcb.o i40e_dcb_nl.o -i40e-$(CONFIG_FCOE:m=y) += i40e_fcoe.o +i40e-$(CONFIG_I40E_FCOE) += i40e_fcoe.o diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c index 433a55886ad2..cb0de455683e 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c +++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c @@ -829,7 +829,7 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n, if (desc_n >= ring->count || desc_n < 0) { dev_info(&pf->pdev->dev, "descriptor %d not found\n", desc_n); - return; + goto out; } if (!is_rx_ring) { txd = I40E_TX_DESC(ring, desc_n); @@ -855,6 +855,8 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n, } else { dev_info(&pf->pdev->dev, "dump desc rx/tx <vsi_seid> <ring_id> [<desc_n>]\n"); } + +out: kfree(ring); } diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 0a7ea4c5f9d3..a5f2660d552d 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -7549,6 +7549,11 @@ static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], if (!(pf->flags & I40E_FLAG_SRIOV_ENABLED)) return -EOPNOTSUPP; + if (vid) { + pr_info("%s: vlans aren't supported yet for dev_uc|mc_add()\n", dev->name); + return -EINVAL; + } + /* Hardware does not support aging addresses so if a * ndm_state is given only allow permanent addresses */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_osdep.h b/drivers/net/ethernet/intel/i40e/i40e_osdep.h index 045b5c4b98b3..ad802dd0f67a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_osdep.h +++ b/drivers/net/ethernet/intel/i40e/i40e_osdep.h @@ -78,7 +78,7 @@ do { \ } while (0) typedef enum i40e_status_code i40e_status; -#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) +#ifdef CONFIG_I40E_FCOE #define I40E_FCOE -#endif /* CONFIG_FCOE or CONFIG_FCOE_MODULE */ +#endif #endif /* _I40E_OSDEP_H_ */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 04b441460bbd..cecb340898fe 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -658,6 +658,8 @@ static inline u32 i40e_get_head(struct i40e_ring *tx_ring) return le32_to_cpu(*(volatile __le32 *)head); } +#define WB_STRIDE 0x3 + /** * i40e_clean_tx_irq - Reclaim resources after transmit completes * @tx_ring: tx ring to clean @@ -759,6 +761,18 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget) tx_ring->q_vector->tx.total_bytes += total_bytes; tx_ring->q_vector->tx.total_packets += total_packets; + /* check to see if there are any non-cache aligned descriptors + * waiting to be written back, and kick the hardware to force + * them to be written back in case of napi polling + */ + if (budget && + !((i & WB_STRIDE) == WB_STRIDE) && + !test_bit(__I40E_DOWN, &tx_ring->vsi->state) && + (I40E_DESC_UNUSED(tx_ring) != tx_ring->count)) + tx_ring->arm_wb = true; + else + tx_ring->arm_wb = false; + if (check_for_tx_hang(tx_ring) && i40e_check_tx_hang(tx_ring)) { /* schedule immediate reset if we believe we hung */ dev_info(tx_ring->dev, "Detected Tx Unit Hang\n" @@ -777,13 +791,16 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget) netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index); dev_info(tx_ring->dev, - "tx hang detected on queue %d, resetting adapter\n", + "tx hang detected on queue %d, reset requested\n", tx_ring->queue_index); - tx_ring->netdev->netdev_ops->ndo_tx_timeout(tx_ring->netdev); + /* do not fire the reset immediately, wait for the stack to + * decide we are truly stuck, also prevents every queue from + * simultaneously requesting a reset + */ - /* the adapter is about to reset, no point in enabling stuff */ - return true; + /* the adapter is about to reset, no point in enabling polling */ + budget = 1; } netdev_tx_completed_queue(netdev_get_tx_queue(tx_ring->netdev, @@ -806,7 +823,25 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget) } } - return budget > 0; + return !!budget; +} + +/** + * i40e_force_wb - Arm hardware to do a wb on noncache aligned descriptors + * @vsi: the VSI we care about + * @q_vector: the vector on which to force writeback + * + **/ +static void i40e_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector) +{ + u32 val = I40E_PFINT_DYN_CTLN_INTENA_MASK | + I40E_PFINT_DYN_CTLN_SWINT_TRIG_MASK | + I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK + /* allow 00 to be written to the index */; + + wr32(&vsi->back->hw, + I40E_PFINT_DYN_CTLN(q_vector->v_idx + vsi->base_vector - 1), + val); } /** @@ -1290,9 +1325,7 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi, * so the total length of IPv4 header is IHL*4 bytes * The UDP_0 bit *may* bet set if the *inner* header is UDP */ - if (ipv4_tunnel && - (decoded.inner_prot != I40E_RX_PTYPE_INNER_PROT_UDP) && - !(rx_status & (1 << I40E_RX_DESC_STATUS_UDP_0_SHIFT))) { + if (ipv4_tunnel) { skb->transport_header = skb->mac_header + sizeof(struct ethhdr) + (ip_hdr(skb)->ihl * 4); @@ -1302,15 +1335,19 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi, skb->protocol == htons(ETH_P_8021AD)) ? VLAN_HLEN : 0; - rx_udp_csum = udp_csum(skb); - iph = ip_hdr(skb); - csum = csum_tcpudp_magic( - iph->saddr, iph->daddr, - (skb->len - skb_transport_offset(skb)), - IPPROTO_UDP, rx_udp_csum); + if ((ip_hdr(skb)->protocol == IPPROTO_UDP) && + (udp_hdr(skb)->check != 0)) { + rx_udp_csum = udp_csum(skb); + iph = ip_hdr(skb); + csum = csum_tcpudp_magic( + iph->saddr, iph->daddr, + (skb->len - skb_transport_offset(skb)), + IPPROTO_UDP, rx_udp_csum); - if (udp_hdr(skb)->check != csum) - goto checksum_fail; + if (udp_hdr(skb)->check != csum) + goto checksum_fail; + + } /* else its GRE and so no outer UDP header */ } skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -1581,6 +1618,7 @@ int i40e_napi_poll(struct napi_struct *napi, int budget) struct i40e_vsi *vsi = q_vector->vsi; struct i40e_ring *ring; bool clean_complete = true; + bool arm_wb = false; int budget_per_ring; if (test_bit(__I40E_DOWN, &vsi->state)) { @@ -1591,8 +1629,10 @@ int i40e_napi_poll(struct napi_struct *napi, int budget) /* Since the actual Tx work is minimal, we can give the Tx a larger * budget and be more aggressive about cleaning up the Tx descriptors. */ - i40e_for_each_ring(ring, q_vector->tx) + i40e_for_each_ring(ring, q_vector->tx) { clean_complete &= i40e_clean_tx_irq(ring, vsi->work_limit); + arm_wb |= ring->arm_wb; + } /* We attempt to distribute budget to each Rx queue fairly, but don't * allow the budget to go below 1 because that would exit polling early. @@ -1603,8 +1643,11 @@ int i40e_napi_poll(struct napi_struct *napi, int budget) clean_complete &= i40e_clean_rx_irq(ring, budget_per_ring); /* If work not completed, return budget and polling will return */ - if (!clean_complete) + if (!clean_complete) { + if (arm_wb) + i40e_force_wb(vsi, q_vector); return budget; + } /* Work is done so exit the polling mode and re-enable the interrupt */ napi_complete(napi); @@ -1840,17 +1883,16 @@ static int i40e_tso(struct i40e_ring *tx_ring, struct sk_buff *skb, if (err < 0) return err; - if (protocol == htons(ETH_P_IP)) { - iph = skb->encapsulation ? inner_ip_hdr(skb) : ip_hdr(skb); + iph = skb->encapsulation ? inner_ip_hdr(skb) : ip_hdr(skb); + ipv6h = skb->encapsulation ? inner_ipv6_hdr(skb) : ipv6_hdr(skb); + + if (iph->version == 4) { tcph = skb->encapsulation ? inner_tcp_hdr(skb) : tcp_hdr(skb); iph->tot_len = 0; iph->check = 0; tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, 0, IPPROTO_TCP, 0); - } else if (skb_is_gso_v6(skb)) { - - ipv6h = skb->encapsulation ? inner_ipv6_hdr(skb) - : ipv6_hdr(skb); + } else if (ipv6h->version == 6) { tcph = skb->encapsulation ? inner_tcp_hdr(skb) : tcp_hdr(skb); ipv6h->payload_len = 0; tcph->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, @@ -1946,13 +1988,9 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 tx_flags, I40E_TX_CTX_EXT_IP_IPV4_NO_CSUM; } } else if (tx_flags & I40E_TX_FLAGS_IPV6) { - if (tx_flags & I40E_TX_FLAGS_TSO) { - *cd_tunneling |= I40E_TX_CTX_EXT_IP_IPV6; + *cd_tunneling |= I40E_TX_CTX_EXT_IP_IPV6; + if (tx_flags & I40E_TX_FLAGS_TSO) ip_hdr(skb)->check = 0; - } else { - *cd_tunneling |= - I40E_TX_CTX_EXT_IP_IPV4_NO_CSUM; - } } /* Now set the ctx descriptor fields */ @@ -1962,7 +2000,10 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 tx_flags, ((skb_inner_network_offset(skb) - skb_transport_offset(skb)) >> 1) << I40E_TXD_CTX_QW0_NATLEN_SHIFT; - + if (this_ip_hdr->version == 6) { + tx_flags &= ~I40E_TX_FLAGS_IPV4; + tx_flags |= I40E_TX_FLAGS_IPV6; + } } else { network_hdr_len = skb_network_header_len(skb); this_ip_hdr = ip_hdr(skb); @@ -2198,7 +2239,6 @@ static void i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb, /* Place RS bit on last descriptor of any packet that spans across the * 4th descriptor (WB_STRIDE aka 0x3) in a 64B cacheline. */ -#define WB_STRIDE 0x3 if (((i & WB_STRIDE) != WB_STRIDE) && (first <= &tx_ring->tx_bi[i]) && (first >= &tx_ring->tx_bi[i & ~WB_STRIDE])) { diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h index e60d3accb2e2..18b00231d2f1 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h @@ -241,6 +241,7 @@ struct i40e_ring { unsigned long last_rx_timestamp; bool ring_active; /* is ring online or not */ + bool arm_wb; /* do something to arm write back */ /* stats structs */ struct i40e_queue_stats stats; diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c index 051ea94bdcd3..0f69ef81751a 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/drivers/net/ethernet/intel/igb/e1000_82575.c @@ -1125,7 +1125,7 @@ static s32 igb_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask) u32 swmask = mask; u32 fwmask = mask << 16; s32 ret_val = 0; - s32 i = 0, timeout = 200; /* FIXME: find real value to use here */ + s32 i = 0, timeout = 200; while (i < timeout) { if (igb_get_hw_semaphore(hw)) { diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 6ff214de1111..ac6a8f1eea6c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -475,7 +475,8 @@ static int mlx4_en_tunnel_steer_add(struct mlx4_en_priv *priv, unsigned char *ad { int err; - if (priv->mdev->dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) + if (priv->mdev->dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN || + priv->mdev->dev->caps.dmfs_high_steer_mode == MLX4_STEERING_DMFS_A0_STATIC) return 0; /* do nothing */ err = mlx4_tunnel_steer_add(priv->mdev->dev, addr, priv->port, qpn, @@ -1569,8 +1570,15 @@ int mlx4_en_start_port(struct net_device *dev) mlx4_en_free_affinity_hint(priv, i); goto cq_err; } - for (j = 0; j < cq->size; j++) - cq->buf[j].owner_sr_opcode = MLX4_CQE_OWNER_MASK; + + for (j = 0; j < cq->size; j++) { + struct mlx4_cqe *cqe = NULL; + + cqe = mlx4_en_get_cqe(cq->buf, j, priv->cqe_size) + + priv->cqe_factor; + cqe->owner_sr_opcode = MLX4_CQE_OWNER_MASK; + } + err = mlx4_en_set_cq_moder(priv, cq); if (err) { en_err(priv, "Failed setting cq moderation parameters\n"); @@ -2358,9 +2366,11 @@ static void mlx4_en_del_vxlan_port(struct net_device *dev, queue_work(priv->mdev->workqueue, &priv->vxlan_del_task); } -static bool mlx4_en_gso_check(struct sk_buff *skb, struct net_device *dev) +static netdev_features_t mlx4_en_features_check(struct sk_buff *skb, + struct net_device *dev, + netdev_features_t features) { - return vxlan_gso_check(skb); + return vxlan_features_check(skb, features); } #endif @@ -2393,7 +2403,7 @@ static const struct net_device_ops mlx4_netdev_ops = { #ifdef CONFIG_MLX4_EN_VXLAN .ndo_add_vxlan_port = mlx4_en_add_vxlan_port, .ndo_del_vxlan_port = mlx4_en_del_vxlan_port, - .ndo_gso_check = mlx4_en_gso_check, + .ndo_features_check = mlx4_en_features_check, #endif }; @@ -2427,7 +2437,7 @@ static const struct net_device_ops mlx4_netdev_ops_master = { #ifdef CONFIG_MLX4_EN_VXLAN .ndo_add_vxlan_port = mlx4_en_add_vxlan_port, .ndo_del_vxlan_port = mlx4_en_del_vxlan_port, - .ndo_gso_check = mlx4_en_gso_check, + .ndo_features_check = mlx4_en_features_check, #endif }; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index a308d41e4de0..e3357bf523df 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c @@ -962,7 +962,17 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) tx_desc->ctrl.owner_opcode = op_own; if (send_doorbell) { wmb(); - iowrite32(ring->doorbell_qpn, + /* Since there is no iowrite*_native() that writes the + * value as is, without byteswapping - using the one + * the doesn't do byteswapping in the relevant arch + * endianness. + */ +#if defined(__LITTLE_ENDIAN) + iowrite32( +#else + iowrite32be( +#endif + ring->doorbell_qpn, ring->bf.uar->map + MLX4_SEND_DOORBELL); } else { ring->xmit_more++; diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index ef3b95bac2ad..982861d1df44 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -787,11 +787,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) if ((1 << (field & 0x3f)) > (PAGE_SIZE / dev_cap->bf_reg_size)) field = 3; dev_cap->bf_regs_per_page = 1 << (field & 0x3f); - mlx4_dbg(dev, "BlueFlame available (reg size %d, regs/page %d)\n", - dev_cap->bf_reg_size, dev_cap->bf_regs_per_page); } else { dev_cap->bf_reg_size = 0; - mlx4_dbg(dev, "BlueFlame not available\n"); } MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_SG_SQ_OFFSET); @@ -902,9 +899,6 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) goto out; } - mlx4_dbg(dev, "Base MM extensions: flags %08x, rsvd L_Key %08x\n", - dev_cap->bmme_flags, dev_cap->reserved_lkey); - /* * Each UAR has 4 EQ doorbells; so if a UAR is reserved, then * we can't use any EQs whose doorbell falls on that page, @@ -916,6 +910,21 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) else dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_SYS_EQS; +out: + mlx4_free_cmd_mailbox(dev, mailbox); + return err; +} + +void mlx4_dev_cap_dump(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) +{ + if (dev_cap->bf_reg_size > 0) + mlx4_dbg(dev, "BlueFlame available (reg size %d, regs/page %d)\n", + dev_cap->bf_reg_size, dev_cap->bf_regs_per_page); + else + mlx4_dbg(dev, "BlueFlame not available\n"); + + mlx4_dbg(dev, "Base MM extensions: flags %08x, rsvd L_Key %08x\n", + dev_cap->bmme_flags, dev_cap->reserved_lkey); mlx4_dbg(dev, "Max ICM size %lld MB\n", (unsigned long long) dev_cap->max_icm_sz >> 20); mlx4_dbg(dev, "Max QPs: %d, reserved QPs: %d, entry size: %d\n", @@ -949,13 +958,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev_cap->dmfs_high_rate_qpn_base); mlx4_dbg(dev, "DMFS high rate steer QPn range: %d\n", dev_cap->dmfs_high_rate_qpn_range); - dump_dev_cap_flags(dev, dev_cap->flags); dump_dev_cap_flags2(dev, dev_cap->flags2); - -out: - mlx4_free_cmd_mailbox(dev, mailbox); - return err; } int mlx4_QUERY_PORT(struct mlx4_dev *dev, int port, struct mlx4_port_cap *port_cap) @@ -1848,8 +1852,8 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev, /* CX3 is capable of extending CQEs\EQEs to strides larger than 64B */ MLX4_GET(byte_field, outbox, INIT_HCA_EQE_CQE_STRIDE_OFFSET); if (byte_field) { - param->dev_cap_enabled |= MLX4_DEV_CAP_64B_EQE_ENABLED; - param->dev_cap_enabled |= MLX4_DEV_CAP_64B_CQE_ENABLED; + param->dev_cap_enabled |= MLX4_DEV_CAP_EQE_STRIDE_ENABLED; + param->dev_cap_enabled |= MLX4_DEV_CAP_CQE_STRIDE_ENABLED; param->cqe_size = 1 << ((byte_field & MLX4_CQE_SIZE_MASK_STRIDE) + 5); param->eqe_size = 1 << (((byte_field & diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h index 794e2826609a..62562b60fa87 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.h +++ b/drivers/net/ethernet/mellanox/mlx4/fw.h @@ -224,6 +224,7 @@ struct mlx4_set_ib_param { u32 cap_mask; }; +void mlx4_dev_cap_dump(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap); int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap); int mlx4_QUERY_PORT(struct mlx4_dev *dev, int port, struct mlx4_port_cap *port_cap); int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u8 gen_or_port, diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index e25436b24ce7..6e08352ec994 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -171,9 +171,9 @@ int mlx4_check_port_params(struct mlx4_dev *dev, { int i; - for (i = 0; i < dev->caps.num_ports - 1; i++) { - if (port_type[i] != port_type[i + 1]) { - if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_DPDP)) { + if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_DPDP)) { + for (i = 0; i < dev->caps.num_ports - 1; i++) { + if (port_type[i] != port_type[i + 1]) { mlx4_err(dev, "Only same port types supported on this HCA, aborting\n"); return -EINVAL; } @@ -305,6 +305,7 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting\n"); return err; } + mlx4_dev_cap_dump(dev, dev_cap); if (dev_cap->min_page_sz > PAGE_SIZE) { mlx4_err(dev, "HCA minimum page size of %d bigger than kernel PAGE_SIZE of %ld, aborting\n", @@ -1743,8 +1744,7 @@ static void choose_tunnel_offload_mode(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) { if (dev->caps.steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED && - dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS && - dev->caps.dmfs_high_steer_mode != MLX4_STEERING_DMFS_A0_STATIC) + dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS) dev->caps.tunnel_offload_mode = MLX4_TUNNEL_OFFLOAD_MODE_VXLAN; else dev->caps.tunnel_offload_mode = MLX4_TUNNEL_OFFLOAD_MODE_NONE; @@ -1828,7 +1828,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) err = mlx4_dev_cap(dev, &dev_cap); if (err) { mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting\n"); - goto err_stop_fw; + return err; } choose_steering_mode(dev, &dev_cap); @@ -1859,7 +1859,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) &init_hca); if ((long long) icm_size < 0) { err = icm_size; - goto err_stop_fw; + return err; } dev->caps.max_fmr_maps = (1 << (32 - ilog2(dev->caps.num_mpts))) - 1; @@ -1873,7 +1873,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) err = mlx4_init_icm(dev, &dev_cap, &init_hca, icm_size); if (err) - goto err_stop_fw; + return err; err = mlx4_INIT_HCA(dev, &init_hca); if (err) { @@ -1885,7 +1885,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) err = mlx4_query_func(dev, &dev_cap); if (err < 0) { mlx4_err(dev, "QUERY_FUNC command failed, aborting.\n"); - goto err_stop_fw; + goto err_close; } else if (err & MLX4_QUERY_FUNC_NUM_SYS_EQS) { dev->caps.num_eqs = dev_cap.max_eqs; dev->caps.reserved_eqs = dev_cap.reserved_eqs; @@ -2005,11 +2005,6 @@ err_free_icm: if (!mlx4_is_slave(dev)) mlx4_free_icms(dev); -err_stop_fw: - if (!mlx4_is_slave(dev)) { - mlx4_UNMAP_FA(dev); - mlx4_free_icm(dev, priv->fw.fw_icm, 0); - } return err; } @@ -2488,41 +2483,42 @@ static u64 mlx4_enable_sriov(struct mlx4_dev *dev, struct pci_dev *pdev, u8 total_vfs, int existing_vfs) { u64 dev_flags = dev->flags; + int err = 0; + + atomic_inc(&pf_loading); + if (dev->flags & MLX4_FLAG_SRIOV) { + if (existing_vfs != total_vfs) { + mlx4_err(dev, "SR-IOV was already enabled, but with num_vfs (%d) different than requested (%d)\n", + existing_vfs, total_vfs); + total_vfs = existing_vfs; + } + } - dev->dev_vfs = kzalloc( - total_vfs * sizeof(*dev->dev_vfs), - GFP_KERNEL); + dev->dev_vfs = kzalloc(total_vfs * sizeof(*dev->dev_vfs), GFP_KERNEL); if (NULL == dev->dev_vfs) { mlx4_err(dev, "Failed to allocate memory for VFs\n"); goto disable_sriov; - } else if (!(dev->flags & MLX4_FLAG_SRIOV)) { - int err = 0; - - atomic_inc(&pf_loading); - if (existing_vfs) { - if (existing_vfs != total_vfs) - mlx4_err(dev, "SR-IOV was already enabled, but with num_vfs (%d) different than requested (%d)\n", - existing_vfs, total_vfs); - } else { - mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n", total_vfs); - err = pci_enable_sriov(pdev, total_vfs); - } - if (err) { - mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d)\n", - err); - atomic_dec(&pf_loading); - goto disable_sriov; - } else { - mlx4_warn(dev, "Running in master mode\n"); - dev_flags |= MLX4_FLAG_SRIOV | - MLX4_FLAG_MASTER; - dev_flags &= ~MLX4_FLAG_SLAVE; - dev->num_vfs = total_vfs; - } + } + + if (!(dev->flags & MLX4_FLAG_SRIOV)) { + mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n", total_vfs); + err = pci_enable_sriov(pdev, total_vfs); + } + if (err) { + mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d)\n", + err); + goto disable_sriov; + } else { + mlx4_warn(dev, "Running in master mode\n"); + dev_flags |= MLX4_FLAG_SRIOV | + MLX4_FLAG_MASTER; + dev_flags &= ~MLX4_FLAG_SLAVE; + dev->num_vfs = total_vfs; } return dev_flags; disable_sriov: + atomic_dec(&pf_loading); dev->num_vfs = 0; kfree(dev->dev_vfs); return dev_flags & ~MLX4_FLAG_MASTER; @@ -2606,8 +2602,10 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, } if (total_vfs) { - existing_vfs = pci_num_vf(pdev); dev->flags = MLX4_FLAG_MASTER; + existing_vfs = pci_num_vf(pdev); + if (existing_vfs) + dev->flags |= MLX4_FLAG_SRIOV; dev->num_vfs = total_vfs; } } @@ -2643,6 +2641,7 @@ slave_start: } if (mlx4_is_master(dev)) { + /* when we hit the goto slave_start below, dev_cap already initialized */ if (!dev_cap) { dev_cap = kzalloc(sizeof(*dev_cap), GFP_KERNEL); @@ -2849,6 +2848,7 @@ slave_start: if (mlx4_is_master(dev) && dev->num_vfs) atomic_dec(&pf_loading); + kfree(dev_cap); return 0; err_port: diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c index d6f549685c0f..7094a9c70fd5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/drivers/net/ethernet/mellanox/mlx4/mr.c @@ -584,6 +584,7 @@ EXPORT_SYMBOL_GPL(mlx4_mr_free); void mlx4_mr_rereg_mem_cleanup(struct mlx4_dev *dev, struct mlx4_mr *mr) { mlx4_mtt_cleanup(dev, &mr->mtt); + mr->mtt.order = -1; } EXPORT_SYMBOL_GPL(mlx4_mr_rereg_mem_cleanup); @@ -593,14 +594,14 @@ int mlx4_mr_rereg_mem_write(struct mlx4_dev *dev, struct mlx4_mr *mr, { int err; - mpt_entry->start = cpu_to_be64(iova); - mpt_entry->length = cpu_to_be64(size); - mpt_entry->entity_size = cpu_to_be32(page_shift); - err = mlx4_mtt_init(dev, npages, page_shift, &mr->mtt); if (err) return err; + mpt_entry->start = cpu_to_be64(mr->iova); + mpt_entry->length = cpu_to_be64(mr->size); + mpt_entry->entity_size = cpu_to_be32(mr->mtt.page_shift); + mpt_entry->pd_flags &= cpu_to_be32(MLX4_MPT_PD_MASK | MLX4_MPT_PD_FLAG_EN_INV); mpt_entry->flags &= cpu_to_be32(MLX4_MPT_FLAG_FREE | diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c index ab684463780b..da82991239a8 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c @@ -157,6 +157,8 @@ static const char *eqe_type_str(u8 type) return "MLX5_EVENT_TYPE_CMD"; case MLX5_EVENT_TYPE_PAGE_REQUEST: return "MLX5_EVENT_TYPE_PAGE_REQUEST"; + case MLX5_EVENT_TYPE_PAGE_FAULT: + return "MLX5_EVENT_TYPE_PAGE_FAULT"; default: return "Unrecognized event"; } @@ -279,6 +281,11 @@ static int mlx5_eq_int(struct mlx5_core_dev *dev, struct mlx5_eq *eq) } break; +#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING + case MLX5_EVENT_TYPE_PAGE_FAULT: + mlx5_eq_pagefault(dev, eqe); + break; +#endif default: mlx5_core_warn(dev, "Unhandled event 0x%x on EQ 0x%x\n", @@ -446,8 +453,12 @@ void mlx5_eq_cleanup(struct mlx5_core_dev *dev) int mlx5_start_eqs(struct mlx5_core_dev *dev) { struct mlx5_eq_table *table = &dev->priv.eq_table; + u32 async_event_mask = MLX5_ASYNC_EVENT_MASK; int err; + if (dev->caps.gen.flags & MLX5_DEV_CAP_FLAG_ON_DMND_PG) + async_event_mask |= (1ull << MLX5_EVENT_TYPE_PAGE_FAULT); + err = mlx5_create_map_eq(dev, &table->cmd_eq, MLX5_EQ_VEC_CMD, MLX5_NUM_CMD_EQE, 1ull << MLX5_EVENT_TYPE_CMD, "mlx5_cmd_eq", &dev->priv.uuari.uars[0]); @@ -459,7 +470,7 @@ int mlx5_start_eqs(struct mlx5_core_dev *dev) mlx5_cmd_use_events(dev); err = mlx5_create_map_eq(dev, &table->async_eq, MLX5_EQ_VEC_ASYNC, - MLX5_NUM_ASYNC_EQE, MLX5_ASYNC_EVENT_MASK, + MLX5_NUM_ASYNC_EQE, async_event_mask, "mlx5_async_eq", &dev->priv.uuari.uars[0]); if (err) { mlx5_core_warn(dev, "failed to create async EQ %d\n", err); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw.c b/drivers/net/ethernet/mellanox/mlx5/core/fw.c index 087c4c797deb..06f9036acd83 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fw.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fw.c @@ -69,6 +69,46 @@ int mlx5_cmd_query_hca_cap(struct mlx5_core_dev *dev, struct mlx5_caps *caps) return mlx5_core_get_caps(dev, caps, HCA_CAP_OPMOD_GET_CUR); } +int mlx5_query_odp_caps(struct mlx5_core_dev *dev, struct mlx5_odp_caps *caps) +{ + u8 in[MLX5_ST_SZ_BYTES(query_hca_cap_in)]; + int out_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out); + void *out; + int err; + + if (!(dev->caps.gen.flags & MLX5_DEV_CAP_FLAG_ON_DMND_PG)) + return -ENOTSUPP; + + memset(in, 0, sizeof(in)); + out = kzalloc(out_sz, GFP_KERNEL); + if (!out) + return -ENOMEM; + MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP); + MLX5_SET(query_hca_cap_in, in, op_mod, HCA_CAP_OPMOD_GET_ODP_CUR); + err = mlx5_cmd_exec(dev, in, sizeof(in), out, out_sz); + if (err) + goto out; + + err = mlx5_cmd_status_to_err_v2(out); + if (err) { + mlx5_core_warn(dev, "query cur hca ODP caps failed, %d\n", err); + goto out; + } + + memcpy(caps, MLX5_ADDR_OF(query_hca_cap_out, out, capability_struct), + sizeof(*caps)); + + mlx5_core_dbg(dev, "on-demand paging capabilities:\nrc: %08x\nuc: %08x\nud: %08x\n", + be32_to_cpu(caps->per_transport_caps.rc_odp_caps), + be32_to_cpu(caps->per_transport_caps.uc_odp_caps), + be32_to_cpu(caps->per_transport_caps.ud_odp_caps)); + +out: + kfree(out); + return err; +} +EXPORT_SYMBOL(mlx5_query_odp_caps); + int mlx5_cmd_init_hca(struct mlx5_core_dev *dev) { struct mlx5_cmd_init_hca_mbox_in in; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/qp.c b/drivers/net/ethernet/mellanox/mlx5/core/qp.c index 5261a2b0da43..575d853dbe05 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/qp.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/qp.c @@ -88,6 +88,95 @@ void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type) mlx5_core_put_rsc(common); } +#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING +void mlx5_eq_pagefault(struct mlx5_core_dev *dev, struct mlx5_eqe *eqe) +{ + struct mlx5_eqe_page_fault *pf_eqe = &eqe->data.page_fault; + int qpn = be32_to_cpu(pf_eqe->flags_qpn) & MLX5_QPN_MASK; + struct mlx5_core_rsc_common *common = mlx5_get_rsc(dev, qpn); + struct mlx5_core_qp *qp = + container_of(common, struct mlx5_core_qp, common); + struct mlx5_pagefault pfault; + + if (!qp) { + mlx5_core_warn(dev, "ODP event for non-existent QP %06x\n", + qpn); + return; + } + + pfault.event_subtype = eqe->sub_type; + pfault.flags = (be32_to_cpu(pf_eqe->flags_qpn) >> MLX5_QPN_BITS) & + (MLX5_PFAULT_REQUESTOR | MLX5_PFAULT_WRITE | MLX5_PFAULT_RDMA); + pfault.bytes_committed = be32_to_cpu( + pf_eqe->bytes_committed); + + mlx5_core_dbg(dev, + "PAGE_FAULT: subtype: 0x%02x, flags: 0x%02x,\n", + eqe->sub_type, pfault.flags); + + switch (eqe->sub_type) { + case MLX5_PFAULT_SUBTYPE_RDMA: + /* RDMA based event */ + pfault.rdma.r_key = + be32_to_cpu(pf_eqe->rdma.r_key); + pfault.rdma.packet_size = + be16_to_cpu(pf_eqe->rdma.packet_length); + pfault.rdma.rdma_op_len = + be32_to_cpu(pf_eqe->rdma.rdma_op_len); + pfault.rdma.rdma_va = + be64_to_cpu(pf_eqe->rdma.rdma_va); + mlx5_core_dbg(dev, + "PAGE_FAULT: qpn: 0x%06x, r_key: 0x%08x,\n", + qpn, pfault.rdma.r_key); + mlx5_core_dbg(dev, + "PAGE_FAULT: rdma_op_len: 0x%08x,\n", + pfault.rdma.rdma_op_len); + mlx5_core_dbg(dev, + "PAGE_FAULT: rdma_va: 0x%016llx,\n", + pfault.rdma.rdma_va); + mlx5_core_dbg(dev, + "PAGE_FAULT: bytes_committed: 0x%06x\n", + pfault.bytes_committed); + break; + + case MLX5_PFAULT_SUBTYPE_WQE: + /* WQE based event */ + pfault.wqe.wqe_index = + be16_to_cpu(pf_eqe->wqe.wqe_index); + pfault.wqe.packet_size = + be16_to_cpu(pf_eqe->wqe.packet_length); + mlx5_core_dbg(dev, + "PAGE_FAULT: qpn: 0x%06x, wqe_index: 0x%04x,\n", + qpn, pfault.wqe.wqe_index); + mlx5_core_dbg(dev, + "PAGE_FAULT: bytes_committed: 0x%06x\n", + pfault.bytes_committed); + break; + + default: + mlx5_core_warn(dev, + "Unsupported page fault event sub-type: 0x%02hhx, QP %06x\n", + eqe->sub_type, qpn); + /* Unsupported page faults should still be resolved by the + * page fault handler + */ + } + + if (qp->pfault_handler) { + qp->pfault_handler(qp, &pfault); + } else { + mlx5_core_err(dev, + "ODP event for QP %08x, without a fault handler in QP\n", + qpn); + /* Page fault will remain unresolved. QP will hang until it is + * destroyed + */ + } + + mlx5_core_put_rsc(common); +} +#endif + int mlx5_core_create_qp(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp, struct mlx5_create_qp_mbox_in *in, @@ -322,3 +411,33 @@ int mlx5_core_xrcd_dealloc(struct mlx5_core_dev *dev, u32 xrcdn) return err; } EXPORT_SYMBOL_GPL(mlx5_core_xrcd_dealloc); + +#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING +int mlx5_core_page_fault_resume(struct mlx5_core_dev *dev, u32 qpn, + u8 flags, int error) +{ + struct mlx5_page_fault_resume_mbox_in in; + struct mlx5_page_fault_resume_mbox_out out; + int err; + + memset(&in, 0, sizeof(in)); + memset(&out, 0, sizeof(out)); + in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_PAGE_FAULT_RESUME); + in.hdr.opmod = 0; + flags &= (MLX5_PAGE_FAULT_RESUME_REQUESTOR | + MLX5_PAGE_FAULT_RESUME_WRITE | + MLX5_PAGE_FAULT_RESUME_RDMA); + flags |= (error ? MLX5_PAGE_FAULT_RESUME_ERROR : 0); + in.flags_qpn = cpu_to_be32((qpn & MLX5_QPN_MASK) | + (flags << MLX5_QPN_BITS)); + err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); + if (err) + return err; + + if (out.hdr.status) + err = mlx5_cmd_status_to_err(&out.hdr); + + return err; +} +EXPORT_SYMBOL_GPL(mlx5_core_page_fault_resume); +#endif diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index f1ebed6c63b1..2fa6ae026e4f 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -2303,12 +2303,6 @@ static inline int port_chk_force_flow_ctrl(struct ksz_hw *hw, int p) /* Spanning Tree */ -static inline void port_cfg_dis_learn(struct ksz_hw *hw, int p, int set) -{ - port_cfg(hw, p, - KS8842_PORT_CTRL_2_OFFSET, PORT_LEARN_DISABLE, set); -} - static inline void port_cfg_rx(struct ksz_hw *hw, int p, int set) { port_cfg(hw, p, diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c index af099057f0e9..71af98bb72cb 100644 --- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c @@ -4033,8 +4033,10 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) (void)pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); mgp->cmd = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->cmd), &mgp->cmd_bus, GFP_KERNEL); - if (mgp->cmd == NULL) + if (!mgp->cmd) { + status = -ENOMEM; goto abort_with_enabled; + } mgp->board_span = pci_resource_len(pdev, 0); mgp->iomem_base = pci_resource_start(pdev, 0); diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c index f5e4b820128b..db0c7a9aee60 100644 --- a/drivers/net/ethernet/neterion/s2io.c +++ b/drivers/net/ethernet/neterion/s2io.c @@ -6987,7 +6987,9 @@ static int s2io_add_isr(struct s2io_nic *sp) if (sp->s2io_entries[i].in_use == MSIX_FLG) { if (sp->s2io_entries[i].type == MSIX_RING_TYPE) { - sprintf(sp->desc[i], "%s:MSI-X-%d-RX", + snprintf(sp->desc[i], + sizeof(sp->desc[i]), + "%s:MSI-X-%d-RX", dev->name, i); err = request_irq(sp->entries[i].vector, s2io_msix_ring_handle, @@ -6996,7 +6998,9 @@ static int s2io_add_isr(struct s2io_nic *sp) sp->s2io_entries[i].arg); } else if (sp->s2io_entries[i].type == MSIX_ALARM_TYPE) { - sprintf(sp->desc[i], "%s:MSI-X-%d-TX", + snprintf(sp->desc[i], + sizeof(sp->desc[i]), + "%s:MSI-X-%d-TX", dev->name, i); err = request_irq(sp->entries[i].vector, s2io_msix_fifo_handle, @@ -8154,7 +8158,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) "%s: UDP Fragmentation Offload(UFO) enabled\n", dev->name); /* Initialize device name */ - sprintf(sp->name, "%s Neterion %s", dev->name, sp->product_name); + snprintf(sp->name, sizeof(sp->name), "%s Neterion %s", dev->name, + sp->product_name); if (vlan_tag_strip) sp->vlan_strip_flag = 1; diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c index c2f09af5c25b..4847713211ca 100644 --- a/drivers/net/ethernet/qlogic/qla3xxx.c +++ b/drivers/net/ethernet/qlogic/qla3xxx.c @@ -146,10 +146,7 @@ static int ql_wait_for_drvr_lock(struct ql3_adapter *qdev) { int i = 0; - while (i < 10) { - if (i) - ssleep(1); - + do { if (ql_sem_lock(qdev, QL_DRVR_SEM_MASK, (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) @@ -158,7 +155,8 @@ static int ql_wait_for_drvr_lock(struct ql3_adapter *qdev) "driver lock acquired\n"); return 1; } - } + ssleep(1); + } while (++i < 10); netdev_err(qdev->ndev, "Timed out waiting for driver lock...\n"); return 0; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 1aa25b13ace1..2528c3fb6b90 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -505,9 +505,11 @@ static void qlcnic_del_vxlan_port(struct net_device *netdev, adapter->flags |= QLCNIC_DEL_VXLAN_PORT; } -static bool qlcnic_gso_check(struct sk_buff *skb, struct net_device *dev) +static netdev_features_t qlcnic_features_check(struct sk_buff *skb, + struct net_device *dev, + netdev_features_t features) { - return vxlan_gso_check(skb); + return vxlan_features_check(skb, features); } #endif @@ -532,7 +534,7 @@ static const struct net_device_ops qlcnic_netdev_ops = { #ifdef CONFIG_QLCNIC_VXLAN .ndo_add_vxlan_port = qlcnic_add_vxlan_port, .ndo_del_vxlan_port = qlcnic_del_vxlan_port, - .ndo_gso_check = qlcnic_gso_check, + .ndo_features_check = qlcnic_features_check, #endif #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = qlcnic_poll_controller, @@ -2603,6 +2605,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } else { dev_err(&pdev->dev, "%s: failed. Please Reboot\n", __func__); + err = -ENODEV; goto err_out_free_hw; } diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c index 6d0b9dfac313..78bb4ceb1cdd 100644 --- a/drivers/net/ethernet/realtek/8139too.c +++ b/drivers/net/ethernet/realtek/8139too.c @@ -787,10 +787,10 @@ static struct net_device *rtl8139_init_board(struct pci_dev *pdev) if (rc) goto err_out; + disable_dev_on_err = 1; rc = pci_request_regions (pdev, DRV_NAME); if (rc) goto err_out; - disable_dev_on_err = 1; pci_set_master (pdev); @@ -1110,6 +1110,7 @@ static int rtl8139_init_one(struct pci_dev *pdev, return 0; err_out: + netif_napi_del(&tp->napi); __rtl8139_cleanup_dev (dev); pci_disable_device (pdev); return i; @@ -1124,6 +1125,7 @@ static void rtl8139_remove_one(struct pci_dev *pdev) assert (dev != NULL); cancel_delayed_work_sync(&tp->thread); + netif_napi_del(&tp->napi); unregister_netdev (dev); diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index c29ba80ae02b..6576243222af 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -473,6 +473,7 @@ static struct sh_eth_cpu_data r8a777x_data = { .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI, + .fdr_value = 0x00000f0f, .apr = 1, .mpr = 1, @@ -495,6 +496,9 @@ static struct sh_eth_cpu_data r8a779x_data = { .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI, + .fdr_value = 0x00000f0f, + + .trscer_err_mask = DESC_I_RINT8, .apr = 1, .mpr = 1, @@ -856,6 +860,9 @@ static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd) if (!cd->eesr_err_check) cd->eesr_err_check = DEFAULT_EESR_ERR_CHECK; + + if (!cd->trscer_err_mask) + cd->trscer_err_mask = DEFAULT_TRSCER_ERR_MASK; } static int sh_eth_check_reset(struct net_device *ndev) @@ -1294,7 +1301,7 @@ static int sh_eth_dev_init(struct net_device *ndev, bool start) /* Frame recv control (enable multiple-packets per rx irq) */ sh_eth_write(ndev, RMCR_RNC, RMCR); - sh_eth_write(ndev, DESC_I_RINT8 | DESC_I_RINT5 | DESC_I_TINT2, TRSCER); + sh_eth_write(ndev, mdp->cd->trscer_err_mask, TRSCER); if (mdp->cd->bculr) sh_eth_write(ndev, 0x800, BCULR); /* Burst sycle set */ @@ -1820,6 +1827,9 @@ static int sh_eth_get_settings(struct net_device *ndev, unsigned long flags; int ret; + if (!mdp->phydev) + return -ENODEV; + spin_lock_irqsave(&mdp->lock, flags); ret = phy_ethtool_gset(mdp->phydev, ecmd); spin_unlock_irqrestore(&mdp->lock, flags); @@ -1834,6 +1844,9 @@ static int sh_eth_set_settings(struct net_device *ndev, unsigned long flags; int ret; + if (!mdp->phydev) + return -ENODEV; + spin_lock_irqsave(&mdp->lock, flags); /* disable tx and rx */ @@ -1868,6 +1881,9 @@ static int sh_eth_nway_reset(struct net_device *ndev) unsigned long flags; int ret; + if (!mdp->phydev) + return -ENODEV; + spin_lock_irqsave(&mdp->lock, flags); ret = phy_start_aneg(mdp->phydev); spin_unlock_irqrestore(&mdp->lock, flags); @@ -2177,6 +2193,7 @@ static int sh_eth_close(struct net_device *ndev) if (mdp->phydev) { phy_stop(mdp->phydev); phy_disconnect(mdp->phydev); + mdp->phydev = NULL; } free_irq(ndev->irq, ndev); @@ -2410,7 +2427,7 @@ static int sh_eth_tsu_purge_all(struct net_device *ndev) struct sh_eth_private *mdp = netdev_priv(ndev); int i, ret; - if (unlikely(!mdp->cd->tsu)) + if (!mdp->cd->tsu) return 0; for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++) { @@ -2433,7 +2450,7 @@ static void sh_eth_tsu_purge_mcast(struct net_device *ndev) void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0); int i; - if (unlikely(!mdp->cd->tsu)) + if (!mdp->cd->tsu) return; for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++, reg_offset += 8) { @@ -2443,8 +2460,8 @@ static void sh_eth_tsu_purge_mcast(struct net_device *ndev) } } -/* Multicast reception directions set */ -static void sh_eth_set_multicast_list(struct net_device *ndev) +/* Update promiscuous flag and multicast filter */ +static void sh_eth_set_rx_mode(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); u32 ecmr_bits; @@ -2455,7 +2472,9 @@ static void sh_eth_set_multicast_list(struct net_device *ndev) /* Initial condition is MCT = 1, PRM = 0. * Depending on ndev->flags, set PRM or clear MCT */ - ecmr_bits = (sh_eth_read(ndev, ECMR) & ~ECMR_PRM) | ECMR_MCT; + ecmr_bits = sh_eth_read(ndev, ECMR) & ~ECMR_PRM; + if (mdp->cd->tsu) + ecmr_bits |= ECMR_MCT; if (!(ndev->flags & IFF_MULTICAST)) { sh_eth_tsu_purge_mcast(ndev); @@ -2484,9 +2503,6 @@ static void sh_eth_set_multicast_list(struct net_device *ndev) } } } - } else { - /* Normal, unicast/broadcast-only mode. */ - ecmr_bits = (ecmr_bits & ~ECMR_PRM) | ECMR_MCT; } /* update the ethernet mode */ @@ -2694,6 +2710,7 @@ static const struct net_device_ops sh_eth_netdev_ops = { .ndo_stop = sh_eth_close, .ndo_start_xmit = sh_eth_start_xmit, .ndo_get_stats = sh_eth_get_stats, + .ndo_set_rx_mode = sh_eth_set_rx_mode, .ndo_tx_timeout = sh_eth_tx_timeout, .ndo_do_ioctl = sh_eth_do_ioctl, .ndo_validate_addr = eth_validate_addr, @@ -2706,7 +2723,7 @@ static const struct net_device_ops sh_eth_netdev_ops_tsu = { .ndo_stop = sh_eth_close, .ndo_start_xmit = sh_eth_start_xmit, .ndo_get_stats = sh_eth_get_stats, - .ndo_set_rx_mode = sh_eth_set_multicast_list, + .ndo_set_rx_mode = sh_eth_set_rx_mode, .ndo_vlan_rx_add_vid = sh_eth_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = sh_eth_vlan_rx_kill_vid, .ndo_tx_timeout = sh_eth_tx_timeout, diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index 22301bf9c21d..71f5de1171bd 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h @@ -369,6 +369,8 @@ enum DESC_I_BIT { DESC_I_RINT1 = 0x0001, }; +#define DEFAULT_TRSCER_ERR_MASK (DESC_I_RINT8 | DESC_I_RINT5 | DESC_I_TINT2) + /* RPADIR */ enum RPADIR_BIT { RPADIR_PADS1 = 0x20000, RPADIR_PADS0 = 0x10000, @@ -470,6 +472,9 @@ struct sh_eth_cpu_data { unsigned long tx_check; unsigned long eesr_err_check; + /* Error mask */ + unsigned long trscer_err_mask; + /* hardware features */ unsigned long irq_flags; /* IRQ configuration flags */ unsigned no_psr:1; /* EtherC DO NOT have PSR */ diff --git a/drivers/net/ethernet/s6gmac.c b/drivers/net/ethernet/s6gmac.c deleted file mode 100644 index f537cbea20e5..000000000000 --- a/drivers/net/ethernet/s6gmac.c +++ /dev/null @@ -1,1058 +0,0 @@ -/* - * Ethernet driver for S6105 on chip network device - * (c)2008 emlix GmbH http://www.emlix.com - * Authors: Oskar Schirmer <oskar@scara.com> - * Daniel Gloeckner <dg@emlix.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/types.h> -#include <linux/delay.h> -#include <linux/spinlock.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/if.h> -#include <linux/stddef.h> -#include <linux/mii.h> -#include <linux/phy.h> -#include <linux/platform_device.h> -#include <variant/hardware.h> -#include <variant/dmac.h> - -#define DRV_NAME "s6gmac" -#define DRV_PRMT DRV_NAME ": " - - -/* register declarations */ - -#define S6_GMAC_MACCONF1 0x000 -#define S6_GMAC_MACCONF1_TXENA 0 -#define S6_GMAC_MACCONF1_SYNCTX 1 -#define S6_GMAC_MACCONF1_RXENA 2 -#define S6_GMAC_MACCONF1_SYNCRX 3 -#define S6_GMAC_MACCONF1_TXFLOWCTRL 4 -#define S6_GMAC_MACCONF1_RXFLOWCTRL 5 -#define S6_GMAC_MACCONF1_LOOPBACK 8 -#define S6_GMAC_MACCONF1_RESTXFUNC 16 -#define S6_GMAC_MACCONF1_RESRXFUNC 17 -#define S6_GMAC_MACCONF1_RESTXMACCTRL 18 -#define S6_GMAC_MACCONF1_RESRXMACCTRL 19 -#define S6_GMAC_MACCONF1_SIMULRES 30 -#define S6_GMAC_MACCONF1_SOFTRES 31 -#define S6_GMAC_MACCONF2 0x004 -#define S6_GMAC_MACCONF2_FULL 0 -#define S6_GMAC_MACCONF2_CRCENA 1 -#define S6_GMAC_MACCONF2_PADCRCENA 2 -#define S6_GMAC_MACCONF2_LENGTHFCHK 4 -#define S6_GMAC_MACCONF2_HUGEFRAMENA 5 -#define S6_GMAC_MACCONF2_IFMODE 8 -#define S6_GMAC_MACCONF2_IFMODE_NIBBLE 1 -#define S6_GMAC_MACCONF2_IFMODE_BYTE 2 -#define S6_GMAC_MACCONF2_IFMODE_MASK 3 -#define S6_GMAC_MACCONF2_PREAMBLELEN 12 -#define S6_GMAC_MACCONF2_PREAMBLELEN_MASK 0x0F -#define S6_GMAC_MACIPGIFG 0x008 -#define S6_GMAC_MACIPGIFG_B2BINTERPGAP 0 -#define S6_GMAC_MACIPGIFG_B2BINTERPGAP_MASK 0x7F -#define S6_GMAC_MACIPGIFG_MINIFGENFORCE 8 -#define S6_GMAC_MACIPGIFG_B2BINTERPGAP2 16 -#define S6_GMAC_MACIPGIFG_B2BINTERPGAP1 24 -#define S6_GMAC_MACHALFDUPLEX 0x00C -#define S6_GMAC_MACHALFDUPLEX_COLLISWIN 0 -#define S6_GMAC_MACHALFDUPLEX_COLLISWIN_MASK 0x3F -#define S6_GMAC_MACHALFDUPLEX_RETXMAX 12 -#define S6_GMAC_MACHALFDUPLEX_RETXMAX_MASK 0x0F -#define S6_GMAC_MACHALFDUPLEX_EXCESSDEF 16 -#define S6_GMAC_MACHALFDUPLEX_NOBACKOFF 17 -#define S6_GMAC_MACHALFDUPLEX_BPNOBCKOF 18 -#define S6_GMAC_MACHALFDUPLEX_ALTBEBENA 19 -#define S6_GMAC_MACHALFDUPLEX_ALTBEBTRN 20 -#define S6_GMAC_MACHALFDUPLEX_ALTBEBTR_MASK 0x0F -#define S6_GMAC_MACMAXFRAMELEN 0x010 -#define S6_GMAC_MACMIICONF 0x020 -#define S6_GMAC_MACMIICONF_CSEL 0 -#define S6_GMAC_MACMIICONF_CSEL_DIV10 0 -#define S6_GMAC_MACMIICONF_CSEL_DIV12 1 -#define S6_GMAC_MACMIICONF_CSEL_DIV14 2 -#define S6_GMAC_MACMIICONF_CSEL_DIV18 3 -#define S6_GMAC_MACMIICONF_CSEL_DIV24 4 -#define S6_GMAC_MACMIICONF_CSEL_DIV34 5 -#define S6_GMAC_MACMIICONF_CSEL_DIV68 6 -#define S6_GMAC_MACMIICONF_CSEL_DIV168 7 -#define S6_GMAC_MACMIICONF_CSEL_MASK 7 -#define S6_GMAC_MACMIICONF_PREAMBLESUPR 4 -#define S6_GMAC_MACMIICONF_SCANAUTOINCR 5 -#define S6_GMAC_MACMIICMD 0x024 -#define S6_GMAC_MACMIICMD_READ 0 -#define S6_GMAC_MACMIICMD_SCAN 1 -#define S6_GMAC_MACMIIADDR 0x028 -#define S6_GMAC_MACMIIADDR_REG 0 -#define S6_GMAC_MACMIIADDR_REG_MASK 0x1F -#define S6_GMAC_MACMIIADDR_PHY 8 -#define S6_GMAC_MACMIIADDR_PHY_MASK 0x1F -#define S6_GMAC_MACMIICTRL 0x02C -#define S6_GMAC_MACMIISTAT 0x030 -#define S6_GMAC_MACMIIINDI 0x034 -#define S6_GMAC_MACMIIINDI_BUSY 0 -#define S6_GMAC_MACMIIINDI_SCAN 1 -#define S6_GMAC_MACMIIINDI_INVAL 2 -#define S6_GMAC_MACINTERFSTAT 0x03C -#define S6_GMAC_MACINTERFSTAT_LINKFAIL 3 -#define S6_GMAC_MACINTERFSTAT_EXCESSDEF 9 -#define S6_GMAC_MACSTATADDR1 0x040 -#define S6_GMAC_MACSTATADDR2 0x044 - -#define S6_GMAC_FIFOCONF0 0x048 -#define S6_GMAC_FIFOCONF0_HSTRSTWT 0 -#define S6_GMAC_FIFOCONF0_HSTRSTSR 1 -#define S6_GMAC_FIFOCONF0_HSTRSTFR 2 -#define S6_GMAC_FIFOCONF0_HSTRSTST 3 -#define S6_GMAC_FIFOCONF0_HSTRSTFT 4 -#define S6_GMAC_FIFOCONF0_WTMENREQ 8 -#define S6_GMAC_FIFOCONF0_SRFENREQ 9 -#define S6_GMAC_FIFOCONF0_FRFENREQ 10 -#define S6_GMAC_FIFOCONF0_STFENREQ 11 -#define S6_GMAC_FIFOCONF0_FTFENREQ 12 -#define S6_GMAC_FIFOCONF0_WTMENRPLY 16 -#define S6_GMAC_FIFOCONF0_SRFENRPLY 17 -#define S6_GMAC_FIFOCONF0_FRFENRPLY 18 -#define S6_GMAC_FIFOCONF0_STFENRPLY 19 -#define S6_GMAC_FIFOCONF0_FTFENRPLY 20 -#define S6_GMAC_FIFOCONF1 0x04C -#define S6_GMAC_FIFOCONF2 0x050 -#define S6_GMAC_FIFOCONF2_CFGLWM 0 -#define S6_GMAC_FIFOCONF2_CFGHWM 16 -#define S6_GMAC_FIFOCONF3 0x054 -#define S6_GMAC_FIFOCONF3_CFGFTTH 0 -#define S6_GMAC_FIFOCONF3_CFGHWMFT 16 -#define S6_GMAC_FIFOCONF4 0x058 -#define S6_GMAC_FIFOCONF_RSV_PREVDROP 0 -#define S6_GMAC_FIFOCONF_RSV_RUNT 1 -#define S6_GMAC_FIFOCONF_RSV_FALSECAR 2 -#define S6_GMAC_FIFOCONF_RSV_CODEERR 3 -#define S6_GMAC_FIFOCONF_RSV_CRCERR 4 -#define S6_GMAC_FIFOCONF_RSV_LENGTHERR 5 -#define S6_GMAC_FIFOCONF_RSV_LENRANGE 6 -#define S6_GMAC_FIFOCONF_RSV_OK 7 -#define S6_GMAC_FIFOCONF_RSV_MULTICAST 8 -#define S6_GMAC_FIFOCONF_RSV_BROADCAST 9 -#define S6_GMAC_FIFOCONF_RSV_DRIBBLE 10 -#define S6_GMAC_FIFOCONF_RSV_CTRLFRAME 11 -#define S6_GMAC_FIFOCONF_RSV_PAUSECTRL 12 -#define S6_GMAC_FIFOCONF_RSV_UNOPCODE 13 -#define S6_GMAC_FIFOCONF_RSV_VLANTAG 14 -#define S6_GMAC_FIFOCONF_RSV_LONGEVENT 15 -#define S6_GMAC_FIFOCONF_RSV_TRUNCATED 16 -#define S6_GMAC_FIFOCONF_RSV_MASK 0x3FFFF -#define S6_GMAC_FIFOCONF5 0x05C -#define S6_GMAC_FIFOCONF5_DROPLT64 18 -#define S6_GMAC_FIFOCONF5_CFGBYTM 19 -#define S6_GMAC_FIFOCONF5_RXDROPSIZE 20 -#define S6_GMAC_FIFOCONF5_RXDROPSIZE_MASK 0xF - -#define S6_GMAC_STAT_REGS 0x080 -#define S6_GMAC_STAT_SIZE_MIN 12 -#define S6_GMAC_STATTR64 0x080 -#define S6_GMAC_STATTR64_SIZE 18 -#define S6_GMAC_STATTR127 0x084 -#define S6_GMAC_STATTR127_SIZE 18 -#define S6_GMAC_STATTR255 0x088 -#define S6_GMAC_STATTR255_SIZE 18 -#define S6_GMAC_STATTR511 0x08C -#define S6_GMAC_STATTR511_SIZE 18 -#define S6_GMAC_STATTR1K 0x090 -#define S6_GMAC_STATTR1K_SIZE 18 -#define S6_GMAC_STATTRMAX 0x094 -#define S6_GMAC_STATTRMAX_SIZE 18 -#define S6_GMAC_STATTRMGV 0x098 -#define S6_GMAC_STATTRMGV_SIZE 18 -#define S6_GMAC_STATRBYT 0x09C -#define S6_GMAC_STATRBYT_SIZE 24 -#define S6_GMAC_STATRPKT 0x0A0 -#define S6_GMAC_STATRPKT_SIZE 18 -#define S6_GMAC_STATRFCS 0x0A4 -#define S6_GMAC_STATRFCS_SIZE 12 -#define S6_GMAC_STATRMCA 0x0A8 -#define S6_GMAC_STATRMCA_SIZE 18 -#define S6_GMAC_STATRBCA 0x0AC -#define S6_GMAC_STATRBCA_SIZE 22 -#define S6_GMAC_STATRXCF 0x0B0 -#define S6_GMAC_STATRXCF_SIZE 18 -#define S6_GMAC_STATRXPF 0x0B4 -#define S6_GMAC_STATRXPF_SIZE 12 -#define S6_GMAC_STATRXUO 0x0B8 -#define S6_GMAC_STATRXUO_SIZE 12 -#define S6_GMAC_STATRALN 0x0BC -#define S6_GMAC_STATRALN_SIZE 12 -#define S6_GMAC_STATRFLR 0x0C0 -#define S6_GMAC_STATRFLR_SIZE 16 -#define S6_GMAC_STATRCDE 0x0C4 -#define S6_GMAC_STATRCDE_SIZE 12 -#define S6_GMAC_STATRCSE 0x0C8 -#define S6_GMAC_STATRCSE_SIZE 12 -#define S6_GMAC_STATRUND 0x0CC -#define S6_GMAC_STATRUND_SIZE 12 -#define S6_GMAC_STATROVR 0x0D0 -#define S6_GMAC_STATROVR_SIZE 12 -#define S6_GMAC_STATRFRG 0x0D4 -#define S6_GMAC_STATRFRG_SIZE 12 -#define S6_GMAC_STATRJBR 0x0D8 -#define S6_GMAC_STATRJBR_SIZE 12 -#define S6_GMAC_STATRDRP 0x0DC -#define S6_GMAC_STATRDRP_SIZE 12 -#define S6_GMAC_STATTBYT 0x0E0 -#define S6_GMAC_STATTBYT_SIZE 24 -#define S6_GMAC_STATTPKT 0x0E4 -#define S6_GMAC_STATTPKT_SIZE 18 -#define S6_GMAC_STATTMCA 0x0E8 -#define S6_GMAC_STATTMCA_SIZE 18 -#define S6_GMAC_STATTBCA 0x0EC -#define S6_GMAC_STATTBCA_SIZE 18 -#define S6_GMAC_STATTXPF 0x0F0 -#define S6_GMAC_STATTXPF_SIZE 12 -#define S6_GMAC_STATTDFR 0x0F4 -#define S6_GMAC_STATTDFR_SIZE 12 -#define S6_GMAC_STATTEDF 0x0F8 -#define S6_GMAC_STATTEDF_SIZE 12 -#define S6_GMAC_STATTSCL 0x0FC -#define S6_GMAC_STATTSCL_SIZE 12 -#define S6_GMAC_STATTMCL 0x100 -#define S6_GMAC_STATTMCL_SIZE 12 -#define S6_GMAC_STATTLCL 0x104 -#define S6_GMAC_STATTLCL_SIZE 12 -#define S6_GMAC_STATTXCL 0x108 -#define S6_GMAC_STATTXCL_SIZE 12 -#define S6_GMAC_STATTNCL 0x10C -#define S6_GMAC_STATTNCL_SIZE 13 -#define S6_GMAC_STATTPFH 0x110 -#define S6_GMAC_STATTPFH_SIZE 12 -#define S6_GMAC_STATTDRP 0x114 -#define S6_GMAC_STATTDRP_SIZE 12 -#define S6_GMAC_STATTJBR 0x118 -#define S6_GMAC_STATTJBR_SIZE 12 -#define S6_GMAC_STATTFCS 0x11C -#define S6_GMAC_STATTFCS_SIZE 12 -#define S6_GMAC_STATTXCF 0x120 -#define S6_GMAC_STATTXCF_SIZE 12 -#define S6_GMAC_STATTOVR 0x124 -#define S6_GMAC_STATTOVR_SIZE 12 -#define S6_GMAC_STATTUND 0x128 -#define S6_GMAC_STATTUND_SIZE 12 -#define S6_GMAC_STATTFRG 0x12C -#define S6_GMAC_STATTFRG_SIZE 12 -#define S6_GMAC_STATCARRY(n) (0x130 + 4*(n)) -#define S6_GMAC_STATCARRYMSK(n) (0x138 + 4*(n)) -#define S6_GMAC_STATCARRY1_RDRP 0 -#define S6_GMAC_STATCARRY1_RJBR 1 -#define S6_GMAC_STATCARRY1_RFRG 2 -#define S6_GMAC_STATCARRY1_ROVR 3 -#define S6_GMAC_STATCARRY1_RUND 4 -#define S6_GMAC_STATCARRY1_RCSE 5 -#define S6_GMAC_STATCARRY1_RCDE 6 -#define S6_GMAC_STATCARRY1_RFLR 7 -#define S6_GMAC_STATCARRY1_RALN 8 -#define S6_GMAC_STATCARRY1_RXUO 9 -#define S6_GMAC_STATCARRY1_RXPF 10 -#define S6_GMAC_STATCARRY1_RXCF 11 -#define S6_GMAC_STATCARRY1_RBCA 12 -#define S6_GMAC_STATCARRY1_RMCA 13 -#define S6_GMAC_STATCARRY1_RFCS 14 -#define S6_GMAC_STATCARRY1_RPKT 15 -#define S6_GMAC_STATCARRY1_RBYT 16 -#define S6_GMAC_STATCARRY1_TRMGV 25 -#define S6_GMAC_STATCARRY1_TRMAX 26 -#define S6_GMAC_STATCARRY1_TR1K 27 -#define S6_GMAC_STATCARRY1_TR511 28 -#define S6_GMAC_STATCARRY1_TR255 29 -#define S6_GMAC_STATCARRY1_TR127 30 -#define S6_GMAC_STATCARRY1_TR64 31 -#define S6_GMAC_STATCARRY2_TDRP 0 -#define S6_GMAC_STATCARRY2_TPFH 1 -#define S6_GMAC_STATCARRY2_TNCL 2 -#define S6_GMAC_STATCARRY2_TXCL 3 -#define S6_GMAC_STATCARRY2_TLCL 4 -#define S6_GMAC_STATCARRY2_TMCL 5 -#define S6_GMAC_STATCARRY2_TSCL 6 -#define S6_GMAC_STATCARRY2_TEDF 7 -#define S6_GMAC_STATCARRY2_TDFR 8 -#define S6_GMAC_STATCARRY2_TXPF 9 -#define S6_GMAC_STATCARRY2_TBCA 10 -#define S6_GMAC_STATCARRY2_TMCA 11 -#define S6_GMAC_STATCARRY2_TPKT 12 -#define S6_GMAC_STATCARRY2_TBYT 13 -#define S6_GMAC_STATCARRY2_TFRG 14 -#define S6_GMAC_STATCARRY2_TUND 15 -#define S6_GMAC_STATCARRY2_TOVR 16 -#define S6_GMAC_STATCARRY2_TXCF 17 -#define S6_GMAC_STATCARRY2_TFCS 18 -#define S6_GMAC_STATCARRY2_TJBR 19 - -#define S6_GMAC_HOST_PBLKCTRL 0x140 -#define S6_GMAC_HOST_PBLKCTRL_TXENA 0 -#define S6_GMAC_HOST_PBLKCTRL_RXENA 1 -#define S6_GMAC_HOST_PBLKCTRL_TXSRES 2 -#define S6_GMAC_HOST_PBLKCTRL_RXSRES 3 -#define S6_GMAC_HOST_PBLKCTRL_TXBSIZ 8 -#define S6_GMAC_HOST_PBLKCTRL_RXBSIZ 12 -#define S6_GMAC_HOST_PBLKCTRL_SIZ_16 4 -#define S6_GMAC_HOST_PBLKCTRL_SIZ_32 5 -#define S6_GMAC_HOST_PBLKCTRL_SIZ_64 6 -#define S6_GMAC_HOST_PBLKCTRL_SIZ_128 7 -#define S6_GMAC_HOST_PBLKCTRL_SIZ_MASK 0xF -#define S6_GMAC_HOST_PBLKCTRL_STATENA 16 -#define S6_GMAC_HOST_PBLKCTRL_STATAUTOZ 17 -#define S6_GMAC_HOST_PBLKCTRL_STATCLEAR 18 -#define S6_GMAC_HOST_PBLKCTRL_RGMII 19 -#define S6_GMAC_HOST_INTMASK 0x144 -#define S6_GMAC_HOST_INTSTAT 0x148 -#define S6_GMAC_HOST_INT_TXBURSTOVER 3 -#define S6_GMAC_HOST_INT_TXPREWOVER 4 -#define S6_GMAC_HOST_INT_RXBURSTUNDER 5 -#define S6_GMAC_HOST_INT_RXPOSTRFULL 6 -#define S6_GMAC_HOST_INT_RXPOSTRUNDER 7 -#define S6_GMAC_HOST_RXFIFOHWM 0x14C -#define S6_GMAC_HOST_CTRLFRAMXP 0x150 -#define S6_GMAC_HOST_DSTADDRLO(n) (0x160 + 8*(n)) -#define S6_GMAC_HOST_DSTADDRHI(n) (0x164 + 8*(n)) -#define S6_GMAC_HOST_DSTMASKLO(n) (0x180 + 8*(n)) -#define S6_GMAC_HOST_DSTMASKHI(n) (0x184 + 8*(n)) - -#define S6_GMAC_BURST_PREWR 0x1B0 -#define S6_GMAC_BURST_PREWR_LEN 0 -#define S6_GMAC_BURST_PREWR_LEN_MASK ((1 << 20) - 1) -#define S6_GMAC_BURST_PREWR_CFE 20 -#define S6_GMAC_BURST_PREWR_PPE 21 -#define S6_GMAC_BURST_PREWR_FCS 22 -#define S6_GMAC_BURST_PREWR_PAD 23 -#define S6_GMAC_BURST_POSTRD 0x1D0 -#define S6_GMAC_BURST_POSTRD_LEN 0 -#define S6_GMAC_BURST_POSTRD_LEN_MASK ((1 << 20) - 1) -#define S6_GMAC_BURST_POSTRD_DROP 20 - - -/* data handling */ - -#define S6_NUM_TX_SKB 8 /* must be larger than TX fifo size */ -#define S6_NUM_RX_SKB 16 -#define S6_MAX_FRLEN 1536 - -struct s6gmac { - u32 reg; - u32 tx_dma; - u32 rx_dma; - u32 io; - u8 tx_chan; - u8 rx_chan; - spinlock_t lock; - u8 tx_skb_i, tx_skb_o; - u8 rx_skb_i, rx_skb_o; - struct sk_buff *tx_skb[S6_NUM_TX_SKB]; - struct sk_buff *rx_skb[S6_NUM_RX_SKB]; - unsigned long carry[sizeof(struct net_device_stats) / sizeof(long)]; - unsigned long stats[sizeof(struct net_device_stats) / sizeof(long)]; - struct phy_device *phydev; - struct { - struct mii_bus *bus; - int irq[PHY_MAX_ADDR]; - } mii; - struct { - unsigned int mbit; - u8 giga; - u8 isup; - u8 full; - } link; -}; - -static void s6gmac_rx_fillfifo(struct net_device *dev) -{ - struct s6gmac *pd = netdev_priv(dev); - struct sk_buff *skb; - while ((((u8)(pd->rx_skb_i - pd->rx_skb_o)) < S6_NUM_RX_SKB) && - (!s6dmac_fifo_full(pd->rx_dma, pd->rx_chan)) && - (skb = netdev_alloc_skb(dev, S6_MAX_FRLEN + 2))) { - pd->rx_skb[(pd->rx_skb_i++) % S6_NUM_RX_SKB] = skb; - s6dmac_put_fifo_cache(pd->rx_dma, pd->rx_chan, - pd->io, (u32)skb->data, S6_MAX_FRLEN); - } -} - -static void s6gmac_rx_interrupt(struct net_device *dev) -{ - struct s6gmac *pd = netdev_priv(dev); - u32 pfx; - struct sk_buff *skb; - while (((u8)(pd->rx_skb_i - pd->rx_skb_o)) > - s6dmac_pending_count(pd->rx_dma, pd->rx_chan)) { - skb = pd->rx_skb[(pd->rx_skb_o++) % S6_NUM_RX_SKB]; - pfx = readl(pd->reg + S6_GMAC_BURST_POSTRD); - if (pfx & (1 << S6_GMAC_BURST_POSTRD_DROP)) { - dev_kfree_skb_irq(skb); - } else { - skb_put(skb, (pfx >> S6_GMAC_BURST_POSTRD_LEN) - & S6_GMAC_BURST_POSTRD_LEN_MASK); - skb->protocol = eth_type_trans(skb, dev); - skb->ip_summed = CHECKSUM_UNNECESSARY; - netif_rx(skb); - } - } -} - -static void s6gmac_tx_interrupt(struct net_device *dev) -{ - struct s6gmac *pd = netdev_priv(dev); - while (((u8)(pd->tx_skb_i - pd->tx_skb_o)) > - s6dmac_pending_count(pd->tx_dma, pd->tx_chan)) { - dev_kfree_skb_irq(pd->tx_skb[(pd->tx_skb_o++) % S6_NUM_TX_SKB]); - } - if (!s6dmac_fifo_full(pd->tx_dma, pd->tx_chan)) - netif_wake_queue(dev); -} - -struct s6gmac_statinf { - unsigned reg_size : 4; /* 0: unused */ - unsigned reg_off : 6; - unsigned net_index : 6; -}; - -#define S6_STATS_B (8 * sizeof(u32)) -#define S6_STATS_C(b, r, f) [b] = { \ - BUILD_BUG_ON_ZERO(r##_SIZE < S6_GMAC_STAT_SIZE_MIN) + \ - BUILD_BUG_ON_ZERO((r##_SIZE - (S6_GMAC_STAT_SIZE_MIN - 1)) \ - >= (1<<4)) + \ - r##_SIZE - (S6_GMAC_STAT_SIZE_MIN - 1), \ - BUILD_BUG_ON_ZERO(((unsigned)((r - S6_GMAC_STAT_REGS) / sizeof(u32))) \ - >= ((1<<6)-1)) + \ - (r - S6_GMAC_STAT_REGS) / sizeof(u32), \ - BUILD_BUG_ON_ZERO((offsetof(struct net_device_stats, f)) \ - % sizeof(unsigned long)) + \ - BUILD_BUG_ON_ZERO((((unsigned)(offsetof(struct net_device_stats, f)) \ - / sizeof(unsigned long)) >= (1<<6))) + \ - BUILD_BUG_ON_ZERO((sizeof(((struct net_device_stats *)0)->f) \ - != sizeof(unsigned long))) + \ - (offsetof(struct net_device_stats, f)) / sizeof(unsigned long)}, - -static const struct s6gmac_statinf statinf[2][S6_STATS_B] = { { - S6_STATS_C(S6_GMAC_STATCARRY1_RBYT, S6_GMAC_STATRBYT, rx_bytes) - S6_STATS_C(S6_GMAC_STATCARRY1_RPKT, S6_GMAC_STATRPKT, rx_packets) - S6_STATS_C(S6_GMAC_STATCARRY1_RFCS, S6_GMAC_STATRFCS, rx_crc_errors) - S6_STATS_C(S6_GMAC_STATCARRY1_RMCA, S6_GMAC_STATRMCA, multicast) - S6_STATS_C(S6_GMAC_STATCARRY1_RALN, S6_GMAC_STATRALN, rx_frame_errors) - S6_STATS_C(S6_GMAC_STATCARRY1_RFLR, S6_GMAC_STATRFLR, rx_length_errors) - S6_STATS_C(S6_GMAC_STATCARRY1_RCDE, S6_GMAC_STATRCDE, rx_missed_errors) - S6_STATS_C(S6_GMAC_STATCARRY1_RUND, S6_GMAC_STATRUND, rx_length_errors) - S6_STATS_C(S6_GMAC_STATCARRY1_ROVR, S6_GMAC_STATROVR, rx_length_errors) - S6_STATS_C(S6_GMAC_STATCARRY1_RFRG, S6_GMAC_STATRFRG, rx_crc_errors) - S6_STATS_C(S6_GMAC_STATCARRY1_RJBR, S6_GMAC_STATRJBR, rx_crc_errors) - S6_STATS_C(S6_GMAC_STATCARRY1_RDRP, S6_GMAC_STATRDRP, rx_dropped) -}, { - S6_STATS_C(S6_GMAC_STATCARRY2_TBYT, S6_GMAC_STATTBYT, tx_bytes) - S6_STATS_C(S6_GMAC_STATCARRY2_TPKT, S6_GMAC_STATTPKT, tx_packets) - S6_STATS_C(S6_GMAC_STATCARRY2_TEDF, S6_GMAC_STATTEDF, tx_aborted_errors) - S6_STATS_C(S6_GMAC_STATCARRY2_TXCL, S6_GMAC_STATTXCL, tx_aborted_errors) - S6_STATS_C(S6_GMAC_STATCARRY2_TNCL, S6_GMAC_STATTNCL, collisions) - S6_STATS_C(S6_GMAC_STATCARRY2_TDRP, S6_GMAC_STATTDRP, tx_dropped) - S6_STATS_C(S6_GMAC_STATCARRY2_TJBR, S6_GMAC_STATTJBR, tx_errors) - S6_STATS_C(S6_GMAC_STATCARRY2_TFCS, S6_GMAC_STATTFCS, tx_errors) - S6_STATS_C(S6_GMAC_STATCARRY2_TOVR, S6_GMAC_STATTOVR, tx_errors) - S6_STATS_C(S6_GMAC_STATCARRY2_TUND, S6_GMAC_STATTUND, tx_errors) - S6_STATS_C(S6_GMAC_STATCARRY2_TFRG, S6_GMAC_STATTFRG, tx_errors) -} }; - -static void s6gmac_stats_collect(struct s6gmac *pd, - const struct s6gmac_statinf *inf) -{ - int b; - for (b = 0; b < S6_STATS_B; b++) { - if (inf[b].reg_size) { - pd->stats[inf[b].net_index] += - readl(pd->reg + S6_GMAC_STAT_REGS - + sizeof(u32) * inf[b].reg_off); - } - } -} - -static void s6gmac_stats_carry(struct s6gmac *pd, - const struct s6gmac_statinf *inf, u32 mask) -{ - int b; - while (mask) { - b = fls(mask) - 1; - mask &= ~(1 << b); - pd->carry[inf[b].net_index] += (1 << inf[b].reg_size); - } -} - -static inline u32 s6gmac_stats_pending(struct s6gmac *pd, int carry) -{ - int r = readl(pd->reg + S6_GMAC_STATCARRY(carry)) & - ~readl(pd->reg + S6_GMAC_STATCARRYMSK(carry)); - return r; -} - -static inline void s6gmac_stats_interrupt(struct s6gmac *pd, int carry) -{ - u32 mask; - mask = s6gmac_stats_pending(pd, carry); - if (mask) { - writel(mask, pd->reg + S6_GMAC_STATCARRY(carry)); - s6gmac_stats_carry(pd, &statinf[carry][0], mask); - } -} - -static irqreturn_t s6gmac_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = (struct net_device *)dev_id; - struct s6gmac *pd = netdev_priv(dev); - if (!dev) - return IRQ_NONE; - spin_lock(&pd->lock); - if (s6dmac_termcnt_irq(pd->rx_dma, pd->rx_chan)) - s6gmac_rx_interrupt(dev); - s6gmac_rx_fillfifo(dev); - if (s6dmac_termcnt_irq(pd->tx_dma, pd->tx_chan)) - s6gmac_tx_interrupt(dev); - s6gmac_stats_interrupt(pd, 0); - s6gmac_stats_interrupt(pd, 1); - spin_unlock(&pd->lock); - return IRQ_HANDLED; -} - -static inline void s6gmac_set_dstaddr(struct s6gmac *pd, int n, - u32 addrlo, u32 addrhi, u32 masklo, u32 maskhi) -{ - writel(addrlo, pd->reg + S6_GMAC_HOST_DSTADDRLO(n)); - writel(addrhi, pd->reg + S6_GMAC_HOST_DSTADDRHI(n)); - writel(masklo, pd->reg + S6_GMAC_HOST_DSTMASKLO(n)); - writel(maskhi, pd->reg + S6_GMAC_HOST_DSTMASKHI(n)); -} - -static inline void s6gmac_stop_device(struct net_device *dev) -{ - struct s6gmac *pd = netdev_priv(dev); - writel(0, pd->reg + S6_GMAC_MACCONF1); -} - -static inline void s6gmac_init_device(struct net_device *dev) -{ - struct s6gmac *pd = netdev_priv(dev); - int is_rgmii = !!(pd->phydev->supported - & (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)); -#if 0 - writel(1 << S6_GMAC_MACCONF1_SYNCTX | - 1 << S6_GMAC_MACCONF1_SYNCRX | - 1 << S6_GMAC_MACCONF1_TXFLOWCTRL | - 1 << S6_GMAC_MACCONF1_RXFLOWCTRL | - 1 << S6_GMAC_MACCONF1_RESTXFUNC | - 1 << S6_GMAC_MACCONF1_RESRXFUNC | - 1 << S6_GMAC_MACCONF1_RESTXMACCTRL | - 1 << S6_GMAC_MACCONF1_RESRXMACCTRL, - pd->reg + S6_GMAC_MACCONF1); -#endif - writel(1 << S6_GMAC_MACCONF1_SOFTRES, pd->reg + S6_GMAC_MACCONF1); - udelay(1000); - writel(1 << S6_GMAC_MACCONF1_TXENA | 1 << S6_GMAC_MACCONF1_RXENA, - pd->reg + S6_GMAC_MACCONF1); - writel(1 << S6_GMAC_HOST_PBLKCTRL_TXSRES | - 1 << S6_GMAC_HOST_PBLKCTRL_RXSRES, - pd->reg + S6_GMAC_HOST_PBLKCTRL); - writel(S6_GMAC_HOST_PBLKCTRL_SIZ_128 << S6_GMAC_HOST_PBLKCTRL_TXBSIZ | - S6_GMAC_HOST_PBLKCTRL_SIZ_128 << S6_GMAC_HOST_PBLKCTRL_RXBSIZ | - 1 << S6_GMAC_HOST_PBLKCTRL_STATENA | - 1 << S6_GMAC_HOST_PBLKCTRL_STATCLEAR | - is_rgmii << S6_GMAC_HOST_PBLKCTRL_RGMII, - pd->reg + S6_GMAC_HOST_PBLKCTRL); - writel(1 << S6_GMAC_MACCONF1_TXENA | - 1 << S6_GMAC_MACCONF1_RXENA | - (dev->flags & IFF_LOOPBACK ? 1 : 0) - << S6_GMAC_MACCONF1_LOOPBACK, - pd->reg + S6_GMAC_MACCONF1); - writel(dev->mtu && (dev->mtu < (S6_MAX_FRLEN - ETH_HLEN-ETH_FCS_LEN)) ? - dev->mtu+ETH_HLEN+ETH_FCS_LEN : S6_MAX_FRLEN, - pd->reg + S6_GMAC_MACMAXFRAMELEN); - writel((pd->link.full ? 1 : 0) << S6_GMAC_MACCONF2_FULL | - 1 << S6_GMAC_MACCONF2_PADCRCENA | - 1 << S6_GMAC_MACCONF2_LENGTHFCHK | - (pd->link.giga ? - S6_GMAC_MACCONF2_IFMODE_BYTE : - S6_GMAC_MACCONF2_IFMODE_NIBBLE) - << S6_GMAC_MACCONF2_IFMODE | - 7 << S6_GMAC_MACCONF2_PREAMBLELEN, - pd->reg + S6_GMAC_MACCONF2); - writel(0, pd->reg + S6_GMAC_MACSTATADDR1); - writel(0, pd->reg + S6_GMAC_MACSTATADDR2); - writel(1 << S6_GMAC_FIFOCONF0_WTMENREQ | - 1 << S6_GMAC_FIFOCONF0_SRFENREQ | - 1 << S6_GMAC_FIFOCONF0_FRFENREQ | - 1 << S6_GMAC_FIFOCONF0_STFENREQ | - 1 << S6_GMAC_FIFOCONF0_FTFENREQ, - pd->reg + S6_GMAC_FIFOCONF0); - writel(128 << S6_GMAC_FIFOCONF3_CFGFTTH | - 128 << S6_GMAC_FIFOCONF3_CFGHWMFT, - pd->reg + S6_GMAC_FIFOCONF3); - writel((S6_GMAC_FIFOCONF_RSV_MASK & ~( - 1 << S6_GMAC_FIFOCONF_RSV_RUNT | - 1 << S6_GMAC_FIFOCONF_RSV_CRCERR | - 1 << S6_GMAC_FIFOCONF_RSV_OK | - 1 << S6_GMAC_FIFOCONF_RSV_DRIBBLE | - 1 << S6_GMAC_FIFOCONF_RSV_CTRLFRAME | - 1 << S6_GMAC_FIFOCONF_RSV_PAUSECTRL | - 1 << S6_GMAC_FIFOCONF_RSV_UNOPCODE | - 1 << S6_GMAC_FIFOCONF_RSV_TRUNCATED)) | - 1 << S6_GMAC_FIFOCONF5_DROPLT64 | - pd->link.giga << S6_GMAC_FIFOCONF5_CFGBYTM | - 1 << S6_GMAC_FIFOCONF5_RXDROPSIZE, - pd->reg + S6_GMAC_FIFOCONF5); - writel(1 << S6_GMAC_FIFOCONF_RSV_RUNT | - 1 << S6_GMAC_FIFOCONF_RSV_CRCERR | - 1 << S6_GMAC_FIFOCONF_RSV_DRIBBLE | - 1 << S6_GMAC_FIFOCONF_RSV_CTRLFRAME | - 1 << S6_GMAC_FIFOCONF_RSV_PAUSECTRL | - 1 << S6_GMAC_FIFOCONF_RSV_UNOPCODE | - 1 << S6_GMAC_FIFOCONF_RSV_TRUNCATED, - pd->reg + S6_GMAC_FIFOCONF4); - s6gmac_set_dstaddr(pd, 0, - 0xFFFFFFFF, 0x0000FFFF, 0xFFFFFFFF, 0x0000FFFF); - s6gmac_set_dstaddr(pd, 1, - dev->dev_addr[5] | - dev->dev_addr[4] << 8 | - dev->dev_addr[3] << 16 | - dev->dev_addr[2] << 24, - dev->dev_addr[1] | - dev->dev_addr[0] << 8, - 0xFFFFFFFF, 0x0000FFFF); - s6gmac_set_dstaddr(pd, 2, - 0x00000000, 0x00000100, 0x00000000, 0x00000100); - s6gmac_set_dstaddr(pd, 3, - 0x00000000, 0x00000000, 0x00000000, 0x00000000); - writel(1 << S6_GMAC_HOST_PBLKCTRL_TXENA | - 1 << S6_GMAC_HOST_PBLKCTRL_RXENA | - S6_GMAC_HOST_PBLKCTRL_SIZ_128 << S6_GMAC_HOST_PBLKCTRL_TXBSIZ | - S6_GMAC_HOST_PBLKCTRL_SIZ_128 << S6_GMAC_HOST_PBLKCTRL_RXBSIZ | - 1 << S6_GMAC_HOST_PBLKCTRL_STATENA | - 1 << S6_GMAC_HOST_PBLKCTRL_STATCLEAR | - is_rgmii << S6_GMAC_HOST_PBLKCTRL_RGMII, - pd->reg + S6_GMAC_HOST_PBLKCTRL); -} - -static void s6mii_enable(struct s6gmac *pd) -{ - writel(readl(pd->reg + S6_GMAC_MACCONF1) & - ~(1 << S6_GMAC_MACCONF1_SOFTRES), - pd->reg + S6_GMAC_MACCONF1); - writel((readl(pd->reg + S6_GMAC_MACMIICONF) - & ~(S6_GMAC_MACMIICONF_CSEL_MASK << S6_GMAC_MACMIICONF_CSEL)) - | (S6_GMAC_MACMIICONF_CSEL_DIV168 << S6_GMAC_MACMIICONF_CSEL), - pd->reg + S6_GMAC_MACMIICONF); -} - -static int s6mii_busy(struct s6gmac *pd, int tmo) -{ - while (readl(pd->reg + S6_GMAC_MACMIIINDI)) { - if (--tmo == 0) - return -ETIME; - udelay(64); - } - return 0; -} - -static int s6mii_read(struct mii_bus *bus, int phy_addr, int regnum) -{ - struct s6gmac *pd = bus->priv; - s6mii_enable(pd); - if (s6mii_busy(pd, 256)) - return -ETIME; - writel(phy_addr << S6_GMAC_MACMIIADDR_PHY | - regnum << S6_GMAC_MACMIIADDR_REG, - pd->reg + S6_GMAC_MACMIIADDR); - writel(1 << S6_GMAC_MACMIICMD_READ, pd->reg + S6_GMAC_MACMIICMD); - writel(0, pd->reg + S6_GMAC_MACMIICMD); - if (s6mii_busy(pd, 256)) - return -ETIME; - return (u16)readl(pd->reg + S6_GMAC_MACMIISTAT); -} - -static int s6mii_write(struct mii_bus *bus, int phy_addr, int regnum, u16 value) -{ - struct s6gmac *pd = bus->priv; - s6mii_enable(pd); - if (s6mii_busy(pd, 256)) - return -ETIME; - writel(phy_addr << S6_GMAC_MACMIIADDR_PHY | - regnum << S6_GMAC_MACMIIADDR_REG, - pd->reg + S6_GMAC_MACMIIADDR); - writel(value, pd->reg + S6_GMAC_MACMIICTRL); - if (s6mii_busy(pd, 256)) - return -ETIME; - return 0; -} - -static int s6mii_reset(struct mii_bus *bus) -{ - struct s6gmac *pd = bus->priv; - s6mii_enable(pd); - if (s6mii_busy(pd, PHY_INIT_TIMEOUT)) - return -ETIME; - return 0; -} - -static void s6gmac_set_rgmii_txclock(struct s6gmac *pd) -{ - u32 pllsel = readl(S6_REG_GREG1 + S6_GREG1_PLLSEL); - pllsel &= ~(S6_GREG1_PLLSEL_GMAC_MASK << S6_GREG1_PLLSEL_GMAC); - switch (pd->link.mbit) { - case 10: - pllsel |= S6_GREG1_PLLSEL_GMAC_2500KHZ << S6_GREG1_PLLSEL_GMAC; - break; - case 100: - pllsel |= S6_GREG1_PLLSEL_GMAC_25MHZ << S6_GREG1_PLLSEL_GMAC; - break; - case 1000: - pllsel |= S6_GREG1_PLLSEL_GMAC_125MHZ << S6_GREG1_PLLSEL_GMAC; - break; - default: - return; - } - writel(pllsel, S6_REG_GREG1 + S6_GREG1_PLLSEL); -} - -static inline void s6gmac_linkisup(struct net_device *dev, int isup) -{ - struct s6gmac *pd = netdev_priv(dev); - struct phy_device *phydev = pd->phydev; - - pd->link.full = phydev->duplex; - pd->link.giga = (phydev->speed == 1000); - if (pd->link.mbit != phydev->speed) { - pd->link.mbit = phydev->speed; - s6gmac_set_rgmii_txclock(pd); - } - pd->link.isup = isup; - if (isup) - netif_carrier_on(dev); - phy_print_status(phydev); -} - -static void s6gmac_adjust_link(struct net_device *dev) -{ - struct s6gmac *pd = netdev_priv(dev); - struct phy_device *phydev = pd->phydev; - if (pd->link.isup && - (!phydev->link || - (pd->link.mbit != phydev->speed) || - (pd->link.full != phydev->duplex))) { - pd->link.isup = 0; - netif_tx_disable(dev); - if (!phydev->link) { - netif_carrier_off(dev); - phy_print_status(phydev); - } - } - if (!pd->link.isup && phydev->link) { - if (pd->link.full != phydev->duplex) { - u32 maccfg = readl(pd->reg + S6_GMAC_MACCONF2); - if (phydev->duplex) - maccfg |= 1 << S6_GMAC_MACCONF2_FULL; - else - maccfg &= ~(1 << S6_GMAC_MACCONF2_FULL); - writel(maccfg, pd->reg + S6_GMAC_MACCONF2); - } - - if (pd->link.giga != (phydev->speed == 1000)) { - u32 fifocfg = readl(pd->reg + S6_GMAC_FIFOCONF5); - u32 maccfg = readl(pd->reg + S6_GMAC_MACCONF2); - maccfg &= ~(S6_GMAC_MACCONF2_IFMODE_MASK - << S6_GMAC_MACCONF2_IFMODE); - if (phydev->speed == 1000) { - fifocfg |= 1 << S6_GMAC_FIFOCONF5_CFGBYTM; - maccfg |= S6_GMAC_MACCONF2_IFMODE_BYTE - << S6_GMAC_MACCONF2_IFMODE; - } else { - fifocfg &= ~(1 << S6_GMAC_FIFOCONF5_CFGBYTM); - maccfg |= S6_GMAC_MACCONF2_IFMODE_NIBBLE - << S6_GMAC_MACCONF2_IFMODE; - } - writel(fifocfg, pd->reg + S6_GMAC_FIFOCONF5); - writel(maccfg, pd->reg + S6_GMAC_MACCONF2); - } - - if (!s6dmac_fifo_full(pd->tx_dma, pd->tx_chan)) - netif_wake_queue(dev); - s6gmac_linkisup(dev, 1); - } -} - -static inline int s6gmac_phy_start(struct net_device *dev) -{ - struct s6gmac *pd = netdev_priv(dev); - int i = 0; - struct phy_device *p = NULL; - while ((i < PHY_MAX_ADDR) && (!(p = pd->mii.bus->phy_map[i]))) - i++; - p = phy_connect(dev, dev_name(&p->dev), &s6gmac_adjust_link, - PHY_INTERFACE_MODE_RGMII); - if (IS_ERR(p)) { - printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); - return PTR_ERR(p); - } - p->supported &= PHY_GBIT_FEATURES; - p->advertising = p->supported; - pd->phydev = p; - return 0; -} - -static inline void s6gmac_init_stats(struct net_device *dev) -{ - struct s6gmac *pd = netdev_priv(dev); - u32 mask; - mask = 1 << S6_GMAC_STATCARRY1_RDRP | - 1 << S6_GMAC_STATCARRY1_RJBR | - 1 << S6_GMAC_STATCARRY1_RFRG | - 1 << S6_GMAC_STATCARRY1_ROVR | - 1 << S6_GMAC_STATCARRY1_RUND | - 1 << S6_GMAC_STATCARRY1_RCDE | - 1 << S6_GMAC_STATCARRY1_RFLR | - 1 << S6_GMAC_STATCARRY1_RALN | - 1 << S6_GMAC_STATCARRY1_RMCA | - 1 << S6_GMAC_STATCARRY1_RFCS | - 1 << S6_GMAC_STATCARRY1_RPKT | - 1 << S6_GMAC_STATCARRY1_RBYT; - writel(mask, pd->reg + S6_GMAC_STATCARRY(0)); - writel(~mask, pd->reg + S6_GMAC_STATCARRYMSK(0)); - mask = 1 << S6_GMAC_STATCARRY2_TDRP | - 1 << S6_GMAC_STATCARRY2_TNCL | - 1 << S6_GMAC_STATCARRY2_TXCL | - 1 << S6_GMAC_STATCARRY2_TEDF | - 1 << S6_GMAC_STATCARRY2_TPKT | - 1 << S6_GMAC_STATCARRY2_TBYT | - 1 << S6_GMAC_STATCARRY2_TFRG | - 1 << S6_GMAC_STATCARRY2_TUND | - 1 << S6_GMAC_STATCARRY2_TOVR | - 1 << S6_GMAC_STATCARRY2_TFCS | - 1 << S6_GMAC_STATCARRY2_TJBR; - writel(mask, pd->reg + S6_GMAC_STATCARRY(1)); - writel(~mask, pd->reg + S6_GMAC_STATCARRYMSK(1)); -} - -static inline void s6gmac_init_dmac(struct net_device *dev) -{ - struct s6gmac *pd = netdev_priv(dev); - s6dmac_disable_chan(pd->tx_dma, pd->tx_chan); - s6dmac_disable_chan(pd->rx_dma, pd->rx_chan); - s6dmac_disable_error_irqs(pd->tx_dma, 1 << S6_HIFDMA_GMACTX); - s6dmac_disable_error_irqs(pd->rx_dma, 1 << S6_HIFDMA_GMACRX); -} - -static int s6gmac_tx(struct sk_buff *skb, struct net_device *dev) -{ - struct s6gmac *pd = netdev_priv(dev); - unsigned long flags; - - spin_lock_irqsave(&pd->lock, flags); - writel(skb->len << S6_GMAC_BURST_PREWR_LEN | - 0 << S6_GMAC_BURST_PREWR_CFE | - 1 << S6_GMAC_BURST_PREWR_PPE | - 1 << S6_GMAC_BURST_PREWR_FCS | - ((skb->len < ETH_ZLEN) ? 1 : 0) << S6_GMAC_BURST_PREWR_PAD, - pd->reg + S6_GMAC_BURST_PREWR); - s6dmac_put_fifo_cache(pd->tx_dma, pd->tx_chan, - (u32)skb->data, pd->io, skb->len); - if (s6dmac_fifo_full(pd->tx_dma, pd->tx_chan)) - netif_stop_queue(dev); - if (((u8)(pd->tx_skb_i - pd->tx_skb_o)) >= S6_NUM_TX_SKB) { - printk(KERN_ERR "GMAC BUG: skb tx ring overflow [%x, %x]\n", - pd->tx_skb_o, pd->tx_skb_i); - BUG(); - } - pd->tx_skb[(pd->tx_skb_i++) % S6_NUM_TX_SKB] = skb; - spin_unlock_irqrestore(&pd->lock, flags); - return 0; -} - -static void s6gmac_tx_timeout(struct net_device *dev) -{ - struct s6gmac *pd = netdev_priv(dev); - unsigned long flags; - spin_lock_irqsave(&pd->lock, flags); - s6gmac_tx_interrupt(dev); - spin_unlock_irqrestore(&pd->lock, flags); -} - -static int s6gmac_open(struct net_device *dev) -{ - struct s6gmac *pd = netdev_priv(dev); - unsigned long flags; - phy_read_status(pd->phydev); - spin_lock_irqsave(&pd->lock, flags); - pd->link.mbit = 0; - s6gmac_linkisup(dev, pd->phydev->link); - s6gmac_init_device(dev); - s6gmac_init_stats(dev); - s6gmac_init_dmac(dev); - s6gmac_rx_fillfifo(dev); - s6dmac_enable_chan(pd->rx_dma, pd->rx_chan, - 2, 1, 0, 1, 0, 0, 0, 7, -1, 2, 0, 1); - s6dmac_enable_chan(pd->tx_dma, pd->tx_chan, - 2, 0, 1, 0, 0, 0, 0, 7, -1, 2, 0, 1); - writel(0 << S6_GMAC_HOST_INT_TXBURSTOVER | - 0 << S6_GMAC_HOST_INT_TXPREWOVER | - 0 << S6_GMAC_HOST_INT_RXBURSTUNDER | - 0 << S6_GMAC_HOST_INT_RXPOSTRFULL | - 0 << S6_GMAC_HOST_INT_RXPOSTRUNDER, - pd->reg + S6_GMAC_HOST_INTMASK); - spin_unlock_irqrestore(&pd->lock, flags); - phy_start(pd->phydev); - netif_start_queue(dev); - return 0; -} - -static int s6gmac_stop(struct net_device *dev) -{ - struct s6gmac *pd = netdev_priv(dev); - unsigned long flags; - netif_stop_queue(dev); - phy_stop(pd->phydev); - spin_lock_irqsave(&pd->lock, flags); - s6gmac_init_dmac(dev); - s6gmac_stop_device(dev); - while (pd->tx_skb_i != pd->tx_skb_o) - dev_kfree_skb(pd->tx_skb[(pd->tx_skb_o++) % S6_NUM_TX_SKB]); - while (pd->rx_skb_i != pd->rx_skb_o) - dev_kfree_skb(pd->rx_skb[(pd->rx_skb_o++) % S6_NUM_RX_SKB]); - spin_unlock_irqrestore(&pd->lock, flags); - return 0; -} - -static struct net_device_stats *s6gmac_stats(struct net_device *dev) -{ - struct s6gmac *pd = netdev_priv(dev); - struct net_device_stats *st = (struct net_device_stats *)&pd->stats; - int i; - do { - unsigned long flags; - spin_lock_irqsave(&pd->lock, flags); - for (i = 0; i < ARRAY_SIZE(pd->stats); i++) - pd->stats[i] = - pd->carry[i] << (S6_GMAC_STAT_SIZE_MIN - 1); - s6gmac_stats_collect(pd, &statinf[0][0]); - s6gmac_stats_collect(pd, &statinf[1][0]); - i = s6gmac_stats_pending(pd, 0) | - s6gmac_stats_pending(pd, 1); - spin_unlock_irqrestore(&pd->lock, flags); - } while (i); - st->rx_errors = st->rx_crc_errors + - st->rx_frame_errors + - st->rx_length_errors + - st->rx_missed_errors; - st->tx_errors += st->tx_aborted_errors; - return st; -} - -static int s6gmac_probe(struct platform_device *pdev) -{ - struct net_device *dev; - struct s6gmac *pd; - int res; - unsigned long i; - struct mii_bus *mb; - - dev = alloc_etherdev(sizeof(*pd)); - if (!dev) - return -ENOMEM; - - dev->open = s6gmac_open; - dev->stop = s6gmac_stop; - dev->hard_start_xmit = s6gmac_tx; - dev->tx_timeout = s6gmac_tx_timeout; - dev->watchdog_timeo = HZ; - dev->get_stats = s6gmac_stats; - dev->irq = platform_get_irq(pdev, 0); - pd = netdev_priv(dev); - memset(pd, 0, sizeof(*pd)); - spin_lock_init(&pd->lock); - pd->reg = platform_get_resource(pdev, IORESOURCE_MEM, 0)->start; - i = platform_get_resource(pdev, IORESOURCE_DMA, 0)->start; - pd->tx_dma = DMA_MASK_DMAC(i); - pd->tx_chan = DMA_INDEX_CHNL(i); - i = platform_get_resource(pdev, IORESOURCE_DMA, 1)->start; - pd->rx_dma = DMA_MASK_DMAC(i); - pd->rx_chan = DMA_INDEX_CHNL(i); - pd->io = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; - res = request_irq(dev->irq, s6gmac_interrupt, 0, dev->name, dev); - if (res) { - printk(KERN_ERR DRV_PRMT "irq request failed: %d\n", dev->irq); - goto errirq; - } - res = register_netdev(dev); - if (res) { - printk(KERN_ERR DRV_PRMT "error registering device %s\n", - dev->name); - goto errdev; - } - mb = mdiobus_alloc(); - if (!mb) { - printk(KERN_ERR DRV_PRMT "error allocating mii bus\n"); - res = -ENOMEM; - goto errmii; - } - mb->name = "s6gmac_mii"; - mb->read = s6mii_read; - mb->write = s6mii_write; - mb->reset = s6mii_reset; - mb->priv = pd; - snprintf(mb->id, MII_BUS_ID_SIZE, "%s-%x", pdev->name, pdev->id); - mb->phy_mask = ~(1 << 0); - mb->irq = &pd->mii.irq[0]; - for (i = 0; i < PHY_MAX_ADDR; i++) { - int n = platform_get_irq(pdev, i + 1); - if (n < 0) - n = PHY_POLL; - pd->mii.irq[i] = n; - } - mdiobus_register(mb); - pd->mii.bus = mb; - res = s6gmac_phy_start(dev); - if (res) - return res; - platform_set_drvdata(pdev, dev); - return 0; -errmii: - unregister_netdev(dev); -errdev: - free_irq(dev->irq, dev); -errirq: - free_netdev(dev); - return res; -} - -static int s6gmac_remove(struct platform_device *pdev) -{ - struct net_device *dev = platform_get_drvdata(pdev); - if (dev) { - struct s6gmac *pd = netdev_priv(dev); - mdiobus_unregister(pd->mii.bus); - unregister_netdev(dev); - free_irq(dev->irq, dev); - free_netdev(dev); - } - return 0; -} - -static struct platform_driver s6gmac_driver = { - .probe = s6gmac_probe, - .remove = s6gmac_remove, - .driver = { - .name = "s6gmac", - }, -}; - -module_platform_driver(s6gmac_driver); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("S6105 on chip Ethernet driver"); -MODULE_AUTHOR("Oskar Schirmer <oskar@scara.com>"); diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c index 698494481d18..b1a271853d85 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c @@ -474,13 +474,19 @@ static int init_rx_ring(struct net_device *dev, u8 queue_no, /* allocate memory for RX skbuff array */ rx_ring->rx_skbuff_dma = kmalloc_array(rx_rsize, sizeof(dma_addr_t), GFP_KERNEL); - if (rx_ring->rx_skbuff_dma == NULL) - goto dmamem_err; + if (!rx_ring->rx_skbuff_dma) { + dma_free_coherent(priv->device, + rx_rsize * sizeof(struct sxgbe_rx_norm_desc), + rx_ring->dma_rx, rx_ring->dma_rx_phy); + goto error; + } rx_ring->rx_skbuff = kmalloc_array(rx_rsize, sizeof(struct sk_buff *), GFP_KERNEL); - if (rx_ring->rx_skbuff == NULL) - goto rxbuff_err; + if (!rx_ring->rx_skbuff) { + kfree(rx_ring->rx_skbuff_dma); + goto error; + } /* initialise the buffers */ for (desc_index = 0; desc_index < rx_rsize; desc_index++) { @@ -502,13 +508,6 @@ static int init_rx_ring(struct net_device *dev, u8 queue_no, err_init_rx_buffers: while (--desc_index >= 0) free_rx_ring(priv->device, rx_ring, desc_index); - kfree(rx_ring->rx_skbuff); -rxbuff_err: - kfree(rx_ring->rx_skbuff_dma); -dmamem_err: - dma_free_coherent(priv->device, - rx_rsize * sizeof(struct sxgbe_rx_norm_desc), - rx_ring->dma_rx, rx_ring->dma_rx_phy); error: return -ENOMEM; } diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c index 866560ea9e18..b02eed12bfc5 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c @@ -108,10 +108,6 @@ static int sxgbe_platform_probe(struct platform_device *pdev) } } - /* Get MAC address if available (DT) */ - if (mac) - ether_addr_copy(priv->dev->dev_addr, mac); - priv = sxgbe_drv_probe(&(pdev->dev), plat_dat, addr); if (!priv) { pr_err("%s: main driver probe failed\n", __func__); @@ -125,6 +121,10 @@ static int sxgbe_platform_probe(struct platform_device *pdev) goto err_drv_remove; } + /* Get MAC address if available (DT) */ + if (mac) + ether_addr_copy(priv->dev->dev_addr, mac); + /* Get the TX/RX IRQ numbers */ for (i = 0, chan = 1; i < SXGBE_TX_QUEUES; i++) { priv->txq[i]->irq_no = irq_of_parse_and_map(node, chan++); diff --git a/drivers/net/ethernet/smsc/Kconfig b/drivers/net/ethernet/smsc/Kconfig index 627926800ff3..9468e64e6007 100644 --- a/drivers/net/ethernet/smsc/Kconfig +++ b/drivers/net/ethernet/smsc/Kconfig @@ -39,7 +39,7 @@ config SMC91X select CRC32 select MII depends on (ARM || M32R || SUPERH || MIPS || BLACKFIN || \ - MN10300 || COLDFIRE || ARM64 || XTENSA || NIOS2) + MN10300 || COLDFIRE || ARM64 || XTENSA || NIOS2) && (!OF || GPIOLIB) ---help--- This is a driver for SMC's 91x series of Ethernet chipsets, including the SMC91C94 and the SMC91C111. Say Y if you want it diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c index 0e137751e76e..056b358b4a72 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c @@ -309,16 +309,16 @@ static int sti_dwmac_parse_data(struct sti_dwmac *dwmac, if (IS_PHY_IF_MODE_GBIT(dwmac->interface)) { const char *rs; - dwmac->tx_retime_src = TX_RETIME_SRC_CLKGEN; err = of_property_read_string(np, "st,tx-retime-src", &rs); - if (err < 0) + if (err < 0) { dev_warn(dev, "Use internal clock source\n"); - - if (!strcasecmp(rs, "clk_125")) + dwmac->tx_retime_src = TX_RETIME_SRC_CLKGEN; + } else if (!strcasecmp(rs, "clk_125")) { dwmac->tx_retime_src = TX_RETIME_SRC_CLK_125; - else if (!strcasecmp(rs, "txclk")) + } else if (!strcasecmp(rs, "txclk")) { dwmac->tx_retime_src = TX_RETIME_SRC_TXCLK; + } dwmac->speed = SPEED_1000; } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 118a427d1942..8c6b7c1651e5 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1671,7 +1671,7 @@ static void stmmac_init_tx_coalesce(struct stmmac_priv *priv) * 0 on success and an appropriate (-)ve integer as defined in errno.h * file on failure. */ -static int stmmac_hw_setup(struct net_device *dev) +static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) { struct stmmac_priv *priv = netdev_priv(dev); int ret; @@ -1708,9 +1708,11 @@ static int stmmac_hw_setup(struct net_device *dev) stmmac_mmc_setup(priv); - ret = stmmac_init_ptp(priv); - if (ret && ret != -EOPNOTSUPP) - pr_warn("%s: failed PTP initialisation\n", __func__); + if (init_ptp) { + ret = stmmac_init_ptp(priv); + if (ret && ret != -EOPNOTSUPP) + pr_warn("%s: failed PTP initialisation\n", __func__); + } #ifdef CONFIG_DEBUG_FS ret = stmmac_init_fs(dev); @@ -1787,7 +1789,7 @@ static int stmmac_open(struct net_device *dev) goto init_error; } - ret = stmmac_hw_setup(dev); + ret = stmmac_hw_setup(dev, true); if (ret < 0) { pr_err("%s: Hw setup failed\n", __func__); goto init_error; @@ -3036,7 +3038,7 @@ int stmmac_resume(struct net_device *ndev) netif_device_attach(ndev); init_dma_desc_rings(ndev, GFP_ATOMIC); - stmmac_hw_setup(ndev); + stmmac_hw_setup(ndev, false); stmmac_init_tx_coalesce(priv); napi_enable(&priv->napi); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 4032b170fe24..3039de2465ba 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -430,7 +430,6 @@ static struct platform_driver stmmac_pltfr_driver = { .remove = stmmac_pltfr_remove, .driver = { .name = STMMAC_RESOURCE_NAME, - .owner = THIS_MODULE, .pm = &stmmac_pltfr_pm_ops, .of_match_table = of_match_ptr(stmmac_dt_ids), }, diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index 45c408ef67d0..d2835bf7b4fb 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -1201,6 +1201,7 @@ static int vnet_handle_offloads(struct vnet_port *port, struct sk_buff *skb) segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO); if (IS_ERR(segs)) { dev->stats.tx_dropped++; + dev_kfree_skb_any(skb); return NETDEV_TX_OK; } diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index c560f9aeb55d..e068d48b0f21 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -610,7 +610,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable) /* Clear all mcast from ALE */ cpsw_ale_flush_multicast(ale, ALE_ALL_PORTS << - priv->host_port); + priv->host_port, -1); /* Flood All Unicast Packets to Host port */ cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 1); @@ -634,6 +634,12 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable) static void cpsw_ndo_set_rx_mode(struct net_device *ndev) { struct cpsw_priv *priv = netdev_priv(ndev); + int vid; + + if (priv->data.dual_emac) + vid = priv->slaves[priv->emac_port].port_vlan; + else + vid = priv->data.default_vlan; if (ndev->flags & IFF_PROMISC) { /* Enable promiscuous mode */ @@ -649,7 +655,8 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev) cpsw_ale_set_allmulti(priv->ale, priv->ndev->flags & IFF_ALLMULTI); /* Clear all mcast from ALE */ - cpsw_ale_flush_multicast(priv->ale, ALE_ALL_PORTS << priv->host_port); + cpsw_ale_flush_multicast(priv->ale, ALE_ALL_PORTS << priv->host_port, + vid); if (!netdev_mc_empty(ndev)) { struct netdev_hw_addr *ha; @@ -757,6 +764,14 @@ requeue: static irqreturn_t cpsw_interrupt(int irq, void *dev_id) { struct cpsw_priv *priv = dev_id; + int value = irq - priv->irqs_table[0]; + + /* NOTICE: Ending IRQ here. The trick with the 'value' variable above + * is to make sure we will always write the correct value to the EOI + * register. Namely 0 for RX_THRESH Interrupt, 1 for RX Interrupt, 2 + * for TX Interrupt and 3 for MISC Interrupt. + */ + cpdma_ctlr_eoi(priv->dma, value); cpsw_intr_disable(priv); if (priv->irq_enabled == true) { @@ -786,8 +801,6 @@ static int cpsw_poll(struct napi_struct *napi, int budget) int num_tx, num_rx; num_tx = cpdma_chan_process(priv->txch, 128); - if (num_tx) - cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); num_rx = cpdma_chan_process(priv->rxch, budget); if (num_rx < budget) { @@ -795,7 +808,6 @@ static int cpsw_poll(struct napi_struct *napi, int budget) napi_complete(napi); cpsw_intr_enable(priv); - cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); prim_cpsw = cpsw_get_slave_priv(priv, 0); if (prim_cpsw->irq_enabled == false) { prim_cpsw->irq_enabled = true; @@ -1310,8 +1322,6 @@ static int cpsw_ndo_open(struct net_device *ndev) napi_enable(&priv->napi); cpdma_ctlr_start(priv->dma); cpsw_intr_enable(priv); - cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); - cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); prim_cpsw = cpsw_get_slave_priv(priv, 0); if (prim_cpsw->irq_enabled == false) { @@ -1578,9 +1588,6 @@ static void cpsw_ndo_tx_timeout(struct net_device *ndev) cpdma_chan_start(priv->txch); cpdma_ctlr_int_ctrl(priv->dma, true); cpsw_intr_enable(priv); - cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); - cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); - } static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p) @@ -1620,9 +1627,6 @@ static void cpsw_ndo_poll_controller(struct net_device *ndev) cpsw_interrupt(ndev->irq, priv); cpdma_ctlr_int_ctrl(priv->dma, true); cpsw_intr_enable(priv); - cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); - cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); - } #endif @@ -1630,16 +1634,24 @@ static inline int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv, unsigned short vid) { int ret; - int unreg_mcast_mask; + int unreg_mcast_mask = 0; + u32 port_mask; - if (priv->ndev->flags & IFF_ALLMULTI) - unreg_mcast_mask = ALE_ALL_PORTS; - else - unreg_mcast_mask = ALE_PORT_1 | ALE_PORT_2; + if (priv->data.dual_emac) { + port_mask = (1 << (priv->emac_port + 1)) | ALE_PORT_HOST; + + if (priv->ndev->flags & IFF_ALLMULTI) + unreg_mcast_mask = port_mask; + } else { + port_mask = ALE_ALL_PORTS; + + if (priv->ndev->flags & IFF_ALLMULTI) + unreg_mcast_mask = ALE_ALL_PORTS; + else + unreg_mcast_mask = ALE_PORT_1 | ALE_PORT_2; + } - ret = cpsw_ale_add_vlan(priv->ale, vid, - ALE_ALL_PORTS << priv->host_port, - 0, ALE_ALL_PORTS << priv->host_port, + ret = cpsw_ale_add_vlan(priv->ale, vid, port_mask, 0, port_mask, unreg_mcast_mask << priv->host_port); if (ret != 0) return ret; @@ -1650,8 +1662,7 @@ static inline int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv, goto clean_vid; ret = cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, - ALE_ALL_PORTS << priv->host_port, - ALE_VLAN, vid, 0); + port_mask, ALE_VLAN, vid, 0); if (ret != 0) goto clean_vlan_ucast; return 0; diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c index 097ebe7077ac..5246b3a18ff8 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.c +++ b/drivers/net/ethernet/ti/cpsw_ale.c @@ -234,7 +234,7 @@ static void cpsw_ale_flush_mcast(struct cpsw_ale *ale, u32 *ale_entry, cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); } -int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask) +int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid) { u32 ale_entry[ALE_ENTRY_WORDS]; int ret, idx; @@ -245,6 +245,14 @@ int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask) if (ret != ALE_TYPE_ADDR && ret != ALE_TYPE_VLAN_ADDR) continue; + /* if vid passed is -1 then remove all multicast entry from + * the table irrespective of vlan id, if a valid vlan id is + * passed then remove only multicast added to that vlan id. + * if vlan id doesn't match then move on to next entry. + */ + if (vid != -1 && cpsw_ale_get_vlan_id(ale_entry) != vid) + continue; + if (cpsw_ale_get_mcast(ale_entry)) { u8 addr[6]; diff --git a/drivers/net/ethernet/ti/cpsw_ale.h b/drivers/net/ethernet/ti/cpsw_ale.h index c0d4127aa549..af1e7ecd87c6 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.h +++ b/drivers/net/ethernet/ti/cpsw_ale.h @@ -92,7 +92,7 @@ void cpsw_ale_stop(struct cpsw_ale *ale); int cpsw_ale_set_ageout(struct cpsw_ale *ale, int ageout); int cpsw_ale_flush(struct cpsw_ale *ale, int port_mask); -int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask); +int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid); int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port, int flags, u16 vid); int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port, diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index ea712512c7d1..5fae4354722c 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -62,6 +62,7 @@ #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_device.h> +#include <linux/of_mdio.h> #include <linux/of_irq.h> #include <linux/of_net.h> @@ -343,9 +344,7 @@ struct emac_priv { u32 multicast_hash_cnt[EMAC_NUM_MULTICAST_BITS]; u32 rx_addr_type; const char *phy_id; -#ifdef CONFIG_OF struct device_node *phy_node; -#endif struct phy_device *phydev; spinlock_t lock; /*platform specific members*/ @@ -922,6 +921,16 @@ static void emac_int_disable(struct emac_priv *priv) if (priv->int_disable) priv->int_disable(); + /* NOTE: Rx Threshold and Misc interrupts are not enabled */ + + /* ack rxen only then a new pulse will be generated */ + emac_write(EMAC_DM646X_MACEOIVECTOR, + EMAC_DM646X_MAC_EOI_C0_RXEN); + + /* ack txen- only then a new pulse will be generated */ + emac_write(EMAC_DM646X_MACEOIVECTOR, + EMAC_DM646X_MAC_EOI_C0_TXEN); + local_irq_restore(flags); } else { @@ -951,15 +960,6 @@ static void emac_int_enable(struct emac_priv *priv) * register */ /* NOTE: Rx Threshold and Misc interrupts are not enabled */ - - /* ack rxen only then a new pulse will be generated */ - emac_write(EMAC_DM646X_MACEOIVECTOR, - EMAC_DM646X_MAC_EOI_C0_RXEN); - - /* ack txen- only then a new pulse will be generated */ - emac_write(EMAC_DM646X_MACEOIVECTOR, - EMAC_DM646X_MAC_EOI_C0_TXEN); - } else { /* Set DM644x control registers for interrupt control */ emac_ctrl_write(EMAC_CTRL_EWCTL, 0x1); @@ -1537,7 +1537,13 @@ static int emac_dev_open(struct net_device *ndev) int i = 0; struct emac_priv *priv = netdev_priv(ndev); - pm_runtime_get(&priv->pdev->dev); + ret = pm_runtime_get_sync(&priv->pdev->dev); + if (ret < 0) { + pm_runtime_put_noidle(&priv->pdev->dev); + dev_err(&priv->pdev->dev, "%s: failed to get_sync(%d)\n", + __func__, ret); + return ret; + } netif_carrier_off(ndev); for (cnt = 0; cnt < ETH_ALEN; cnt++) @@ -1596,8 +1602,20 @@ static int emac_dev_open(struct net_device *ndev) cpdma_ctlr_start(priv->dma); priv->phydev = NULL; + + if (priv->phy_node) { + priv->phydev = of_phy_connect(ndev, priv->phy_node, + &emac_adjust_link, 0, 0); + if (!priv->phydev) { + dev_err(emac_dev, "could not connect to phy %s\n", + priv->phy_node->full_name); + ret = -ENODEV; + goto err; + } + } + /* use the first phy on the bus if pdata did not give us a phy id */ - if (!priv->phy_id) { + if (!priv->phydev && !priv->phy_id) { struct device *phy; phy = bus_find_device(&mdio_bus_type, NULL, NULL, @@ -1606,7 +1624,7 @@ static int emac_dev_open(struct net_device *ndev) priv->phy_id = dev_name(phy); } - if (priv->phy_id && *priv->phy_id) { + if (!priv->phydev && priv->phy_id && *priv->phy_id) { priv->phydev = phy_connect(ndev, priv->phy_id, &emac_adjust_link, PHY_INTERFACE_MODE_MII); @@ -1627,7 +1645,9 @@ static int emac_dev_open(struct net_device *ndev) "(mii_bus:phy_addr=%s, id=%x)\n", priv->phydev->drv->name, dev_name(&priv->phydev->dev), priv->phydev->phy_id); - } else { + } + + if (!priv->phydev) { /* No PHY , fix the link, speed and duplex settings */ dev_notice(emac_dev, "no phy, defaulting to 100/full\n"); priv->link = 1; @@ -1724,6 +1744,15 @@ static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev) struct emac_priv *priv = netdev_priv(ndev); u32 mac_control; u32 stats_clear_mask; + int err; + + err = pm_runtime_get_sync(&priv->pdev->dev); + if (err < 0) { + pm_runtime_put_noidle(&priv->pdev->dev); + dev_err(&priv->pdev->dev, "%s: failed to get_sync(%d)\n", + __func__, err); + return &ndev->stats; + } /* update emac hardware stats and reset the registers*/ @@ -1766,6 +1795,8 @@ static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev) ndev->stats.tx_fifo_errors += emac_read(EMAC_TXUNDERRUN); emac_write(EMAC_TXUNDERRUN, stats_clear_mask); + pm_runtime_put(&priv->pdev->dev); + return &ndev->stats; } @@ -1859,7 +1890,7 @@ davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv) static int davinci_emac_probe(struct platform_device *pdev) { int rc = 0; - struct resource *res; + struct resource *res, *res_ctrl; struct net_device *ndev; struct emac_priv *priv; unsigned long hw_ram_addr; @@ -1876,6 +1907,7 @@ static int davinci_emac_probe(struct platform_device *pdev) return -EBUSY; } emac_bus_frequency = clk_get_rate(emac_clk); + devm_clk_put(&pdev->dev, emac_clk); /* TODO: Probe PHY here if possible */ @@ -1917,11 +1949,20 @@ static int davinci_emac_probe(struct platform_device *pdev) rc = PTR_ERR(priv->remap_addr); goto no_pdata; } + + res_ctrl = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (res_ctrl) { + priv->ctrl_base = + devm_ioremap_resource(&pdev->dev, res_ctrl); + if (IS_ERR(priv->ctrl_base)) + goto no_pdata; + } else { + priv->ctrl_base = priv->remap_addr + pdata->ctrl_mod_reg_offset; + } + priv->emac_base = priv->remap_addr + pdata->ctrl_reg_offset; ndev->base_addr = (unsigned long)priv->remap_addr; - priv->ctrl_base = priv->remap_addr + pdata->ctrl_mod_reg_offset; - hw_ram_addr = pdata->hw_ram_addr; if (!hw_ram_addr) hw_ram_addr = (u32 __force)res->start + pdata->ctrl_ram_offset; @@ -1980,12 +2021,22 @@ static int davinci_emac_probe(struct platform_device *pdev) ndev->ethtool_ops = ðtool_ops; netif_napi_add(ndev, &priv->napi, emac_poll, EMAC_POLL_WEIGHT); + pm_runtime_enable(&pdev->dev); + rc = pm_runtime_get_sync(&pdev->dev); + if (rc < 0) { + pm_runtime_put_noidle(&pdev->dev); + dev_err(&pdev->dev, "%s: failed to get_sync(%d)\n", + __func__, rc); + goto no_cpdma_chan; + } + /* register the network device */ SET_NETDEV_DEV(ndev, &pdev->dev); rc = register_netdev(ndev); if (rc) { dev_err(&pdev->dev, "error in register_netdev\n"); rc = -ENODEV; + pm_runtime_put(&pdev->dev); goto no_cpdma_chan; } @@ -1995,9 +2046,7 @@ static int davinci_emac_probe(struct platform_device *pdev) "(regs: %p, irq: %d)\n", (void *)priv->emac_base_phys, ndev->irq); } - - pm_runtime_enable(&pdev->dev); - pm_runtime_resume(&pdev->dev); + pm_runtime_put(&pdev->dev); return 0; @@ -2071,9 +2120,14 @@ static const struct emac_platform_data am3517_emac_data = { .hw_ram_addr = 0x01e20000, }; +static const struct emac_platform_data dm816_emac_data = { + .version = EMAC_VERSION_2, +}; + static const struct of_device_id davinci_emac_of_match[] = { {.compatible = "ti,davinci-dm6467-emac", }, {.compatible = "ti,am3517-emac", .data = &am3517_emac_data, }, + {.compatible = "ti,dm816-emac", .data = &dm816_emac_data, }, {}, }; MODULE_DEVICE_TABLE(of, davinci_emac_of_match); diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index 9c2d91ea0af4..dbcbf0c5bcfa 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -1043,6 +1043,7 @@ static int temac_of_probe(struct platform_device *op) lp->regs = of_iomap(op->dev.of_node, 0); if (!lp->regs) { dev_err(&op->dev, "could not map temac regs.\n"); + rc = -ENOMEM; goto nodev; } @@ -1062,6 +1063,7 @@ static int temac_of_probe(struct platform_device *op) np = of_parse_phandle(op->dev.of_node, "llink-connected", 0); if (!np) { dev_err(&op->dev, "could not find DMA node\n"); + rc = -ENODEV; goto err_iounmap; } diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h index 44b8d2bad8c3..4c9b4fa1d3c1 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet.h +++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h @@ -388,7 +388,6 @@ struct axidma_bd { * @dma_err_tasklet: Tasklet structure to process Axi DMA errors * @tx_irq: Axidma TX IRQ number * @rx_irq: Axidma RX IRQ number - * @temac_type: axienet type to identify between soft and hard temac * @phy_type: Phy type to identify between MII/GMII/RGMII/SGMII/1000 Base-X * @options: AxiEthernet option word * @last_link: Phy link state in which the PHY was negotiated earlier @@ -431,7 +430,6 @@ struct axienet_local { int tx_irq; int rx_irq; - u32 temac_type; u32 phy_type; u32 options; /* Current options word */ diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 4ea2d4e6f1d1..a6d2860b712c 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -1501,6 +1501,7 @@ static int axienet_of_probe(struct platform_device *op) lp->regs = of_iomap(op->dev.of_node, 0); if (!lp->regs) { dev_err(&op->dev, "could not map Axi Ethernet regs.\n"); + ret = -ENOMEM; goto nodev; } /* Setup checksum offload, but default to off if not specified */ @@ -1555,10 +1556,6 @@ static int axienet_of_probe(struct platform_device *op) if ((be32_to_cpup(p)) >= 0x4000) lp->jumbo_support = 1; } - p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,temac-type", - NULL); - if (p) - lp->temac_type = be32_to_cpup(p); p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,phy-type", NULL); if (p) lp->phy_type = be32_to_cpup(p); @@ -1567,6 +1564,7 @@ static int axienet_of_probe(struct platform_device *op) np = of_parse_phandle(op->dev.of_node, "axistream-connected", 0); if (!np) { dev_err(&op->dev, "could not find DMA node\n"); + ret = -ENODEV; goto err_iounmap; } lp->dma_regs = of_iomap(np, 0); diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c index 24858799c204..9d4ce388510a 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c @@ -1109,6 +1109,7 @@ static int xemaclite_of_probe(struct platform_device *ofdev) res = platform_get_resource(ofdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(dev, "no IRQ found\n"); + rc = -ENXIO; goto error; } diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index 2f48f790c9b4..384ca4f4de4a 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -590,6 +590,7 @@ struct nvsp_message { #define NETVSC_RECEIVE_BUFFER_ID 0xcafe +#define NETVSC_SEND_BUFFER_ID 0 #define NETVSC_PACKET_SIZE 4096 diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index dd867e6cabd6..9f49c0129a78 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -161,8 +161,8 @@ static int netvsc_destroy_buf(struct netvsc_device *net_device) /* Deal with the send buffer we may have setup. * If we got a send section size, it means we received a - * SendsendBufferComplete msg (ie sent - * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need + * NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE msg (ie sent + * NVSP_MSG1_TYPE_SEND_SEND_BUF msg) therefore, we need * to send a revoke msg here */ if (net_device->send_section_size) { @@ -172,7 +172,8 @@ static int netvsc_destroy_buf(struct netvsc_device *net_device) revoke_packet->hdr.msg_type = NVSP_MSG1_TYPE_REVOKE_SEND_BUF; - revoke_packet->msg.v1_msg.revoke_recv_buf.id = 0; + revoke_packet->msg.v1_msg.revoke_send_buf.id = + NETVSC_SEND_BUFFER_ID; ret = vmbus_sendpacket(net_device->dev->channel, revoke_packet, @@ -204,7 +205,7 @@ static int netvsc_destroy_buf(struct netvsc_device *net_device) net_device->send_buf_gpadl_handle = 0; } if (net_device->send_buf) { - /* Free up the receive buffer */ + /* Free up the send buffer */ vfree(net_device->send_buf); net_device->send_buf = NULL; } @@ -339,9 +340,9 @@ static int netvsc_init_buf(struct hv_device *device) init_packet = &net_device->channel_init_pkt; memset(init_packet, 0, sizeof(struct nvsp_message)); init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_SEND_BUF; - init_packet->msg.v1_msg.send_recv_buf.gpadl_handle = + init_packet->msg.v1_msg.send_send_buf.gpadl_handle = net_device->send_buf_gpadl_handle; - init_packet->msg.v1_msg.send_recv_buf.id = 0; + init_packet->msg.v1_msg.send_send_buf.id = NETVSC_SEND_BUFFER_ID; /* Send the gpadl notification request */ ret = vmbus_sendpacket(device->channel, init_packet, @@ -364,7 +365,7 @@ static int netvsc_init_buf(struct hv_device *device) netdev_err(ndev, "Unable to complete send buffer " "initialization with NetVsp - status %d\n", init_packet->msg.v1_msg. - send_recv_buf_complete.status); + send_send_buf_complete.status); ret = -EINVAL; goto cleanup; } diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 60f7ee5fafbe..7df221788cd4 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -46,16 +46,18 @@ struct macvtap_queue { struct list_head next; }; -#define MACVTAP_FEATURES (IFF_VNET_HDR | IFF_VNET_LE | IFF_MULTI_QUEUE) +#define MACVTAP_FEATURES (IFF_VNET_HDR | IFF_MULTI_QUEUE) + +#define MACVTAP_VNET_LE 0x80000000 static inline u16 macvtap16_to_cpu(struct macvtap_queue *q, __virtio16 val) { - return __virtio16_to_cpu(q->flags & IFF_VNET_LE, val); + return __virtio16_to_cpu(q->flags & MACVTAP_VNET_LE, val); } static inline __virtio16 cpu_to_macvtap16(struct macvtap_queue *q, u16 val) { - return __cpu_to_virtio16(q->flags & IFF_VNET_LE, val); + return __cpu_to_virtio16(q->flags & MACVTAP_VNET_LE, val); } static struct proto macvtap_proto = { @@ -999,7 +1001,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd, void __user *argp = (void __user *)arg; struct ifreq __user *ifr = argp; unsigned int __user *up = argp; - unsigned int u; + unsigned short u; int __user *sp = argp; int s; int ret; @@ -1014,7 +1016,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd, if ((u & ~MACVTAP_FEATURES) != (IFF_NO_PI | IFF_TAP)) ret = -EINVAL; else - q->flags = u; + q->flags = (q->flags & ~MACVTAP_FEATURES) | u; return ret; @@ -1027,8 +1029,9 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd, } ret = 0; + u = q->flags; if (copy_to_user(&ifr->ifr_name, vlan->dev->name, IFNAMSIZ) || - put_user(q->flags, &ifr->ifr_flags)) + put_user(u, &ifr->ifr_flags)) ret = -EFAULT; macvtap_put_vlan(vlan); rtnl_unlock(); @@ -1069,6 +1072,21 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd, q->vnet_hdr_sz = s; return 0; + case TUNGETVNETLE: + s = !!(q->flags & MACVTAP_VNET_LE); + if (put_user(s, sp)) + return -EFAULT; + return 0; + + case TUNSETVNETLE: + if (get_user(s, sp)) + return -EFAULT; + if (s) + q->flags |= MACVTAP_VNET_LE; + else + q->flags &= ~MACVTAP_VNET_LE; + return 0; + case TUNSETOFFLOAD: /* let the user check for future flags */ if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 | diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index b4b0f804e84c..a3c251b79f38 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -119,8 +119,8 @@ config MICREL_PHY Supports the KSZ9021, VSC8201, KS8001 PHYs. config FIXED_PHY - bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs" - depends on PHYLIB=y + tristate "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs" + depends on PHYLIB ---help--- Adds the platform "fixed" MDIO Bus to cover the boards that use PHYs that are not connected to the real MDIO bus. diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index eb3b18b5978b..501ea7699a2d 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -17,7 +17,7 @@ obj-$(CONFIG_BCM87XX_PHY) += bcm87xx.o obj-$(CONFIG_ICPLUS_PHY) += icplus.o obj-$(CONFIG_REALTEK_PHY) += realtek.o obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o -obj-$(CONFIG_FIXED_PHY) += fixed.o +obj-$(CONFIG_FIXED_PHY) += fixed_phy.o obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o obj-$(CONFIG_MDIO_GPIO) += mdio-gpio.o obj-$(CONFIG_NATIONAL_PHY) += national.o diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed_phy.c index 3ad0e6e16c39..3ad0e6e16c39 100644 --- a/drivers/net/phy/fixed.c +++ b/drivers/net/phy/fixed_phy.c diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index c530de1e63f5..3ad8ca76196d 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -88,6 +88,7 @@ struct kszphy_priv { static const struct kszphy_type ksz8021_type = { .led_mode_reg = MII_KSZPHY_CTRL_2, + .has_broadcast_disable = true, .has_rmii_ref_clk_sel = true, }; @@ -258,19 +259,6 @@ static int kszphy_config_init(struct phy_device *phydev) return 0; } -static int ksz8021_config_init(struct phy_device *phydev) -{ - int rc; - - rc = kszphy_config_init(phydev); - if (rc) - return rc; - - rc = kszphy_broadcast_disable(phydev); - - return rc < 0 ? rc : 0; -} - static int ksz9021_load_values_from_of(struct phy_device *phydev, struct device_node *of_node, u16 reg, char *field1, char *field2, @@ -584,7 +572,7 @@ static struct phy_driver ksphy_driver[] = { .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .driver_data = &ksz8021_type, .probe = kszphy_probe, - .config_init = ksz8021_config_init, + .config_init = kszphy_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, @@ -601,7 +589,7 @@ static struct phy_driver ksphy_driver[] = { .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .driver_data = &ksz8021_type, .probe = kszphy_probe, - .config_init = ksz8021_config_init, + .config_init = kszphy_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 93e224217e24..f7ff493f1e73 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -629,6 +629,7 @@ static int team_change_mode(struct team *team, const char *kind) static void team_notify_peers_work(struct work_struct *work) { struct team *team; + int val; team = container_of(work, struct team, notify_peers.dw.work); @@ -636,9 +637,14 @@ static void team_notify_peers_work(struct work_struct *work) schedule_delayed_work(&team->notify_peers.dw, 0); return; } + val = atomic_dec_if_positive(&team->notify_peers.count_pending); + if (val < 0) { + rtnl_unlock(); + return; + } call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, team->dev); rtnl_unlock(); - if (!atomic_dec_and_test(&team->notify_peers.count_pending)) + if (val) schedule_delayed_work(&team->notify_peers.dw, msecs_to_jiffies(team->notify_peers.interval)); } @@ -669,6 +675,7 @@ static void team_notify_peers_fini(struct team *team) static void team_mcast_rejoin_work(struct work_struct *work) { struct team *team; + int val; team = container_of(work, struct team, mcast_rejoin.dw.work); @@ -676,9 +683,14 @@ static void team_mcast_rejoin_work(struct work_struct *work) schedule_delayed_work(&team->mcast_rejoin.dw, 0); return; } + val = atomic_dec_if_positive(&team->mcast_rejoin.count_pending); + if (val < 0) { + rtnl_unlock(); + return; + } call_netdevice_notifiers(NETDEV_RESEND_IGMP, team->dev); rtnl_unlock(); - if (!atomic_dec_and_test(&team->mcast_rejoin.count_pending)) + if (val) schedule_delayed_work(&team->mcast_rejoin.dw, msecs_to_jiffies(team->mcast_rejoin.interval)); } diff --git a/drivers/net/tun.c b/drivers/net/tun.c index a5cbf67517f0..8c8dc16839a7 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -110,9 +110,11 @@ do { \ * overload it to mean fasync when stored there. */ #define TUN_FASYNC IFF_ATTACH_QUEUE +/* High bits in flags field are unused. */ +#define TUN_VNET_LE 0x80000000 #define TUN_FEATURES (IFF_NO_PI | IFF_ONE_QUEUE | IFF_VNET_HDR | \ - IFF_VNET_LE | IFF_MULTI_QUEUE) + IFF_MULTI_QUEUE) #define GOODCOPY_LEN 128 #define FLT_EXACT_COUNT 8 @@ -208,12 +210,12 @@ struct tun_struct { static inline u16 tun16_to_cpu(struct tun_struct *tun, __virtio16 val) { - return __virtio16_to_cpu(tun->flags & IFF_VNET_LE, val); + return __virtio16_to_cpu(tun->flags & TUN_VNET_LE, val); } static inline __virtio16 cpu_to_tun16(struct tun_struct *tun, u16 val) { - return __cpu_to_virtio16(tun->flags & IFF_VNET_LE, val); + return __cpu_to_virtio16(tun->flags & TUN_VNET_LE, val); } static inline u32 tun_hashfn(u32 rxhash) @@ -1843,6 +1845,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, int sndbuf; int vnet_hdr_sz; unsigned int ifindex; + int le; int ret; if (cmd == TUNSETIFF || cmd == TUNSETQUEUE || _IOC_TYPE(cmd) == 0x89) { @@ -2042,6 +2045,23 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, tun->vnet_hdr_sz = vnet_hdr_sz; break; + case TUNGETVNETLE: + le = !!(tun->flags & TUN_VNET_LE); + if (put_user(le, (int __user *)argp)) + ret = -EFAULT; + break; + + case TUNSETVNETLE: + if (get_user(le, (int __user *)argp)) { + ret = -EFAULT; + break; + } + if (le) + tun->flags |= TUN_VNET_LE; + else + tun->flags &= ~TUN_VNET_LE; + break; + case TUNATTACHFILTER: /* Can be set only for TAPs */ ret = -EINVAL; diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index dcb6d33141e0..1e9cdca37014 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c @@ -1276,7 +1276,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length) awd.done = 0; urb->context = &awd; - status = usb_submit_urb(urb, GFP_NOIO); + status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { // something went wrong usb_free_urb(urb); diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index b8a82b86f909..602dc6668c3a 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -56,6 +56,8 @@ struct qmi_wwan_state { /* default ethernet address used by the modem */ static const u8 default_modem_addr[ETH_ALEN] = {0x02, 0x50, 0xf3}; +static const u8 buggy_fw_addr[ETH_ALEN] = {0x00, 0xa0, 0xc6, 0x00, 0x00, 0x00}; + /* Make up an ethernet header if the packet doesn't have one. * * A firmware bug common among several devices cause them to send raw @@ -332,10 +334,12 @@ next_desc: usb_driver_release_interface(driver, info->data); } - /* Never use the same address on both ends of the link, even - * if the buggy firmware told us to. + /* Never use the same address on both ends of the link, even if the + * buggy firmware told us to. Or, if device is assigned the well-known + * buggy firmware MAC address, replace it with a random address, */ - if (ether_addr_equal(dev->net->dev_addr, default_modem_addr)) + if (ether_addr_equal(dev->net->dev_addr, default_modem_addr) || + ether_addr_equal(dev->net->dev_addr, buggy_fw_addr)) eth_hw_addr_random(dev->net); /* make MAC addr easily distinguishable from an IP header */ diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 2d1c77e81836..bf405f134d3a 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -833,9 +833,6 @@ static void ocp_write_word(struct r8152 *tp, u16 type, u16 index, u32 data) index &= ~3; } - generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); - - data |= __le32_to_cpu(tmp) & ~mask; tmp = __cpu_to_le32(data); generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type); @@ -874,9 +871,6 @@ static void ocp_write_byte(struct r8152 *tp, u16 type, u16 index, u32 data) index &= ~3; } - generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); - - data |= __le32_to_cpu(tmp) & ~mask; tmp = __cpu_to_le32(data); generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type); @@ -926,12 +920,6 @@ static void sram_write(struct r8152 *tp, u16 addr, u16 data) ocp_reg_write(tp, OCP_SRAM_DATA, data); } -static u16 sram_read(struct r8152 *tp, u16 addr) -{ - ocp_reg_write(tp, OCP_SRAM_ADDR, addr); - return ocp_reg_read(tp, OCP_SRAM_DATA); -} - static int read_mii_word(struct net_device *netdev, int phy_id, int reg) { struct r8152 *tp = netdev_priv(netdev); @@ -1897,6 +1885,22 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev) netif_wake_queue(netdev); } +static netdev_features_t +rtl8152_features_check(struct sk_buff *skb, struct net_device *dev, + netdev_features_t features) +{ + u32 mss = skb_shinfo(skb)->gso_size; + int max_offset = mss ? GTTCPHO_MAX : TCPHO_MAX; + int offset = skb_transport_offset(skb); + + if ((mss || skb->ip_summed == CHECKSUM_PARTIAL) && offset > max_offset) + features &= ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK); + else if ((skb->len + sizeof(struct tx_desc)) > agg_buf_sz) + features &= ~NETIF_F_GSO_MASK; + + return features; +} + static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, struct net_device *netdev) { @@ -2502,24 +2506,18 @@ static void r8153_hw_phy_cfg(struct r8152 *tp) data = ocp_reg_read(tp, OCP_POWER_CFG); data |= EN_10M_PLLOFF; ocp_reg_write(tp, OCP_POWER_CFG, data); - data = sram_read(tp, SRAM_IMPEDANCE); - data &= ~RX_DRIVING_MASK; - sram_write(tp, SRAM_IMPEDANCE, data); + sram_write(tp, SRAM_IMPEDANCE, 0x0b13); ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR); ocp_data |= PFM_PWM_SWITCH; ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); - data = sram_read(tp, SRAM_LPF_CFG); - data |= LPF_AUTO_TUNE; - sram_write(tp, SRAM_LPF_CFG, data); + /* Enable LPF corner auto tune */ + sram_write(tp, SRAM_LPF_CFG, 0xf70f); - data = sram_read(tp, SRAM_10M_AMP1); - data |= GDAC_IB_UPALL; - sram_write(tp, SRAM_10M_AMP1, data); - data = sram_read(tp, SRAM_10M_AMP2); - data |= AMP_DN; - sram_write(tp, SRAM_10M_AMP2, data); + /* Adjust 10M Amplitude */ + sram_write(tp, SRAM_10M_AMP1, 0x00af); + sram_write(tp, SRAM_10M_AMP2, 0x0208); set_bit(PHY_RESET, &tp->flags); } @@ -3706,6 +3704,7 @@ static const struct net_device_ops rtl8152_netdev_ops = { .ndo_set_mac_address = rtl8152_set_mac_address, .ndo_change_mtu = rtl8152_change_mtu, .ndo_validate_addr = eth_validate_addr, + .ndo_features_check = rtl8152_features_check, }; static void r8152b_get_version(struct r8152 *tp) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index b8bd7191572d..5ca97713bfb3 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -760,7 +760,6 @@ static int virtnet_poll(struct napi_struct *napi, int budget) container_of(napi, struct receive_queue, napi); unsigned int r, received = 0; -again: received += virtnet_receive(rq, budget - received); /* Out of packets? */ @@ -771,7 +770,6 @@ again: napi_schedule_prep(napi)) { virtqueue_disable_cb(rq->vq); __napi_schedule(napi); - goto again; } } diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 49d9f2291998..7fbd89fbe107 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -1579,8 +1579,10 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs, bool udp_sum = !udp_get_no_check6_tx(vs->sock->sk); skb = udp_tunnel_handle_offloads(skb, udp_sum); - if (IS_ERR(skb)) - return -EINVAL; + if (IS_ERR(skb)) { + err = -EINVAL; + goto err; + } skb_scrub_packet(skb, xnet); @@ -1590,12 +1592,16 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs, /* Need space for new headers (invalidates iph ptr) */ err = skb_cow_head(skb, min_headroom); - if (unlikely(err)) - return err; + if (unlikely(err)) { + kfree_skb(skb); + goto err; + } skb = vlan_hwaccel_push_inside(skb); - if (WARN_ON(!skb)) - return -ENOMEM; + if (WARN_ON(!skb)) { + err = -ENOMEM; + goto err; + } vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh)); vxh->vx_flags = htonl(VXLAN_FLAGS); @@ -1606,6 +1612,9 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs, udp_tunnel6_xmit_skb(vs->sock, dst, skb, dev, saddr, daddr, prio, ttl, src_port, dst_port); return 0; +err: + dst_release(dst); + return err; } #endif @@ -1621,7 +1630,7 @@ int vxlan_xmit_skb(struct vxlan_sock *vs, skb = udp_tunnel_handle_offloads(skb, udp_sum); if (IS_ERR(skb)) - return -EINVAL; + return PTR_ERR(skb); min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len + VXLAN_HLEN + sizeof(struct iphdr) @@ -1629,8 +1638,10 @@ int vxlan_xmit_skb(struct vxlan_sock *vs, /* Need space for new headers (invalidates iph ptr) */ err = skb_cow_head(skb, min_headroom); - if (unlikely(err)) + if (unlikely(err)) { + kfree_skb(skb); return err; + } skb = vlan_hwaccel_push_inside(skb); if (WARN_ON(!skb)) @@ -1776,9 +1787,12 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, tos, ttl, df, src_port, dst_port, htonl(vni << 8), !net_eq(vxlan->net, dev_net(vxlan->dev))); - - if (err < 0) + if (err < 0) { + /* skb is already freed. */ + skb = NULL; goto rt_tx_error; + } + iptunnel_xmit_stats(err, &dev->stats, dev->tstats); #if IS_ENABLED(CONFIG_IPV6) } else { diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 3c06e9365949..9880dae2a569 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -1070,7 +1070,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, */ if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) && ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) || - (sdiodev->pdata->oob_irq_supported))) + (sdiodev->pdata && sdiodev->pdata->oob_irq_supported))) bus_if->wowl_supported = true; #endif @@ -1167,7 +1167,7 @@ static int brcmf_ops_sdio_resume(struct device *dev) struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; brcmf_dbg(SDIO, "Enter\n"); - if (sdiodev->pdata->oob_irq_supported) + if (sdiodev->pdata && sdiodev->pdata->oob_irq_supported) disable_irq_wake(sdiodev->pdata->oob_irq_nr); brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS); atomic_set(&sdiodev->suspend, false); diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index a104d7ac3796..eb8584a9c49a 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -316,7 +316,7 @@ static const u16 xmtfifo_sz[][NFIFO] = { static const char * const fifo_names[] = { "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" }; #else -static const char fifo_names[6][0]; +static const char fifo_names[6][1]; #endif #ifdef DEBUG diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index b6ec51923b20..50033aa7c7d5 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -381,18 +381,15 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr) res = pcmcia_read_config_byte(hw_priv->link, CISREG_COR, &old_cor); if (res != 0) { - printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 1 " - "(%d)\n", res); + printk(KERN_DEBUG "%s failed 1 (%d)\n", __func__, res); return; } - printk(KERN_DEBUG "prism2_pccard_genesis_sreset: original COR %02x\n", - old_cor); + printk(KERN_DEBUG "%s: original COR %02x\n", __func__, old_cor); res = pcmcia_write_config_byte(hw_priv->link, CISREG_COR, old_cor | COR_SOFT_RESET); if (res != 0) { - printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 2 " - "(%d)\n", res); + printk(KERN_DEBUG "%s failed 2 (%d)\n", __func__, res); return; } @@ -401,8 +398,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr) /* Setup Genesis mode */ res = pcmcia_write_config_byte(hw_priv->link, CISREG_CCSR, hcr); if (res != 0) { - printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 3 " - "(%d)\n", res); + printk(KERN_DEBUG "%s failed 3 (%d)\n", __func__, res); return; } mdelay(10); @@ -410,8 +406,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr) res = pcmcia_write_config_byte(hw_priv->link, CISREG_COR, old_cor & ~COR_SOFT_RESET); if (res != 0) { - printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 4 " - "(%d)\n", res); + printk(KERN_DEBUG "%s failed 4 (%d)\n", __func__, res); return; } diff --git a/drivers/net/wireless/ipw2x00/Kconfig b/drivers/net/wireless/ipw2x00/Kconfig index 91c0cb3c368e..21de4fe6cf2d 100644 --- a/drivers/net/wireless/ipw2x00/Kconfig +++ b/drivers/net/wireless/ipw2x00/Kconfig @@ -65,7 +65,8 @@ config IPW2100_DEBUG config IPW2200 tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection" - depends on PCI && CFG80211 && CFG80211_WEXT + depends on PCI && CFG80211 + select CFG80211_WEXT select WIRELESS_EXT select WEXT_SPY select WEXT_PRIV diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c index e5be2d21868f..a5f9198d5747 100644 --- a/drivers/net/wireless/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/iwlwifi/iwl-7000.c @@ -69,8 +69,8 @@ #include "iwl-agn-hw.h" /* Highest firmware API version supported */ -#define IWL7260_UCODE_API_MAX 10 -#define IWL3160_UCODE_API_MAX 10 +#define IWL7260_UCODE_API_MAX 12 +#define IWL3160_UCODE_API_MAX 12 /* Oldest version we won't warn about */ #define IWL7260_UCODE_API_OK 10 @@ -105,7 +105,7 @@ #define IWL7265_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode" #define IWL7265D_FW_PRE "iwlwifi-7265D-" -#define IWL7265D_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode" +#define IWL7265D_MODULE_FIRMWARE(api) IWL7265D_FW_PRE __stringify(api) ".ucode" #define NVM_HW_SECTION_NUM_FAMILY_7000 0 diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c index bf0a95cb7153..3668fc57e770 100644 --- a/drivers/net/wireless/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/iwlwifi/iwl-8000.c @@ -69,7 +69,7 @@ #include "iwl-agn-hw.h" /* Highest firmware API version supported */ -#define IWL8000_UCODE_API_MAX 10 +#define IWL8000_UCODE_API_MAX 12 /* Oldest version we won't warn about */ #define IWL8000_UCODE_API_OK 10 diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 38de1513e4de..850b85a47806 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -1323,10 +1323,10 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) try_again: /* try next, if any */ - kfree(pieces); release_firmware(ucode_raw); if (iwl_request_firmware(drv, false)) goto out_unbind; + kfree(pieces); return; out_free_fw: diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 9564ae173d06..1f7f15eb86da 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -310,6 +310,7 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl) #define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000) #define FH_MEM_TFDIB_REG1_ADDR_BITSHIFT 28 +#define FH_MEM_TB_MAX_LENGTH (0x00020000) /* TFDB Area - TFDs buffer table */ #define FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK (0xFFFFFFFF) diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index f2a047f6bb3e..1bbe4fc47b97 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h @@ -243,6 +243,9 @@ enum iwl_ucode_tlv_flag { * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif. * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time * longer than the passive one, which is essential for fragmented scan. + * @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command, + * regardless of the band or the number of the probes. FW will calculate + * the actual dwell time. */ enum iwl_ucode_tlv_api { IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0), @@ -253,6 +256,7 @@ enum iwl_ucode_tlv_api { IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6), IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7), IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), + IWL_UCODE_TLV_API_BASIC_DWELL = BIT(13), }; /** diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index 1f2acf47bfb2..201846de94e7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h @@ -672,6 +672,7 @@ struct iwl_scan_channel_opt { * @IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED: all passive scans will be fragmented * @IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED: insert WFA vendor-specific TPC report * and DS parameter set IEs into probe requests. + * @IWL_MVM_LMAC_SCAN_FLAG_MATCH: Send match found notification on matches */ enum iwl_mvm_lmac_scan_flags { IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL = BIT(0), @@ -681,6 +682,7 @@ enum iwl_mvm_lmac_scan_flags { IWL_MVM_LMAC_SCAN_FLAG_MULTIPLE_SSIDS = BIT(4), IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED = BIT(5), IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED = BIT(6), + IWL_MVM_LMAC_SCAN_FLAG_MATCH = BIT(9), }; enum iwl_scan_priority { diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 31a5b3f4266c..e880f9d4717b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -1004,8 +1004,13 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm) { lockdep_assert_held(&mvm->mutex); - /* disallow low power states when the FW is down */ - iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); + /* + * Disallow low power states when the FW is down by taking + * the UCODE_DOWN ref. in case of ongoing hw restart the + * ref is already taken, so don't take it again. + */ + if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) + iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); /* async_handlers_wk is now blocked */ @@ -1023,6 +1028,12 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm) /* the fw is stopped, the aux sta is dead: clean up driver state */ iwl_mvm_del_aux_sta(mvm); + /* + * Clear IN_HW_RESTART flag when stopping the hw (as restart_complete() + * won't be called in this case). + */ + clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); + mvm->ucode_loaded = false; } diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index e5294d01181e..ec9a8e7bae1d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -171,15 +171,21 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_ssid_ie *cmd_ssid, * already included in the probe template, so we need to set only * req->n_ssids - 1 bits in addition to the first bit. */ -static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) +static u16 iwl_mvm_get_active_dwell(struct iwl_mvm *mvm, + enum ieee80211_band band, int n_ssids) { + if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BASIC_DWELL) + return 10; if (band == IEEE80211_BAND_2GHZ) return 20 + 3 * (n_ssids + 1); return 10 + 2 * (n_ssids + 1); } -static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band) +static u16 iwl_mvm_get_passive_dwell(struct iwl_mvm *mvm, + enum ieee80211_band band) { + if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BASIC_DWELL) + return 110; return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10; } @@ -331,7 +337,8 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm, */ if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { u32 passive_dwell = - iwl_mvm_get_passive_dwell(IEEE80211_BAND_2GHZ); + iwl_mvm_get_passive_dwell(mvm, + IEEE80211_BAND_2GHZ); params->max_out_time = passive_dwell; } else { params->passive_fragmented = true; @@ -348,8 +355,8 @@ not_bound: params->dwell[band].passive = frag_passive_dwell; else params->dwell[band].passive = - iwl_mvm_get_passive_dwell(band); - params->dwell[band].active = iwl_mvm_get_active_dwell(band, + iwl_mvm_get_passive_dwell(mvm, band); + params->dwell[band].active = iwl_mvm_get_active_dwell(mvm, band, n_ssids); } } @@ -1448,6 +1455,8 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm, if (iwl_mvm_scan_pass_all(mvm, req)) flags |= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL; + else + flags |= IWL_MVM_LMAC_SCAN_FLAG_MATCH; if (req->n_ssids == 1 && req->ssids[0].ssid_len != 0) flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION; diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 4f15d9decc81..4333306ccdee 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c @@ -108,8 +108,12 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, tx_flags &= ~TX_CMD_FLG_SEQ_CTL; } - /* tid_tspec will default to 0 = BE when QOS isn't enabled */ - ac = tid_to_mac80211_ac[tx_cmd->tid_tspec]; + /* Default to 0 (BE) when tid_spec is set to IWL_TID_NON_QOS */ + if (tx_cmd->tid_tspec < IWL_MAX_TID_COUNT) + ac = tid_to_mac80211_ac[tx_cmd->tid_tspec]; + else + ac = tid_to_mac80211_ac[0]; + tx_flags |= iwl_mvm_bt_coex_tx_prio(mvm, hdr, info, ac) << TX_CMD_FLG_BT_PRIO_POS; diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index e56e77ef5d2e..917431e30f74 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c @@ -665,7 +665,7 @@ bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm) if (num_of_ant(mvm->fw->valid_rx_ant) == 1) return false; - if (!mvm->cfg->rx_with_siso_diversity) + if (mvm->cfg->rx_with_siso_diversity) return false; ieee80211_iterate_active_interfaces_atomic( diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 3ee8e3848876..d5aadb00dd9e 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c @@ -367,7 +367,11 @@ static const struct pci_device_id iwl_hw_card_ids[] = { /* 3165 Series */ {IWL_PCI_DEVICE(0x3165, 0x4010, iwl3165_2ac_cfg)}, + {IWL_PCI_DEVICE(0x3165, 0x4012, iwl3165_2ac_cfg)}, + {IWL_PCI_DEVICE(0x3165, 0x4110, iwl3165_2ac_cfg)}, {IWL_PCI_DEVICE(0x3165, 0x4210, iwl3165_2ac_cfg)}, + {IWL_PCI_DEVICE(0x3165, 0x4410, iwl3165_2ac_cfg)}, + {IWL_PCI_DEVICE(0x3165, 0x4510, iwl3165_2ac_cfg)}, /* 7265 Series */ {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, @@ -523,8 +527,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) else if (cfg == &iwl7265_n_cfg) cfg_7265d = &iwl7265d_n_cfg; if (cfg_7265d && - (iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D) + (iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D) { cfg = cfg_7265d; + iwl_trans->cfg = cfg_7265d; + } #endif pci_set_drvdata(pdev, iwl_trans); diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 5d79a1f44b8e..523fe0c88dcb 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -614,7 +614,7 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num, { u8 *v_addr; dma_addr_t p_addr; - u32 offset, chunk_sz = section->len; + u32 offset, chunk_sz = min_t(u32, FH_MEM_TB_MAX_LENGTH, section->len); int ret = 0; IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n", @@ -1012,16 +1012,21 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) /* Stop the device, and put it in low power state */ iwl_pcie_apm_stop(trans); - /* Upon stop, the APM issues an interrupt if HW RF kill is set. - * Clean again the interrupt here + /* stop and reset the on-board processor */ + iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); + udelay(20); + + /* + * Upon stop, the APM issues an interrupt if HW RF kill is set. + * This is a bug in certain verions of the hardware. + * Certain devices also keep sending HW RF kill interrupt all + * the time, unless the interrupt is ACKed even if the interrupt + * should be masked. Re-ACK all the interrupts here. */ spin_lock(&trans_pcie->irq_lock); iwl_disable_interrupts(trans); spin_unlock(&trans_pcie->irq_lock); - /* stop and reset the on-board processor */ - iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); - udelay(20); /* clear all status bits */ clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status); diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 846a2e6e34d8..c70efb9a6e78 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -666,7 +666,8 @@ tx_status_ok: } static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw, - u8 *entry, int rxring_idx, int desc_idx) + struct sk_buff *new_skb, u8 *entry, + int rxring_idx, int desc_idx) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); @@ -674,11 +675,15 @@ static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw, u8 tmp_one = 1; struct sk_buff *skb; + if (likely(new_skb)) { + skb = new_skb; + goto remap; + } skb = dev_alloc_skb(rtlpci->rxbuffersize); if (!skb) return 0; - rtlpci->rx_ring[rxring_idx].rx_buf[desc_idx] = skb; +remap: /* just set skb->cb to mapping addr for pci_unmap_single use */ *((dma_addr_t *)skb->cb) = pci_map_single(rtlpci->pdev, skb_tail_pointer(skb), @@ -686,6 +691,7 @@ static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw, bufferaddress = *((dma_addr_t *)skb->cb); if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress)) return 0; + rtlpci->rx_ring[rxring_idx].rx_buf[desc_idx] = skb; if (rtlpriv->use_new_trx_flow) { rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false, HW_DESC_RX_PREPARE, @@ -781,6 +787,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) /*rx pkt */ struct sk_buff *skb = rtlpci->rx_ring[rxring_idx].rx_buf[ rtlpci->rx_ring[rxring_idx].idx]; + struct sk_buff *new_skb; if (rtlpriv->use_new_trx_flow) { rx_remained_cnt = @@ -807,6 +814,13 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) pci_unmap_single(rtlpci->pdev, *((dma_addr_t *)skb->cb), rtlpci->rxbuffersize, PCI_DMA_FROMDEVICE); + /* get a new skb - if fail, old one will be reused */ + new_skb = dev_alloc_skb(rtlpci->rxbuffersize); + if (unlikely(!new_skb)) { + pr_err("Allocation of new skb failed in %s\n", + __func__); + goto no_new; + } if (rtlpriv->use_new_trx_flow) { buffer_desc = &rtlpci->rx_ring[rxring_idx].buffer_desc @@ -911,14 +925,16 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) schedule_work(&rtlpriv->works.lps_change_work); } end: + skb = new_skb; +no_new: if (rtlpriv->use_new_trx_flow) { - _rtl_pci_init_one_rxdesc(hw, (u8 *)buffer_desc, + _rtl_pci_init_one_rxdesc(hw, skb, (u8 *)buffer_desc, rxring_idx, - rtlpci->rx_ring[rxring_idx].idx); + rtlpci->rx_ring[rxring_idx].idx); } else { - _rtl_pci_init_one_rxdesc(hw, (u8 *)pdesc, rxring_idx, + _rtl_pci_init_one_rxdesc(hw, skb, (u8 *)pdesc, + rxring_idx, rtlpci->rx_ring[rxring_idx].idx); - if (rtlpci->rx_ring[rxring_idx].idx == rtlpci->rxringcount - 1) rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, @@ -1307,7 +1323,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw, int rxring_idx) rtlpci->rx_ring[rxring_idx].idx = 0; for (i = 0; i < rtlpci->rxringcount; i++) { entry = &rtlpci->rx_ring[rxring_idx].buffer_desc[i]; - if (!_rtl_pci_init_one_rxdesc(hw, (u8 *)entry, + if (!_rtl_pci_init_one_rxdesc(hw, NULL, (u8 *)entry, rxring_idx, i)) return -ENOMEM; } @@ -1332,7 +1348,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw, int rxring_idx) for (i = 0; i < rtlpci->rxringcount; i++) { entry = &rtlpci->rx_ring[rxring_idx].desc[i]; - if (!_rtl_pci_init_one_rxdesc(hw, (u8 *)entry, + if (!_rtl_pci_init_one_rxdesc(hw, NULL, (u8 *)entry, rxring_idx, i)) return -ENOMEM; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index d2ec5160bbf0..5c646d5f7bb8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -955,6 +955,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) local_save_flags(flags); local_irq_enable(); + rtlhal->fw_ready = false; rtlpriv->intf_ops->disable_aspm(hw); rtstatus = _rtl92ce_init_mac(hw); if (!rtstatus) { @@ -971,6 +972,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) goto exit; } + rtlhal->fw_ready = true; rtlhal->last_hmeboxnum = 0; rtl92c_phy_mac_config(hw); /* because last function modify RCR, so we update diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 873363acbacf..551321728ae0 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -1592,7 +1592,7 @@ void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } } -bool usb_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb) +static bool usb_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb) { /* Currently nothing happens here. * Traffic stops after some seconds in WPA2 802.11n mode. diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c b/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c index 9be106109921..ba30b0d250fd 100644 --- a/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c @@ -2078,8 +2078,7 @@ void rtl8821ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw, if (rtldm->tx_rate != 0xFF) tx_rate = rtl8821ae_hw_rate_to_mrate(hw, rtldm->tx_rate); - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - "===>rtl8812ae_dm_txpwr_track_set_pwr\n"); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "===>%s\n", __func__); if (tx_rate != 0xFF) { /* Mimic Modify High Rate BBSwing Limit.*/ /*CCK*/ @@ -2128,7 +2127,7 @@ void rtl8821ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw, if (method == BBSWING) { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - "===>rtl8812ae_dm_txpwr_track_set_pwr\n"); + "===>%s\n", __func__); if (rf_path == RF90_PATH_A) { final_swing_idx[RF90_PATH_A] = (rtldm->ofdm_index[RF90_PATH_A] > @@ -2260,7 +2259,8 @@ void rtl8821ae_dm_txpower_tracking_callback_thermalmeter( rtldm->txpower_trackinginit = true; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - "===>rtl8812ae_dm_txpower_tracking_callback_thermalmeter,\n pDM_Odm->BbSwingIdxCckBase: %d,pDM_Odm->BbSwingIdxOfdmBase[A]:%d, pDM_Odm->DefaultOfdmIndex: %d\n", + "===>%s,\n pDM_Odm->BbSwingIdxCckBase: %d,pDM_Odm->BbSwingIdxOfdmBase[A]:%d, pDM_Odm->DefaultOfdmIndex: %d\n", + __func__, rtldm->swing_idx_cck_base, rtldm->swing_idx_ofdm_base[RF90_PATH_A], rtldm->default_ofdm_index); @@ -2539,8 +2539,7 @@ void rtl8821ae_dm_txpower_tracking_callback_thermalmeter( } } - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - "<===rtl8812ae_dm_txpower_tracking_callback_thermalmeter\n"); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===%s\n", __func__); } void rtl8821ae_dm_check_txpower_tracking_thermalmeter(struct ieee80211_hw *hw) diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index 73a49b868035..07b94eda9604 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c @@ -129,7 +129,7 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr r = zd_ioread16v_locked(chip, v16, a16, count16); if (r) { dev_dbg_f(zd_chip_dev(chip), - "error: zd_ioread16v_locked. Error number %d\n", r); + "error: %s. Error number %d\n", __func__, r); return r; } @@ -256,8 +256,8 @@ int zd_iowrite32a_locked(struct zd_chip *chip, if (r) { zd_usb_iowrite16v_async_end(&chip->usb, 0); dev_dbg_f(zd_chip_dev(chip), - "error _zd_iowrite32v_locked." - " Error number %d\n", r); + "error _%s. Error number %d\n", __func__, + r); return r; } } diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h index 083ecc93fe5e..5f1fda44882b 100644 --- a/drivers/net/xen-netback/common.h +++ b/drivers/net/xen-netback/common.h @@ -230,6 +230,8 @@ struct xenvif { */ bool disabled; unsigned long status; + unsigned long drain_timeout; + unsigned long stall_timeout; /* Queues */ struct xenvif_queue *queues; @@ -328,7 +330,7 @@ irqreturn_t xenvif_interrupt(int irq, void *dev_id); extern bool separate_tx_rx_irq; extern unsigned int rx_drain_timeout_msecs; -extern unsigned int rx_drain_timeout_jiffies; +extern unsigned int rx_stall_timeout_msecs; extern unsigned int xenvif_max_queues; #ifdef CONFIG_DEBUG_FS diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index a6a32d337bbb..9259a732e8a4 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -166,7 +166,7 @@ static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev) goto drop; cb = XENVIF_RX_CB(skb); - cb->expires = jiffies + rx_drain_timeout_jiffies; + cb->expires = jiffies + vif->drain_timeout; xenvif_rx_queue_tail(queue, skb); xenvif_kick_thread(queue); @@ -414,6 +414,8 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, vif->ip_csum = 1; vif->dev = dev; vif->disabled = false; + vif->drain_timeout = msecs_to_jiffies(rx_drain_timeout_msecs); + vif->stall_timeout = msecs_to_jiffies(rx_stall_timeout_msecs); /* Start out with no queues. */ vif->queues = NULL; diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 4a509f715fe8..908e65e9b821 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -60,14 +60,12 @@ module_param(separate_tx_rx_irq, bool, 0644); */ unsigned int rx_drain_timeout_msecs = 10000; module_param(rx_drain_timeout_msecs, uint, 0444); -unsigned int rx_drain_timeout_jiffies; /* The length of time before the frontend is considered unresponsive * because it isn't providing Rx slots. */ -static unsigned int rx_stall_timeout_msecs = 60000; +unsigned int rx_stall_timeout_msecs = 60000; module_param(rx_stall_timeout_msecs, uint, 0444); -static unsigned int rx_stall_timeout_jiffies; unsigned int xenvif_max_queues; module_param_named(max_queues, xenvif_max_queues, uint, 0644); @@ -2020,7 +2018,7 @@ static bool xenvif_rx_queue_stalled(struct xenvif_queue *queue) return !queue->stalled && prod - cons < XEN_NETBK_RX_SLOTS_MAX && time_after(jiffies, - queue->last_rx_time + rx_stall_timeout_jiffies); + queue->last_rx_time + queue->vif->stall_timeout); } static bool xenvif_rx_queue_ready(struct xenvif_queue *queue) @@ -2038,8 +2036,9 @@ static bool xenvif_have_rx_work(struct xenvif_queue *queue) { return (!skb_queue_empty(&queue->rx_queue) && xenvif_rx_ring_slots_available(queue, XEN_NETBK_RX_SLOTS_MAX)) - || xenvif_rx_queue_stalled(queue) - || xenvif_rx_queue_ready(queue) + || (queue->vif->stall_timeout && + (xenvif_rx_queue_stalled(queue) + || xenvif_rx_queue_ready(queue))) || kthread_should_stop() || queue->vif->disabled; } @@ -2092,6 +2091,9 @@ int xenvif_kthread_guest_rx(void *data) struct xenvif_queue *queue = data; struct xenvif *vif = queue->vif; + if (!vif->stall_timeout) + xenvif_queue_carrier_on(queue); + for (;;) { xenvif_wait_for_rx_work(queue); @@ -2118,10 +2120,12 @@ int xenvif_kthread_guest_rx(void *data) * while it's probably not responsive, drop the * carrier so packets are dropped earlier. */ - if (xenvif_rx_queue_stalled(queue)) - xenvif_queue_carrier_off(queue); - else if (xenvif_rx_queue_ready(queue)) - xenvif_queue_carrier_on(queue); + if (vif->stall_timeout) { + if (xenvif_rx_queue_stalled(queue)) + xenvif_queue_carrier_off(queue); + else if (xenvif_rx_queue_ready(queue)) + xenvif_queue_carrier_on(queue); + } /* Queued packets may have foreign pages from other * domains. These cannot be queued indefinitely as @@ -2192,9 +2196,6 @@ static int __init netback_init(void) if (rc) goto failed_init; - rx_drain_timeout_jiffies = msecs_to_jiffies(rx_drain_timeout_msecs); - rx_stall_timeout_jiffies = msecs_to_jiffies(rx_stall_timeout_msecs); - #ifdef CONFIG_DEBUG_FS xen_netback_dbg_root = debugfs_create_dir("xen-netback", NULL); if (IS_ERR_OR_NULL(xen_netback_dbg_root)) diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c index d44cd19169bd..794204e34fba 100644 --- a/drivers/net/xen-netback/xenbus.c +++ b/drivers/net/xen-netback/xenbus.c @@ -737,6 +737,7 @@ static void connect(struct backend_info *be) } queue->remaining_credit = credit_bytes; + queue->credit_usec = credit_usec; err = connect_rings(be, queue); if (err) { @@ -887,9 +888,15 @@ static int read_xenbus_vif_flags(struct backend_info *be) return -EOPNOTSUPP; if (xenbus_scanf(XBT_NIL, dev->otherend, - "feature-rx-notify", "%d", &val) < 0 || val == 0) { - xenbus_dev_fatal(dev, -EINVAL, "feature-rx-notify is mandatory"); - return -EINVAL; + "feature-rx-notify", "%d", &val) < 0) + val = 0; + if (!val) { + /* - Reduce drain timeout to poll more frequently for + * Rx requests. + * - Disable Rx stall detection. + */ + be->vif->drain_timeout = msecs_to_jiffies(30); + be->vif->stall_timeout = 0; } if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-sg", diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 2f0a9ce9ff73..d8c10764f130 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -88,10 +88,8 @@ struct netfront_cb { #define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3) struct netfront_stats { - u64 rx_packets; - u64 tx_packets; - u64 rx_bytes; - u64 tx_bytes; + u64 packets; + u64 bytes; struct u64_stats_sync syncp; }; @@ -160,7 +158,8 @@ struct netfront_info { struct netfront_queue *queues; /* Statistics */ - struct netfront_stats __percpu *stats; + struct netfront_stats __percpu *rx_stats; + struct netfront_stats __percpu *tx_stats; atomic_t rx_gso_checksum_fixup; }; @@ -565,7 +564,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) { unsigned short id; struct netfront_info *np = netdev_priv(dev); - struct netfront_stats *stats = this_cpu_ptr(np->stats); + struct netfront_stats *tx_stats = this_cpu_ptr(np->tx_stats); struct xen_netif_tx_request *tx; char *data = skb->data; RING_IDX i; @@ -672,10 +671,10 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) if (notify) notify_remote_via_irq(queue->tx_irq); - u64_stats_update_begin(&stats->syncp); - stats->tx_bytes += skb->len; - stats->tx_packets++; - u64_stats_update_end(&stats->syncp); + u64_stats_update_begin(&tx_stats->syncp); + tx_stats->bytes += skb->len; + tx_stats->packets++; + u64_stats_update_end(&tx_stats->syncp); /* Note: It is not safe to access skb after xennet_tx_buf_gc()! */ xennet_tx_buf_gc(queue); @@ -931,7 +930,7 @@ static int checksum_setup(struct net_device *dev, struct sk_buff *skb) static int handle_incoming_queue(struct netfront_queue *queue, struct sk_buff_head *rxq) { - struct netfront_stats *stats = this_cpu_ptr(queue->info->stats); + struct netfront_stats *rx_stats = this_cpu_ptr(queue->info->rx_stats); int packets_dropped = 0; struct sk_buff *skb; @@ -952,10 +951,10 @@ static int handle_incoming_queue(struct netfront_queue *queue, continue; } - u64_stats_update_begin(&stats->syncp); - stats->rx_packets++; - stats->rx_bytes += skb->len; - u64_stats_update_end(&stats->syncp); + u64_stats_update_begin(&rx_stats->syncp); + rx_stats->packets++; + rx_stats->bytes += skb->len; + u64_stats_update_end(&rx_stats->syncp); /* Pass it up. */ napi_gro_receive(&queue->napi, skb); @@ -977,7 +976,6 @@ static int xennet_poll(struct napi_struct *napi, int budget) struct sk_buff_head rxq; struct sk_buff_head errq; struct sk_buff_head tmpq; - unsigned long flags; int err; spin_lock(&queue->rx_lock); @@ -1050,15 +1048,11 @@ err: if (work_done < budget) { int more_to_do = 0; - napi_gro_flush(napi, false); - - local_irq_save(flags); + napi_complete(napi); RING_FINAL_CHECK_FOR_RESPONSES(&queue->rx, more_to_do); - if (!more_to_do) - __napi_complete(napi); - - local_irq_restore(flags); + if (more_to_do) + napi_schedule(napi); } spin_unlock(&queue->rx_lock); @@ -1084,18 +1078,22 @@ static struct rtnl_link_stats64 *xennet_get_stats64(struct net_device *dev, int cpu; for_each_possible_cpu(cpu) { - struct netfront_stats *stats = per_cpu_ptr(np->stats, cpu); + struct netfront_stats *rx_stats = per_cpu_ptr(np->rx_stats, cpu); + struct netfront_stats *tx_stats = per_cpu_ptr(np->tx_stats, cpu); u64 rx_packets, rx_bytes, tx_packets, tx_bytes; unsigned int start; do { - start = u64_stats_fetch_begin_irq(&stats->syncp); + start = u64_stats_fetch_begin_irq(&tx_stats->syncp); + tx_packets = tx_stats->packets; + tx_bytes = tx_stats->bytes; + } while (u64_stats_fetch_retry_irq(&tx_stats->syncp, start)); - rx_packets = stats->rx_packets; - tx_packets = stats->tx_packets; - rx_bytes = stats->rx_bytes; - tx_bytes = stats->tx_bytes; - } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); + do { + start = u64_stats_fetch_begin_irq(&rx_stats->syncp); + rx_packets = rx_stats->packets; + rx_bytes = rx_stats->bytes; + } while (u64_stats_fetch_retry_irq(&rx_stats->syncp, start)); tot->rx_packets += rx_packets; tot->tx_packets += tx_packets; @@ -1280,6 +1278,15 @@ static const struct net_device_ops xennet_netdev_ops = { #endif }; +static void xennet_free_netdev(struct net_device *netdev) +{ + struct netfront_info *np = netdev_priv(netdev); + + free_percpu(np->rx_stats); + free_percpu(np->tx_stats); + free_netdev(netdev); +} + static struct net_device *xennet_create_dev(struct xenbus_device *dev) { int err; @@ -1300,8 +1307,11 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev) np->queues = NULL; err = -ENOMEM; - np->stats = netdev_alloc_pcpu_stats(struct netfront_stats); - if (np->stats == NULL) + np->rx_stats = netdev_alloc_pcpu_stats(struct netfront_stats); + if (np->rx_stats == NULL) + goto exit; + np->tx_stats = netdev_alloc_pcpu_stats(struct netfront_stats); + if (np->tx_stats == NULL) goto exit; netdev->netdev_ops = &xennet_netdev_ops; @@ -1332,7 +1342,7 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev) return netdev; exit: - free_netdev(netdev); + xennet_free_netdev(netdev); return ERR_PTR(err); } @@ -1374,7 +1384,7 @@ static int netfront_probe(struct xenbus_device *dev, return 0; fail: - free_netdev(netdev); + xennet_free_netdev(netdev); dev_set_drvdata(&dev->dev, NULL); return err; } @@ -2194,9 +2204,7 @@ static int xennet_remove(struct xenbus_device *dev) info->queues = NULL; } - free_percpu(info->stats); - - free_netdev(info->netdev); + xennet_free_netdev(info->netdev); return 0; } diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c index d2ccd2890647..aa6a333b2ead 100644 --- a/drivers/nfc/trf7970a.c +++ b/drivers/nfc/trf7970a.c @@ -2154,7 +2154,7 @@ static int trf7970a_resume(struct device *dev) } #endif -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM static int trf7970a_pm_runtime_suspend(struct device *dev) { struct spi_device *spi = container_of(dev, struct spi_device, dev); diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index ea63fbd228ed..352b4f28f82c 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -114,17 +114,6 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov, ret = of_overlay_apply_one(ov, tchild, child); if (ret) return ret; - - /* The properties are already copied, now do the child nodes */ - for_each_child_of_node(child, grandchild) { - ret = of_overlay_apply_single_device_node(ov, tchild, grandchild); - if (ret) { - pr_err("%s: Failed to apply single node @%s/%s\n", - __func__, tchild->full_name, - grandchild->name); - return ret; - } - } } return ret; diff --git a/drivers/of/platform.c b/drivers/of/platform.c index cd87a36495be..b0d50d70a8a1 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -19,6 +19,7 @@ #include <linux/slab.h> #include <linux/of_address.h> #include <linux/of_device.h> +#include <linux/of_iommu.h> #include <linux/of_irq.h> #include <linux/of_platform.h> #include <linux/platform_device.h> @@ -164,6 +165,9 @@ static void of_dma_configure(struct device *dev) { u64 dma_addr, paddr, size; int ret; + bool coherent; + unsigned long offset; + struct iommu_ops *iommu; /* * Set default dma-mask to 32 bit. Drivers are expected to setup @@ -178,28 +182,30 @@ static void of_dma_configure(struct device *dev) if (!dev->dma_mask) dev->dma_mask = &dev->coherent_dma_mask; - /* - * if dma-coherent property exist, call arch hook to setup - * dma coherent operations. - */ - if (of_dma_is_coherent(dev->of_node)) { - set_arch_dma_coherent_ops(dev); - dev_dbg(dev, "device is dma coherent\n"); - } - - /* - * if dma-ranges property doesn't exist - just return else - * setup the dma offset - */ ret = of_dma_get_range(dev->of_node, &dma_addr, &paddr, &size); if (ret < 0) { - dev_dbg(dev, "no dma range information to setup\n"); - return; + dma_addr = offset = 0; + size = dev->coherent_dma_mask; + } else { + offset = PFN_DOWN(paddr - dma_addr); + dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset); } + dev->dma_pfn_offset = offset; + + coherent = of_dma_is_coherent(dev->of_node); + dev_dbg(dev, "device is%sdma coherent\n", + coherent ? " " : " not "); + + iommu = of_iommu_configure(dev); + dev_dbg(dev, "device is%sbehind an iommu\n", + iommu ? " " : " not "); + + arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent); +} - /* DMA ranges found. Calculate and set dma_pfn_offset */ - dev->dma_pfn_offset = PFN_DOWN(paddr - dma_addr); - dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", dev->dma_pfn_offset); +static void of_dma_deconfigure(struct device *dev) +{ + arch_teardown_dma_ops(dev); } /** @@ -228,16 +234,12 @@ static struct platform_device *of_platform_device_create_pdata( if (!dev) goto err_clear_flag; - of_dma_configure(&dev->dev); dev->dev.bus = &platform_bus_type; dev->dev.platform_data = platform_data; - - /* We do not fill the DMA ops for platform devices by default. - * This is currently the responsibility of the platform code - * to do such, possibly using a device notifier - */ + of_dma_configure(&dev->dev); if (of_device_add(dev) != 0) { + of_dma_deconfigure(&dev->dev); platform_device_put(dev); goto err_clear_flag; } @@ -564,6 +566,10 @@ static int of_platform_notify(struct notifier_block *nb, if (!of_node_check_flag(rd->dn->parent, OF_POPULATED_BUS)) return NOTIFY_OK; /* not for us */ + /* already populated? (driver using of_populate manually) */ + if (of_node_check_flag(rd->dn, OF_POPULATED)) + return NOTIFY_OK; + /* pdev_parent may be NULL when no bus platform device */ pdev_parent = of_find_device_by_node(rd->dn->parent); pdev = of_platform_device_create(rd->dn, NULL, @@ -579,6 +585,11 @@ static int of_platform_notify(struct notifier_block *nb, break; case OF_RECONFIG_CHANGE_REMOVE: + + /* already depopulated? */ + if (!of_node_check_flag(rd->dn, OF_POPULATED)) + return NOTIFY_OK; + /* find our device by node */ pdev = of_find_device_by_node(rd->dn); if (pdev == NULL) diff --git a/drivers/of/unittest-data/tests-overlay.dtsi b/drivers/of/unittest-data/tests-overlay.dtsi index 75976da22b2e..a2b687d5f324 100644 --- a/drivers/of/unittest-data/tests-overlay.dtsi +++ b/drivers/of/unittest-data/tests-overlay.dtsi @@ -176,5 +176,60 @@ }; }; + overlay10 { + fragment@0 { + target-path = "/testcase-data/overlay-node/test-bus"; + __overlay__ { + + /* suppress DTC warning */ + #address-cells = <1>; + #size-cells = <0>; + + test-selftest10 { + compatible = "selftest"; + status = "okay"; + reg = <10>; + + #address-cells = <1>; + #size-cells = <0>; + + test-selftest101 { + compatible = "selftest"; + status = "okay"; + reg = <1>; + }; + + }; + }; + }; + }; + + overlay11 { + fragment@0 { + target-path = "/testcase-data/overlay-node/test-bus"; + __overlay__ { + + /* suppress DTC warning */ + #address-cells = <1>; + #size-cells = <0>; + + test-selftest11 { + compatible = "selftest"; + status = "okay"; + reg = <11>; + + #address-cells = <1>; + #size-cells = <0>; + + test-selftest111 { + compatible = "selftest"; + status = "okay"; + reg = <1>; + }; + + }; + }; + }; + }; }; }; diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 844838e11ef1..41a4a138f53b 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -978,6 +978,9 @@ static int selftest_probe(struct platform_device *pdev) } dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name); + + of_platform_populate(np, NULL, NULL, &pdev->dev); + return 0; } @@ -1385,6 +1388,39 @@ static void of_selftest_overlay_8(void) selftest(1, "overlay test %d passed\n", 8); } +/* test insertion of a bus with parent devices */ +static void of_selftest_overlay_10(void) +{ + int ret; + char *child_path; + + /* device should disable */ + ret = of_selftest_apply_overlay_check(10, 10, 0, 1); + if (selftest(ret == 0, "overlay test %d failed; overlay application\n", 10)) + return; + + child_path = kasprintf(GFP_KERNEL, "%s/test-selftest101", + selftest_path(10)); + if (selftest(child_path, "overlay test %d failed; kasprintf\n", 10)) + return; + + ret = of_path_platform_device_exists(child_path); + kfree(child_path); + if (selftest(ret, "overlay test %d failed; no child device\n", 10)) + return; +} + +/* test insertion of a bus with parent devices (and revert) */ +static void of_selftest_overlay_11(void) +{ + int ret; + + /* device should disable */ + ret = of_selftest_apply_revert_overlay_check(11, 11, 0, 1); + if (selftest(ret == 0, "overlay test %d failed; overlay application\n", 11)) + return; +} + static void __init of_selftest_overlay(void) { struct device_node *bus_np = NULL; @@ -1433,6 +1469,9 @@ static void __init of_selftest_overlay(void) of_selftest_overlay_6(); of_selftest_overlay_8(); + of_selftest_overlay_10(); + of_selftest_overlay_11(); + out: of_node_put(bus_np); } diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index 37e71ff6408d..dceb9ddfd99a 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c @@ -694,9 +694,8 @@ lba_fixup_bus(struct pci_bus *bus) int i; /* PCI-PCI Bridge */ pci_read_bridge_bases(bus); - for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) { - pci_claim_resource(bus->self, i); - } + for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) + pci_claim_bridge_resource(bus->self, i); } else { /* Host-PCI Bridge */ int err; diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index cced84233ac0..7a8f1c5e65af 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -67,7 +67,7 @@ config XEN_PCIDEV_FRONTEND config HT_IRQ bool "Interrupts on hypertransport devices" default y - depends on PCI && X86_LOCAL_APIC && X86_IO_APIC + depends on PCI && X86_LOCAL_APIC help This allows native hypertransport devices to use interrupts. @@ -110,13 +110,6 @@ config PCI_PASID If unsure, say N. -config PCI_IOAPIC - bool "PCI IO-APIC hotplug support" if X86 - depends on PCI - depends on ACPI - depends on X86_IO_APIC - default !X86 - config PCI_LABEL def_bool y if (DMI || ACPI) select NLS diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index e04fe2d9df3b..73e4af400a5a 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -13,8 +13,6 @@ obj-$(CONFIG_PCI_QUIRKS) += quirks.o # Build PCI Express stuff if needed obj-$(CONFIG_PCIEPORTBUS) += pcie/ -obj-$(CONFIG_PCI_IOAPIC) += ioapic.o - # Build the PCI Hotplug drivers if we were asked to obj-$(CONFIG_HOTPLUG_PCI) += hotplug/ ifdef CONFIG_HOTPLUG_PCI diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 73aef51a28f0..8fb16188cd82 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -228,6 +228,49 @@ int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, } EXPORT_SYMBOL(pci_bus_alloc_resource); +/* + * The @idx resource of @dev should be a PCI-PCI bridge window. If this + * resource fits inside a window of an upstream bridge, do nothing. If it + * overlaps an upstream window but extends outside it, clip the resource so + * it fits completely inside. + */ +bool pci_bus_clip_resource(struct pci_dev *dev, int idx) +{ + struct pci_bus *bus = dev->bus; + struct resource *res = &dev->resource[idx]; + struct resource orig_res = *res; + struct resource *r; + int i; + + pci_bus_for_each_resource(bus, r, i) { + resource_size_t start, end; + + if (!r) + continue; + + if (resource_type(res) != resource_type(r)) + continue; + + start = max(r->start, res->start); + end = min(r->end, res->end); + + if (start > end) + continue; /* no overlap */ + + if (res->start == start && res->end == end) + return false; /* no change */ + + res->start = start; + res->end = end; + dev_printk(KERN_DEBUG, &dev->dev, "%pR clipped to %pR\n", + &orig_res, res); + + return true; + } + + return false; +} + void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { } /** diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index 3efaf4c38528..96c5c729cdbc 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c @@ -36,6 +36,7 @@ #include <linux/wait.h> #include "../pci.h" #include <asm/pci_x86.h> /* for struct irq_routing_table */ +#include <asm/io_apic.h> #include "ibmphp.h" #define attn_on(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNON) @@ -155,13 +156,10 @@ int ibmphp_init_devno(struct slot **cur_slot) for (loop = 0; loop < len; loop++) { if ((*cur_slot)->number == rtable->slots[loop].slot && (*cur_slot)->bus == rtable->slots[loop].bus) { - struct io_apic_irq_attr irq_attr; - (*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn); for (i = 0; i < 4; i++) (*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector((int) (*cur_slot)->bus, - (int) (*cur_slot)->device, i, - &irq_attr); + (int) (*cur_slot)->device, i); debug("(*cur_slot)->irq[0] = %x\n", (*cur_slot)->irq[0]); diff --git a/drivers/pci/ioapic.c b/drivers/pci/ioapic.c deleted file mode 100644 index f6219d36227f..000000000000 --- a/drivers/pci/ioapic.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * IOAPIC/IOxAPIC/IOSAPIC driver - * - * Copyright (C) 2009 Fujitsu Limited. - * (c) Copyright 2009 Hewlett-Packard Development Company, L.P. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* - * This driver manages PCI I/O APICs added by hotplug after boot. We try to - * claim all I/O APIC PCI devices, but those present at boot were registered - * when we parsed the ACPI MADT, so we'll fail when we try to re-register - * them. - */ - -#include <linux/pci.h> -#include <linux/module.h> -#include <linux/acpi.h> -#include <linux/slab.h> - -struct ioapic { - acpi_handle handle; - u32 gsi_base; -}; - -static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent) -{ - acpi_handle handle; - acpi_status status; - unsigned long long gsb; - struct ioapic *ioapic; - int ret; - char *type; - struct resource *res; - - handle = ACPI_HANDLE(&dev->dev); - if (!handle) - return -EINVAL; - - status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb); - if (ACPI_FAILURE(status)) - return -EINVAL; - - /* - * The previous code in acpiphp evaluated _MAT if _GSB failed, but - * ACPI spec 4.0 sec 6.2.2 requires _GSB for hot-pluggable I/O APICs. - */ - - ioapic = kzalloc(sizeof(*ioapic), GFP_KERNEL); - if (!ioapic) - return -ENOMEM; - - ioapic->handle = handle; - ioapic->gsi_base = (u32) gsb; - - if (dev->class == PCI_CLASS_SYSTEM_PIC_IOAPIC) - type = "IOAPIC"; - else - type = "IOxAPIC"; - - ret = pci_enable_device(dev); - if (ret < 0) - goto exit_free; - - pci_set_master(dev); - - if (pci_request_region(dev, 0, type)) - goto exit_disable; - - res = &dev->resource[0]; - if (acpi_register_ioapic(ioapic->handle, res->start, ioapic->gsi_base)) - goto exit_release; - - pci_set_drvdata(dev, ioapic); - dev_info(&dev->dev, "%s at %pR, GSI %u\n", type, res, ioapic->gsi_base); - return 0; - -exit_release: - pci_release_region(dev, 0); -exit_disable: - pci_disable_device(dev); -exit_free: - kfree(ioapic); - return -ENODEV; -} - -static void ioapic_remove(struct pci_dev *dev) -{ - struct ioapic *ioapic = pci_get_drvdata(dev); - - acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base); - pci_release_region(dev, 0); - pci_disable_device(dev); - kfree(ioapic); -} - - -static const struct pci_device_id ioapic_devices[] = { - { PCI_DEVICE_CLASS(PCI_CLASS_SYSTEM_PIC_IOAPIC, ~0) }, - { PCI_DEVICE_CLASS(PCI_CLASS_SYSTEM_PIC_IOXAPIC, ~0) }, - { } -}; -MODULE_DEVICE_TABLE(pci, ioapic_devices); - -static struct pci_driver ioapic_driver = { - .name = "ioapic", - .id_table = ioapic_devices, - .probe = ioapic_probe, - .remove = ioapic_remove, -}; - -static int __init ioapic_init(void) -{ - return pci_register_driver(&ioapic_driver); -} -module_init(ioapic_init); - -MODULE_LICENSE("GPL"); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index cab05f31223f..e9d4fd861ba1 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3271,7 +3271,8 @@ static int pci_parent_bus_reset(struct pci_dev *dev, int probe) { struct pci_dev *pdev; - if (pci_is_root_bus(dev->bus) || dev->subordinate || !dev->bus->self) + if (pci_is_root_bus(dev->bus) || dev->subordinate || + !dev->bus->self || dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET) return -ENOTTY; list_for_each_entry(pdev, &dev->bus->devices, bus_list) @@ -3305,7 +3306,8 @@ static int pci_dev_reset_slot_function(struct pci_dev *dev, int probe) { struct pci_dev *pdev; - if (dev->subordinate || !dev->slot) + if (dev->subordinate || !dev->slot || + dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET) return -ENOTTY; list_for_each_entry(pdev, &dev->bus->devices, bus_list) @@ -3557,6 +3559,20 @@ int pci_try_reset_function(struct pci_dev *dev) } EXPORT_SYMBOL_GPL(pci_try_reset_function); +/* Do any devices on or below this bus prevent a bus reset? */ +static bool pci_bus_resetable(struct pci_bus *bus) +{ + struct pci_dev *dev; + + list_for_each_entry(dev, &bus->devices, bus_list) { + if (dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET || + (dev->subordinate && !pci_bus_resetable(dev->subordinate))) + return false; + } + + return true; +} + /* Lock devices from the top of the tree down */ static void pci_bus_lock(struct pci_bus *bus) { @@ -3607,6 +3623,22 @@ unlock: return 0; } +/* Do any devices on or below this slot prevent a bus reset? */ +static bool pci_slot_resetable(struct pci_slot *slot) +{ + struct pci_dev *dev; + + list_for_each_entry(dev, &slot->bus->devices, bus_list) { + if (!dev->slot || dev->slot != slot) + continue; + if (dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET || + (dev->subordinate && !pci_bus_resetable(dev->subordinate))) + return false; + } + + return true; +} + /* Lock devices from the top of the tree down */ static void pci_slot_lock(struct pci_slot *slot) { @@ -3728,7 +3760,7 @@ static int pci_slot_reset(struct pci_slot *slot, int probe) { int rc; - if (!slot) + if (!slot || !pci_slot_resetable(slot)) return -ENOTTY; if (!probe) @@ -3820,7 +3852,7 @@ EXPORT_SYMBOL_GPL(pci_try_reset_slot); static int pci_bus_reset(struct pci_bus *bus, int probe) { - if (!bus->self) + if (!bus->self || !pci_bus_resetable(bus)) return -ENOTTY; if (probe) diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 8aff29a804ff..d54632a1db43 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -208,6 +208,7 @@ void __pci_bus_size_bridges(struct pci_bus *bus, void __pci_bus_assign_resources(const struct pci_bus *bus, struct list_head *realloc_head, struct list_head *fail_head); +bool pci_bus_clip_resource(struct pci_dev *dev, int idx); /** * pci_ari_enabled - query ARI forwarding status diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index ed6f89b6efe5..e52356aa09b8 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3028,6 +3028,20 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_REALTEK, 0x8169, DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, PCI_ANY_ID, quirk_broken_intx_masking); +static void quirk_no_bus_reset(struct pci_dev *dev) +{ + dev->dev_flags |= PCI_DEV_FLAGS_NO_BUS_RESET; +} + +/* + * Atheros AR93xx chips do not behave after a bus reset. The device will + * throw a Link Down error on AER-capable systems and regardless of AER, + * config space of the device is never accessible again and typically + * causes the system to hang or reset when access is attempted. + * http://www.spinics.net/lists/linux-pci/msg34797.html + */ +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset); + #ifdef CONFIG_ACPI /* * Apple: Shutdown Cactus Ridge Thunderbolt controller. diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 0482235eee92..e3e17f3c0f0f 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -530,9 +530,8 @@ EXPORT_SYMBOL(pci_setup_cardbus); config space writes, so it's quite possible that an I/O window of the bridge will have some undesirable address (e.g. 0) after the first write. Ditto 64-bit prefetchable MMIO. */ -static void pci_setup_bridge_io(struct pci_bus *bus) +static void pci_setup_bridge_io(struct pci_dev *bridge) { - struct pci_dev *bridge = bus->self; struct resource *res; struct pci_bus_region region; unsigned long io_mask; @@ -545,7 +544,7 @@ static void pci_setup_bridge_io(struct pci_bus *bus) io_mask = PCI_IO_1K_RANGE_MASK; /* Set up the top and bottom of the PCI I/O segment for this bus. */ - res = bus->resource[0]; + res = &bridge->resource[PCI_BRIDGE_RESOURCES + 0]; pcibios_resource_to_bus(bridge->bus, ®ion, res); if (res->flags & IORESOURCE_IO) { pci_read_config_word(bridge, PCI_IO_BASE, &l); @@ -568,15 +567,14 @@ static void pci_setup_bridge_io(struct pci_bus *bus) pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, io_upper16); } -static void pci_setup_bridge_mmio(struct pci_bus *bus) +static void pci_setup_bridge_mmio(struct pci_dev *bridge) { - struct pci_dev *bridge = bus->self; struct resource *res; struct pci_bus_region region; u32 l; /* Set up the top and bottom of the PCI Memory segment for this bus. */ - res = bus->resource[1]; + res = &bridge->resource[PCI_BRIDGE_RESOURCES + 1]; pcibios_resource_to_bus(bridge->bus, ®ion, res); if (res->flags & IORESOURCE_MEM) { l = (region.start >> 16) & 0xfff0; @@ -588,9 +586,8 @@ static void pci_setup_bridge_mmio(struct pci_bus *bus) pci_write_config_dword(bridge, PCI_MEMORY_BASE, l); } -static void pci_setup_bridge_mmio_pref(struct pci_bus *bus) +static void pci_setup_bridge_mmio_pref(struct pci_dev *bridge) { - struct pci_dev *bridge = bus->self; struct resource *res; struct pci_bus_region region; u32 l, bu, lu; @@ -602,7 +599,7 @@ static void pci_setup_bridge_mmio_pref(struct pci_bus *bus) /* Set up PREF base/limit. */ bu = lu = 0; - res = bus->resource[2]; + res = &bridge->resource[PCI_BRIDGE_RESOURCES + 2]; pcibios_resource_to_bus(bridge->bus, ®ion, res); if (res->flags & IORESOURCE_PREFETCH) { l = (region.start >> 16) & 0xfff0; @@ -630,13 +627,13 @@ static void __pci_setup_bridge(struct pci_bus *bus, unsigned long type) &bus->busn_res); if (type & IORESOURCE_IO) - pci_setup_bridge_io(bus); + pci_setup_bridge_io(bridge); if (type & IORESOURCE_MEM) - pci_setup_bridge_mmio(bus); + pci_setup_bridge_mmio(bridge); if (type & IORESOURCE_PREFETCH) - pci_setup_bridge_mmio_pref(bus); + pci_setup_bridge_mmio_pref(bridge); pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); } @@ -649,6 +646,41 @@ void pci_setup_bridge(struct pci_bus *bus) __pci_setup_bridge(bus, type); } + +int pci_claim_bridge_resource(struct pci_dev *bridge, int i) +{ + if (i < PCI_BRIDGE_RESOURCES || i > PCI_BRIDGE_RESOURCE_END) + return 0; + + if (pci_claim_resource(bridge, i) == 0) + return 0; /* claimed the window */ + + if ((bridge->class >> 8) != PCI_CLASS_BRIDGE_PCI) + return 0; + + if (!pci_bus_clip_resource(bridge, i)) + return -EINVAL; /* clipping didn't change anything */ + + switch (i - PCI_BRIDGE_RESOURCES) { + case 0: + pci_setup_bridge_io(bridge); + break; + case 1: + pci_setup_bridge_mmio(bridge); + break; + case 2: + pci_setup_bridge_mmio_pref(bridge); + break; + default: + return -EINVAL; + } + + if (pci_claim_resource(bridge, i) == 0) + return 0; /* claimed a smaller window */ + + return -EINVAL; +} + /* Check whether the bridge supports optional I/O and prefetchable memory ranges. If not, the respective base/limit registers must be read-only and read as 0. */ diff --git a/drivers/phy/phy-miphy28lp.c b/drivers/phy/phy-miphy28lp.c index e34da13885e8..27fa62ce6136 100644 --- a/drivers/phy/phy-miphy28lp.c +++ b/drivers/phy/phy-miphy28lp.c @@ -1050,7 +1050,8 @@ static int miphy28lp_init(struct phy *phy) ret = miphy28lp_init_usb3(miphy_phy); break; default: - return -EINVAL; + ret = -EINVAL; + break; } mutex_unlock(&miphy_dev->miphy_mutex); diff --git a/drivers/phy/phy-omap-control.c b/drivers/phy/phy-omap-control.c index c96e8183a8ff..efe724f97e02 100644 --- a/drivers/phy/phy-omap-control.c +++ b/drivers/phy/phy-omap-control.c @@ -29,10 +29,9 @@ /** * omap_control_pcie_pcs - set the PCS delay count * @dev: the control module device - * @id: index of the pcie PHY (should be 1 or 2) * @delay: 8 bit delay value */ -void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay) +void omap_control_pcie_pcs(struct device *dev, u8 delay) { u32 val; struct omap_control_phy *control_phy; @@ -55,8 +54,8 @@ void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay) val = readl(control_phy->pcie_pcs); val &= ~(OMAP_CTRL_PCIE_PCS_MASK << - (id * OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT)); - val |= delay << (id * OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT); + OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT); + val |= (delay << OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT); writel(val, control_phy->pcie_pcs); } EXPORT_SYMBOL_GPL(omap_control_pcie_pcs); diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c index 4e489a8850e5..6f4aef3db248 100644 --- a/drivers/phy/phy-omap-usb2.c +++ b/drivers/phy/phy-omap-usb2.c @@ -318,7 +318,7 @@ static int omap_usb2_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM static int omap_usb2_runtime_suspend(struct device *dev) { diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c index fb02a67c9181..a2b08f3ccb03 100644 --- a/drivers/phy/phy-sun4i-usb.c +++ b/drivers/phy/phy-sun4i-usb.c @@ -244,7 +244,8 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) else data->num_phys = 3; - if (of_device_is_compatible(np, "allwinner,sun4i-a10-usb-phy")) + if (of_device_is_compatible(np, "allwinner,sun4i-a10-usb-phy") || + of_device_is_compatible(np, "allwinner,sun6i-a31-usb-phy")) data->disc_thresh = 3; else data->disc_thresh = 2; diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c index c297b7a10d30..465de2c800f2 100644 --- a/drivers/phy/phy-ti-pipe3.c +++ b/drivers/phy/phy-ti-pipe3.c @@ -82,7 +82,6 @@ struct ti_pipe3 { struct clk *refclk; struct clk *div_clk; struct pipe3_dpll_map *dpll_map; - u8 id; }; static struct pipe3_dpll_map dpll_map_usb[] = { @@ -217,8 +216,13 @@ static int ti_pipe3_init(struct phy *x) u32 val; int ret = 0; + /* + * Set pcie_pcs register to 0x96 for proper functioning of phy + * as recommended in AM572x TRM SPRUHZ6, section 18.5.2.2, table + * 18-1804. + */ if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) { - omap_control_pcie_pcs(phy->control_dev, phy->id, 0xF1); + omap_control_pcie_pcs(phy->control_dev, 0x96); return 0; } @@ -347,8 +351,6 @@ static int ti_pipe3_probe(struct platform_device *pdev) } if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { - if (of_property_read_u8(node, "id", &phy->id) < 0) - phy->id = 1; clk = devm_clk_get(phy->dev, "dpll_ref"); if (IS_ERR(clk)) { @@ -423,7 +425,7 @@ static int ti_pipe3_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM static int ti_pipe3_runtime_suspend(struct device *dev) { diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index e4f65510c87e..89dca77ca038 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -1801,14 +1801,15 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev) if (pctldev == NULL) return; - mutex_lock(&pinctrldev_list_mutex); mutex_lock(&pctldev->mutex); - pinctrl_remove_device_debugfs(pctldev); + mutex_unlock(&pctldev->mutex); if (!IS_ERR(pctldev->p)) pinctrl_put(pctldev->p); + mutex_lock(&pinctrldev_list_mutex); + mutex_lock(&pctldev->mutex); /* TODO: check that no pinmuxes are still active? */ list_del(&pctldev->node); /* Destroy descriptor tree */ diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index ba74f0aa60c7..43eacc924b7e 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -89,6 +89,7 @@ struct rockchip_iomux { * @reg_pull: optional separate register for additional pull settings * @clk: clock of the gpio bank * @irq: interrupt of the gpio bank + * @saved_enables: Saved content of GPIO_INTEN at suspend time. * @pin_base: first pin number * @nr_pins: number of pins in this bank * @name: name of the bank @@ -107,6 +108,7 @@ struct rockchip_pin_bank { struct regmap *regmap_pull; struct clk *clk; int irq; + u32 saved_enables; u32 pin_base; u8 nr_pins; char *name; @@ -1396,10 +1398,7 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) { struct irq_chip *chip = irq_get_chip(irq); struct rockchip_pin_bank *bank = irq_get_handler_data(irq); - u32 polarity = 0, data = 0; u32 pend; - bool edge_changed = false; - unsigned long flags; dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name); @@ -1407,12 +1406,6 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) pend = readl_relaxed(bank->reg_base + GPIO_INT_STATUS); - if (bank->toggle_edge_mode) { - polarity = readl_relaxed(bank->reg_base + - GPIO_INT_POLARITY); - data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT); - } - while (pend) { unsigned int virq; @@ -1432,27 +1425,31 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) * needs manual intervention. */ if (bank->toggle_edge_mode & BIT(irq)) { - if (data & BIT(irq)) - polarity &= ~BIT(irq); - else - polarity |= BIT(irq); + u32 data, data_old, polarity; + unsigned long flags; - edge_changed = true; - } + data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT); + do { + spin_lock_irqsave(&bank->slock, flags); - generic_handle_irq(virq); - } + polarity = readl_relaxed(bank->reg_base + + GPIO_INT_POLARITY); + if (data & BIT(irq)) + polarity &= ~BIT(irq); + else + polarity |= BIT(irq); + writel(polarity, + bank->reg_base + GPIO_INT_POLARITY); - if (bank->toggle_edge_mode && edge_changed) { - /* Interrupt params should only be set with ints disabled */ - spin_lock_irqsave(&bank->slock, flags); + spin_unlock_irqrestore(&bank->slock, flags); - data = readl_relaxed(bank->reg_base + GPIO_INTEN); - writel_relaxed(0, bank->reg_base + GPIO_INTEN); - writel(polarity, bank->reg_base + GPIO_INT_POLARITY); - writel(data, bank->reg_base + GPIO_INTEN); + data_old = data; + data = readl_relaxed(bank->reg_base + + GPIO_EXT_PORT); + } while ((data & BIT(irq)) != (data_old & BIT(irq))); + } - spin_unlock_irqrestore(&bank->slock, flags); + generic_handle_irq(virq); } chained_irq_exit(chip, desc); @@ -1543,6 +1540,51 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) return 0; } +static void rockchip_irq_suspend(struct irq_data *d) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + struct rockchip_pin_bank *bank = gc->private; + + bank->saved_enables = irq_reg_readl(gc, GPIO_INTEN); + irq_reg_writel(gc, gc->wake_active, GPIO_INTEN); +} + +static void rockchip_irq_resume(struct irq_data *d) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + struct rockchip_pin_bank *bank = gc->private; + + irq_reg_writel(gc, bank->saved_enables, GPIO_INTEN); +} + +static void rockchip_irq_disable(struct irq_data *d) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + u32 val; + + irq_gc_lock(gc); + + val = irq_reg_readl(gc, GPIO_INTEN); + val &= ~d->mask; + irq_reg_writel(gc, val, GPIO_INTEN); + + irq_gc_unlock(gc); +} + +static void rockchip_irq_enable(struct irq_data *d) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + u32 val; + + irq_gc_lock(gc); + + val = irq_reg_readl(gc, GPIO_INTEN); + val |= d->mask; + irq_reg_writel(gc, val, GPIO_INTEN); + + irq_gc_unlock(gc); +} + static int rockchip_interrupts_register(struct platform_device *pdev, struct rockchip_pinctrl *info) { @@ -1581,12 +1623,16 @@ static int rockchip_interrupts_register(struct platform_device *pdev, gc = irq_get_domain_generic_chip(bank->domain, 0); gc->reg_base = bank->reg_base; gc->private = bank; - gc->chip_types[0].regs.mask = GPIO_INTEN; + gc->chip_types[0].regs.mask = GPIO_INTMASK; gc->chip_types[0].regs.ack = GPIO_PORTS_EOI; gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit; - gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; - gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; + gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit; + gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit; + gc->chip_types[0].chip.irq_enable = rockchip_irq_enable; + gc->chip_types[0].chip.irq_disable = rockchip_irq_disable; gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; + gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend; + gc->chip_types[0].chip.irq_resume = rockchip_irq_resume; gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type; gc->wake_enabled = IRQ_MSK(bank->nr_pins); diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c index 7c9d51382248..9e5ec00084bb 100644 --- a/drivers/pinctrl/pinctrl-st.c +++ b/drivers/pinctrl/pinctrl-st.c @@ -1012,8 +1012,10 @@ static void st_pinconf_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, unsigned pin_id) { unsigned long config; - st_pinconf_get(pctldev, pin_id, &config); + mutex_unlock(&pctldev->mutex); + st_pinconf_get(pctldev, pin_id, &config); + mutex_lock(&pctldev->mutex); seq_printf(s, "[OE:%ld,PU:%ld,OD:%ld]\n" "\t\t[retime:%ld,invclk:%ld,clknotdat:%ld," "de:%ld,rt-clk:%ld,rt-delay:%ld]", @@ -1443,6 +1445,7 @@ static struct gpio_chip st_gpio_template = { static struct irq_chip st_gpio_irqchip = { .name = "GPIO", + .irq_disable = st_gpio_irq_mask, .irq_mask = st_gpio_irq_mask, .irq_unmask = st_gpio_irq_unmask, .irq_set_type = st_gpio_irq_set_type, diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c index c5cef59f5965..779950c62e53 100644 --- a/drivers/pinctrl/pinctrl-xway.c +++ b/drivers/pinctrl/pinctrl-xway.c @@ -798,10 +798,8 @@ static int pinmux_xway_probe(struct platform_device *pdev) /* load the gpio chip */ xway_chip.dev = &pdev->dev; - of_gpiochip_add(&xway_chip); ret = gpiochip_add(&xway_chip); if (ret) { - of_gpiochip_remove(&xway_chip); dev_err(&pdev->dev, "Failed to register gpio chip\n"); return ret; } diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index e730935fa457..ed7017df065d 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -865,10 +865,10 @@ static int msm_ps_hold_restart(struct notifier_block *nb, unsigned long action, static void msm_pinctrl_setup_pm_reset(struct msm_pinctrl *pctrl) { - int i = 0; + int i; const struct msm_function *func = pctrl->soc->functions; - for (; i <= pctrl->soc->nfunctions; i++) + for (i = 0; i < pctrl->soc->nfunctions; i++) if (!strcmp(func[i].name, "ps_hold")) { pctrl->restart_nb.notifier_call = msm_ps_hold_restart; pctrl->restart_nb.priority = 128; diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index a2eabe6ff9ad..638e797037da 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -38,7 +38,8 @@ config ACER_WMI config ACERHDF tristate "Acer Aspire One temperature and fan driver" - depends on THERMAL && ACPI + depends on ACPI && THERMAL + select THERMAL_GOV_BANG_BANG ---help--- This is a driver for Acer Aspire One netbooks. It allows to access the temperature sensor and to control the fan. @@ -128,10 +129,10 @@ config DELL_WMI_AIO be called dell-wmi-aio. config DELL_SMO8800 - tristate "Dell Latitude freefall driver (ACPI SMO8800/SMO8810)" + tristate "Dell Latitude freefall driver (ACPI SMO88XX)" depends on ACPI ---help--- - Say Y here if you want to support SMO8800/SMO8810 freefall device + Say Y here if you want to support SMO88XX freefall devices on Dell Latitude laptops. To compile this driver as a module, choose M here: the module will diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index aaf37c5f12f9..594c918b553d 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c @@ -50,7 +50,7 @@ */ #undef START_IN_KERNEL_MODE -#define DRV_VER "0.5.26" +#define DRV_VER "0.7.0" /* * According to the Atom N270 datasheet, @@ -119,116 +119,152 @@ struct fancmd { u8 cmd_auto; }; +struct manualcmd { + u8 mreg; + u8 moff; +}; + +/* default register and command to disable fan in manual mode */ +static const struct manualcmd mcmd = { + .mreg = 0x94, + .moff = 0xff, +}; + /* BIOS settings */ -struct bios_settings_t { +struct bios_settings { const char *vendor; const char *product; const char *version; - unsigned char fanreg; - unsigned char tempreg; + u8 fanreg; + u8 tempreg; struct fancmd cmd; + int mcmd_enable; }; /* Register addresses and values for different BIOS versions */ -static const struct bios_settings_t bios_tbl[] = { +static const struct bios_settings bios_tbl[] = { /* AOA110 */ - {"Acer", "AOA110", "v0.3109", 0x55, 0x58, {0x1f, 0x00} }, - {"Acer", "AOA110", "v0.3114", 0x55, 0x58, {0x1f, 0x00} }, - {"Acer", "AOA110", "v0.3301", 0x55, 0x58, {0xaf, 0x00} }, - {"Acer", "AOA110", "v0.3304", 0x55, 0x58, {0xaf, 0x00} }, - {"Acer", "AOA110", "v0.3305", 0x55, 0x58, {0xaf, 0x00} }, - {"Acer", "AOA110", "v0.3307", 0x55, 0x58, {0xaf, 0x00} }, - {"Acer", "AOA110", "v0.3308", 0x55, 0x58, {0x21, 0x00} }, - {"Acer", "AOA110", "v0.3309", 0x55, 0x58, {0x21, 0x00} }, - {"Acer", "AOA110", "v0.3310", 0x55, 0x58, {0x21, 0x00} }, + {"Acer", "AOA110", "v0.3109", 0x55, 0x58, {0x1f, 0x00}, 0}, + {"Acer", "AOA110", "v0.3114", 0x55, 0x58, {0x1f, 0x00}, 0}, + {"Acer", "AOA110", "v0.3301", 0x55, 0x58, {0xaf, 0x00}, 0}, + {"Acer", "AOA110", "v0.3304", 0x55, 0x58, {0xaf, 0x00}, 0}, + {"Acer", "AOA110", "v0.3305", 0x55, 0x58, {0xaf, 0x00}, 0}, + {"Acer", "AOA110", "v0.3307", 0x55, 0x58, {0xaf, 0x00}, 0}, + {"Acer", "AOA110", "v0.3308", 0x55, 0x58, {0x21, 0x00}, 0}, + {"Acer", "AOA110", "v0.3309", 0x55, 0x58, {0x21, 0x00}, 0}, + {"Acer", "AOA110", "v0.3310", 0x55, 0x58, {0x21, 0x00}, 0}, /* AOA150 */ - {"Acer", "AOA150", "v0.3114", 0x55, 0x58, {0x1f, 0x00} }, - {"Acer", "AOA150", "v0.3301", 0x55, 0x58, {0x20, 0x00} }, - {"Acer", "AOA150", "v0.3304", 0x55, 0x58, {0x20, 0x00} }, - {"Acer", "AOA150", "v0.3305", 0x55, 0x58, {0x20, 0x00} }, - {"Acer", "AOA150", "v0.3307", 0x55, 0x58, {0x20, 0x00} }, - {"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x00} }, - {"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x00} }, - {"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x00} }, + {"Acer", "AOA150", "v0.3114", 0x55, 0x58, {0x1f, 0x00}, 0}, + {"Acer", "AOA150", "v0.3301", 0x55, 0x58, {0x20, 0x00}, 0}, + {"Acer", "AOA150", "v0.3304", 0x55, 0x58, {0x20, 0x00}, 0}, + {"Acer", "AOA150", "v0.3305", 0x55, 0x58, {0x20, 0x00}, 0}, + {"Acer", "AOA150", "v0.3307", 0x55, 0x58, {0x20, 0x00}, 0}, + {"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x00}, 0}, + {"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x00}, 0}, + {"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x00}, 0}, /* LT1005u */ - {"Acer", "LT-10Q", "v0.3310", 0x55, 0x58, {0x20, 0x00} }, + {"Acer", "LT-10Q", "v0.3310", 0x55, 0x58, {0x20, 0x00}, 0}, /* Acer 1410 */ - {"Acer", "Aspire 1410", "v0.3108", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1410", "v0.3113", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1410", "v0.3115", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1410", "v0.3117", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1410", "v0.3119", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1410", "v0.3120", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1410", "v1.3204", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1410", "v1.3303", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1410", "v1.3308", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1410", "v1.3310", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1410", "v1.3314", 0x55, 0x58, {0x9e, 0x00} }, + {"Acer", "Aspire 1410", "v0.3108", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1410", "v0.3113", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1410", "v0.3115", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1410", "v0.3117", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1410", "v0.3119", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1410", "v0.3120", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1410", "v1.3204", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1410", "v1.3303", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1410", "v1.3308", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1410", "v1.3310", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1410", "v1.3314", 0x55, 0x58, {0x9e, 0x00}, 0}, /* Acer 1810xx */ - {"Acer", "Aspire 1810TZ", "v0.3108", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810T", "v0.3108", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810TZ", "v0.3113", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810T", "v0.3113", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810TZ", "v0.3115", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810T", "v0.3115", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810TZ", "v0.3117", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810T", "v0.3117", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810TZ", "v0.3119", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810T", "v0.3119", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810TZ", "v0.3120", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810T", "v0.3120", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810TZ", "v1.3204", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810T", "v1.3204", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810TZ", "v1.3303", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810T", "v1.3303", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810TZ", "v1.3308", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810T", "v1.3308", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810TZ", "v1.3310", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810T", "v1.3310", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810TZ", "v1.3314", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810T", "v1.3314", 0x55, 0x58, {0x9e, 0x00} }, + {"Acer", "Aspire 1810TZ", "v0.3108", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1810T", "v0.3108", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1810TZ", "v0.3113", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1810T", "v0.3113", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1810TZ", "v0.3115", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1810T", "v0.3115", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1810TZ", "v0.3117", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1810T", "v0.3117", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1810TZ", "v0.3119", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1810T", "v0.3119", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1810TZ", "v0.3120", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1810T", "v0.3120", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1810TZ", "v1.3204", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1810T", "v1.3204", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1810TZ", "v1.3303", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1810T", "v1.3303", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1810TZ", "v1.3308", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1810T", "v1.3308", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1810TZ", "v1.3310", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1810T", "v1.3310", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1810TZ", "v1.3314", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1810T", "v1.3314", 0x55, 0x58, {0x9e, 0x00}, 0}, + /* Acer 5755G */ + {"Acer", "Aspire 5755G", "V1.20", 0xab, 0xb4, {0x00, 0x08}, 0}, + {"Acer", "Aspire 5755G", "V1.21", 0xab, 0xb3, {0x00, 0x08}, 0}, + /* Acer 521 */ + {"Acer", "AO521", "V1.11", 0x55, 0x58, {0x1f, 0x00}, 0}, /* Acer 531 */ - {"Acer", "AO531h", "v0.3104", 0x55, 0x58, {0x20, 0x00} }, - {"Acer", "AO531h", "v0.3201", 0x55, 0x58, {0x20, 0x00} }, - {"Acer", "AO531h", "v0.3304", 0x55, 0x58, {0x20, 0x00} }, + {"Acer", "AO531h", "v0.3104", 0x55, 0x58, {0x20, 0x00}, 0}, + {"Acer", "AO531h", "v0.3201", 0x55, 0x58, {0x20, 0x00}, 0}, + {"Acer", "AO531h", "v0.3304", 0x55, 0x58, {0x20, 0x00}, 0}, /* Acer 751 */ - {"Acer", "AO751h", "V0.3212", 0x55, 0x58, {0x21, 0x00} }, + {"Acer", "AO751h", "V0.3206", 0x55, 0x58, {0x21, 0x00}, 0}, + {"Acer", "AO751h", "V0.3212", 0x55, 0x58, {0x21, 0x00}, 0}, + /* Acer 753 */ + {"Acer", "Aspire One 753", "V1.24", 0x93, 0xac, {0x14, 0x04}, 1}, /* Acer 1825 */ - {"Acer", "Aspire 1825PTZ", "V1.3118", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1825PTZ", "V1.3127", 0x55, 0x58, {0x9e, 0x00} }, + {"Acer", "Aspire 1825PTZ", "V1.3118", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Acer", "Aspire 1825PTZ", "V1.3127", 0x55, 0x58, {0x9e, 0x00}, 0}, + /* Acer Extensa 5420 */ + {"Acer", "Extensa 5420", "V1.17", 0x93, 0xac, {0x14, 0x04}, 1}, + /* Acer Aspire 5315 */ + {"Acer", "Aspire 5315", "V1.19", 0x93, 0xac, {0x14, 0x04}, 1}, + /* Acer Aspire 5739 */ + {"Acer", "Aspire 5739G", "V1.3311", 0x55, 0x58, {0x20, 0x00}, 0}, /* Acer TravelMate 7730 */ - {"Acer", "TravelMate 7730G", "v0.3509", 0x55, 0x58, {0xaf, 0x00} }, + {"Acer", "TravelMate 7730G", "v0.3509", 0x55, 0x58, {0xaf, 0x00}, 0}, + /* Acer TravelMate TM8573T */ + {"Acer", "TM8573T", "V1.13", 0x93, 0xa8, {0x14, 0x04}, 1}, /* Gateway */ - {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x00} }, - {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x00} }, - {"Gateway", "LT31", "v1.3103", 0x55, 0x58, {0x9e, 0x00} }, - {"Gateway", "LT31", "v1.3201", 0x55, 0x58, {0x9e, 0x00} }, - {"Gateway", "LT31", "v1.3302", 0x55, 0x58, {0x9e, 0x00} }, - {"Gateway", "LT31", "v1.3303t", 0x55, 0x58, {0x9e, 0x00} }, + {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x00}, 0}, + {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x00}, 0}, + {"Gateway", "LT31", "v1.3103", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Gateway", "LT31", "v1.3201", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Gateway", "LT31", "v1.3302", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Gateway", "LT31", "v1.3303t", 0x55, 0x58, {0x9e, 0x00}, 0}, /* Packard Bell */ - {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00} }, - {"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} }, - {"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x00} }, - {"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} }, - {"Packard Bell", "ENBFT", "V1.3118", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "ENBFT", "V1.3127", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v1.3303", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v0.3120", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v0.3108", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v0.3113", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v0.3115", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v0.3117", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v0.3119", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v1.3204", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMA", "v1.3201", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMA", "v1.3302", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMA", "v1.3303t", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTVR46", "v1.3308", 0x55, 0x58, {0x9e, 0x00} }, + {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00}, 0}, + {"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00}, 0}, + {"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x00}, 0}, + {"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00}, 0}, + {"Packard Bell", "ENBFT", "V1.3118", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Packard Bell", "ENBFT", "V1.3127", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Packard Bell", "DOTMU", "v1.3303", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Packard Bell", "DOTMU", "v0.3120", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Packard Bell", "DOTMU", "v0.3108", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Packard Bell", "DOTMU", "v0.3113", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Packard Bell", "DOTMU", "v0.3115", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Packard Bell", "DOTMU", "v0.3117", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Packard Bell", "DOTMU", "v0.3119", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Packard Bell", "DOTMU", "v1.3204", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Packard Bell", "DOTMA", "v1.3201", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Packard Bell", "DOTMA", "v1.3302", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Packard Bell", "DOTMA", "v1.3303t", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Packard Bell", "DOTVR46", "v1.3308", 0x55, 0x58, {0x9e, 0x00}, 0}, /* pewpew-terminator */ - {"", "", "", 0, 0, {0, 0} } + {"", "", "", 0, 0, {0, 0}, 0} }; -static const struct bios_settings_t *bios_cfg __read_mostly; +static const struct bios_settings *bios_cfg __read_mostly; + +/* + * this struct is used to instruct thermal layer to use bang_bang instead of + * default governor for acerhdf + */ +static struct thermal_zone_params acerhdf_zone_params = { + .governor_name = "bang_bang", +}; static int acerhdf_get_temp(int *temp) { @@ -275,6 +311,12 @@ static void acerhdf_change_fanstate(int state) fanstate = state; ec_write(bios_cfg->fanreg, cmd); + + if (bios_cfg->mcmd_enable && state == ACERHDF_FAN_OFF) { + if (verbose) + pr_notice("turning off fan manually\n"); + ec_write(mcmd.mreg, mcmd.moff); + } } static void acerhdf_check_param(struct thermal_zone_device *thermal) @@ -401,6 +443,21 @@ static int acerhdf_get_trip_type(struct thermal_zone_device *thermal, int trip, { if (trip == 0) *type = THERMAL_TRIP_ACTIVE; + else if (trip == 1) + *type = THERMAL_TRIP_CRITICAL; + else + return -EINVAL; + + return 0; +} + +static int acerhdf_get_trip_hyst(struct thermal_zone_device *thermal, int trip, + unsigned long *temp) +{ + if (trip != 0) + return -EINVAL; + + *temp = fanon - fanoff; return 0; } @@ -410,6 +467,10 @@ static int acerhdf_get_trip_temp(struct thermal_zone_device *thermal, int trip, { if (trip == 0) *temp = fanon; + else if (trip == 1) + *temp = ACERHDF_TEMP_CRIT; + else + return -EINVAL; return 0; } @@ -429,6 +490,7 @@ static struct thermal_zone_device_ops acerhdf_dev_ops = { .get_mode = acerhdf_get_mode, .set_mode = acerhdf_set_mode, .get_trip_type = acerhdf_get_trip_type, + .get_trip_hyst = acerhdf_get_trip_hyst, .get_trip_temp = acerhdf_get_trip_temp, .get_crit_temp = acerhdf_get_crit_temp, }; @@ -481,9 +543,7 @@ static int acerhdf_set_cur_state(struct thermal_cooling_device *cdev, } if (state == 0) { - /* turn fan off only if below fanoff temperature */ - if ((cur_state == ACERHDF_FAN_AUTO) && - (cur_temp < fanoff)) + if (cur_state == ACERHDF_FAN_AUTO) acerhdf_change_fanstate(ACERHDF_FAN_OFF); } else { if (cur_state == ACERHDF_FAN_OFF) @@ -558,7 +618,7 @@ static int str_starts_with(const char *str, const char *start) static int acerhdf_check_hardware(void) { char const *vendor, *version, *product; - const struct bios_settings_t *bt = NULL; + const struct bios_settings *bt = NULL; /* get BIOS data */ vendor = dmi_get_system_info(DMI_SYS_VENDOR); @@ -660,12 +720,20 @@ static int acerhdf_register_thermal(void) if (IS_ERR(cl_dev)) return -EINVAL; - thz_dev = thermal_zone_device_register("acerhdf", 1, 0, NULL, - &acerhdf_dev_ops, NULL, 0, + thz_dev = thermal_zone_device_register("acerhdf", 2, 0, NULL, + &acerhdf_dev_ops, + &acerhdf_zone_params, 0, (kernelmode) ? interval*1000 : 0); if (IS_ERR(thz_dev)) return -EINVAL; + if (strcmp(thz_dev->governor->name, + acerhdf_zone_params.governor_name)) { + pr_err("Didn't get thermal governor %s, perhaps not compiled into thermal subsystem.\n", + acerhdf_zone_params.governor_name); + return -EINVAL; + } + return 0; } @@ -722,9 +790,15 @@ MODULE_ALIAS("dmi:*:*Acer*:pnAOA*:"); MODULE_ALIAS("dmi:*:*Acer*:pnAO751h*:"); MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1410*:"); MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1810*:"); +MODULE_ALIAS("dmi:*:*Acer*:pnAspire*5755G:"); MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1825PTZ:"); +MODULE_ALIAS("dmi:*:*Acer*:pnAO521*:"); MODULE_ALIAS("dmi:*:*Acer*:pnAO531*:"); +MODULE_ALIAS("dmi:*:*Acer*:pnAspire*5739G:"); +MODULE_ALIAS("dmi:*:*Acer*:pnAspire*One*753:"); +MODULE_ALIAS("dmi:*:*Acer*:pnAspire*5315:"); MODULE_ALIAS("dmi:*:*Acer*:TravelMate*7730G:"); +MODULE_ALIAS("dmi:*:*Acer*:TM8573T:"); MODULE_ALIAS("dmi:*:*Gateway*:pnAOA*:"); MODULE_ALIAS("dmi:*:*Gateway*:pnLT31*:"); MODULE_ALIAS("dmi:*:*Packard*Bell*:pnAOA*:"); @@ -733,6 +807,7 @@ MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTMU*:"); MODULE_ALIAS("dmi:*:*Packard*Bell*:pnENBFT*:"); MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTMA*:"); MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTVR46*:"); +MODULE_ALIAS("dmi:*:*Acer*:pnExtensa 5420*:"); module_init(acerhdf_init); module_exit(acerhdf_exit); diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 05647f1a427e..f71700e0d132 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -843,8 +843,7 @@ static int asus_backlight_init(struct asus_laptop *asus) static void asus_backlight_exit(struct asus_laptop *asus) { - if (asus->backlight_device) - backlight_device_unregister(asus->backlight_device); + backlight_device_unregister(asus->backlight_device); asus->backlight_device = NULL; } diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c index c1a6cd66af42..abdaed34c728 100644 --- a/drivers/platform/x86/asus-nb-wmi.c +++ b/drivers/platform/x86/asus-nb-wmi.c @@ -191,6 +191,15 @@ static const struct dmi_system_id asus_quirks[] = { }, { .callback = dmi_matched, + .ident = "ASUSTeK COMPUTER INC. X551CA", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X551CA"), + }, + .driver_data = &quirk_asus_wapf4, + }, + { + .callback = dmi_matched, .ident = "ASUSTeK COMPUTER INC. X55A", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 21fc932da3a1..7543a56e0f45 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -1308,8 +1308,7 @@ static int asus_wmi_backlight_init(struct asus_wmi *asus) static void asus_wmi_backlight_exit(struct asus_wmi *asus) { - if (asus->backlight_device) - backlight_device_unregister(asus->backlight_device); + backlight_device_unregister(asus->backlight_device); asus->backlight_device = NULL; } diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index f6a28d7161f5..3d21efe11d7b 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -563,7 +563,7 @@ static bool dell_laptop_i8042_filter(unsigned char data, unsigned char str, { static bool extended; - if (str & 0x20) + if (str & I8042_STR_AUXDATA) return false; if (unlikely(data == 0xe0)) { diff --git a/drivers/platform/x86/dell-smo8800.c b/drivers/platform/x86/dell-smo8800.c index a653716055d1..0aec4fd4c48e 100644 --- a/drivers/platform/x86/dell-smo8800.c +++ b/drivers/platform/x86/dell-smo8800.c @@ -1,5 +1,5 @@ /* - * dell-smo8800.c - Dell Latitude ACPI SMO8800/SMO8810 freefall sensor driver + * dell-smo8800.c - Dell Latitude ACPI SMO88XX freefall sensor driver * * Copyright (C) 2012 Sonal Santan <sonal.santan@gmail.com> * Copyright (C) 2014 Pali Rohár <pali.rohar@gmail.com> @@ -209,7 +209,13 @@ static int smo8800_remove(struct acpi_device *device) static const struct acpi_device_id smo8800_ids[] = { { "SMO8800", 0 }, + { "SMO8801", 0 }, { "SMO8810", 0 }, + { "SMO8811", 0 }, + { "SMO8820", 0 }, + { "SMO8821", 0 }, + { "SMO8830", 0 }, + { "SMO8831", 0 }, { "", 0 }, }; @@ -228,6 +234,6 @@ static struct acpi_driver smo8800_driver = { module_acpi_driver(smo8800_driver); -MODULE_DESCRIPTION("Dell Latitude freefall driver (ACPI SMO8800/SMO8810)"); +MODULE_DESCRIPTION("Dell Latitude freefall driver (ACPI SMO88XX)"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Sonal Santan, Pali Rohár"); diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 25721bf20092..6512a06bc053 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c @@ -65,10 +65,8 @@ static const struct key_entry dell_wmi_legacy_keymap[] __initconst = { /* Battery health status button */ { KE_KEY, 0xe007, { KEY_BATTERY } }, - /* This is actually for all radios. Although physically a - * switch, the notification does not provide an indication of - * state and so it should be reported as a key */ - { KE_KEY, 0xe008, { KEY_WLAN } }, + /* Radio devices state change */ + { KE_IGNORE, 0xe008, { KEY_RFKILL } }, /* The next device is at offset 6, the active devices are at offset 8 and the attached devices at offset 10 */ @@ -145,57 +143,154 @@ static const u16 bios_to_linux_keycode[256] __initconst = { static struct input_dev *dell_wmi_input_dev; +static void dell_wmi_process_key(int reported_key) +{ + const struct key_entry *key; + + key = sparse_keymap_entry_from_scancode(dell_wmi_input_dev, + reported_key); + if (!key) { + pr_info("Unknown key %x pressed\n", reported_key); + return; + } + + pr_debug("Key %x pressed\n", reported_key); + + /* Don't report brightness notifications that will also come via ACPI */ + if ((key->keycode == KEY_BRIGHTNESSUP || + key->keycode == KEY_BRIGHTNESSDOWN) && acpi_video) + return; + + sparse_keymap_report_entry(dell_wmi_input_dev, key, 1, true); +} + static void dell_wmi_notify(u32 value, void *context) { struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *obj; acpi_status status; + acpi_size buffer_size; + u16 *buffer_entry, *buffer_end; + int len, i; status = wmi_get_event_data(value, &response); if (status != AE_OK) { - pr_info("bad event status 0x%x\n", status); + pr_warn("bad event status 0x%x\n", status); return; } obj = (union acpi_object *)response.pointer; + if (!obj) { + pr_warn("no response\n"); + return; + } - if (obj && obj->type == ACPI_TYPE_BUFFER) { - const struct key_entry *key; - int reported_key; - u16 *buffer_entry = (u16 *)obj->buffer.pointer; - int buffer_size = obj->buffer.length/2; - - if (buffer_size >= 2 && dell_new_hk_type && buffer_entry[1] != 0x10) { - pr_info("Received unknown WMI event (0x%x)\n", - buffer_entry[1]); - kfree(obj); - return; - } + if (obj->type != ACPI_TYPE_BUFFER) { + pr_warn("bad response type %x\n", obj->type); + kfree(obj); + return; + } - if (buffer_size >= 3 && (dell_new_hk_type || buffer_entry[1] == 0x0)) - reported_key = (int)buffer_entry[2]; + pr_debug("Received WMI event (%*ph)\n", + obj->buffer.length, obj->buffer.pointer); + + buffer_entry = (u16 *)obj->buffer.pointer; + buffer_size = obj->buffer.length/2; + + if (!dell_new_hk_type) { + if (buffer_size >= 3 && buffer_entry[1] == 0x0) + dell_wmi_process_key(buffer_entry[2]); else if (buffer_size >= 2) - reported_key = (int)buffer_entry[1] & 0xffff; - else { + dell_wmi_process_key(buffer_entry[1]); + else pr_info("Received unknown WMI event\n"); - kfree(obj); - return; + kfree(obj); + return; + } + + buffer_end = buffer_entry + buffer_size; + + while (buffer_entry < buffer_end) { + + len = buffer_entry[0]; + if (len == 0) + break; + + len++; + + if (buffer_entry + len > buffer_end) { + pr_warn("Invalid length of WMI event\n"); + break; } - key = sparse_keymap_entry_from_scancode(dell_wmi_input_dev, - reported_key); - if (!key) { - pr_info("Unknown key %x pressed\n", reported_key); - } else if ((key->keycode == KEY_BRIGHTNESSUP || - key->keycode == KEY_BRIGHTNESSDOWN) && acpi_video) { - /* Don't report brightness notifications that will also - * come via ACPI */ - ; - } else { - sparse_keymap_report_entry(dell_wmi_input_dev, key, - 1, true); + pr_debug("Process buffer (%*ph)\n", len*2, buffer_entry); + + switch (buffer_entry[1]) { + case 0x00: + for (i = 2; i < len; ++i) { + switch (buffer_entry[i]) { + case 0xe043: + /* NIC Link is Up */ + pr_debug("NIC Link is Up\n"); + break; + case 0xe044: + /* NIC Link is Down */ + pr_debug("NIC Link is Down\n"); + break; + case 0xe045: + /* Unknown event but defined in DSDT */ + default: + /* Unknown event */ + pr_info("Unknown WMI event type 0x00: " + "0x%x\n", (int)buffer_entry[i]); + break; + } + } + break; + case 0x10: + /* Keys pressed */ + for (i = 2; i < len; ++i) + dell_wmi_process_key(buffer_entry[i]); + break; + case 0x11: + for (i = 2; i < len; ++i) { + switch (buffer_entry[i]) { + case 0xfff0: + /* Battery unplugged */ + pr_debug("Battery unplugged\n"); + break; + case 0xfff1: + /* Battery inserted */ + pr_debug("Battery inserted\n"); + break; + case 0x01e1: + case 0x02ea: + case 0x02eb: + case 0x02ec: + case 0x02f6: + /* Keyboard backlight level changed */ + pr_debug("Keyboard backlight level " + "changed\n"); + break; + default: + /* Unknown event */ + pr_info("Unknown WMI event type 0x11: " + "0x%x\n", (int)buffer_entry[i]); + break; + } + } + break; + default: + /* Unknown event */ + pr_info("Unknown WMI event type 0x%x\n", + (int)buffer_entry[1]); + break; } + + buffer_entry += len; + } + kfree(obj); } @@ -213,11 +308,16 @@ static const struct key_entry * __init dell_wmi_prepare_new_keymap(void) for (i = 0; i < hotkey_num; i++) { const struct dell_bios_keymap_entry *bios_entry = &dell_bios_hotkey_table->keymap[i]; - keymap[i].type = KE_KEY; - keymap[i].code = bios_entry->scancode; - keymap[i].keycode = bios_entry->keycode < 256 ? + u16 keycode = bios_entry->keycode < 256 ? bios_to_linux_keycode[bios_entry->keycode] : KEY_RESERVED; + + if (keycode == KEY_KBDILLUMTOGGLE) + keymap[i].type = KE_IGNORE; + else + keymap[i].type = KE_KEY; + keymap[i].code = bios_entry->scancode; + keymap[i].keycode = keycode; } keymap[hotkey_num].type = KE_END; diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 5a54d35a61de..844c2096bde9 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -417,8 +417,7 @@ static ssize_t cpufv_disabled_store(struct device *dev, switch (value) { case 0: if (eeepc->cpufv_disabled) - pr_warn("cpufv enabled (not officially supported " - "on this model)\n"); + pr_warn("cpufv enabled (not officially supported on this model)\n"); eeepc->cpufv_disabled = false; return count; case 1: @@ -580,59 +579,58 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) mutex_lock(&eeepc->hotplug_lock); pci_lock_rescan_remove(); - if (eeepc->hotplug_slot) { - port = acpi_get_pci_dev(handle); - if (!port) { - pr_warning("Unable to find port\n"); - goto out_unlock; - } + if (!eeepc->hotplug_slot) + goto out_unlock; - bus = port->subordinate; + port = acpi_get_pci_dev(handle); + if (!port) { + pr_warning("Unable to find port\n"); + goto out_unlock; + } - if (!bus) { - pr_warn("Unable to find PCI bus 1?\n"); - goto out_put_dev; - } + bus = port->subordinate; - if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) { - pr_err("Unable to read PCI config space?\n"); - goto out_put_dev; - } + if (!bus) { + pr_warn("Unable to find PCI bus 1?\n"); + goto out_put_dev; + } + + if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) { + pr_err("Unable to read PCI config space?\n"); + goto out_put_dev; + } - absent = (l == 0xffffffff); + absent = (l == 0xffffffff); - if (blocked != absent) { - pr_warn("BIOS says wireless lan is %s, " - "but the pci device is %s\n", - blocked ? "blocked" : "unblocked", - absent ? "absent" : "present"); - pr_warn("skipped wireless hotplug as probably " - "inappropriate for this model\n"); + if (blocked != absent) { + pr_warn("BIOS says wireless lan is %s, but the pci device is %s\n", + blocked ? "blocked" : "unblocked", + absent ? "absent" : "present"); + pr_warn("skipped wireless hotplug as probably inappropriate for this model\n"); + goto out_put_dev; + } + + if (!blocked) { + dev = pci_get_slot(bus, 0); + if (dev) { + /* Device already present */ + pci_dev_put(dev); goto out_put_dev; } - - if (!blocked) { - dev = pci_get_slot(bus, 0); - if (dev) { - /* Device already present */ - pci_dev_put(dev); - goto out_put_dev; - } - dev = pci_scan_single_device(bus, 0); - if (dev) { - pci_bus_assign_resources(bus); - pci_bus_add_device(dev); - } - } else { - dev = pci_get_slot(bus, 0); - if (dev) { - pci_stop_and_remove_bus_device(dev); - pci_dev_put(dev); - } + dev = pci_scan_single_device(bus, 0); + if (dev) { + pci_bus_assign_resources(bus); + pci_bus_add_device(dev); + } + } else { + dev = pci_get_slot(bus, 0); + if (dev) { + pci_stop_and_remove_bus_device(dev); + pci_dev_put(dev); } -out_put_dev: - pci_dev_put(port); } +out_put_dev: + pci_dev_put(port); out_unlock: pci_unlock_rescan_remove(); @@ -821,11 +819,15 @@ static int eeepc_new_rfkill(struct eeepc_laptop *eeepc, return 0; } +static char EEEPC_RFKILL_NODE_1[] = "\\_SB.PCI0.P0P5"; +static char EEEPC_RFKILL_NODE_2[] = "\\_SB.PCI0.P0P6"; +static char EEEPC_RFKILL_NODE_3[] = "\\_SB.PCI0.P0P7"; + static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc) { - eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5"); - eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6"); - eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7"); + eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_1); + eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_2); + eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_3); if (eeepc->wlan_rfkill) { rfkill_unregister(eeepc->wlan_rfkill); rfkill_destroy(eeepc->wlan_rfkill); @@ -897,9 +899,9 @@ static int eeepc_rfkill_init(struct eeepc_laptop *eeepc) if (result == -EBUSY) result = 0; - eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5"); - eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6"); - eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7"); + eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_1); + eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_2); + eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_3); exit: if (result && result != -ENODEV) @@ -915,7 +917,7 @@ static int eeepc_hotk_thaw(struct device *device) struct eeepc_laptop *eeepc = dev_get_drvdata(device); if (eeepc->wlan_rfkill) { - bool wlan; + int wlan; /* * Work around bios bug - acpi _PTS turns off the wireless led @@ -923,7 +925,8 @@ static int eeepc_hotk_thaw(struct device *device) * we should kick it ourselves in case hibernation is aborted. */ wlan = get_acpi(eeepc, CM_ASL_WLAN); - set_acpi(eeepc, CM_ASL_WLAN, wlan); + if (wlan >= 0) + set_acpi(eeepc, CM_ASL_WLAN, wlan); } return 0; @@ -935,9 +938,9 @@ static int eeepc_hotk_restore(struct device *device) /* Refresh both wlan rfkill state and pci hotplug */ if (eeepc->wlan_rfkill) { - eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P5"); - eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P6"); - eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P7"); + eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_1); + eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_2); + eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_3); } if (eeepc->bluetooth_rfkill) @@ -977,18 +980,28 @@ static struct platform_driver platform_driver = { #define EEEPC_EC_SFB0 0xD0 #define EEEPC_EC_FAN_CTRL (EEEPC_EC_SFB0 + 3) /* Byte containing SF25 */ +static inline int eeepc_pwm_to_lmsensors(int value) +{ + return value * 255 / 100; +} + +static inline int eeepc_lmsensors_to_pwm(int value) +{ + value = clamp_val(value, 0, 255); + return value * 100 / 255; +} + static int eeepc_get_fan_pwm(void) { u8 value = 0; ec_read(EEEPC_EC_FAN_PWM, &value); - return value * 255 / 100; + return eeepc_pwm_to_lmsensors(value); } static void eeepc_set_fan_pwm(int value) { - value = clamp_val(value, 0, 255); - value = value * 100 / 255; + value = eeepc_lmsensors_to_pwm(value); ec_write(EEEPC_EC_FAN_PWM, value); } @@ -1002,15 +1015,19 @@ static int eeepc_get_fan_rpm(void) return high << 8 | low; } +#define EEEPC_EC_FAN_CTRL_BIT 0x02 +#define EEEPC_FAN_CTRL_MANUAL 1 +#define EEEPC_FAN_CTRL_AUTO 2 + static int eeepc_get_fan_ctrl(void) { u8 value = 0; ec_read(EEEPC_EC_FAN_CTRL, &value); - if (value & 0x02) - return 1; /* manual */ + if (value & EEEPC_EC_FAN_CTRL_BIT) + return EEEPC_FAN_CTRL_MANUAL; else - return 2; /* automatic */ + return EEEPC_FAN_CTRL_AUTO; } static void eeepc_set_fan_ctrl(int manual) @@ -1018,10 +1035,10 @@ static void eeepc_set_fan_ctrl(int manual) u8 value = 0; ec_read(EEEPC_EC_FAN_CTRL, &value); - if (manual == 1) - value |= 0x02; + if (manual == EEEPC_FAN_CTRL_MANUAL) + value |= EEEPC_EC_FAN_CTRL_BIT; else - value &= ~0x02; + value &= ~EEEPC_EC_FAN_CTRL_BIT; ec_write(EEEPC_EC_FAN_CTRL, value); } @@ -1156,8 +1173,7 @@ static int eeepc_backlight_init(struct eeepc_laptop *eeepc) static void eeepc_backlight_exit(struct eeepc_laptop *eeepc) { - if (eeepc->backlight_device) - backlight_device_unregister(eeepc->backlight_device); + backlight_device_unregister(eeepc->backlight_device); eeepc->backlight_device = NULL; } @@ -1216,7 +1232,7 @@ static void eeepc_input_exit(struct eeepc_laptop *eeepc) static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event) { if (!eeepc->inputdev) - return ; + return; if (!sparse_keymap_report_event(eeepc->inputdev, event, 1, true)) pr_info("Unknown key %x pressed\n", event); } @@ -1224,6 +1240,7 @@ static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event) static void eeepc_acpi_notify(struct acpi_device *device, u32 event) { struct eeepc_laptop *eeepc = acpi_driver_data(device); + int old_brightness, new_brightness; u16 count; if (event > ACPI_MAX_SYS_NOTIFY) @@ -1234,34 +1251,32 @@ static void eeepc_acpi_notify(struct acpi_device *device, u32 event) count); /* Brightness events are special */ - if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) { - - /* Ignore them completely if the acpi video driver is used */ - if (eeepc->backlight_device != NULL) { - int old_brightness, new_brightness; - - /* Update the backlight device. */ - old_brightness = eeepc_backlight_notify(eeepc); - - /* Convert event to keypress (obsolescent hack) */ - new_brightness = event - NOTIFY_BRN_MIN; - - if (new_brightness < old_brightness) { - event = NOTIFY_BRN_MIN; /* brightness down */ - } else if (new_brightness > old_brightness) { - event = NOTIFY_BRN_MAX; /* brightness up */ - } else { - /* - * no change in brightness - already at min/max, - * event will be desired value (or else ignored) - */ - } - eeepc_input_notify(eeepc, event); - } - } else { - /* Everything else is a bona-fide keypress event */ + if (event < NOTIFY_BRN_MIN || event > NOTIFY_BRN_MAX) { eeepc_input_notify(eeepc, event); + return; + } + + /* Ignore them completely if the acpi video driver is used */ + if (!eeepc->backlight_device) + return; + + /* Update the backlight device. */ + old_brightness = eeepc_backlight_notify(eeepc); + + /* Convert event to keypress (obsolescent hack) */ + new_brightness = event - NOTIFY_BRN_MIN; + + if (new_brightness < old_brightness) { + event = NOTIFY_BRN_MIN; /* brightness down */ + } else if (new_brightness > old_brightness) { + event = NOTIFY_BRN_MAX; /* brightness up */ + } else { + /* + * no change in brightness - already at min/max, + * event will be desired value (or else ignored) + */ } + eeepc_input_notify(eeepc, event); } static void eeepc_dmi_check(struct eeepc_laptop *eeepc) @@ -1293,8 +1308,8 @@ static void eeepc_dmi_check(struct eeepc_laptop *eeepc) */ if (strcmp(model, "701") == 0 || strcmp(model, "702") == 0) { eeepc->cpufv_disabled = true; - pr_info("model %s does not officially support setting cpu " - "speed\n", model); + pr_info("model %s does not officially support setting cpu speed\n", + model); pr_info("cpufv disabled to avoid instability\n"); } @@ -1320,8 +1335,8 @@ static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name) Check if cm_getv[cm] works and, if yes, assume cm should be set. */ if (!(eeepc->cm_supported & (1 << cm)) && !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) { - pr_info("%s (%x) not reported by BIOS," - " enabling anyway\n", name, 1 << cm); + pr_info("%s (%x) not reported by BIOS, enabling anyway\n", + name, 1 << cm); eeepc->cm_supported |= 1 << cm; } } diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index be55bd78b503..7c21c1c44dfa 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -1153,8 +1153,7 @@ fail_hotkey1: fail_hotkey: platform_driver_unregister(&fujitsupf_driver); fail_backlight: - if (fujitsu->bl_device) - backlight_device_unregister(fujitsu->bl_device); + backlight_device_unregister(fujitsu->bl_device); fail_sysfs_group: sysfs_remove_group(&fujitsu->pf_device->dev.kobj, &fujitsupf_attribute_group); @@ -1178,8 +1177,7 @@ static void __exit fujitsu_cleanup(void) platform_driver_unregister(&fujitsupf_driver); - if (fujitsu->bl_device) - backlight_device_unregister(fujitsu->bl_device); + backlight_device_unregister(fujitsu->bl_device); sysfs_remove_group(&fujitsu->pf_device->dev.kobj, &fujitsupf_attribute_group); diff --git a/drivers/platform/x86/hp-wireless.c b/drivers/platform/x86/hp-wireless.c index 415348fc1210..4e4cc8bd7557 100644 --- a/drivers/platform/x86/hp-wireless.c +++ b/drivers/platform/x86/hp-wireless.c @@ -85,6 +85,9 @@ static int hpwl_add(struct acpi_device *device) int err; err = hp_wireless_input_setup(); + if (err) + pr_err("Failed to setup hp wireless hotkeys\n"); + return err; } diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index 6bec745b6b92..10ce6cba4455 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c @@ -246,6 +246,7 @@ static const struct dmi_system_id lis3lv02d_dmi_ids[] = { AXIS_DMI_MATCH("HPB64xx", "HP ProBook 64", xy_swap), AXIS_DMI_MATCH("HPB64xx", "HP EliteBook 84", xy_swap), AXIS_DMI_MATCH("HPB65xx", "HP ProBook 65", x_inverted), + AXIS_DMI_MATCH("HPZBook15", "HP ZBook 15", x_inverted), { NULL, } /* Laptop models without axis info (yet): * "NC6910" "HP Compaq 6910" diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index c860eace1ce3..b3d419a84723 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -729,8 +729,7 @@ static int ideapad_backlight_init(struct ideapad_private *priv) static void ideapad_backlight_exit(struct ideapad_private *priv) { - if (priv->blightdev) - backlight_device_unregister(priv->blightdev); + backlight_device_unregister(priv->blightdev); priv->blightdev = NULL; } diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index ecd36e332c3c..e2065e06a3f3 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -33,7 +33,7 @@ * performance by allocating more power or thermal budget to the CPU or GPU * based on available headroom and activity. * - * The basic algorithm is driven by a 5s moving average of tempurature. If + * The basic algorithm is driven by a 5s moving average of temperature. If * thermal headroom is available, the CPU and/or GPU power clamps may be * adjusted upwards. If we hit the thermal ceiling or a thermal trigger, * we scale back the clamp. Aside from trigger events (when we're critically diff --git a/drivers/platform/x86/intel_oaktrail.c b/drivers/platform/x86/intel_oaktrail.c index 0afaaef5711f..a4a4258f6134 100644 --- a/drivers/platform/x86/intel_oaktrail.c +++ b/drivers/platform/x86/intel_oaktrail.c @@ -271,8 +271,7 @@ static int oaktrail_backlight_init(void) static void oaktrail_backlight_exit(void) { - if (oaktrail_bl_device) - backlight_device_unregister(oaktrail_bl_device); + backlight_device_unregister(oaktrail_bl_device); } static int oaktrail_probe(struct platform_device *pdev) diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index a3f06cb1063f..085987730aab 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c @@ -820,7 +820,7 @@ static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str, { static bool extended; - if (str & 0x20) + if (str & I8042_STR_AUXDATA) return false; /* 0x54 wwan, 0x62 bluetooth, 0x76 wlan, 0xE4 touchpad toggle*/ diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c index 70222f265f68..6d2bac0c463c 100644 --- a/drivers/platform/x86/msi-wmi.c +++ b/drivers/platform/x86/msi-wmi.c @@ -354,8 +354,7 @@ static void __exit msi_wmi_exit(void) sparse_keymap_free(msi_wmi_input_dev); input_unregister_device(msi_wmi_input_dev); } - if (backlight) - backlight_device_unregister(backlight); + backlight_device_unregister(backlight); } module_init(msi_wmi_init); diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index a1a0fd72e9bf..6dd1c0e7dcd9 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -3140,8 +3140,7 @@ static void sony_nc_backlight_setup(void) static void sony_nc_backlight_cleanup(void) { - if (sony_bl_props.dev) - backlight_device_unregister(sony_bl_props.dev); + backlight_device_unregister(sony_bl_props.dev); } static int sony_nc_add(struct acpi_device *device) @@ -3716,8 +3715,7 @@ static void sony_pic_detect_device_type(struct sony_pic_dev *dev) dev->event_types = type2_events; out: - if (pcidev) - pci_dev_put(pcidev); + pci_dev_put(pcidev); pr_info("detected Type%d model\n", dev->model == SONYPI_DEVICE_TYPE1 ? 1 : diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 6414cfe5d848..c3d11fabc46f 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -6557,6 +6557,17 @@ static struct ibm_struct brightness_driver_data = { * bits 3-0 (volume). Other bits in NVRAM may have other functions, * such as bit 7 which is used to detect repeated presses of MUTE, * and we leave them unchanged. + * + * On newer Lenovo ThinkPads, the EC can automatically change the volume + * in response to user input. Unfortunately, this rarely works well. + * The laptop changes the state of its internal MUTE gate and, on some + * models, sends KEY_MUTE, causing any user code that responds to the + * mute button to get confused. The hardware MUTE gate is also + * unnecessary, since user code can handle the mute button without + * kernel or EC help. + * + * To avoid confusing userspace, we simply disable all EC-based mute + * and volume controls when possible. */ #ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT @@ -6611,11 +6622,21 @@ enum tpacpi_volume_capabilities { TPACPI_VOL_CAP_MAX }; +enum tpacpi_mute_btn_mode { + TP_EC_MUTE_BTN_LATCH = 0, /* Mute mutes; up/down unmutes */ + /* We don't know what mode 1 is. */ + TP_EC_MUTE_BTN_NONE = 2, /* Mute and up/down are just keys */ + TP_EC_MUTE_BTN_TOGGLE = 3, /* Mute toggles; up/down unmutes */ +}; + static enum tpacpi_volume_access_mode volume_mode = TPACPI_VOL_MODE_MAX; static enum tpacpi_volume_capabilities volume_capabilities; static bool volume_control_allowed; +static bool software_mute_requested = true; +static bool software_mute_active; +static int software_mute_orig_mode; /* * Used to syncronize writers to TP_EC_AUDIO and @@ -6633,6 +6654,8 @@ static void tpacpi_volume_checkpoint_nvram(void) return; if (!volume_control_allowed) return; + if (software_mute_active) + return; vdbg_printk(TPACPI_DBG_MIXER, "trying to checkpoint mixer state to NVRAM...\n"); @@ -6694,6 +6717,12 @@ static int volume_set_status_ec(const u8 status) dbg_printk(TPACPI_DBG_MIXER, "set EC mixer to 0x%02x\n", status); + /* + * On X200s, and possibly on others, it can take a while for + * reads to become correct. + */ + msleep(1); + return 0; } @@ -6776,6 +6805,57 @@ unlock: return rc; } +static int volume_set_software_mute(bool startup) +{ + int result; + + if (!tpacpi_is_lenovo()) + return -ENODEV; + + if (startup) { + if (!acpi_evalf(ec_handle, &software_mute_orig_mode, + "HAUM", "qd")) + return -EIO; + + dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER, + "Initial HAUM setting was %d\n", + software_mute_orig_mode); + } + + if (!acpi_evalf(ec_handle, &result, "SAUM", "qdd", + (int)TP_EC_MUTE_BTN_NONE)) + return -EIO; + + if (result != TP_EC_MUTE_BTN_NONE) + pr_warn("Unexpected SAUM result %d\n", + result); + + /* + * In software mute mode, the standard codec controls take + * precendence, so we unmute the ThinkPad HW switch at + * startup. Just on case there are SAUM-capable ThinkPads + * with level controls, set max HW volume as well. + */ + if (tp_features.mixer_no_level_control) + result = volume_set_mute(false); + else + result = volume_set_status(TP_EC_VOLUME_MAX); + + if (result != 0) + pr_warn("Failed to unmute the HW mute switch\n"); + + return 0; +} + +static void volume_exit_software_mute(void) +{ + int r; + + if (!acpi_evalf(ec_handle, &r, "SAUM", "qdd", software_mute_orig_mode) + || r != software_mute_orig_mode) + pr_warn("Failed to restore mute mode\n"); +} + static int volume_alsa_set_volume(const u8 vol) { dbg_printk(TPACPI_DBG_MIXER, @@ -6883,7 +6963,12 @@ static void volume_suspend(void) static void volume_resume(void) { - volume_alsa_notify_change(); + if (software_mute_active) { + if (volume_set_software_mute(false) < 0) + pr_warn("Failed to restore software mute\n"); + } else { + volume_alsa_notify_change(); + } } static void volume_shutdown(void) @@ -6899,6 +6984,9 @@ static void volume_exit(void) } tpacpi_volume_checkpoint_nvram(); + + if (software_mute_active) + volume_exit_software_mute(); } static int __init volume_create_alsa_mixer(void) @@ -7083,16 +7171,20 @@ static int __init volume_init(struct ibm_init_struct *iibm) "mute is supported, volume control is %s\n", str_supported(!tp_features.mixer_no_level_control)); - rc = volume_create_alsa_mixer(); - if (rc) { - pr_err("Could not create the ALSA mixer interface\n"); - return rc; - } + if (software_mute_requested && volume_set_software_mute(true) == 0) { + software_mute_active = true; + } else { + rc = volume_create_alsa_mixer(); + if (rc) { + pr_err("Could not create the ALSA mixer interface\n"); + return rc; + } - pr_info("Console audio control enabled, mode: %s\n", - (volume_control_allowed) ? - "override (read/write)" : - "monitor (read only)"); + pr_info("Console audio control enabled, mode: %s\n", + (volume_control_allowed) ? + "override (read/write)" : + "monitor (read only)"); + } vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER, "registering volume hotkeys as change notification\n"); @@ -9089,6 +9181,10 @@ MODULE_PARM_DESC(volume_control, "Enables software override for the console audio " "control when true"); +module_param_named(software_mute, software_mute_requested, bool, 0444); +MODULE_PARM_DESC(software_mute, + "Request full software mute control"); + /* ALSA module API parameters */ module_param_named(index, alsa_index, int, 0444); MODULE_PARM_DESC(index, "ALSA index for the ACPI EC Mixer"); diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index ab6151f05420..fc34a71866ed 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -186,6 +186,7 @@ static struct toshiba_acpi_dev *toshiba_acpi; static const struct acpi_device_id toshiba_device_ids[] = { {"TOS6200", 0}, + {"TOS6207", 0}, {"TOS6208", 0}, {"TOS1900", 0}, {"", 0}, @@ -928,9 +929,7 @@ static int lcd_proc_open(struct inode *inode, struct file *file) static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value) { - u32 in[TCI_WORDS] = { HCI_SET, HCI_LCD_BRIGHTNESS, 0, 0, 0, 0 }; - u32 out[TCI_WORDS]; - acpi_status status; + u32 hci_result; if (dev->tr_backlight_supported) { bool enable = !value; @@ -941,20 +940,9 @@ static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value) value--; } - in[2] = value << HCI_LCD_BRIGHTNESS_SHIFT; - status = tci_raw(dev, in, out); - if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) { - pr_err("ACPI call to set brightness failed"); - return -EIO; - } - /* Extra check for "incomplete" backlight method, where the AML code - * doesn't check for HCI_SET or HCI_GET and returns TOS_SUCCESS, - * the actual brightness, and in some cases the max brightness. - */ - if (out[2] > 0 || out[3] == 0xE000) - return -ENODEV; - - return out[0] == TOS_SUCCESS ? 0 : -EIO; + value = value << HCI_LCD_BRIGHTNESS_SHIFT; + hci_result = hci_write1(dev, HCI_LCD_BRIGHTNESS, value); + return hci_result == TOS_SUCCESS ? 0 : -EIO; } static int set_lcd_status(struct backlight_device *bd) @@ -1406,12 +1394,6 @@ static ssize_t toshiba_kbd_bl_mode_store(struct device *dev, if (ret) return ret; - /* Update sysfs entries on successful mode change*/ - ret = sysfs_update_group(&toshiba->acpi_dev->dev.kobj, - &toshiba_attr_group); - if (ret) - return ret; - toshiba->kbd_mode = mode; } @@ -1586,10 +1568,32 @@ static umode_t toshiba_sysfs_is_visible(struct kobject *kobj, return exists ? attr->mode : 0; } +/* + * Hotkeys + */ +static int toshiba_acpi_enable_hotkeys(struct toshiba_acpi_dev *dev) +{ + acpi_status status; + u32 result; + + status = acpi_evaluate_object(dev->acpi_dev->handle, + "ENAB", NULL, NULL); + if (ACPI_FAILURE(status)) + return -ENODEV; + + result = hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE); + if (result == TOS_FAILURE) + return -EIO; + else if (result == TOS_NOT_SUPPORTED) + return -ENODEV; + + return 0; +} + static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str, struct serio *port) { - if (str & 0x20) + if (str & I8042_STR_AUXDATA) return false; if (unlikely(data == 0xe0)) @@ -1648,9 +1652,45 @@ static void toshiba_acpi_report_hotkey(struct toshiba_acpi_dev *dev, pr_info("Unknown key %x\n", scancode); } +static void toshiba_acpi_process_hotkeys(struct toshiba_acpi_dev *dev) +{ + u32 hci_result, value; + int retries = 3; + int scancode; + + if (dev->info_supported) { + scancode = toshiba_acpi_query_hotkey(dev); + if (scancode < 0) + pr_err("Failed to query hotkey event\n"); + else if (scancode != 0) + toshiba_acpi_report_hotkey(dev, scancode); + } else if (dev->system_event_supported) { + do { + hci_result = hci_read1(dev, HCI_SYSTEM_EVENT, &value); + switch (hci_result) { + case TOS_SUCCESS: + toshiba_acpi_report_hotkey(dev, (int)value); + break; + case TOS_NOT_SUPPORTED: + /* + * This is a workaround for an unresolved + * issue on some machines where system events + * sporadically become disabled. + */ + hci_result = + hci_write1(dev, HCI_SYSTEM_EVENT, 1); + pr_notice("Re-enabled hotkeys\n"); + /* fall through */ + default: + retries--; + break; + } + } while (retries && hci_result != TOS_FIFO_EMPTY); + } +} + static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) { - acpi_status status; acpi_handle ec_handle; int error; u32 hci_result; @@ -1677,7 +1717,6 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) * supported, so if it's present set up an i8042 key filter * for this purpose. */ - status = AE_ERROR; ec_handle = ec_get_handle(); if (ec_handle && acpi_has_method(ec_handle, "NTFY")) { INIT_WORK(&dev->hotkey_work, toshiba_acpi_hotkey_work); @@ -1708,10 +1747,9 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) goto err_remove_filter; } - status = acpi_evaluate_object(dev->acpi_dev->handle, "ENAB", NULL, NULL); - if (ACPI_FAILURE(status)) { + error = toshiba_acpi_enable_hotkeys(dev); + if (error) { pr_info("Unable to enable hotkeys\n"); - error = -ENODEV; goto err_remove_filter; } @@ -1721,7 +1759,6 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) goto err_remove_filter; } - hci_result = hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE); return 0; err_remove_filter: @@ -1810,8 +1847,7 @@ static int toshiba_acpi_remove(struct acpi_device *acpi_dev) rfkill_destroy(dev->bt_rfk); } - if (dev->backlight_dev) - backlight_device_unregister(dev->backlight_dev); + backlight_device_unregister(dev->backlight_dev); if (dev->illumination_supported) led_classdev_unregister(&dev->led_dev); @@ -1967,41 +2003,29 @@ error: static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event) { struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); - u32 hci_result, value; - int retries = 3; - int scancode; - - if (event != 0x80) - return; + int ret; - if (dev->info_supported) { - scancode = toshiba_acpi_query_hotkey(dev); - if (scancode < 0) - pr_err("Failed to query hotkey event\n"); - else if (scancode != 0) - toshiba_acpi_report_hotkey(dev, scancode); - } else if (dev->system_event_supported) { - do { - hci_result = hci_read1(dev, HCI_SYSTEM_EVENT, &value); - switch (hci_result) { - case TOS_SUCCESS: - toshiba_acpi_report_hotkey(dev, (int)value); - break; - case TOS_NOT_SUPPORTED: - /* - * This is a workaround for an unresolved - * issue on some machines where system events - * sporadically become disabled. - */ - hci_result = - hci_write1(dev, HCI_SYSTEM_EVENT, 1); - pr_notice("Re-enabled hotkeys\n"); - /* fall through */ - default: - retries--; - break; - } - } while (retries && hci_result != TOS_FIFO_EMPTY); + switch (event) { + case 0x80: /* Hotkeys and some system events */ + toshiba_acpi_process_hotkeys(dev); + break; + case 0x92: /* Keyboard backlight mode changed */ + /* Update sysfs entries */ + ret = sysfs_update_group(&acpi_dev->dev.kobj, + &toshiba_attr_group); + if (ret) + pr_err("Unable to update sysfs entries\n"); + break; + case 0x81: /* Unknown */ + case 0x82: /* Unknown */ + case 0x83: /* Unknown */ + case 0x8c: /* Unknown */ + case 0x8e: /* Unknown */ + case 0x8f: /* Unknown */ + case 0x90: /* Unknown */ + default: + pr_info("Unknown event received %x\n", event); + break; } } @@ -2020,16 +2044,12 @@ static int toshiba_acpi_suspend(struct device *device) static int toshiba_acpi_resume(struct device *device) { struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device)); - u32 result; - acpi_status status; + int error; if (dev->hotkey_dev) { - status = acpi_evaluate_object(dev->acpi_dev->handle, "ENAB", - NULL, NULL); - if (ACPI_FAILURE(status)) + error = toshiba_acpi_enable_hotkeys(dev); + if (error) pr_info("Unable to re-enable hotkeys\n"); - - result = hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE); } return 0; diff --git a/drivers/power/ds2782_battery.c b/drivers/power/ds2782_battery.c index 041f9b638d28..39694883d3bf 100644 --- a/drivers/power/ds2782_battery.c +++ b/drivers/power/ds2782_battery.c @@ -351,13 +351,9 @@ static int ds278x_resume(struct device *dev) schedule_delayed_work(&info->bat_work, DS278x_DELAY); return 0; } +#endif /* CONFIG_PM_SLEEP */ static SIMPLE_DEV_PM_OPS(ds278x_battery_pm_ops, ds278x_suspend, ds278x_resume); -#define DS278X_BATTERY_PM_OPS (&ds278x_battery_pm_ops) - -#else -#define DS278X_BATTERY_PM_OPS NULL -#endif /* CONFIG_PM_SLEEP */ enum ds278x_num_id { DS2782 = 0, @@ -460,7 +456,7 @@ MODULE_DEVICE_TABLE(i2c, ds278x_id); static struct i2c_driver ds278x_battery_driver = { .driver = { .name = "ds2782-battery", - .pm = DS278X_BATTERY_PM_OPS, + .pm = &ds278x_battery_pm_ops, }, .probe = ds278x_battery_probe, .remove = ds278x_battery_remove, diff --git a/drivers/power/gpio-charger.c b/drivers/power/gpio-charger.c index 3ee889fe0021..aef74bdf7ab3 100644 --- a/drivers/power/gpio-charger.c +++ b/drivers/power/gpio-charger.c @@ -22,6 +22,8 @@ #include <linux/platform_device.h> #include <linux/power_supply.h> #include <linux/slab.h> +#include <linux/of.h> +#include <linux/of_gpio.h> #include <linux/power/gpio-charger.h> @@ -69,6 +71,59 @@ static enum power_supply_property gpio_charger_properties[] = { POWER_SUPPLY_PROP_ONLINE, }; +static +struct gpio_charger_platform_data *gpio_charger_parse_dt(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct gpio_charger_platform_data *pdata; + const char *chargetype; + enum of_gpio_flags flags; + int ret; + + if (!np) + return ERR_PTR(-ENOENT); + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + pdata->name = np->name; + + pdata->gpio = of_get_gpio_flags(np, 0, &flags); + if (pdata->gpio < 0) { + if (pdata->gpio != -EPROBE_DEFER) + dev_err(dev, "could not get charger gpio\n"); + return ERR_PTR(pdata->gpio); + } + + pdata->gpio_active_low = !!(flags & OF_GPIO_ACTIVE_LOW); + + pdata->type = POWER_SUPPLY_TYPE_UNKNOWN; + ret = of_property_read_string(np, "charger-type", &chargetype); + if (ret >= 0) { + if (!strncmp("unknown", chargetype, 7)) + pdata->type = POWER_SUPPLY_TYPE_UNKNOWN; + else if (!strncmp("battery", chargetype, 7)) + pdata->type = POWER_SUPPLY_TYPE_BATTERY; + else if (!strncmp("ups", chargetype, 3)) + pdata->type = POWER_SUPPLY_TYPE_UPS; + else if (!strncmp("mains", chargetype, 5)) + pdata->type = POWER_SUPPLY_TYPE_MAINS; + else if (!strncmp("usb-sdp", chargetype, 7)) + pdata->type = POWER_SUPPLY_TYPE_USB; + else if (!strncmp("usb-dcp", chargetype, 7)) + pdata->type = POWER_SUPPLY_TYPE_USB_DCP; + else if (!strncmp("usb-cdp", chargetype, 7)) + pdata->type = POWER_SUPPLY_TYPE_USB_CDP; + else if (!strncmp("usb-aca", chargetype, 7)) + pdata->type = POWER_SUPPLY_TYPE_USB_ACA; + else + dev_warn(dev, "unknown charger type %s\n", chargetype); + } + + return pdata; +} + static int gpio_charger_probe(struct platform_device *pdev) { const struct gpio_charger_platform_data *pdata = pdev->dev.platform_data; @@ -78,8 +133,13 @@ static int gpio_charger_probe(struct platform_device *pdev) int irq; if (!pdata) { - dev_err(&pdev->dev, "No platform data\n"); - return -EINVAL; + pdata = gpio_charger_parse_dt(&pdev->dev); + if (IS_ERR(pdata)) { + ret = PTR_ERR(pdata); + if (ret != -EPROBE_DEFER) + dev_err(&pdev->dev, "No platform data\n"); + return ret; + } } if (!gpio_is_valid(pdata->gpio)) { @@ -103,6 +163,7 @@ static int gpio_charger_probe(struct platform_device *pdev) charger->get_property = gpio_charger_get_property; charger->supplied_to = pdata->supplied_to; charger->num_supplicants = pdata->num_supplicants; + charger->of_node = pdev->dev.of_node; ret = gpio_request(pdata->gpio, dev_name(&pdev->dev)); if (ret) { @@ -189,12 +250,19 @@ static int gpio_charger_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(gpio_charger_pm_ops, gpio_charger_suspend, gpio_charger_resume); +static const struct of_device_id gpio_charger_match[] = { + { .compatible = "gpio-charger" }, + { } +}; +MODULE_DEVICE_TABLE(of, gpio_charger_match); + static struct platform_driver gpio_charger_driver = { .probe = gpio_charger_probe, .remove = gpio_charger_remove, .driver = { .name = "gpio-charger", .pm = &gpio_charger_pm_ops, + .of_match_table = gpio_charger_match, }, }; diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index 62c15af58c9a..777324992c59 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -951,8 +951,6 @@ static int pm2xxx_wall_charger_suspend(struct device *dev) #endif -#ifdef CONFIG_PM_RUNTIME - static int pm2xxx_runtime_suspend(struct device *dev) { struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev); @@ -977,8 +975,6 @@ static int pm2xxx_runtime_resume(struct device *dev) return 0; } -#endif - static const struct dev_pm_ops pm2xxx_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(pm2xxx_wall_charger_suspend, pm2xxx_wall_charger_resume) diff --git a/drivers/power/reset/axxia-reset.c b/drivers/power/reset/axxia-reset.c index 3b1f8d601784..4e4cd1c8fe50 100644 --- a/drivers/power/reset/axxia-reset.c +++ b/drivers/power/reset/axxia-reset.c @@ -19,14 +19,12 @@ #include <linux/kernel.h> #include <linux/mfd/syscon.h> #include <linux/module.h> +#include <linux/notifier.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/reboot.h> #include <linux/regmap.h> -#include <asm/system_misc.h> - - #define SC_CRIT_WRITE_KEY 0x1000 #define SC_LATCH_ON_RESET 0x1004 #define SC_RESET_CONTROL 0x1008 @@ -39,7 +37,8 @@ static struct regmap *syscon; -static void do_axxia_restart(enum reboot_mode reboot_mode, const char *cmd) +static int axxia_restart_handler(struct notifier_block *this, + unsigned long mode, void *cmd) { /* Access Key (0xab) */ regmap_write(syscon, SC_CRIT_WRITE_KEY, 0xab); @@ -50,11 +49,19 @@ static void do_axxia_restart(enum reboot_mode reboot_mode, const char *cmd) /* Assert chip reset */ regmap_update_bits(syscon, SC_RESET_CONTROL, RSTCTL_RST_CHIP, RSTCTL_RST_CHIP); + + return NOTIFY_DONE; } +static struct notifier_block axxia_restart_nb = { + .notifier_call = axxia_restart_handler, + .priority = 128, +}; + static int axxia_reset_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + int err; syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon"); if (IS_ERR(syscon)) { @@ -62,9 +69,11 @@ static int axxia_reset_probe(struct platform_device *pdev) return PTR_ERR(syscon); } - arm_pm_restart = do_axxia_restart; + err = register_restart_handler(&axxia_restart_nb); + if (err) + dev_err(dev, "cannot register restart handler (err=%d)\n", err); - return 0; + return err; } static const struct of_device_id of_axxia_reset_match[] = { diff --git a/drivers/power/reset/brcmstb-reboot.c b/drivers/power/reset/brcmstb-reboot.c index c523ea7a90ee..100606f9b3dc 100644 --- a/drivers/power/reset/brcmstb-reboot.c +++ b/drivers/power/reset/brcmstb-reboot.c @@ -16,6 +16,7 @@ #include <linux/init.h> #include <linux/io.h> #include <linux/jiffies.h> +#include <linux/notifier.h> #include <linux/of_address.h> #include <linux/of_irq.h> #include <linux/of_platform.h> @@ -26,8 +27,6 @@ #include <linux/smp.h> #include <linux/mfd/syscon.h> -#include <asm/system_misc.h> - #define RESET_SOURCE_ENABLE_REG 1 #define SW_MASTER_RESET_REG 2 @@ -35,7 +34,8 @@ static struct regmap *regmap; static u32 rst_src_en; static u32 sw_mstr_rst; -static void brcmstb_reboot(enum reboot_mode mode, const char *cmd) +static int brcmstb_restart_handler(struct notifier_block *this, + unsigned long mode, void *cmd) { int rc; u32 tmp; @@ -43,31 +43,38 @@ static void brcmstb_reboot(enum reboot_mode mode, const char *cmd) rc = regmap_write(regmap, rst_src_en, 1); if (rc) { pr_err("failed to write rst_src_en (%d)\n", rc); - return; + return NOTIFY_DONE; } rc = regmap_read(regmap, rst_src_en, &tmp); if (rc) { pr_err("failed to read rst_src_en (%d)\n", rc); - return; + return NOTIFY_DONE; } rc = regmap_write(regmap, sw_mstr_rst, 1); if (rc) { pr_err("failed to write sw_mstr_rst (%d)\n", rc); - return; + return NOTIFY_DONE; } rc = regmap_read(regmap, sw_mstr_rst, &tmp); if (rc) { pr_err("failed to read sw_mstr_rst (%d)\n", rc); - return; + return NOTIFY_DONE; } while (1) ; + + return NOTIFY_DONE; } +static struct notifier_block brcmstb_restart_nb = { + .notifier_call = brcmstb_restart_handler, + .priority = 128, +}; + static int brcmstb_reboot_probe(struct platform_device *pdev) { int rc; @@ -93,9 +100,12 @@ static int brcmstb_reboot_probe(struct platform_device *pdev) return -EINVAL; } - arm_pm_restart = brcmstb_reboot; + rc = register_restart_handler(&brcmstb_restart_nb); + if (rc) + dev_err(&pdev->dev, + "cannot register restart handler (err=%d)\n", rc); - return 0; + return rc; } static const struct of_device_id of_match[] = { diff --git a/drivers/power/reset/hisi-reboot.c b/drivers/power/reset/hisi-reboot.c index 0c91d0231d36..5385460e23bb 100644 --- a/drivers/power/reset/hisi-reboot.c +++ b/drivers/power/reset/hisi-reboot.c @@ -14,27 +14,36 @@ #include <linux/delay.h> #include <linux/io.h> #include <linux/module.h> +#include <linux/notifier.h> #include <linux/of_address.h> #include <linux/platform_device.h> #include <linux/reboot.h> #include <asm/proc-fns.h> -#include <asm/system_misc.h> static void __iomem *base; static u32 reboot_offset; -static void hisi_restart(enum reboot_mode mode, const char *cmd) +static int hisi_restart_handler(struct notifier_block *this, + unsigned long mode, void *cmd) { writel_relaxed(0xdeadbeef, base + reboot_offset); while (1) cpu_do_idle(); + + return NOTIFY_DONE; } +static struct notifier_block hisi_restart_nb = { + .notifier_call = hisi_restart_handler, + .priority = 128, +}; + static int hisi_reboot_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; + int err; base = of_iomap(np, 0); if (!base) { @@ -47,9 +56,12 @@ static int hisi_reboot_probe(struct platform_device *pdev) return -EINVAL; } - arm_pm_restart = hisi_restart; + err = register_restart_handler(&hisi_restart_nb); + if (err) + dev_err(&pdev->dev, "cannot register restart handler (err=%d)\n", + err); - return 0; + return err; } static struct of_device_id hisi_reboot_of_match[] = { diff --git a/drivers/power/reset/keystone-reset.c b/drivers/power/reset/keystone-reset.c index 86bc100818b2..faedf16c8111 100644 --- a/drivers/power/reset/keystone-reset.c +++ b/drivers/power/reset/keystone-reset.c @@ -12,9 +12,9 @@ #include <linux/io.h> #include <linux/module.h> +#include <linux/notifier.h> #include <linux/reboot.h> #include <linux/regmap.h> -#include <asm/system_misc.h> #include <linux/mfd/syscon.h> #include <linux/of_platform.h> @@ -52,7 +52,8 @@ static inline int rsctrl_enable_rspll_write(void) RSCTRL_KEY_MASK, RSCTRL_KEY); } -static void rsctrl_restart(enum reboot_mode mode, const char *cmd) +static int rsctrl_restart_handler(struct notifier_block *this, + unsigned long mode, void *cmd) { /* enable write access to RSTCTRL */ rsctrl_enable_rspll_write(); @@ -60,8 +61,15 @@ static void rsctrl_restart(enum reboot_mode mode, const char *cmd) /* reset the SOC */ regmap_update_bits(pllctrl_regs, rspll_offset + RSCTRL_RG, RSCTRL_RESET_MASK, 0); + + return NOTIFY_DONE; } +static struct notifier_block rsctrl_restart_nb = { + .notifier_call = rsctrl_restart_handler, + .priority = 128, +}; + static struct of_device_id rsctrl_of_match[] = { {.compatible = "ti,keystone-reset", }, {}, @@ -114,8 +122,6 @@ static int rsctrl_probe(struct platform_device *pdev) if (ret) return ret; - arm_pm_restart = rsctrl_restart; - /* disable a reset isolation for all module clocks */ ret = regmap_write(pllctrl_regs, rspll_offset + RSISO_RG, 0); if (ret) @@ -147,7 +153,11 @@ static int rsctrl_probe(struct platform_device *pdev) return ret; } - return 0; + ret = register_restart_handler(&rsctrl_restart_nb); + if (ret) + dev_err(dev, "cannot register restart handler (err=%d)\n", ret); + + return ret; } static struct platform_driver rsctrl_driver = { diff --git a/drivers/power/reset/syscon-reboot.c b/drivers/power/reset/syscon-reboot.c index 815b901822cf..c4049f45663f 100644 --- a/drivers/power/reset/syscon-reboot.c +++ b/drivers/power/reset/syscon-reboot.c @@ -68,7 +68,7 @@ static int syscon_reboot_probe(struct platform_device *pdev) return -EINVAL; ctx->restart_handler.notifier_call = syscon_restart_handle; - ctx->restart_handler.priority = 128; + ctx->restart_handler.priority = 192; err = register_restart_handler(&ctx->restart_handler); if (err) dev_err(dev, "can't register restart notifier (err=%d)\n", err); diff --git a/drivers/power/reset/vexpress-poweroff.c b/drivers/power/reset/vexpress-poweroff.c index 4dc102e2b230..9dfc9cee3232 100644 --- a/drivers/power/reset/vexpress-poweroff.c +++ b/drivers/power/reset/vexpress-poweroff.c @@ -12,14 +12,14 @@ */ #include <linux/delay.h> +#include <linux/notifier.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/platform_device.h> +#include <linux/reboot.h> #include <linux/stat.h> #include <linux/vexpress.h> -#include <asm/system_misc.h> - static void vexpress_reset_do(struct device *dev, const char *what) { int err = -ENOENT; @@ -43,11 +43,19 @@ static void vexpress_power_off(void) static struct device *vexpress_restart_device; -static void vexpress_restart(enum reboot_mode reboot_mode, const char *cmd) +static int vexpress_restart(struct notifier_block *this, unsigned long mode, + void *cmd) { vexpress_reset_do(vexpress_restart_device, "restart"); + + return NOTIFY_DONE; } +static struct notifier_block vexpress_restart_nb = { + .notifier_call = vexpress_restart, + .priority = 128, +}; + static ssize_t vexpress_reset_active_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -86,12 +94,28 @@ static struct of_device_id vexpress_reset_of_match[] = { {} }; +static int _vexpress_register_restart_handler(struct device *dev) +{ + int err; + + vexpress_restart_device = dev; + err = register_restart_handler(&vexpress_restart_nb); + if (err) { + dev_err(dev, "cannot register restart handler (err=%d)\n", err); + return err; + } + device_create_file(dev, &dev_attr_active); + + return 0; +} + static int vexpress_reset_probe(struct platform_device *pdev) { enum vexpress_reset_func func; const struct of_device_id *match = of_match_device(vexpress_reset_of_match, &pdev->dev); struct regmap *regmap; + int ret = 0; if (match) func = (enum vexpress_reset_func)match->data; @@ -110,18 +134,14 @@ static int vexpress_reset_probe(struct platform_device *pdev) break; case FUNC_RESET: if (!vexpress_restart_device) - vexpress_restart_device = &pdev->dev; - arm_pm_restart = vexpress_restart; - device_create_file(&pdev->dev, &dev_attr_active); + ret = _vexpress_register_restart_handler(&pdev->dev); break; case FUNC_REBOOT: - vexpress_restart_device = &pdev->dev; - arm_pm_restart = vexpress_restart; - device_create_file(&pdev->dev, &dev_attr_active); + ret = _vexpress_register_restart_handler(&pdev->dev); break; }; - return 0; + return ret; } static const struct platform_device_id vexpress_reset_id_table[] = { diff --git a/drivers/power/reset/xgene-reboot.c b/drivers/power/reset/xgene-reboot.c index 6b49be6867ab..b0e5002f8deb 100644 --- a/drivers/power/reset/xgene-reboot.c +++ b/drivers/power/reset/xgene-reboot.c @@ -24,63 +24,67 @@ * For system shutdown, this is board specify. If a board designer * implements GPIO shutdown, use the gpio-poweroff.c driver. */ +#include <linux/delay.h> #include <linux/io.h> +#include <linux/notifier.h> #include <linux/of_device.h> #include <linux/of_address.h> #include <linux/platform_device.h> +#include <linux/reboot.h> #include <linux/stat.h> #include <linux/slab.h> -#include <asm/system_misc.h> struct xgene_reboot_context { - struct platform_device *pdev; + struct device *dev; void *csr; u32 mask; + struct notifier_block restart_handler; }; -static struct xgene_reboot_context *xgene_restart_ctx; - -static void xgene_restart(enum reboot_mode mode, const char *cmd) +static int xgene_restart_handler(struct notifier_block *this, + unsigned long mode, void *cmd) { - struct xgene_reboot_context *ctx = xgene_restart_ctx; - unsigned long timeout; + struct xgene_reboot_context *ctx = + container_of(this, struct xgene_reboot_context, + restart_handler); /* Issue the reboot */ - if (ctx) - writel(ctx->mask, ctx->csr); + writel(ctx->mask, ctx->csr); + + mdelay(1000); - timeout = jiffies + HZ; - while (time_before(jiffies, timeout)) - cpu_relax(); + dev_emerg(ctx->dev, "Unable to restart system\n"); - dev_emerg(&ctx->pdev->dev, "Unable to restart system\n"); + return NOTIFY_DONE; } static int xgene_reboot_probe(struct platform_device *pdev) { struct xgene_reboot_context *ctx; + struct device *dev = &pdev->dev; + int err; - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) { - dev_err(&pdev->dev, "out of memory for context\n"); - return -ENODEV; - } + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; - ctx->csr = of_iomap(pdev->dev.of_node, 0); + ctx->csr = of_iomap(dev->of_node, 0); if (!ctx->csr) { - devm_kfree(&pdev->dev, ctx); - dev_err(&pdev->dev, "can not map resource\n"); + dev_err(dev, "can not map resource\n"); return -ENODEV; } - if (of_property_read_u32(pdev->dev.of_node, "mask", &ctx->mask)) + if (of_property_read_u32(dev->of_node, "mask", &ctx->mask)) ctx->mask = 0xFFFFFFFF; - ctx->pdev = pdev; - arm_pm_restart = xgene_restart; - xgene_restart_ctx = ctx; + ctx->dev = dev; + ctx->restart_handler.notifier_call = xgene_restart_handler; + ctx->restart_handler.priority = 128; + err = register_restart_handler(&ctx->restart_handler); + if (err) + dev_err(dev, "cannot register restart handler (err=%d)\n", err); - return 0; + return err; } static struct of_device_id xgene_reboot_of_match[] = { diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c index c71443c4f265..97b5e4ee1ca4 100644 --- a/drivers/powercap/intel_rapl.c +++ b/drivers/powercap/intel_rapl.c @@ -1041,6 +1041,7 @@ static const struct x86_cpu_id rapl_ids[] = { RAPL_CPU(0x45, rapl_defaults_core),/* Haswell ULT */ RAPL_CPU(0x4C, rapl_defaults_atom),/* Braswell */ RAPL_CPU(0x4A, rapl_defaults_atom),/* Tangier */ + RAPL_CPU(0x56, rapl_defaults_core),/* Future Xeon */ RAPL_CPU(0x5A, rapl_defaults_atom),/* Annidale */ {} }; diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index ef2dd2e4754b..a3ecf5809634 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -50,6 +50,17 @@ config PWM_ATMEL To compile this driver as a module, choose M here: the module will be called pwm-atmel. +config PWM_ATMEL_HLCDC_PWM + tristate "Atmel HLCDC PWM support" + depends on MFD_ATMEL_HLCDC + help + Generic PWM framework driver for the PWM output of the HLCDC + (Atmel High-end LCD Controller). This PWM output is mainly used + to control the LCD backlight. + + To compile this driver as a module, choose M here: the module + will be called pwm-atmel-hlcdc. + config PWM_ATMEL_TCB tristate "Atmel TC Block PWM support" depends on ATMEL_TCLIB && OF @@ -71,6 +82,15 @@ config PWM_BCM_KONA To compile this driver as a module, choose M here: the module will be called pwm-bcm-kona. +config PWM_BCM2835 + tristate "BCM2835 PWM support" + depends on ARCH_BCM2835 + help + PWM framework driver for BCM2835 controller (Raspberry Pi) + + To compile this driver as a module, choose M here: the module + will be called pwm-bcm2835. + config PWM_BFIN tristate "Blackfin PWM support" depends on BFIN_GPTIMERS @@ -235,7 +255,7 @@ config PWM_ROCKCHIP config PWM_SAMSUNG tristate "Samsung PWM support" - depends on PLAT_SAMSUNG + depends on PLAT_SAMSUNG || ARCH_EXYNOS help Generic PWM framework driver for Samsung. diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index c458606c3755..65259ac1e8de 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -2,8 +2,10 @@ obj-$(CONFIG_PWM) += core.o obj-$(CONFIG_PWM_SYSFS) += sysfs.o obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o obj-$(CONFIG_PWM_ATMEL) += pwm-atmel.o +obj-$(CONFIG_PWM_ATMEL_HLCDC_PWM) += pwm-atmel-hlcdc.o obj-$(CONFIG_PWM_ATMEL_TCB) += pwm-atmel-tcb.o obj-$(CONFIG_PWM_BCM_KONA) += pwm-bcm-kona.o +obj-$(CONFIG_PWM_BCM2835) += pwm-bcm2835.o obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o obj-$(CONFIG_PWM_CLPS711X) += pwm-clps711x.o obj-$(CONFIG_PWM_EP93XX) += pwm-ep93xx.o diff --git a/drivers/pwm/pwm-atmel-hlcdc.c b/drivers/pwm/pwm-atmel-hlcdc.c new file mode 100644 index 000000000000..e7a785fadcdf --- /dev/null +++ b/drivers/pwm/pwm-atmel-hlcdc.c @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2014 Free Electrons + * Copyright (C) 2014 Atmel + * + * Author: Boris BREZILLON <boris.brezillon@free-electrons.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/mfd/atmel-hlcdc.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/pwm.h> +#include <linux/regmap.h> + +#define ATMEL_HLCDC_PWMCVAL_MASK GENMASK(15, 8) +#define ATMEL_HLCDC_PWMCVAL(x) (((x) << 8) & ATMEL_HLCDC_PWMCVAL_MASK) +#define ATMEL_HLCDC_PWMPOL BIT(4) +#define ATMEL_HLCDC_PWMPS_MASK GENMASK(2, 0) +#define ATMEL_HLCDC_PWMPS_MAX 0x6 +#define ATMEL_HLCDC_PWMPS(x) ((x) & ATMEL_HLCDC_PWMPS_MASK) + +struct atmel_hlcdc_pwm_errata { + bool slow_clk_erratum; + bool div1_clk_erratum; +}; + +struct atmel_hlcdc_pwm { + struct pwm_chip chip; + struct atmel_hlcdc *hlcdc; + struct clk *cur_clk; + const struct atmel_hlcdc_pwm_errata *errata; +}; + +static inline struct atmel_hlcdc_pwm *to_atmel_hlcdc_pwm(struct pwm_chip *chip) +{ + return container_of(chip, struct atmel_hlcdc_pwm, chip); +} + +static int atmel_hlcdc_pwm_config(struct pwm_chip *c, + struct pwm_device *pwm, + int duty_ns, int period_ns) +{ + struct atmel_hlcdc_pwm *chip = to_atmel_hlcdc_pwm(c); + struct atmel_hlcdc *hlcdc = chip->hlcdc; + struct clk *new_clk = hlcdc->slow_clk; + u64 pwmcval = duty_ns * 256; + unsigned long clk_freq; + u64 clk_period_ns; + u32 pwmcfg; + int pres; + + if (!chip->errata || !chip->errata->slow_clk_erratum) { + clk_freq = clk_get_rate(new_clk); + clk_period_ns = (u64)NSEC_PER_SEC * 256; + do_div(clk_period_ns, clk_freq); + } + + /* Errata: cannot use slow clk on some IP revisions */ + if ((chip->errata && chip->errata->slow_clk_erratum) || + clk_period_ns > period_ns) { + new_clk = hlcdc->sys_clk; + clk_freq = clk_get_rate(new_clk); + clk_period_ns = (u64)NSEC_PER_SEC * 256; + do_div(clk_period_ns, clk_freq); + } + + for (pres = 0; pres <= ATMEL_HLCDC_PWMPS_MAX; pres++) { + /* Errata: cannot divide by 1 on some IP revisions */ + if (!pres && chip->errata && chip->errata->div1_clk_erratum) + continue; + + if ((clk_period_ns << pres) >= period_ns) + break; + } + + if (pres > ATMEL_HLCDC_PWMPS_MAX) + return -EINVAL; + + pwmcfg = ATMEL_HLCDC_PWMPS(pres); + + if (new_clk != chip->cur_clk) { + u32 gencfg = 0; + int ret; + + ret = clk_prepare_enable(new_clk); + if (ret) + return ret; + + clk_disable_unprepare(chip->cur_clk); + chip->cur_clk = new_clk; + + if (new_clk == hlcdc->sys_clk) + gencfg = ATMEL_HLCDC_CLKPWMSEL; + + ret = regmap_update_bits(hlcdc->regmap, ATMEL_HLCDC_CFG(0), + ATMEL_HLCDC_CLKPWMSEL, gencfg); + if (ret) + return ret; + } + + do_div(pwmcval, period_ns); + + /* + * The PWM duty cycle is configurable from 0/256 to 255/256 of the + * period cycle. Hence we can't set a duty cycle occupying the + * whole period cycle if we're asked to. + * Set it to 255 if pwmcval is greater than 256. + */ + if (pwmcval > 255) + pwmcval = 255; + + pwmcfg |= ATMEL_HLCDC_PWMCVAL(pwmcval); + + return regmap_update_bits(hlcdc->regmap, ATMEL_HLCDC_CFG(6), + ATMEL_HLCDC_PWMCVAL_MASK | + ATMEL_HLCDC_PWMPS_MASK, + pwmcfg); +} + +static int atmel_hlcdc_pwm_set_polarity(struct pwm_chip *c, + struct pwm_device *pwm, + enum pwm_polarity polarity) +{ + struct atmel_hlcdc_pwm *chip = to_atmel_hlcdc_pwm(c); + struct atmel_hlcdc *hlcdc = chip->hlcdc; + u32 cfg = 0; + + if (polarity == PWM_POLARITY_NORMAL) + cfg = ATMEL_HLCDC_PWMPOL; + + return regmap_update_bits(hlcdc->regmap, ATMEL_HLCDC_CFG(6), + ATMEL_HLCDC_PWMPOL, cfg); +} + +static int atmel_hlcdc_pwm_enable(struct pwm_chip *c, struct pwm_device *pwm) +{ + struct atmel_hlcdc_pwm *chip = to_atmel_hlcdc_pwm(c); + struct atmel_hlcdc *hlcdc = chip->hlcdc; + u32 status; + int ret; + + ret = regmap_write(hlcdc->regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_PWM); + if (ret) + return ret; + + while (true) { + ret = regmap_read(hlcdc->regmap, ATMEL_HLCDC_SR, &status); + if (ret) + return ret; + + if ((status & ATMEL_HLCDC_PWM) != 0) + break; + + usleep_range(1, 10); + } + + return 0; +} + +static void atmel_hlcdc_pwm_disable(struct pwm_chip *c, + struct pwm_device *pwm) +{ + struct atmel_hlcdc_pwm *chip = to_atmel_hlcdc_pwm(c); + struct atmel_hlcdc *hlcdc = chip->hlcdc; + u32 status; + int ret; + + ret = regmap_write(hlcdc->regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_PWM); + if (ret) + return; + + while (true) { + ret = regmap_read(hlcdc->regmap, ATMEL_HLCDC_SR, &status); + if (ret) + return; + + if ((status & ATMEL_HLCDC_PWM) == 0) + break; + + usleep_range(1, 10); + } +} + +static const struct pwm_ops atmel_hlcdc_pwm_ops = { + .config = atmel_hlcdc_pwm_config, + .set_polarity = atmel_hlcdc_pwm_set_polarity, + .enable = atmel_hlcdc_pwm_enable, + .disable = atmel_hlcdc_pwm_disable, + .owner = THIS_MODULE, +}; + +static const struct atmel_hlcdc_pwm_errata atmel_hlcdc_pwm_at91sam9x5_errata = { + .slow_clk_erratum = true, +}; + +static const struct atmel_hlcdc_pwm_errata atmel_hlcdc_pwm_sama5d3_errata = { + .div1_clk_erratum = true, +}; + +static const struct of_device_id atmel_hlcdc_dt_ids[] = { + { + .compatible = "atmel,at91sam9x5-hlcdc", + .data = &atmel_hlcdc_pwm_at91sam9x5_errata, + }, + { + .compatible = "atmel,sama5d3-hlcdc", + .data = &atmel_hlcdc_pwm_sama5d3_errata, + }, + { /* sentinel */ }, +}; + +static int atmel_hlcdc_pwm_probe(struct platform_device *pdev) +{ + const struct of_device_id *match; + struct device *dev = &pdev->dev; + struct atmel_hlcdc_pwm *chip; + struct atmel_hlcdc *hlcdc; + int ret; + + hlcdc = dev_get_drvdata(dev->parent); + + chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + ret = clk_prepare_enable(hlcdc->periph_clk); + if (ret) + return ret; + + match = of_match_node(atmel_hlcdc_dt_ids, dev->parent->of_node); + if (match) + chip->errata = match->data; + + chip->hlcdc = hlcdc; + chip->chip.ops = &atmel_hlcdc_pwm_ops; + chip->chip.dev = dev; + chip->chip.base = -1; + chip->chip.npwm = 1; + chip->chip.of_xlate = of_pwm_xlate_with_flags; + chip->chip.of_pwm_n_cells = 3; + chip->chip.can_sleep = 1; + + ret = pwmchip_add(&chip->chip); + if (ret) { + clk_disable_unprepare(hlcdc->periph_clk); + return ret; + } + + platform_set_drvdata(pdev, chip); + + return 0; +} + +static int atmel_hlcdc_pwm_remove(struct platform_device *pdev) +{ + struct atmel_hlcdc_pwm *chip = platform_get_drvdata(pdev); + int ret; + + ret = pwmchip_remove(&chip->chip); + if (ret) + return ret; + + clk_disable_unprepare(chip->hlcdc->periph_clk); + + return 0; +} + +static const struct of_device_id atmel_hlcdc_pwm_dt_ids[] = { + { .compatible = "atmel,hlcdc-pwm" }, + { /* sentinel */ }, +}; + +static struct platform_driver atmel_hlcdc_pwm_driver = { + .driver = { + .name = "atmel-hlcdc-pwm", + .of_match_table = atmel_hlcdc_pwm_dt_ids, + }, + .probe = atmel_hlcdc_pwm_probe, + .remove = atmel_hlcdc_pwm_remove, +}; +module_platform_driver(atmel_hlcdc_pwm_driver); + +MODULE_ALIAS("platform:atmel-hlcdc-pwm"); +MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com>"); +MODULE_DESCRIPTION("Atmel HLCDC PWM driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pwm/pwm-bcm2835.c b/drivers/pwm/pwm-bcm2835.c new file mode 100644 index 000000000000..b4c7f956b6fa --- /dev/null +++ b/drivers/pwm/pwm-bcm2835.c @@ -0,0 +1,205 @@ +/* + * Copyright 2014 Bart Tanghe <bart.tanghe@thomasmore.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2. + */ + +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/pwm.h> + +#define PWM_CONTROL 0x000 +#define PWM_CONTROL_SHIFT(x) ((x) * 8) +#define PWM_CONTROL_MASK 0xff +#define PWM_MODE 0x80 /* set timer in PWM mode */ +#define PWM_ENABLE (1 << 0) +#define PWM_POLARITY (1 << 4) + +#define PERIOD(x) (((x) * 0x10) + 0x10) +#define DUTY(x) (((x) * 0x10) + 0x14) + +#define MIN_PERIOD 108 /* 9.2 MHz max. PWM clock */ + +struct bcm2835_pwm { + struct pwm_chip chip; + struct device *dev; + unsigned long scaler; + void __iomem *base; + struct clk *clk; +}; + +static inline struct bcm2835_pwm *to_bcm2835_pwm(struct pwm_chip *chip) +{ + return container_of(chip, struct bcm2835_pwm, chip); +} + +static int bcm2835_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) +{ + struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); + u32 value; + + value = readl(pc->base + PWM_CONTROL); + value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); + value |= (PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm)); + writel(value, pc->base + PWM_CONTROL); + + return 0; +} + +static void bcm2835_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) +{ + struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); + u32 value; + + value = readl(pc->base + PWM_CONTROL); + value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); + writel(value, pc->base + PWM_CONTROL); +} + +static int bcm2835_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, + int duty_ns, int period_ns) +{ + struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); + + if (period_ns <= MIN_PERIOD) { + dev_err(pc->dev, "period %d not supported, minimum %d\n", + period_ns, MIN_PERIOD); + return -EINVAL; + } + + writel(duty_ns / pc->scaler, pc->base + DUTY(pwm->hwpwm)); + writel(period_ns / pc->scaler, pc->base + PERIOD(pwm->hwpwm)); + + return 0; +} + +static int bcm2835_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) +{ + struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); + u32 value; + + value = readl(pc->base + PWM_CONTROL); + value |= PWM_ENABLE << PWM_CONTROL_SHIFT(pwm->hwpwm); + writel(value, pc->base + PWM_CONTROL); + + return 0; +} + +static void bcm2835_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) +{ + struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); + u32 value; + + value = readl(pc->base + PWM_CONTROL); + value &= ~(PWM_ENABLE << PWM_CONTROL_SHIFT(pwm->hwpwm)); + writel(value, pc->base + PWM_CONTROL); +} + +static int bcm2835_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm, + enum pwm_polarity polarity) +{ + struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); + u32 value; + + value = readl(pc->base + PWM_CONTROL); + + if (polarity == PWM_POLARITY_NORMAL) + value &= ~(PWM_POLARITY << PWM_CONTROL_SHIFT(pwm->hwpwm)); + else + value |= PWM_POLARITY << PWM_CONTROL_SHIFT(pwm->hwpwm); + + writel(value, pc->base + PWM_CONTROL); + + return 0; +} + +static const struct pwm_ops bcm2835_pwm_ops = { + .request = bcm2835_pwm_request, + .free = bcm2835_pwm_free, + .config = bcm2835_pwm_config, + .enable = bcm2835_pwm_enable, + .disable = bcm2835_pwm_disable, + .set_polarity = bcm2835_set_polarity, + .owner = THIS_MODULE, +}; + +static int bcm2835_pwm_probe(struct platform_device *pdev) +{ + struct bcm2835_pwm *pc; + struct resource *res; + int ret; + + pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); + if (!pc) + return -ENOMEM; + + pc->dev = &pdev->dev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + pc->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(pc->base)) + return PTR_ERR(pc->base); + + pc->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(pc->clk)) { + dev_err(&pdev->dev, "clock not found: %ld\n", PTR_ERR(pc->clk)); + return PTR_ERR(pc->clk); + } + + ret = clk_prepare_enable(pc->clk); + if (ret) + return ret; + + pc->scaler = NSEC_PER_SEC / clk_get_rate(pc->clk); + + pc->chip.dev = &pdev->dev; + pc->chip.ops = &bcm2835_pwm_ops; + pc->chip.npwm = 2; + + platform_set_drvdata(pdev, pc); + + ret = pwmchip_add(&pc->chip); + if (ret < 0) + goto add_fail; + + return 0; + +add_fail: + clk_disable_unprepare(pc->clk); + return ret; +} + +static int bcm2835_pwm_remove(struct platform_device *pdev) +{ + struct bcm2835_pwm *pc = platform_get_drvdata(pdev); + + clk_disable_unprepare(pc->clk); + + return pwmchip_remove(&pc->chip); +} + +static const struct of_device_id bcm2835_pwm_of_match[] = { + { .compatible = "brcm,bcm2835-pwm", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, bcm2835_pwm_of_match); + +static struct platform_driver bcm2835_pwm_driver = { + .driver = { + .name = "bcm2835-pwm", + .of_match_table = bcm2835_pwm_of_match, + }, + .probe = bcm2835_pwm_probe, + .remove = bcm2835_pwm_remove, +}; +module_platform_driver(bcm2835_pwm_driver); + +MODULE_AUTHOR("Bart Tanghe <bart.tanghe@thomasmore.be"); +MODULE_DESCRIPTION("Broadcom BCM2835 PWM driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c index 0f2cc7ef7784..f9dfc8b6407a 100644 --- a/drivers/pwm/pwm-fsl-ftm.c +++ b/drivers/pwm/pwm-fsl-ftm.c @@ -17,6 +17,7 @@ #include <linux/mutex.h> #include <linux/of_address.h> #include <linux/platform_device.h> +#include <linux/pm.h> #include <linux/pwm.h> #include <linux/regmap.h> #include <linux/slab.h> @@ -299,7 +300,7 @@ static int fsl_counter_clock_enable(struct fsl_pwm_chip *fpc) { int ret; - if (fpc->use_count != 0) + if (fpc->use_count++ != 0) return 0; /* select counter clock source */ @@ -316,8 +317,6 @@ static int fsl_counter_clock_enable(struct fsl_pwm_chip *fpc) return ret; } - fpc->use_count++; - return 0; } @@ -399,12 +398,23 @@ static int fsl_pwm_init(struct fsl_pwm_chip *fpc) return 0; } +static bool fsl_pwm_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case FTM_CNT: + return true; + } + return false; +} + static const struct regmap_config fsl_pwm_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, .max_register = FTM_PWMLOAD, + .volatile_reg = fsl_pwm_volatile_reg, + .cache_type = REGCACHE_RBTREE, }; static int fsl_pwm_probe(struct platform_device *pdev) @@ -427,7 +437,7 @@ static int fsl_pwm_probe(struct platform_device *pdev) if (IS_ERR(base)) return PTR_ERR(base); - fpc->regmap = devm_regmap_init_mmio_clk(&pdev->dev, NULL, base, + fpc->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "ftm_sys", base, &fsl_pwm_regmap_config); if (IS_ERR(fpc->regmap)) { dev_err(&pdev->dev, "regmap init failed\n"); @@ -478,6 +488,51 @@ static int fsl_pwm_remove(struct platform_device *pdev) return pwmchip_remove(&fpc->chip); } +#ifdef CONFIG_PM_SLEEP +static int fsl_pwm_suspend(struct device *dev) +{ + struct fsl_pwm_chip *fpc = dev_get_drvdata(dev); + u32 val; + + regcache_cache_only(fpc->regmap, true); + regcache_mark_dirty(fpc->regmap); + + /* read from cache */ + regmap_read(fpc->regmap, FTM_OUTMASK, &val); + if ((val & 0xFF) != 0xFF) { + clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_CNTEN]); + clk_disable_unprepare(fpc->clk[fpc->cnt_select]); + clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]); + } + + return 0; +} + +static int fsl_pwm_resume(struct device *dev) +{ + struct fsl_pwm_chip *fpc = dev_get_drvdata(dev); + u32 val; + + /* read from cache */ + regmap_read(fpc->regmap, FTM_OUTMASK, &val); + if ((val & 0xFF) != 0xFF) { + clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]); + clk_prepare_enable(fpc->clk[fpc->cnt_select]); + clk_prepare_enable(fpc->clk[FSL_PWM_CLK_CNTEN]); + } + + /* restore all registers from cache */ + regcache_cache_only(fpc->regmap, false); + regcache_sync(fpc->regmap); + + return 0; +} +#endif + +static const struct dev_pm_ops fsl_pwm_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(fsl_pwm_suspend, fsl_pwm_resume) +}; + static const struct of_device_id fsl_pwm_dt_ids[] = { { .compatible = "fsl,vf610-ftm-pwm", }, { /* sentinel */ } @@ -488,6 +543,7 @@ static struct platform_driver fsl_pwm_driver = { .driver = { .name = "fsl-ftm-pwm", .of_match_table = fsl_pwm_dt_ids, + .pm = &fsl_pwm_pm_ops, }, .probe = fsl_pwm_probe, .remove = fsl_pwm_remove, diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index c1444c3d84c2..2809ae0d6bcd 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -570,7 +570,7 @@ static struct regulator_ops s2mps14_reg_ops = { .enable_mask = S2MPS14_ENABLE_MASK \ } -#define regulator_desc_s2mps14_buck(num, min, step) { \ +#define regulator_desc_s2mps14_buck(num, min, step, min_sel) { \ .name = "BUCK"#num, \ .id = S2MPS14_BUCK##num, \ .ops = &s2mps14_reg_ops, \ @@ -579,7 +579,7 @@ static struct regulator_ops s2mps14_reg_ops = { .min_uV = min, \ .uV_step = step, \ .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ - .linear_min_sel = S2MPS14_BUCK1235_START_SEL, \ + .linear_min_sel = min_sel, \ .ramp_delay = S2MPS14_BUCK_RAMP_DELAY, \ .vsel_reg = S2MPS14_REG_B1CTRL2 + (num - 1) * 2, \ .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \ @@ -613,11 +613,16 @@ static const struct regulator_desc s2mps14_regulators[] = { regulator_desc_s2mps14_ldo(23, MIN_800_MV, STEP_25_MV), regulator_desc_s2mps14_ldo(24, MIN_1800_MV, STEP_25_MV), regulator_desc_s2mps14_ldo(25, MIN_1800_MV, STEP_25_MV), - regulator_desc_s2mps14_buck(1, MIN_600_MV, STEP_6_25_MV), - regulator_desc_s2mps14_buck(2, MIN_600_MV, STEP_6_25_MV), - regulator_desc_s2mps14_buck(3, MIN_600_MV, STEP_6_25_MV), - regulator_desc_s2mps14_buck(4, MIN_1400_MV, STEP_12_5_MV), - regulator_desc_s2mps14_buck(5, MIN_600_MV, STEP_6_25_MV), + regulator_desc_s2mps14_buck(1, MIN_600_MV, STEP_6_25_MV, + S2MPS14_BUCK1235_START_SEL), + regulator_desc_s2mps14_buck(2, MIN_600_MV, STEP_6_25_MV, + S2MPS14_BUCK1235_START_SEL), + regulator_desc_s2mps14_buck(3, MIN_600_MV, STEP_6_25_MV, + S2MPS14_BUCK1235_START_SEL), + regulator_desc_s2mps14_buck(4, MIN_1400_MV, STEP_12_5_MV, + S2MPS14_BUCK4_START_SEL), + regulator_desc_s2mps14_buck(5, MIN_600_MV, STEP_6_25_MV, + S2MPS14_BUCK1235_START_SEL), }; static int s2mps14_pmic_enable_ext_control(struct s2mps11_info *s2mps11, diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c index eebc52cb6984..3d95c87160b3 100644 --- a/drivers/reset/reset-sunxi.c +++ b/drivers/reset/reset-sunxi.c @@ -102,6 +102,8 @@ static int sunxi_reset_init(struct device_node *np) goto err_alloc; } + spin_lock_init(&data->lock); + data->rcdev.owner = THIS_MODULE; data->rcdev.nr_resets = size * 32; data->rcdev.ops = &sunxi_reset_ops; @@ -157,6 +159,8 @@ static int sunxi_reset_probe(struct platform_device *pdev) if (IS_ERR(data->membase)) return PTR_ERR(data->membase); + spin_lock_init(&data->lock); + data->rcdev.owner = THIS_MODULE; data->rcdev.nr_resets = resource_size(res) * 32; data->rcdev.ops = &sunxi_reset_ops; diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 91e97ec01418..4d41bf75c233 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -1163,9 +1163,13 @@ static inline int ap_test_config_card_id(unsigned int id) */ static inline int ap_test_config_domain(unsigned int domain) { - if (!ap_configuration) - return 1; - return ap_test_config(ap_configuration->aqm, domain); + if (!ap_configuration) /* QCI not supported */ + if (domain < 16) + return 1; /* then domains 0...15 are configured */ + else + return 0; + else + return ap_test_config(ap_configuration->aqm, domain); } /** diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index aa915da2a5e5..82abfce1cb42 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -176,7 +176,6 @@ STATIC int NCR_700_slave_alloc(struct scsi_device *SDpnt); STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt); STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt); static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth); -static int NCR_700_change_queue_type(struct scsi_device *SDpnt, int depth); STATIC struct device_attribute *NCR_700_dev_attrs[]; @@ -326,7 +325,6 @@ NCR_700_detect(struct scsi_host_template *tpnt, tpnt->slave_destroy = NCR_700_slave_destroy; tpnt->slave_alloc = NCR_700_slave_alloc; tpnt->change_queue_depth = NCR_700_change_queue_depth; - tpnt->change_queue_type = NCR_700_change_queue_type; tpnt->use_blk_tags = 1; if(tpnt->name == NULL) @@ -904,8 +902,8 @@ process_message(struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata hostdata->tag_negotiated &= ~(1<<scmd_id(SCp)); SCp->device->tagged_supported = 0; + SCp->device->simple_tags = 0; scsi_change_queue_depth(SCp->device, host->cmd_per_lun); - scsi_set_tag_type(SCp->device, 0); } else { shost_printk(KERN_WARNING, host, "(%d:%d) Unexpected REJECT Message %s\n", @@ -1818,8 +1816,8 @@ NCR_700_queuecommand_lck(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *) hostdata->tag_negotiated &= ~(1<<scmd_id(SCp)); } - if((hostdata->tag_negotiated &(1<<scmd_id(SCp))) - && scsi_get_tag_type(SCp->device)) { + if ((hostdata->tag_negotiated & (1<<scmd_id(SCp))) && + SCp->device->simple_tags) { slot->tag = SCp->request->tag; CDEBUG(KERN_DEBUG, SCp, "sending out tag %d, slot %p\n", slot->tag, slot); @@ -2082,39 +2080,6 @@ NCR_700_change_queue_depth(struct scsi_device *SDp, int depth) return scsi_change_queue_depth(SDp, depth); } -static int NCR_700_change_queue_type(struct scsi_device *SDp, int tag_type) -{ - int change_tag = ((tag_type ==0 && scsi_get_tag_type(SDp) != 0) - || (tag_type != 0 && scsi_get_tag_type(SDp) == 0)); - struct NCR_700_Host_Parameters *hostdata = - (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; - - /* We have a global (per target) flag to track whether TCQ is - * enabled, so we'll be turning it off for the entire target here. - * our tag algorithm will fail if we mix tagged and untagged commands, - * so quiesce the device before doing this */ - if (change_tag) - scsi_target_quiesce(SDp->sdev_target); - - scsi_set_tag_type(SDp, tag_type); - if (!tag_type) { - /* shift back to the default unqueued number of commands - * (the user can still raise this) */ - scsi_change_queue_depth(SDp, SDp->host->cmd_per_lun); - hostdata->tag_negotiated &= ~(1 << sdev_id(SDp)); - } else { - /* Here, we cleared the negotiation flag above, so this - * will force the driver to renegotiate */ - scsi_change_queue_depth(SDp, SDp->queue_depth); - if (change_tag) - NCR_700_set_tag_neg_state(SDp, NCR_700_START_TAG_NEGOTIATION); - } - if (change_tag) - scsi_target_resume(SDp->sdev_target); - - return tag_type; -} - static ssize_t NCR_700_show_active_tags(struct device *dev, struct device_attribute *attr, char *buf) { diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 86cf3d671eb9..9c92f415229f 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -1462,18 +1462,17 @@ config SCSI_WD719X SCSI controllers (based on WD33C296A chip). config SCSI_DEBUG - tristate "SCSI debugging host simulator" + tristate "SCSI debugging host and device simulator" depends on SCSI select CRC_T10DIF help - This is a host adapter simulator that can simulate multiple hosts - each with multiple dummy SCSI devices (disks). It defaults to one - host adapter with one dummy SCSI disk. Each dummy disk uses kernel - RAM as storage (i.e. it is a ramdisk). To save space when multiple - dummy disks are simulated, they share the same kernel RAM for - their storage. See <http://sg.danny.cz/sg/sdebug26.html> for more - information. This driver is primarily of use to those testing the - SCSI and block subsystems. If unsure, say N. + This pseudo driver simulates one or more hosts (SCSI initiators), + each with one or more targets, each with one or more logical units. + Defaults to one of each, creating a small RAM disk device. Many + parameters found in the /sys/bus/pseudo/drivers/scsi_debug + directory can be tweaked at run time. + See <http://sg.danny.cz/sg/sdebug26.html> for more information. + Mainly used for testing and best as a module. If unsure, say N. config SCSI_MESH tristate "MESH (Power Mac internal SCSI) support" diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 6719a3390ebd..2c5ce48c8f95 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -7921,9 +7921,9 @@ static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, */ if ((asc_dvc->cur_dvc_qng[scp->device->id] > 0) && (boardp->reqcnt[scp->device->id] % 255) == 0) { - asc_scsi_q->q2.tag_code = MSG_ORDERED_TAG; + asc_scsi_q->q2.tag_code = ORDERED_QUEUE_TAG; } else { - asc_scsi_q->q2.tag_code = MSG_SIMPLE_TAG; + asc_scsi_q->q2.tag_code = SIMPLE_QUEUE_TAG; } /* Build ASC_SCSI_Q */ @@ -8351,7 +8351,7 @@ static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no) } q_addr = ASC_QNO_TO_QADDR(q_no); if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) { - scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG; + scsiq->q2.tag_code &= ~SIMPLE_QUEUE_TAG; } scsiq->q1.status = QS_FREE; AscMemWordCopyPtrToLram(iop_base, @@ -8669,7 +8669,7 @@ static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq) } } if (disable_syn_offset_one_fix) { - scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG; + scsiq->q2.tag_code &= ~SIMPLE_QUEUE_TAG; scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX | ASC_TAG_FLAG_DISABLE_DISCONNECT); } else { diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index 14fc018436c2..02a2512b76a8 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c @@ -63,7 +63,6 @@ static struct scsi_host_template aic94xx_sht = { .scan_finished = asd_scan_finished, .scan_start = asd_scan_start, .change_queue_depth = sas_change_queue_depth, - .change_queue_type = sas_change_queue_type, .bios_param = sas_bios_param, .can_queue = 1, .cmd_per_lun = 1, diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index e861f286b42e..98d06d151958 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -2792,7 +2792,6 @@ static struct scsi_host_template bnx2fc_shost_template = { .eh_host_reset_handler = fc_eh_host_reset, .slave_alloc = fc_slave_alloc, .change_queue_depth = scsi_change_queue_depth, - .change_queue_type = scsi_change_queue_type, .this_id = -1, .cmd_per_lun = 3, .use_clustering = ENABLE_CLUSTERING, diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index 4b56858c1df2..9ecca8504f60 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c @@ -1737,11 +1737,7 @@ void bnx2fc_build_fcp_cmnd(struct bnx2fc_cmd *io_req, fcp_cmnd->fc_pri_ta = 0; fcp_cmnd->fc_tm_flags = io_req->mp_req.tm_flags; fcp_cmnd->fc_flags = io_req->io_req_flags; - - if (sc_cmd->flags & SCMD_TAGGED) - fcp_cmnd->fc_pri_ta = FCP_PTA_SIMPLE; - else - fcp_cmnd->fc_pri_ta = 0; + fcp_cmnd->fc_pri_ta = FCP_PTA_SIMPLE; } static void bnx2fc_parse_fcp_rsp(struct bnx2fc_cmd *io_req, diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c index 51ea5dc5f084..3987284e0d2a 100644 --- a/drivers/scsi/csiostor/csio_scsi.c +++ b/drivers/scsi/csiostor/csio_scsi.c @@ -172,10 +172,7 @@ csio_scsi_fcp_cmnd(struct csio_ioreq *req, void *addr) fcp_cmnd->fc_cmdref = 0; memcpy(fcp_cmnd->fc_cdb, scmnd->cmnd, 16); - if (scmnd->flags & SCMD_TAGGED) - fcp_cmnd->fc_pri_ta = FCP_PTA_SIMPLE; - else - fcp_cmnd->fc_pri_ta = 0; + fcp_cmnd->fc_pri_ta = FCP_PTA_SIMPLE; fcp_cmnd->fc_dl = cpu_to_be32(scsi_bufflen(scmnd)); if (req->nsge) diff --git a/drivers/scsi/esas2r/esas2r_flash.c b/drivers/scsi/esas2r/esas2r_flash.c index b7dc59fca7a6..7bd376d95ed5 100644 --- a/drivers/scsi/esas2r/esas2r_flash.c +++ b/drivers/scsi/esas2r/esas2r_flash.c @@ -684,9 +684,9 @@ static u16 calc_fi_checksum(struct esas2r_flash_context *fc) * 1) verify the fi_version is correct * 2) verify the checksum of the entire image. * 3) validate the adap_typ, action and length fields. - * 4) valdiate each component header. check the img_type and + * 4) validate each component header. check the img_type and * length fields - * 5) valdiate each component image. validate signatures and + * 5) validate each component image. validate signatures and * local checksums */ static bool verify_fi(struct esas2r_adapter *a, diff --git a/drivers/scsi/esas2r/esas2r_main.c b/drivers/scsi/esas2r/esas2r_main.c index 593ff8a63c70..7e1c21e6736b 100644 --- a/drivers/scsi/esas2r/esas2r_main.c +++ b/drivers/scsi/esas2r/esas2r_main.c @@ -255,7 +255,6 @@ static struct scsi_host_template driver_template = { .emulated = 0, .proc_name = ESAS2R_DRVR_NAME, .change_queue_depth = scsi_change_queue_depth, - .change_queue_type = scsi_change_queue_type, .max_sectors = 0xFFFF, .use_blk_tags = 1, }; diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index cd00a6cdf55b..ec193a8357d7 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -281,7 +281,6 @@ static struct scsi_host_template fcoe_shost_template = { .eh_host_reset_handler = fc_eh_host_reset, .slave_alloc = fc_slave_alloc, .change_queue_depth = scsi_change_queue_depth, - .change_queue_type = scsi_change_queue_type, .this_id = -1, .cmd_per_lun = 3, .can_queue = FCOE_MAX_OUTSTANDING_COMMANDS, diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 3b73b96619e2..26270c351624 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -39,7 +39,7 @@ #define DRV_NAME "fnic" #define DRV_DESCRIPTION "Cisco FCoE HBA Driver" -#define DRV_VERSION "1.6.0.16" +#define DRV_VERSION "1.6.0.17" #define PFX DRV_NAME ": " #define DFX DRV_NAME "%d: " diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c index 0c1f8177b5b7..8a0d4d7b3254 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c @@ -111,7 +111,6 @@ static struct scsi_host_template fnic_host_template = { .eh_host_reset_handler = fnic_host_reset, .slave_alloc = fnic_slave_alloc, .change_queue_depth = scsi_change_queue_depth, - .change_queue_type = scsi_change_queue_type, .this_id = -1, .cmd_per_lun = 3, .can_queue = FNIC_DFLT_IO_REQ, diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index 2097de42a147..155b286f1a9d 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -1892,6 +1892,21 @@ int fnic_abort_cmd(struct scsi_cmnd *sc) goto fnic_abort_cmd_end; } + /* IO out of order */ + + if (!(CMD_FLAGS(sc) & (FNIC_IO_ABORTED | FNIC_IO_DONE))) { + spin_unlock_irqrestore(io_lock, flags); + FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, + "Issuing Host reset due to out of order IO\n"); + + if (fnic_host_reset(sc) == FAILED) { + FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, + "fnic_host_reset failed.\n"); + } + ret = FAILED; + goto fnic_abort_cmd_end; + } + CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE; /* diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index f58c6d8e0264..057d27721d5b 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -1615,7 +1615,6 @@ static int ibmvfc_queuecommand_lck(struct scsi_cmnd *cmnd, struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); struct ibmvfc_cmd *vfc_cmd; struct ibmvfc_event *evt; - u8 tag[2]; int rc; if (unlikely((rc = fc_remote_port_chkready(rport))) || @@ -3089,7 +3088,6 @@ static struct scsi_host_template driver_template = { .target_alloc = ibmvfc_target_alloc, .scan_finished = ibmvfc_scan_finished, .change_queue_depth = ibmvfc_change_queue_depth, - .change_queue_type = scsi_change_queue_type, .cmd_per_lun = 16, .can_queue = IBMVFC_MAX_REQUESTS_DEFAULT, .this_id = -1, diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 540294389355..9219953ee949 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -683,6 +683,7 @@ static void ipr_init_ipr_cmnd(struct ipr_cmnd *ipr_cmd, ipr_reinit_ipr_cmnd(ipr_cmd); ipr_cmd->u.scratch = 0; ipr_cmd->sibling = NULL; + ipr_cmd->eh_comp = NULL; ipr_cmd->fast_done = fast_done; init_timer(&ipr_cmd->timer); } @@ -848,6 +849,8 @@ static void ipr_scsi_eh_done(struct ipr_cmnd *ipr_cmd) scsi_dma_unmap(ipr_cmd->scsi_cmd); scsi_cmd->scsi_done(scsi_cmd); + if (ipr_cmd->eh_comp) + complete(ipr_cmd->eh_comp); list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); } @@ -1426,16 +1429,14 @@ static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg, if (res->sdev) { res->del_from_ml = 1; res->res_handle = IPR_INVALID_RES_HANDLE; - if (ioa_cfg->allow_ml_add_del) - schedule_work(&ioa_cfg->work_q); + schedule_work(&ioa_cfg->work_q); } else { ipr_clear_res_target(res); list_move_tail(&res->queue, &ioa_cfg->free_res_q); } } else if (!res->sdev || res->del_from_ml) { res->add_to_ml = 1; - if (ioa_cfg->allow_ml_add_del) - schedule_work(&ioa_cfg->work_q); + schedule_work(&ioa_cfg->work_q); } ipr_send_hcam(ioa_cfg, IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE, hostrcb); @@ -3273,8 +3274,7 @@ static void ipr_worker_thread(struct work_struct *work) restart: do { did_work = 0; - if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds || - !ioa_cfg->allow_ml_add_del) { + if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) { spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); return; } @@ -3311,6 +3311,7 @@ restart: } } + ioa_cfg->scan_done = 1; spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); kobject_uevent(&ioa_cfg->host->shost_dev.kobj, KOBJ_CHANGE); LEAVE; @@ -4346,30 +4347,6 @@ static int ipr_change_queue_depth(struct scsi_device *sdev, int qdepth) } /** - * ipr_change_queue_type - Change the device's queue type - * @dsev: scsi device struct - * @tag_type: type of tags to use - * - * Return value: - * actual queue type set - **/ -static int ipr_change_queue_type(struct scsi_device *sdev, int tag_type) -{ - struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata; - struct ipr_resource_entry *res; - unsigned long lock_flags = 0; - - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - res = (struct ipr_resource_entry *)sdev->hostdata; - if (res && ipr_is_gscsi(res)) - tag_type = scsi_change_queue_type(sdev, tag_type); - else - tag_type = 0; - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - return tag_type; -} - -/** * ipr_show_adapter_handle - Show the adapter's resource handle for this device * @dev: device struct * @attr: device attribute structure @@ -4739,6 +4716,7 @@ static int ipr_slave_configure(struct scsi_device *sdev) sdev->no_uld_attach = 1; } if (ipr_is_vset_device(res)) { + sdev->scsi_level = SCSI_SPC_3; blk_queue_rq_timeout(sdev->request_queue, IPR_VSET_RW_TIMEOUT); blk_queue_max_hw_sectors(sdev->request_queue, IPR_VSET_MAX_SECTORS); @@ -4836,6 +4814,84 @@ static int ipr_slave_alloc(struct scsi_device *sdev) return rc; } +/** + * ipr_match_lun - Match function for specified LUN + * @ipr_cmd: ipr command struct + * @device: device to match (sdev) + * + * Returns: + * 1 if command matches sdev / 0 if command does not match sdev + **/ +static int ipr_match_lun(struct ipr_cmnd *ipr_cmd, void *device) +{ + if (ipr_cmd->scsi_cmd && ipr_cmd->scsi_cmd->device == device) + return 1; + return 0; +} + +/** + * ipr_wait_for_ops - Wait for matching commands to complete + * @ipr_cmd: ipr command struct + * @device: device to match (sdev) + * @match: match function to use + * + * Returns: + * SUCCESS / FAILED + **/ +static int ipr_wait_for_ops(struct ipr_ioa_cfg *ioa_cfg, void *device, + int (*match)(struct ipr_cmnd *, void *)) +{ + struct ipr_cmnd *ipr_cmd; + int wait; + unsigned long flags; + struct ipr_hrr_queue *hrrq; + signed long timeout = IPR_ABORT_TASK_TIMEOUT; + DECLARE_COMPLETION_ONSTACK(comp); + + ENTER; + do { + wait = 0; + + for_each_hrrq(hrrq, ioa_cfg) { + spin_lock_irqsave(hrrq->lock, flags); + list_for_each_entry(ipr_cmd, &hrrq->hrrq_pending_q, queue) { + if (match(ipr_cmd, device)) { + ipr_cmd->eh_comp = ∁ + wait++; + } + } + spin_unlock_irqrestore(hrrq->lock, flags); + } + + if (wait) { + timeout = wait_for_completion_timeout(&comp, timeout); + + if (!timeout) { + wait = 0; + + for_each_hrrq(hrrq, ioa_cfg) { + spin_lock_irqsave(hrrq->lock, flags); + list_for_each_entry(ipr_cmd, &hrrq->hrrq_pending_q, queue) { + if (match(ipr_cmd, device)) { + ipr_cmd->eh_comp = NULL; + wait++; + } + } + spin_unlock_irqrestore(hrrq->lock, flags); + } + + if (wait) + dev_err(&ioa_cfg->pdev->dev, "Timed out waiting for aborted commands\n"); + LEAVE; + return wait ? FAILED : SUCCESS; + } + } + } while (wait); + + LEAVE; + return SUCCESS; +} + static int ipr_eh_host_reset(struct scsi_cmnd *cmd) { struct ipr_ioa_cfg *ioa_cfg; @@ -5055,11 +5111,17 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd *scsi_cmd) static int ipr_eh_dev_reset(struct scsi_cmnd *cmd) { int rc; + struct ipr_ioa_cfg *ioa_cfg; + + ioa_cfg = (struct ipr_ioa_cfg *) cmd->device->host->hostdata; spin_lock_irq(cmd->device->host->host_lock); rc = __ipr_eh_dev_reset(cmd); spin_unlock_irq(cmd->device->host->host_lock); + if (rc == SUCCESS) + rc = ipr_wait_for_ops(ioa_cfg, cmd->device, ipr_match_lun); + return rc; } @@ -5231,19 +5293,46 @@ static int ipr_cancel_op(struct scsi_cmnd *scsi_cmd) * @scsi_cmd: scsi command struct * * Return value: + * 0 if scan in progress / 1 if scan is complete + **/ +static int ipr_scan_finished(struct Scsi_Host *shost, unsigned long elapsed_time) +{ + unsigned long lock_flags; + struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata; + int rc = 0; + + spin_lock_irqsave(shost->host_lock, lock_flags); + if (ioa_cfg->hrrq[IPR_INIT_HRRQ].ioa_is_dead || ioa_cfg->scan_done) + rc = 1; + if ((elapsed_time/HZ) > (ioa_cfg->transop_timeout * 2)) + rc = 1; + spin_unlock_irqrestore(shost->host_lock, lock_flags); + return rc; +} + +/** + * ipr_eh_host_reset - Reset the host adapter + * @scsi_cmd: scsi command struct + * + * Return value: * SUCCESS / FAILED **/ static int ipr_eh_abort(struct scsi_cmnd *scsi_cmd) { unsigned long flags; int rc; + struct ipr_ioa_cfg *ioa_cfg; ENTER; + ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata; + spin_lock_irqsave(scsi_cmd->device->host->host_lock, flags); rc = ipr_cancel_op(scsi_cmd); spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, flags); + if (rc == SUCCESS) + rc = ipr_wait_for_ops(ioa_cfg, scsi_cmd->device, ipr_match_lun); LEAVE; return rc; } @@ -5779,7 +5868,7 @@ static void ipr_erp_cancel_all(struct ipr_cmnd *ipr_cmd) ipr_reinit_ipr_cmnd_for_erp(ipr_cmd); - if (!scsi_get_tag_type(scsi_cmd->device)) { + if (!scsi_cmd->device->simple_tags) { ipr_erp_request_sense(ipr_cmd); return; } @@ -6299,10 +6388,10 @@ static struct scsi_host_template driver_template = { .slave_alloc = ipr_slave_alloc, .slave_configure = ipr_slave_configure, .slave_destroy = ipr_slave_destroy, + .scan_finished = ipr_scan_finished, .target_alloc = ipr_target_alloc, .target_destroy = ipr_target_destroy, .change_queue_depth = ipr_change_queue_depth, - .change_queue_type = ipr_change_queue_type, .bios_param = ipr_biosparam, .can_queue = IPR_MAX_COMMANDS, .this_id = -1, @@ -6841,7 +6930,7 @@ static int ipr_ioa_reset_done(struct ipr_cmnd *ipr_cmd) ioa_cfg->doorbell |= IPR_RUNTIME_RESET; list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { - if (ioa_cfg->allow_ml_add_del && (res->add_to_ml || res->del_from_ml)) { + if (res->add_to_ml || res->del_from_ml) { ipr_trace; break; } @@ -6870,6 +6959,7 @@ static int ipr_ioa_reset_done(struct ipr_cmnd *ipr_cmd) if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) scsi_block_requests(ioa_cfg->host); + schedule_work(&ioa_cfg->work_q); LEAVE; return IPR_RC_JOB_RETURN; } @@ -7610,6 +7700,19 @@ static int ipr_ioafp_page0_inquiry(struct ipr_cmnd *ipr_cmd) type[4] = '\0'; ioa_cfg->type = simple_strtoul((char *)type, NULL, 16); + if (ipr_invalid_adapter(ioa_cfg)) { + dev_err(&ioa_cfg->pdev->dev, + "Adapter not supported in this hardware configuration.\n"); + + if (!ipr_testmode) { + ioa_cfg->reset_retries += IPR_NUM_RESET_RELOAD_RETRIES; + ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); + list_add_tail(&ipr_cmd->queue, + &ioa_cfg->hrrq->hrrq_free_q); + return IPR_RC_JOB_RETURN; + } + } + ipr_cmd->job_step = ipr_ioafp_page3_inquiry; ipr_ioafp_inquiry(ipr_cmd, 1, 0, @@ -8797,20 +8900,6 @@ static int ipr_probe_ioa_part2(struct ipr_ioa_cfg *ioa_cfg) _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_enable_ioa, IPR_SHUTDOWN_NONE); spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); - wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); - spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); - - if (ioa_cfg->hrrq[IPR_INIT_HRRQ].ioa_is_dead) { - rc = -EIO; - } else if (ipr_invalid_adapter(ioa_cfg)) { - if (!ipr_testmode) - rc = -EIO; - - dev_err(&ioa_cfg->pdev->dev, - "Adapter not supported in this hardware configuration.\n"); - } - - spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); LEAVE; return rc; @@ -9264,7 +9353,7 @@ static void ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, * ioa_cfg->max_devs_supported))); } - host->max_channel = IPR_MAX_BUS_TO_SCAN; + host->max_channel = IPR_VSET_BUS; host->unique_id = host->host_no; host->max_cmd_len = IPR_MAX_CDB_LEN; host->can_queue = ioa_cfg->max_cmds; @@ -9764,25 +9853,6 @@ out_scsi_host_put: } /** - * ipr_scan_vsets - Scans for VSET devices - * @ioa_cfg: ioa config struct - * - * Description: Since the VSET resources do not follow SAM in that we can have - * sparse LUNs with no LUN 0, we have to scan for these ourselves. - * - * Return value: - * none - **/ -static void ipr_scan_vsets(struct ipr_ioa_cfg *ioa_cfg) -{ - int target, lun; - - for (target = 0; target < IPR_MAX_NUM_TARGETS_PER_BUS; target++) - for (lun = 0; lun < IPR_MAX_NUM_VSET_LUNS_PER_TARGET; lun++) - scsi_add_device(ioa_cfg->host, IPR_VSET_BUS, target, lun); -} - -/** * ipr_initiate_ioa_bringdown - Bring down an adapter * @ioa_cfg: ioa config struct * @shutdown_type: shutdown type @@ -9937,10 +10007,6 @@ static int ipr_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id) } scsi_scan_host(ioa_cfg->host); - ipr_scan_vsets(ioa_cfg); - scsi_add_device(ioa_cfg->host, IPR_IOA_BUS, IPR_IOA_TARGET, IPR_IOA_LUN); - ioa_cfg->allow_ml_add_del = 1; - ioa_cfg->host->max_channel = IPR_VSET_BUS; ioa_cfg->iopoll_weight = ioa_cfg->chip_cfg->iopoll_weight; if (ioa_cfg->iopoll_weight && ioa_cfg->sis64 && ioa_cfg->nvectors > 1) { diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index 9ebdebd944e7..ec03b42fa2b9 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -157,13 +157,11 @@ #define IPR_MAX_NUM_TARGETS_PER_BUS 256 #define IPR_MAX_NUM_LUNS_PER_TARGET 256 -#define IPR_MAX_NUM_VSET_LUNS_PER_TARGET 8 #define IPR_VSET_BUS 0xff #define IPR_IOA_BUS 0xff #define IPR_IOA_TARGET 0xff #define IPR_IOA_LUN 0xff #define IPR_MAX_NUM_BUSES 16 -#define IPR_MAX_BUS_TO_SCAN IPR_MAX_NUM_BUSES #define IPR_NUM_RESET_RELOAD_RETRIES 3 @@ -1453,7 +1451,7 @@ struct ipr_ioa_cfg { u8 in_ioa_bringdown:1; u8 ioa_unit_checked:1; u8 dump_taken:1; - u8 allow_ml_add_del:1; + u8 scan_done:1; u8 needs_hard_reset:1; u8 dual_raid:1; u8 needs_warm_reset:1; @@ -1608,6 +1606,7 @@ struct ipr_cmnd { struct scsi_device *sdev; } u; + struct completion *eh_comp; struct ipr_hrr_queue *hrrq; struct ipr_ioa_cfg *ioa_cfg; }; diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c index 724c6265b667..cd41b63a2f10 100644 --- a/drivers/scsi/isci/init.c +++ b/drivers/scsi/isci/init.c @@ -158,7 +158,6 @@ static struct scsi_host_template isci_sht = { .scan_finished = isci_host_scan_finished, .scan_start = isci_host_start, .change_queue_depth = sas_change_queue_depth, - .change_queue_type = sas_change_queue_type, .bios_param = sas_bios_param, .can_queue = ISCI_CAN_QUEUE_VAL, .cmd_per_lun = 1, diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 72918d227ead..519dac4e341e 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -906,13 +906,6 @@ int sas_change_queue_depth(struct scsi_device *sdev, int depth) return scsi_change_queue_depth(sdev, depth); } -int sas_change_queue_type(struct scsi_device *scsi_dev, int type) -{ - if (dev_is_sata(sdev_to_domain_dev(scsi_dev))) - return -EINVAL; - return scsi_change_queue_type(scsi_dev, type); -} - int sas_bios_param(struct scsi_device *scsi_dev, struct block_device *bdev, sector_t capacity, int *hsc) @@ -1011,7 +1004,6 @@ EXPORT_SYMBOL_GPL(sas_queuecommand); EXPORT_SYMBOL_GPL(sas_target_alloc); EXPORT_SYMBOL_GPL(sas_slave_configure); EXPORT_SYMBOL_GPL(sas_change_queue_depth); -EXPORT_SYMBOL_GPL(sas_change_queue_type); EXPORT_SYMBOL_GPL(sas_bios_param); EXPORT_SYMBOL_GPL(sas_task_abort); EXPORT_SYMBOL_GPL(sas_phy_reset); diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index fd85952b621d..4f9222eb2266 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -5879,7 +5879,6 @@ struct scsi_host_template lpfc_template = { .max_sectors = 0xFFFF, .vendor_id = LPFC_NL_VENDOR_ID, .change_queue_depth = scsi_change_queue_depth, - .change_queue_type = scsi_change_queue_type, .use_blk_tags = 1, .track_queue_depth = 1, }; @@ -5904,7 +5903,6 @@ struct scsi_host_template lpfc_vport_template = { .shost_attrs = lpfc_vport_attrs, .max_sectors = 0xFFFF, .change_queue_depth = scsi_change_queue_depth, - .change_queue_type = scsi_change_queue_type, .use_blk_tags = 1, .track_queue_depth = 1, }; diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 8431eb10bbb1..6a1c036a6f3f 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -7592,7 +7592,6 @@ static struct scsi_host_template scsih_driver_template = { .scan_finished = _scsih_scan_finished, .scan_start = _scsih_scan_start, .change_queue_depth = _scsih_change_queue_depth, - .change_queue_type = scsi_change_queue_type, .eh_abort_handler = _scsih_abort, .eh_device_reset_handler = _scsih_dev_reset, .eh_target_reset_handler = _scsih_target_reset, diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c index 0d1d06488a28..e689bf20a3ea 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_transport.c +++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c @@ -1006,12 +1006,9 @@ mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, &mpt2sas_phy->remote_identify); _transport_add_phy_to_an_existing_port(ioc, sas_node, mpt2sas_phy, mpt2sas_phy->remote_identify.sas_address); - } else { + } else memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct sas_identify)); - _transport_del_phy_from_an_existing_port(ioc, sas_node, - mpt2sas_phy); - } if (mpt2sas_phy->phy) mpt2sas_phy->phy->negotiated_linkrate = diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index a2b60991efd4..94261ee9e72d 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -7229,7 +7229,6 @@ static struct scsi_host_template scsih_driver_template = { .scan_finished = _scsih_scan_finished, .scan_start = _scsih_scan_start, .change_queue_depth = _scsih_change_queue_depth, - .change_queue_type = scsi_change_queue_type, .eh_abort_handler = _scsih_abort, .eh_device_reset_handler = _scsih_dev_reset, .eh_target_reset_handler = _scsih_target_reset, diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c index d4bafaaebea9..3637ae6c0171 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_transport.c +++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c @@ -1003,12 +1003,9 @@ mpt3sas_transport_update_links(struct MPT3SAS_ADAPTER *ioc, &mpt3sas_phy->remote_identify); _transport_add_phy_to_an_existing_port(ioc, sas_node, mpt3sas_phy, mpt3sas_phy->remote_identify.sas_address); - } else { + } else memset(&mpt3sas_phy->remote_identify, 0 , sizeof(struct sas_identify)); - _transport_del_phy_from_an_existing_port(ioc, sas_node, - mpt3sas_phy); - } if (mpt3sas_phy->phy) mpt3sas_phy->phy->negotiated_linkrate = diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index f15df3de6790..53030b0e8015 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -54,7 +54,6 @@ static struct scsi_host_template mvs_sht = { .scan_finished = mvs_scan_finished, .scan_start = mvs_scan_start, .change_queue_depth = sas_change_queue_depth, - .change_queue_type = sas_change_queue_type, .bios_param = sas_bios_param, .can_queue = 1, .cmd_per_lun = 1, diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 329aba0083ab..65555916d3b8 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -76,7 +76,6 @@ static struct scsi_host_template pm8001_sht = { .scan_finished = pm8001_scan_finished, .scan_start = pm8001_scan_start, .change_queue_depth = sas_change_queue_depth, - .change_queue_type = sas_change_queue_type, .bios_param = sas_bios_param, .can_queue = 1, .cmd_per_lun = 1, diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index b1b1f66b1ab7..8c27b6a77ec4 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -4251,7 +4251,6 @@ static struct scsi_host_template pmcraid_host_template = { .slave_configure = pmcraid_slave_configure, .slave_destroy = pmcraid_slave_destroy, .change_queue_depth = pmcraid_change_queue_depth, - .change_queue_type = scsi_change_queue_type, .can_queue = PMCRAID_MAX_IO_CMD, .this_id = -1, .sg_tablesize = PMCRAID_MAX_IOADLS, diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index a4dde7e80dbd..e59f25bff7ab 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -3237,8 +3237,6 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport) struct fc_rport *rport; unsigned long flags; - qla2x00_rport_del(fcport); - rport_ids.node_name = wwn_to_u64(fcport->node_name); rport_ids.port_name = wwn_to_u64(fcport->port_name); rport_ids.port_id = fcport->d_id.b.domain << 16 | diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 6b4d9235368a..cce1cbc1a927 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -258,7 +258,6 @@ struct scsi_host_template qla2xxx_driver_template = { .scan_finished = qla2xxx_scan_finished, .scan_start = qla2xxx_scan_start, .change_queue_depth = scsi_change_queue_depth, - .change_queue_type = scsi_change_queue_type, .this_id = -1, .cmd_per_lun = 3, .use_clustering = ENABLE_CLUSTERING, @@ -735,7 +734,9 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) * Return target busy if we've received a non-zero retry_delay_timer * in a FCP_RSP. */ - if (time_after(jiffies, fcport->retry_delay_timestamp)) + if (fcport->retry_delay_timestamp == 0) { + /* retry delay not set */ + } else if (time_after(jiffies, fcport->retry_delay_timestamp)) fcport->retry_delay_timestamp = 0; else goto qc24_target_busy; diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index a902fa1db7af..57418258c101 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -3218,25 +3218,25 @@ static inline int qlt_get_fcp_task_attr(struct scsi_qla_host *vha, switch (task_codes) { case ATIO_SIMPLE_QUEUE: - fcp_task_attr = MSG_SIMPLE_TAG; + fcp_task_attr = TCM_SIMPLE_TAG; break; case ATIO_HEAD_OF_QUEUE: - fcp_task_attr = MSG_HEAD_TAG; + fcp_task_attr = TCM_HEAD_TAG; break; case ATIO_ORDERED_QUEUE: - fcp_task_attr = MSG_ORDERED_TAG; + fcp_task_attr = TCM_ORDERED_TAG; break; case ATIO_ACA_QUEUE: - fcp_task_attr = MSG_ACA_TAG; + fcp_task_attr = TCM_ACA_TAG; break; case ATIO_UNTAGGED: - fcp_task_attr = MSG_SIMPLE_TAG; + fcp_task_attr = TCM_SIMPLE_TAG; break; default: ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05d, "qla_target: unknown task code %x, use ORDERED instead\n", task_codes); - fcp_task_attr = MSG_ORDERED_TAG; + fcp_task_attr = TCM_ORDERED_TAG; break; } diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 1ad0c36375b8..e02885451425 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -739,34 +739,12 @@ int scsi_track_queue_full(struct scsi_device *sdev, int depth) if (sdev->last_queue_full_count <= 10) return 0; - if (sdev->last_queue_full_depth < 8) { - /* Drop back to untagged */ - scsi_set_tag_type(sdev, 0); - scsi_change_queue_depth(sdev, sdev->host->cmd_per_lun); - return -1; - } return scsi_change_queue_depth(sdev, depth); } EXPORT_SYMBOL(scsi_track_queue_full); /** - * scsi_change_queue_type() - Change a device's queue type - * @sdev: The SCSI device whose queue depth is to change - * @tag_type: Identifier for queue type - */ -int scsi_change_queue_type(struct scsi_device *sdev, int tag_type) -{ - if (!sdev->tagged_supported) - return 0; - - scsi_set_tag_type(sdev, tag_type); - return tag_type; - -} -EXPORT_SYMBOL(scsi_change_queue_type); - -/** * scsi_vpd_inquiry - Request a device provide us with a VPD page * @sdev: The device to ask * @buffer: Where to put the result diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index aa4b6b80aade..4aca1b0378c2 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -128,7 +128,6 @@ static const char *scsi_debug_version_date = "20141022"; #define DEF_REMOVABLE false #define DEF_SCSI_LEVEL 6 /* INQUIRY, byte2 [6->SPC-4] */ #define DEF_SECTOR_SIZE 512 -#define DEF_TAGGED_QUEUING 0 /* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */ #define DEF_UNMAP_ALIGNMENT 0 #define DEF_UNMAP_GRANULARITY 1 #define DEF_UNMAP_MAX_BLOCKS 0xFFFFFFFF @@ -817,6 +816,7 @@ static int check_readiness(struct scsi_cmnd *SCpnt, int uas_only, UA_CHANGED_ASC, CAPACITY_CHANGED_ASCQ); if (debug) cp = "capacity data changed"; + break; default: pr_warn("%s: unexpected unit attention code=%d\n", __func__, k); @@ -1623,7 +1623,7 @@ resp_rsup_opcodes(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) req_opcode = cmd[3]; req_sa = get_unaligned_be16(cmd + 4); alloc_len = get_unaligned_be32(cmd + 6); - if (alloc_len < 4 && alloc_len > 0xffff) { + if (alloc_len < 4 || alloc_len > 0xffff) { mk_sense_invalid_fld(scp, SDEB_IN_CDB, 6, -1); return check_condition_result; } @@ -1631,7 +1631,7 @@ resp_rsup_opcodes(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) a_len = 8192; else a_len = alloc_len; - arr = kzalloc((a_len < 256) ? 320 : a_len + 64, GFP_KERNEL); + arr = kzalloc((a_len < 256) ? 320 : a_len + 64, GFP_ATOMIC); if (NULL == arr) { mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC, INSUFF_RES_ASCQ); @@ -3045,18 +3045,12 @@ resp_comp_write(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) u8 num; unsigned long iflags; int ret; + int retval = 0; - lba = get_unaligned_be32(cmd + 2); + lba = get_unaligned_be64(cmd + 2); num = cmd[13]; /* 1 to a maximum of 255 logical blocks */ if (0 == num) return 0; /* degenerate case, not an error */ - dnum = 2 * num; - arr = kzalloc(dnum * lb_size, GFP_ATOMIC); - if (NULL == arr) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC, - INSUFF_RES_ASCQ); - return check_condition_result; - } if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION && (cmd[1] & 0xe0)) { mk_sense_invalid_opcode(scp); @@ -3079,6 +3073,13 @@ resp_comp_write(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); return check_condition_result; } + dnum = 2 * num; + arr = kzalloc(dnum * lb_size, GFP_ATOMIC); + if (NULL == arr) { + mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC, + INSUFF_RES_ASCQ); + return check_condition_result; + } write_lock_irqsave(&atomic_rw, iflags); @@ -3089,24 +3090,24 @@ resp_comp_write(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) ret = do_device_access(scp, 0, dnum, true); fake_storep = fake_storep_hold; if (ret == -1) { - write_unlock_irqrestore(&atomic_rw, iflags); - kfree(arr); - return DID_ERROR << 16; + retval = DID_ERROR << 16; + goto cleanup; } else if ((ret < (dnum * lb_size)) && (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) sdev_printk(KERN_INFO, scp->device, "%s: compare_write: cdb " "indicated=%u, IO sent=%d bytes\n", my_name, dnum * lb_size, ret); if (!comp_write_worker(lba, num, arr)) { - write_unlock_irqrestore(&atomic_rw, iflags); - kfree(arr); mk_sense_buffer(scp, MISCOMPARE, MISCOMPARE_VERIFY_ASC, 0); - return check_condition_result; + retval = check_condition_result; + goto cleanup; } if (scsi_debug_lbp()) map_region(lba, num); +cleanup: write_unlock_irqrestore(&atomic_rw, iflags); - return 0; + kfree(arr); + return retval; } struct unmap_block_desc { @@ -4438,6 +4439,7 @@ static ssize_t virtual_gb_store(struct device_driver *ddp, const char *buf, struct sdebug_host_info *sdhp; struct sdebug_dev_info *dp; + spin_lock(&sdebug_host_list_lock); list_for_each_entry(sdhp, &sdebug_host_list, host_list) { list_for_each_entry(dp, &sdhp->dev_info_list, @@ -4446,6 +4448,7 @@ static ssize_t virtual_gb_store(struct device_driver *ddp, const char *buf, dp->uas_bm); } } + spin_unlock(&sdebug_host_list_lock); } return count; } @@ -4988,32 +4991,6 @@ sdebug_change_qdepth(struct scsi_device *sdev, int qdepth) } static int -sdebug_change_qtype(struct scsi_device *sdev, int qtype) -{ - qtype = scsi_change_queue_type(sdev, qtype); - if (SCSI_DEBUG_OPT_Q_NOISE & scsi_debug_opts) { - const char *cp; - - switch (qtype) { - case 0: - cp = "untagged"; - break; - case MSG_SIMPLE_TAG: - cp = "simple tags"; - break; - case MSG_ORDERED_TAG: - cp = "ordered tags"; - break; - default: - cp = "unknown"; - break; - } - sdev_printk(KERN_INFO, sdev, "%s: to %s\n", __func__, cp); - } - return qtype; -} - -static int check_inject(struct scsi_cmnd *scp) { struct sdebug_scmd_extra_t *ep = scsi_cmd_priv(scp); @@ -5212,7 +5189,6 @@ static struct scsi_host_template sdebug_driver_template = { .ioctl = scsi_debug_ioctl, .queuecommand = sdebug_queuecommand_lock_or_not, .change_queue_depth = sdebug_change_qdepth, - .change_queue_type = sdebug_change_qtype, .eh_abort_handler = scsi_debug_abort, .eh_device_reset_handler = scsi_debug_device_reset, .eh_target_reset_handler = scsi_debug_target_reset, diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index c1d04d4d3c6c..262ab837a704 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -211,6 +211,7 @@ static struct { {"Medion", "Flash XL MMC/SD", "2.6D", BLIST_FORCELUN}, {"MegaRAID", "LD", NULL, BLIST_FORCELUN}, {"MICROP", "4110", NULL, BLIST_NOTQ}, + {"MSFT", "Virtual HD", NULL, BLIST_NO_RSOC}, {"MYLEX", "DACARMRB", "*", BLIST_REPORTLUN2}, {"nCipher", "Fastness Crypto", NULL, BLIST_FORCELUN}, {"NAKAMICH", "MJ-4.8S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index e42fff6e8c10..8afb01604d51 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -1041,7 +1041,7 @@ retry: } /* signal not to enter either branch of the if () below */ timeleft = 0; - rtn = NEEDS_RETRY; + rtn = FAILED; } else { timeleft = wait_for_completion_timeout(&done, timeout); rtn = SUCCESS; @@ -1081,7 +1081,7 @@ retry: rtn = FAILED; break; } - } else if (!rtn) { + } else if (rtn != FAILED) { scsi_abort_eh_cmnd(scmd); rtn = FAILED; } diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 43318d556cbc..17bb541f7cc2 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -591,7 +591,6 @@ static void scsi_free_sgtable(struct scsi_data_buffer *sdb, bool mq) static int scsi_alloc_sgtable(struct scsi_data_buffer *sdb, int nents, bool mq) { struct scatterlist *first_chunk = NULL; - gfp_t gfp_mask = mq ? GFP_NOIO : GFP_ATOMIC; int ret; BUG_ON(!nents); @@ -606,7 +605,7 @@ static int scsi_alloc_sgtable(struct scsi_data_buffer *sdb, int nents, bool mq) } ret = __sg_alloc_table(&sdb->table, nents, SCSI_MAX_SG_SEGMENTS, - first_chunk, gfp_mask, scsi_sg_alloc); + first_chunk, GFP_ATOMIC, scsi_sg_alloc); if (unlikely(ret)) scsi_free_sgtable(sdb, mq); return ret; @@ -1144,7 +1143,17 @@ int scsi_init_io(struct scsi_cmnd *cmd) struct scsi_data_buffer *prot_sdb = cmd->prot_sdb; int ivecs, count; - BUG_ON(prot_sdb == NULL); + if (prot_sdb == NULL) { + /* + * This can happen if someone (e.g. multipath) + * queues a command to a device on an adapter + * that does not support DIX. + */ + WARN_ON_ONCE(1); + error = BLKPREP_KILL; + goto err_exit; + } + ivecs = blk_rq_count_integrity_sg(rq->q, rq->bio); if (scsi_alloc_sgtable(prot_sdb, ivecs, is_mq)) { @@ -1918,7 +1927,9 @@ static int scsi_mq_prep_fn(struct request *req) if (scsi_host_get_prot(shost)) { cmd->prot_sdb = (void *)sg + - shost->sg_tablesize * sizeof(struct scatterlist); + min_t(unsigned int, + shost->sg_tablesize, SCSI_MAX_SG_SEGMENTS) * + sizeof(struct scatterlist); memset(cmd->prot_sdb, 0, sizeof(struct scsi_data_buffer)); cmd->prot_sdb->table.sgl = diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c index 7454498c4091..9e43ae1d2163 100644 --- a/drivers/scsi/scsi_pm.c +++ b/drivers/scsi/scsi_pm.c @@ -213,8 +213,6 @@ static int scsi_bus_restore(struct device *dev) #endif /* CONFIG_PM_SLEEP */ -#ifdef CONFIG_PM_RUNTIME - static int sdev_runtime_suspend(struct device *dev) { const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; @@ -332,14 +330,6 @@ void scsi_autopm_put_host(struct Scsi_Host *shost) pm_runtime_put_sync(&shost->shost_gendev); } -#else - -#define scsi_runtime_suspend NULL -#define scsi_runtime_resume NULL -#define scsi_runtime_idle NULL - -#endif /* CONFIG_PM_RUNTIME */ - const struct dev_pm_ops scsi_bus_pm_ops = { .prepare = scsi_bus_prepare, .suspend = scsi_bus_suspend, diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 2dc4a83fb84c..e3902fc66278 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -155,8 +155,7 @@ static inline void scsi_netlink_exit(void) {} /* scsi_pm.c */ #ifdef CONFIG_PM extern const struct dev_pm_ops scsi_bus_pm_ops; -#endif -#ifdef CONFIG_PM_RUNTIME + extern void scsi_autopm_get_target(struct scsi_target *); extern void scsi_autopm_put_target(struct scsi_target *); extern int scsi_autopm_get_host(struct Scsi_Host *); @@ -166,7 +165,7 @@ static inline void scsi_autopm_get_target(struct scsi_target *t) {} static inline void scsi_autopm_put_target(struct scsi_target *t) {} static inline int scsi_autopm_get_host(struct Scsi_Host *h) { return 0; } static inline void scsi_autopm_put_host(struct Scsi_Host *h) {} -#endif /* CONFIG_PM_RUNTIME */ +#endif /* CONFIG_PM */ extern struct async_domain scsi_sd_pm_domain; extern struct async_domain scsi_sd_probe_domain; diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 1cb64a8e18c9..1ac38e73df7e 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -738,30 +738,12 @@ store_queue_type_field(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct scsi_device *sdev = to_scsi_device(dev); - struct scsi_host_template *sht = sdev->host->hostt; - int tag_type = 0, retval; - int prev_tag_type = scsi_get_tag_type(sdev); - - if (!sdev->tagged_supported || !sht->change_queue_type) - return -EINVAL; - /* - * We're never issueing order tags these days, but allow the value - * for backwards compatibility. - */ - if (strncmp(buf, "ordered", 7) == 0 || - strncmp(buf, "simple", 6) == 0) - tag_type = MSG_SIMPLE_TAG; - else if (strncmp(buf, "none", 4) != 0) + if (!sdev->tagged_supported) return -EINVAL; - - if (tag_type == prev_tag_type) - return count; - - retval = sht->change_queue_type(sdev, tag_type); - if (retval < 0) - return retval; - + + sdev_printk(KERN_INFO, sdev, + "ignoring write to deprecated queue_type attribute"); return count; } @@ -938,10 +920,6 @@ static umode_t scsi_sdev_attr_is_visible(struct kobject *kobj, !sdev->host->hostt->change_queue_depth) return 0; - if (attr == &dev_attr_queue_type.attr && - !sdev->host->hostt->change_queue_type) - return S_IRUGO; - return attr->mode; } diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index fa2aece76cc2..31bbb0da3397 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c @@ -1221,7 +1221,7 @@ EXPORT_SYMBOL_GPL(spi_populate_ppr_msg); int spi_populate_tag_msg(unsigned char *msg, struct scsi_cmnd *cmd) { if (cmd->flags & SCMD_TAGGED) { - *msg++ = MSG_SIMPLE_TAG; + *msg++ = SIMPLE_QUEUE_TAG; *msg++ = cmd->request->tag; return 2; } diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index fedab3c21ddf..399516925d80 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2623,8 +2623,9 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) sd_config_discard(sdkp, SD_LBP_WS16); } else { /* LBP VPD page tells us what to use */ - - if (sdkp->lbpws) + if (sdkp->lbpu && sdkp->max_unmap_blocks && !sdkp->lbprz) + sd_config_discard(sdkp, SD_LBP_UNMAP); + else if (sdkp->lbpws) sd_config_discard(sdkp, SD_LBP_WS16); else if (sdkp->lbpws10) sd_config_discard(sdkp, SD_LBP_WS10); diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index e3ba251fb6e7..4cff0ddc2c25 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -1688,13 +1688,12 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) if (ret == -EAGAIN) { /* no more space */ - if (cmd_request->bounce_sgl_count) { + if (cmd_request->bounce_sgl_count) destroy_bounce_buffer(cmd_request->bounce_sgl, cmd_request->bounce_sgl_count); - ret = SCSI_MLQUEUE_DEVICE_BUSY; - goto queue_error; - } + ret = SCSI_MLQUEUE_DEVICE_BUSY; + goto queue_error; } return 0; diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c index 955ed5587011..d15eaa466c59 100644 --- a/drivers/scsi/ufs/ufshcd-pci.c +++ b/drivers/scsi/ufs/ufshcd-pci.c @@ -62,12 +62,7 @@ static int ufshcd_pci_resume(struct device *dev) { return ufshcd_system_resume(dev_get_drvdata(dev)); } -#else -#define ufshcd_pci_suspend NULL -#define ufshcd_pci_resume NULL -#endif /* CONFIG_PM */ -#ifdef CONFIG_PM_RUNTIME static int ufshcd_pci_runtime_suspend(struct device *dev) { return ufshcd_runtime_suspend(dev_get_drvdata(dev)); @@ -80,11 +75,13 @@ static int ufshcd_pci_runtime_idle(struct device *dev) { return ufshcd_runtime_idle(dev_get_drvdata(dev)); } -#else /* !CONFIG_PM_RUNTIME */ +#else /* !CONFIG_PM */ +#define ufshcd_pci_suspend NULL +#define ufshcd_pci_resume NULL #define ufshcd_pci_runtime_suspend NULL #define ufshcd_pci_runtime_resume NULL #define ufshcd_pci_runtime_idle NULL -#endif /* CONFIG_PM_RUNTIME */ +#endif /* CONFIG_PM */ /** * ufshcd_pci_shutdown - main function to put the controller in reset state diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 0c030ad8a960..7db9564f507d 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -261,12 +261,7 @@ static int ufshcd_pltfrm_resume(struct device *dev) { return ufshcd_system_resume(dev_get_drvdata(dev)); } -#else -#define ufshcd_pltfrm_suspend NULL -#define ufshcd_pltfrm_resume NULL -#endif -#ifdef CONFIG_PM_RUNTIME static int ufshcd_pltfrm_runtime_suspend(struct device *dev) { return ufshcd_runtime_suspend(dev_get_drvdata(dev)); @@ -279,11 +274,13 @@ static int ufshcd_pltfrm_runtime_idle(struct device *dev) { return ufshcd_runtime_idle(dev_get_drvdata(dev)); } -#else /* !CONFIG_PM_RUNTIME */ +#else /* !CONFIG_PM */ +#define ufshcd_pltfrm_suspend NULL +#define ufshcd_pltfrm_resume NULL #define ufshcd_pltfrm_runtime_suspend NULL #define ufshcd_pltfrm_runtime_resume NULL #define ufshcd_pltfrm_runtime_idle NULL -#endif /* CONFIG_PM_RUNTIME */ +#endif /* CONFIG_PM */ static void ufshcd_pltfrm_shutdown(struct platform_device *pdev) { diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c index e2fa628e55e7..41b5dc4445f6 100644 --- a/drivers/spi/spi-coldfire-qspi.c +++ b/drivers/spi/spi-coldfire-qspi.c @@ -491,7 +491,7 @@ static int mcfqspi_resume(struct device *dev) } #endif -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM static int mcfqspi_runtime_suspend(struct device *dev) { struct spi_master *master = dev_get_drvdata(dev); diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c index 43781c9fe521..aad6683db81b 100644 --- a/drivers/spi/spi-img-spfi.c +++ b/drivers/spi/spi-img-spfi.c @@ -341,7 +341,7 @@ static int img_spfi_start_dma(struct spi_master *master, default: rxconf.src_addr = spfi->phys + SPFI_RX_8BIT_VALID_DATA; rxconf.src_addr_width = 1; - rxconf.src_maxburst = 1; + rxconf.src_maxburst = 4; } dmaengine_slave_config(spfi->rx_ch, &rxconf); @@ -368,7 +368,7 @@ static int img_spfi_start_dma(struct spi_master *master, default: txconf.dst_addr = spfi->phys + SPFI_TX_8BIT_VALID_DATA; txconf.dst_addr_width = 1; - txconf.dst_maxburst = 1; + txconf.dst_maxburst = 4; break; } dmaengine_slave_config(spfi->tx_ch, &txconf); @@ -390,14 +390,14 @@ static int img_spfi_start_dma(struct spi_master *master, dma_async_issue_pending(spfi->rx_ch); } + spfi_start(spfi); + if (xfer->tx_buf) { spfi->tx_dma_busy = true; dmaengine_submit(txdesc); dma_async_issue_pending(spfi->tx_ch); } - spfi_start(spfi); - return 1; stop_dma: @@ -663,7 +663,7 @@ static int img_spfi_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM static int img_spfi_runtime_suspend(struct device *dev) { struct spi_master *master = dev_get_drvdata(dev); @@ -692,7 +692,7 @@ static int img_spfi_runtime_resume(struct device *dev) return 0; } -#endif /* CONFIG_PM_RUNTIME */ +#endif /* CONFIG_PM */ #ifdef CONFIG_PM_SLEEP static int img_spfi_suspend(struct device *dev) diff --git a/drivers/spi/spi-meson-spifc.c b/drivers/spi/spi-meson-spifc.c index 0e48f8c2037d..1bbac0378bf7 100644 --- a/drivers/spi/spi-meson-spifc.c +++ b/drivers/spi/spi-meson-spifc.c @@ -413,7 +413,7 @@ static int meson_spifc_resume(struct device *dev) } #endif /* CONFIG_PM_SLEEP */ -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM static int meson_spifc_runtime_suspend(struct device *dev) { struct spi_master *master = dev_get_drvdata(dev); @@ -431,7 +431,7 @@ static int meson_spifc_runtime_resume(struct device *dev) return clk_prepare_enable(spifc->clk); } -#endif /* CONFIG_PM_RUNTIME */ +#endif /* CONFIG_PM */ static const struct dev_pm_ops meson_spifc_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(meson_spifc_suspend, meson_spifc_resume) diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index 932da4825e74..3dec9e0b99b8 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c @@ -523,7 +523,7 @@ static int orion_spi_remove(struct platform_device *pdev) MODULE_ALIAS("platform:" DRIVER_NAME); -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM static int orion_spi_runtime_suspend(struct device *dev) { struct spi_master *master = dev_get_drvdata(dev); diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 2a41b2d6fa16..05c623cfb078 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1531,7 +1531,7 @@ static int pxa2xx_spi_resume(struct device *dev) } #endif -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM static int pxa2xx_spi_runtime_suspend(struct device *dev) { struct driver_data *drv_data = dev_get_drvdata(dev); diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c index 390ed712eeed..e7fb5a0d2e8d 100644 --- a/drivers/spi/spi-qup.c +++ b/drivers/spi/spi-qup.c @@ -646,7 +646,7 @@ error: return ret; } -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM static int spi_qup_pm_suspend_runtime(struct device *device) { struct spi_master *master = dev_get_drvdata(device); @@ -672,7 +672,7 @@ static int spi_qup_pm_resume_runtime(struct device *device) writel_relaxed(config, controller->base + QUP_CONFIG); return 0; } -#endif /* CONFIG_PM_RUNTIME */ +#endif /* CONFIG_PM */ #ifdef CONFIG_PM_SLEEP static int spi_qup_suspend(struct device *device) diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c index 44c122558901..daabbabd26b0 100644 --- a/drivers/spi/spi-rockchip.c +++ b/drivers/spi/spi-rockchip.c @@ -799,7 +799,7 @@ static int rockchip_spi_resume(struct device *dev) } #endif /* CONFIG_PM_SLEEP */ -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM static int rockchip_spi_runtime_suspend(struct device *dev) { struct spi_master *master = dev_get_drvdata(dev); @@ -827,7 +827,7 @@ static int rockchip_spi_runtime_resume(struct device *dev) return ret; } -#endif /* CONFIG_PM_RUNTIME */ +#endif /* CONFIG_PM */ static const struct dev_pm_ops rockchip_spi_pm = { SET_SYSTEM_SLEEP_PM_OPS(rockchip_spi_suspend, rockchip_spi_resume) diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 197bcf093174..37b19836f5cb 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -1267,7 +1267,7 @@ static int s3c64xx_spi_resume(struct device *dev) } #endif /* CONFIG_PM_SLEEP */ -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM static int s3c64xx_spi_runtime_suspend(struct device *dev) { struct spi_master *master = dev_get_drvdata(dev); @@ -1297,7 +1297,7 @@ static int s3c64xx_spi_runtime_resume(struct device *dev) return 0; } -#endif /* CONFIG_PM_RUNTIME */ +#endif /* CONFIG_PM */ static const struct dev_pm_ops s3c64xx_spi_pm = { SET_SYSTEM_SLEEP_PM_OPS(s3c64xx_spi_suspend, s3c64xx_spi_resume) diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 239be7cbe5a8..96a5fc0878d8 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -480,6 +480,8 @@ static int sh_msiof_spi_setup(struct spi_device *spi) struct device_node *np = spi->master->dev.of_node; struct sh_msiof_spi_priv *p = spi_master_get_devdata(spi->master); + pm_runtime_get_sync(&p->pdev->dev); + if (!np) { /* * Use spi->controller_data for CS (same strategy as spi_gpio), @@ -498,6 +500,9 @@ static int sh_msiof_spi_setup(struct spi_device *spi) if (spi->cs_gpio >= 0) gpio_set_value(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); + + pm_runtime_put_sync(&p->pdev->dev); + return 0; } diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 9425728b7eb5..815de379a130 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -62,8 +62,6 @@ source "drivers/staging/xgifb/Kconfig" source "drivers/staging/emxx_udc/Kconfig" -source "drivers/staging/bcm/Kconfig" - source "drivers/staging/ft1000/Kconfig" source "drivers/staging/speakup/Kconfig" @@ -106,4 +104,6 @@ source "drivers/staging/skein/Kconfig" source "drivers/staging/unisys/Kconfig" +source "drivers/staging/clocking-wizard/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index bc233dd98a95..33c640b49566 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -25,7 +25,6 @@ obj-$(CONFIG_VME_BUS) += vme/ obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_FB_XGI) += xgifb/ obj-$(CONFIG_USB_EMXX) += emxx_udc/ -obj-$(CONFIG_BCM_WIMAX) += bcm/ obj-$(CONFIG_FT1000) += ft1000/ obj-$(CONFIG_SPEAKUP) += speakup/ obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/ @@ -45,3 +44,4 @@ obj-$(CONFIG_MTD_SPINAND_MT29F) += mt29f_spinand/ obj-$(CONFIG_GS_FPGABOOT) += gs_fpgaboot/ obj-$(CONFIG_CRYPTO_SKEIN) += skein/ obj-$(CONFIG_UNISYSSPAR) += unisys/ +obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD) += clocking-wizard/ diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index 7a0e28852965..7e012f37792b 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -1,37 +1,7 @@ menu "Android" -config ANDROID - bool "Android Drivers" - ---help--- - Enable support for various drivers needed on the Android platform - if ANDROID -config ANDROID_BINDER_IPC - bool "Android Binder IPC Driver" - depends on MMU - default n - ---help--- - Binder is used in Android for both communication between processes, - and remote method invocation. - - This means one Android process can call a method/routine in another - Android process, using Binder to identify, invoke and pass arguments - between said processes. - -config ANDROID_BINDER_IPC_32BIT - bool - depends on !64BIT && ANDROID_BINDER_IPC - default y - ---help--- - The Binder API has been changed to support both 32 and 64bit - applications in a mixed environment. - - Enable this to support an old 32-bit Android user-space (v4.4 and - earlier). - - Note that enabling this will break newer Android user-space. - config ASHMEM bool "Enable the Anonymous Shared Memory Subsystem" default n diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile index 517ad5ffa429..479b2b86f8c8 100644 --- a/drivers/staging/android/Makefile +++ b/drivers/staging/android/Makefile @@ -2,7 +2,6 @@ ccflags-y += -I$(src) # needed for trace events obj-y += ion/ -obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o obj-$(CONFIG_ASHMEM) += ashmem.o obj-$(CONFIG_ANDROID_LOGGER) += logger.o obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o diff --git a/drivers/staging/android/TODO b/drivers/staging/android/TODO index b15fb0d6b152..06954cdf3dba 100644 --- a/drivers/staging/android/TODO +++ b/drivers/staging/android/TODO @@ -5,6 +5,13 @@ TODO: - make sure things build as modules properly - add proper arch dependencies as needed - audit userspace interfaces to make sure they are sane + - kuid_t should never be exposed to user space as it is + kernel internal type. Data structure for this kuid_t is: + typedef struct { + uid_t val; + } kuid_t; + - This bug is introduced by Xiong Zhou in the patch bd471258f2e09 + - ("staging: android: logger: use kuid_t instead of uid_t") Please send patches to Greg Kroah-Hartman <greg@kroah.com> and Cc: Brian Swetland <swetland@google.com> diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 46f8ef42559e..8c7852742f4b 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -446,7 +446,7 @@ ashmem_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) loff_t start = range->pgstart * PAGE_SIZE; loff_t end = (range->pgend + 1) * PAGE_SIZE; - do_fallocate(range->asma->file, + vfs_fallocate(range->asma->file, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, start, end - start); range->purged = ASHMEM_WAS_PURGED; diff --git a/drivers/staging/android/binder.h b/drivers/staging/android/binder.h deleted file mode 100644 index eb0834656dfe..000000000000 --- a/drivers/staging/android/binder.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2008 Google, Inc. - * - * Based on, but no longer compatible with, the original - * OpenBinder.org binder driver interface, which is: - * - * Copyright (c) 2005 Palmsource, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _LINUX_BINDER_H -#define _LINUX_BINDER_H - -#ifdef CONFIG_ANDROID_BINDER_IPC_32BIT -#define BINDER_IPC_32BIT 1 -#endif - -#include "uapi/binder.h" - -#endif /* _LINUX_BINDER_H */ - diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 56604f41ec48..296d347660fc 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -250,7 +250,7 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, our systems the only dma_address space is physical addresses. Additionally, we can't afford the overhead of invalidating every allocation via dma_map_sg. The implicit contract here is that - memory comming from the heaps is ready for dma, ie if it has a + memory coming from the heaps is ready for dma, ie if it has a cached mapping that mapping has been invalidated */ for_each_sg(buffer->sg_table->sgl, sg, buffer->sg_table->nents, i) sg_dma_address(sg) = sg_phys(sg); @@ -263,8 +263,7 @@ err: heap->ops->unmap_dma(heap, buffer); heap->ops->free(buffer); err1: - if (buffer->pages) - vfree(buffer->pages); + vfree(buffer->pages); err2: kfree(buffer); return ERR_PTR(ret); @@ -276,8 +275,7 @@ void ion_buffer_destroy(struct ion_buffer *buffer) buffer->heap->ops->unmap_kernel(buffer->heap, buffer); buffer->heap->ops->unmap_dma(buffer->heap, buffer); buffer->heap->ops->free(buffer); - if (buffer->pages) - vfree(buffer->pages); + vfree(buffer->pages); kfree(buffer); } @@ -902,7 +900,7 @@ void ion_pages_sync_for_device(struct device *dev, struct page *page, sg_set_page(&sg, page, size, 0); /* * This is not correct - sg_dma_address needs a dma_addr_t that is valid - * for the the targeted device, but this works on the currently targeted + * for the targeted device, but this works on the currently targeted * hardware. */ sg_dma_address(&sg) = page_to_phys(page); diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h index d305bb7e9a74..443db8459a9e 100644 --- a/drivers/staging/android/ion/ion.h +++ b/drivers/staging/android/ion/ion.h @@ -76,7 +76,7 @@ struct ion_platform_data { * size * * Calls memblock reserve to set aside memory for heaps that are - * located at specific memory addresses or of specfic sizes not + * located at specific memory addresses or of specific sizes not * managed by the kernel */ void ion_reserve(struct ion_platform_data *data); diff --git a/drivers/staging/android/ion/ion_dummy_driver.c b/drivers/staging/android/ion/ion_dummy_driver.c index f3ea1c31e533..5678870bff48 100644 --- a/drivers/staging/android/ion/ion_dummy_driver.c +++ b/drivers/staging/android/ion/ion_dummy_driver.c @@ -112,10 +112,8 @@ static int __init ion_dummy_init(void) } return 0; err: - for (i = 0; i < dummy_ion_pdata.nr; i++) { - if (heaps[i]) - ion_heap_destroy(heaps[i]); - } + for (i = 0; i < dummy_ion_pdata.nr; ++i) + ion_heap_destroy(heaps[i]); kfree(heaps); if (carveout_ptr) { diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c index 5864f3dfcbc6..4b88f11e52d3 100644 --- a/drivers/staging/android/ion/ion_page_pool.c +++ b/drivers/staging/android/ion/ion_page_pool.c @@ -120,7 +120,7 @@ int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, bool high; if (current_is_kswapd()) - high = 1; + high = true; else high = !!(gfp_mask & __GFP_HIGHMEM); diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h index c8f01757abfa..18a5f93e13b7 100644 --- a/drivers/staging/android/ion/ion_priv.h +++ b/drivers/staging/android/ion/ion_priv.h @@ -345,7 +345,7 @@ void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr, * functions for creating and destroying a heap pool -- allows you * to keep a pool of pre allocated memory to use from your heap. Keeping * a pool of memory that is ready for dma, ie any cached mapping have been - * invalidated from the cache, provides a significant peformance benefit on + * invalidated from the cache, provides a significant performance benefit on * many systems */ /** @@ -362,7 +362,7 @@ void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr, * * Allows you to keep a pool of pre allocated pages to use from your heap. * Keeping a pool of pages that is ready for dma, ie any cached mapping have - * been invalidated from the cache, provides a significant peformance benefit + * been invalidated from the cache, provides a significant performance benefit * on many systems */ struct ion_page_pool { diff --git a/drivers/staging/android/ion/tegra/tegra_ion.c b/drivers/staging/android/ion/tegra/tegra_ion.c index 11c7cceb3c7d..5b8ef0e66010 100644 --- a/drivers/staging/android/ion/tegra/tegra_ion.c +++ b/drivers/staging/android/ion/tegra/tegra_ion.c @@ -54,10 +54,8 @@ static int tegra_ion_probe(struct platform_device *pdev) platform_set_drvdata(pdev, idev); return 0; err: - for (i = 0; i < num_heaps; i++) { - if (heaps[i]) - ion_heap_destroy(heaps[i]); - } + for (i = 0; i < num_heaps; ++i) + ion_heap_destroy(heaps[i]); return err; } diff --git a/drivers/staging/android/sync_debug.c b/drivers/staging/android/sync_debug.c index 257fc91bf02b..1532a86404be 100644 --- a/drivers/staging/android/sync_debug.c +++ b/drivers/staging/android/sync_debug.c @@ -25,6 +25,7 @@ #include <linux/slab.h> #include <linux/uaccess.h> #include <linux/anon_inodes.h> +#include <linux/time64.h> #include "sync.h" #ifdef CONFIG_DEBUG_FS @@ -95,9 +96,9 @@ static void sync_print_pt(struct seq_file *s, struct sync_pt *pt, bool fence) sync_status_str(status)); if (status <= 0) { - struct timeval tv = ktime_to_timeval(pt->base.timestamp); + struct timespec64 ts64 = ktime_to_timespec64(pt->base.timestamp); - seq_printf(s, "@%ld.%06ld", tv.tv_sec, tv.tv_usec); + seq_printf(s, "@%lld.%09ld", (s64)ts64.tv_sec, ts64.tv_nsec); } if (parent->ops->timeline_value_str && diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c index c71ed64931ba..938a35cd99bb 100644 --- a/drivers/staging/android/timed_gpio.c +++ b/drivers/staging/android/timed_gpio.c @@ -20,6 +20,7 @@ #include <linux/hrtimer.h> #include <linux/err.h> #include <linux/gpio.h> +#include <linux/ktime.h> #include "timed_output.h" #include "timed_gpio.h" @@ -46,16 +47,16 @@ static enum hrtimer_restart gpio_timer_func(struct hrtimer *timer) static int gpio_get_time(struct timed_output_dev *dev) { struct timed_gpio_data *data; - struct timeval t; + ktime_t t; data = container_of(dev, struct timed_gpio_data, dev); if (!hrtimer_active(&data->timer)) return 0; - t = ktime_to_timeval(hrtimer_get_remaining(&data->timer)); + t = hrtimer_get_remaining(&data->timer); - return t.tv_sec * 1000 + t.tv_usec / 1000; + return ktime_to_ms(t); } static void gpio_enable(struct timed_output_dev *dev, int value) diff --git a/drivers/staging/android/uapi/binder.h b/drivers/staging/android/uapi/binder.h deleted file mode 100644 index dba4cef3a8d3..000000000000 --- a/drivers/staging/android/uapi/binder.h +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright (C) 2008 Google, Inc. - * - * Based on, but no longer compatible with, the original - * OpenBinder.org binder driver interface, which is: - * - * Copyright (c) 2005 Palmsource, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _UAPI_LINUX_BINDER_H -#define _UAPI_LINUX_BINDER_H - -#include <linux/ioctl.h> - -#define B_PACK_CHARS(c1, c2, c3, c4) \ - ((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4)) -#define B_TYPE_LARGE 0x85 - -enum { - BINDER_TYPE_BINDER = B_PACK_CHARS('s', 'b', '*', B_TYPE_LARGE), - BINDER_TYPE_WEAK_BINDER = B_PACK_CHARS('w', 'b', '*', B_TYPE_LARGE), - BINDER_TYPE_HANDLE = B_PACK_CHARS('s', 'h', '*', B_TYPE_LARGE), - BINDER_TYPE_WEAK_HANDLE = B_PACK_CHARS('w', 'h', '*', B_TYPE_LARGE), - BINDER_TYPE_FD = B_PACK_CHARS('f', 'd', '*', B_TYPE_LARGE), -}; - -enum { - FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff, - FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100, -}; - -#ifdef BINDER_IPC_32BIT -typedef __u32 binder_size_t; -typedef __u32 binder_uintptr_t; -#else -typedef __u64 binder_size_t; -typedef __u64 binder_uintptr_t; -#endif - -/* - * This is the flattened representation of a Binder object for transfer - * between processes. The 'offsets' supplied as part of a binder transaction - * contains offsets into the data where these structures occur. The Binder - * driver takes care of re-writing the structure type and data as it moves - * between processes. - */ -struct flat_binder_object { - /* 8 bytes for large_flat_header. */ - __u32 type; - __u32 flags; - - /* 8 bytes of data. */ - union { - binder_uintptr_t binder; /* local object */ - __u32 handle; /* remote object */ - }; - - /* extra data associated with local object */ - binder_uintptr_t cookie; -}; - -/* - * On 64-bit platforms where user code may run in 32-bits the driver must - * translate the buffer (and local binder) addresses appropriately. - */ - -struct binder_write_read { - binder_size_t write_size; /* bytes to write */ - binder_size_t write_consumed; /* bytes consumed by driver */ - binder_uintptr_t write_buffer; - binder_size_t read_size; /* bytes to read */ - binder_size_t read_consumed; /* bytes consumed by driver */ - binder_uintptr_t read_buffer; -}; - -/* Use with BINDER_VERSION, driver fills in fields. */ -struct binder_version { - /* driver protocol version -- increment with incompatible change */ - __s32 protocol_version; -}; - -/* This is the current protocol version. */ -#ifdef BINDER_IPC_32BIT -#define BINDER_CURRENT_PROTOCOL_VERSION 7 -#else -#define BINDER_CURRENT_PROTOCOL_VERSION 8 -#endif - -#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read) -#define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, __s64) -#define BINDER_SET_MAX_THREADS _IOW('b', 5, __u32) -#define BINDER_SET_IDLE_PRIORITY _IOW('b', 6, __s32) -#define BINDER_SET_CONTEXT_MGR _IOW('b', 7, __s32) -#define BINDER_THREAD_EXIT _IOW('b', 8, __s32) -#define BINDER_VERSION _IOWR('b', 9, struct binder_version) - -/* - * NOTE: Two special error codes you should check for when calling - * in to the driver are: - * - * EINTR -- The operation has been interupted. This should be - * handled by retrying the ioctl() until a different error code - * is returned. - * - * ECONNREFUSED -- The driver is no longer accepting operations - * from your process. That is, the process is being destroyed. - * You should handle this by exiting from your process. Note - * that once this error code is returned, all further calls to - * the driver from any thread will return this same code. - */ - -enum transaction_flags { - TF_ONE_WAY = 0x01, /* this is a one-way call: async, no return */ - TF_ROOT_OBJECT = 0x04, /* contents are the component's root object */ - TF_STATUS_CODE = 0x08, /* contents are a 32-bit status code */ - TF_ACCEPT_FDS = 0x10, /* allow replies with file descriptors */ -}; - -struct binder_transaction_data { - /* The first two are only used for bcTRANSACTION and brTRANSACTION, - * identifying the target and contents of the transaction. - */ - union { - /* target descriptor of command transaction */ - __u32 handle; - /* target descriptor of return transaction */ - binder_uintptr_t ptr; - } target; - binder_uintptr_t cookie; /* target object cookie */ - __u32 code; /* transaction command */ - - /* General information about the transaction. */ - __u32 flags; - pid_t sender_pid; - uid_t sender_euid; - binder_size_t data_size; /* number of bytes of data */ - binder_size_t offsets_size; /* number of bytes of offsets */ - - /* If this transaction is inline, the data immediately - * follows here; otherwise, it ends with a pointer to - * the data buffer. - */ - union { - struct { - /* transaction data */ - binder_uintptr_t buffer; - /* offsets from buffer to flat_binder_object structs */ - binder_uintptr_t offsets; - } ptr; - __u8 buf[8]; - } data; -}; - -struct binder_ptr_cookie { - binder_uintptr_t ptr; - binder_uintptr_t cookie; -}; - -struct binder_handle_cookie { - __u32 handle; - binder_uintptr_t cookie; -} __packed; - -struct binder_pri_desc { - __s32 priority; - __u32 desc; -}; - -struct binder_pri_ptr_cookie { - __s32 priority; - binder_uintptr_t ptr; - binder_uintptr_t cookie; -}; - -enum binder_driver_return_protocol { - BR_ERROR = _IOR('r', 0, __s32), - /* - * int: error code - */ - - BR_OK = _IO('r', 1), - /* No parameters! */ - - BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data), - BR_REPLY = _IOR('r', 3, struct binder_transaction_data), - /* - * binder_transaction_data: the received command. - */ - - BR_ACQUIRE_RESULT = _IOR('r', 4, __s32), - /* - * not currently supported - * int: 0 if the last bcATTEMPT_ACQUIRE was not successful. - * Else the remote object has acquired a primary reference. - */ - - BR_DEAD_REPLY = _IO('r', 5), - /* - * The target of the last transaction (either a bcTRANSACTION or - * a bcATTEMPT_ACQUIRE) is no longer with us. No parameters. - */ - - BR_TRANSACTION_COMPLETE = _IO('r', 6), - /* - * No parameters... always refers to the last transaction requested - * (including replies). Note that this will be sent even for - * asynchronous transactions. - */ - - BR_INCREFS = _IOR('r', 7, struct binder_ptr_cookie), - BR_ACQUIRE = _IOR('r', 8, struct binder_ptr_cookie), - BR_RELEASE = _IOR('r', 9, struct binder_ptr_cookie), - BR_DECREFS = _IOR('r', 10, struct binder_ptr_cookie), - /* - * void *: ptr to binder - * void *: cookie for binder - */ - - BR_ATTEMPT_ACQUIRE = _IOR('r', 11, struct binder_pri_ptr_cookie), - /* - * not currently supported - * int: priority - * void *: ptr to binder - * void *: cookie for binder - */ - - BR_NOOP = _IO('r', 12), - /* - * No parameters. Do nothing and examine the next command. It exists - * primarily so that we can replace it with a BR_SPAWN_LOOPER command. - */ - - BR_SPAWN_LOOPER = _IO('r', 13), - /* - * No parameters. The driver has determined that a process has no - * threads waiting to service incoming transactions. When a process - * receives this command, it must spawn a new service thread and - * register it via bcENTER_LOOPER. - */ - - BR_FINISHED = _IO('r', 14), - /* - * not currently supported - * stop threadpool thread - */ - - BR_DEAD_BINDER = _IOR('r', 15, binder_uintptr_t), - /* - * void *: cookie - */ - BR_CLEAR_DEATH_NOTIFICATION_DONE = _IOR('r', 16, binder_uintptr_t), - /* - * void *: cookie - */ - - BR_FAILED_REPLY = _IO('r', 17), - /* - * The the last transaction (either a bcTRANSACTION or - * a bcATTEMPT_ACQUIRE) failed (e.g. out of memory). No parameters. - */ -}; - -enum binder_driver_command_protocol { - BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data), - BC_REPLY = _IOW('c', 1, struct binder_transaction_data), - /* - * binder_transaction_data: the sent command. - */ - - BC_ACQUIRE_RESULT = _IOW('c', 2, __s32), - /* - * not currently supported - * int: 0 if the last BR_ATTEMPT_ACQUIRE was not successful. - * Else you have acquired a primary reference on the object. - */ - - BC_FREE_BUFFER = _IOW('c', 3, binder_uintptr_t), - /* - * void *: ptr to transaction data received on a read - */ - - BC_INCREFS = _IOW('c', 4, __u32), - BC_ACQUIRE = _IOW('c', 5, __u32), - BC_RELEASE = _IOW('c', 6, __u32), - BC_DECREFS = _IOW('c', 7, __u32), - /* - * int: descriptor - */ - - BC_INCREFS_DONE = _IOW('c', 8, struct binder_ptr_cookie), - BC_ACQUIRE_DONE = _IOW('c', 9, struct binder_ptr_cookie), - /* - * void *: ptr to binder - * void *: cookie for binder - */ - - BC_ATTEMPT_ACQUIRE = _IOW('c', 10, struct binder_pri_desc), - /* - * not currently supported - * int: priority - * int: descriptor - */ - - BC_REGISTER_LOOPER = _IO('c', 11), - /* - * No parameters. - * Register a spawned looper thread with the device. - */ - - BC_ENTER_LOOPER = _IO('c', 12), - BC_EXIT_LOOPER = _IO('c', 13), - /* - * No parameters. - * These two commands are sent as an application-level thread - * enters and exits the binder loop, respectively. They are - * used so the binder can have an accurate count of the number - * of looping threads it has available. - */ - - BC_REQUEST_DEATH_NOTIFICATION = _IOW('c', 14, - struct binder_handle_cookie), - /* - * int: handle - * void *: cookie - */ - - BC_CLEAR_DEATH_NOTIFICATION = _IOW('c', 15, - struct binder_handle_cookie), - /* - * int: handle - * void *: cookie - */ - - BC_DEAD_BINDER_DONE = _IOW('c', 16, binder_uintptr_t), - /* - * void *: cookie - */ -}; - -#endif /* _UAPI_LINUX_BINDER_H */ - diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h deleted file mode 100644 index 940c852e17b7..000000000000 --- a/drivers/staging/bcm/Adapter.h +++ /dev/null @@ -1,474 +0,0 @@ -/*********************************** -* Adapter.h -************************************/ -#ifndef __ADAPTER_H__ -#define __ADAPTER_H__ - -#define MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES 256 -#include "Debug.h" - -struct bcm_leader { - USHORT Vcid; - USHORT PLength; - UCHAR Status; - UCHAR Unused[3]; -} __packed; - -struct bcm_packettosend { - struct bcm_leader Leader; - UCHAR ucPayload; -} __packed; - -struct bcm_control_packet { - PVOID ControlBuff; - UINT ControlBuffLen; - struct bcm_control_packet *next; -} __packed; - -struct bcm_link_request { - struct bcm_leader Leader; - UCHAR szData[4]; -} __packed; - -#define MAX_IP_RANGE_LENGTH 4 -#define MAX_PORT_RANGE 4 -#define MAX_PROTOCOL_LENGTH 32 -#define IPV6_ADDRESS_SIZEINBYTES 0x10 - -union u_ip_address { - struct { - /* Source Ip Address Range */ - ULONG ulIpv4Addr[MAX_IP_RANGE_LENGTH]; - /* Source Ip Mask Address Range */ - ULONG ulIpv4Mask[MAX_IP_RANGE_LENGTH]; - }; - struct { - /* Source Ip Address Range */ - ULONG ulIpv6Addr[MAX_IP_RANGE_LENGTH * 4]; - /* Source Ip Mask Address Range */ - ULONG ulIpv6Mask[MAX_IP_RANGE_LENGTH * 4]; - }; - struct { - UCHAR ucIpv4Address[MAX_IP_RANGE_LENGTH * IP_LENGTH_OF_ADDRESS]; - UCHAR ucIpv4Mask[MAX_IP_RANGE_LENGTH * IP_LENGTH_OF_ADDRESS]; - }; - struct { - UCHAR ucIpv6Address[MAX_IP_RANGE_LENGTH * IPV6_ADDRESS_SIZEINBYTES]; - UCHAR ucIpv6Mask[MAX_IP_RANGE_LENGTH * IPV6_ADDRESS_SIZEINBYTES]; - }; -}; - -struct bcm_hdr_suppression_contextinfo { - /* Intermediate buffer to accumulate pkt Header for PHS */ - UCHAR ucaHdrSuppressionInBuf[MAX_PHS_LENGTHS]; - /* Intermediate buffer containing pkt Header after PHS */ - UCHAR ucaHdrSuppressionOutBuf[MAX_PHS_LENGTHS + PHSI_LEN]; -}; - -struct bcm_classifier_rule { - ULONG ulSFID; - UCHAR ucReserved[2]; - B_UINT16 uiClassifierRuleIndex; - bool bUsed; - USHORT usVCID_Value; - /* This field detemines the Classifier Priority */ - B_UINT8 u8ClassifierRulePriority; - union u_ip_address stSrcIpAddress; - UCHAR ucIPSourceAddressLength; /* Ip Source Address Length */ - - union u_ip_address stDestIpAddress; - /* Ip Destination Address Length */ - UCHAR ucIPDestinationAddressLength; - UCHAR ucIPTypeOfServiceLength; /* Type of service Length */ - UCHAR ucTosLow; /* Tos Low */ - UCHAR ucTosHigh; /* Tos High */ - UCHAR ucTosMask; /* Tos Mask */ - - UCHAR ucProtocolLength; /* protocol Length */ - UCHAR ucProtocol[MAX_PROTOCOL_LENGTH]; /* protocol Length */ - USHORT usSrcPortRangeLo[MAX_PORT_RANGE]; - USHORT usSrcPortRangeHi[MAX_PORT_RANGE]; - UCHAR ucSrcPortRangeLength; - - USHORT usDestPortRangeLo[MAX_PORT_RANGE]; - USHORT usDestPortRangeHi[MAX_PORT_RANGE]; - UCHAR ucDestPortRangeLength; - - bool bProtocolValid; - bool bTOSValid; - bool bDestIpValid; - bool bSrcIpValid; - - /* For IPv6 Addressing */ - UCHAR ucDirection; - bool bIpv6Protocol; - UINT32 u32PHSRuleID; - struct bcm_phs_rule sPhsRule; - UCHAR u8AssociatedPHSI; - - /* Classification fields for ETH CS */ - UCHAR ucEthCSSrcMACLen; - UCHAR au8EThCSSrcMAC[MAC_ADDRESS_SIZE]; - UCHAR au8EThCSSrcMACMask[MAC_ADDRESS_SIZE]; - UCHAR ucEthCSDestMACLen; - UCHAR au8EThCSDestMAC[MAC_ADDRESS_SIZE]; - UCHAR au8EThCSDestMACMask[MAC_ADDRESS_SIZE]; - UCHAR ucEtherTypeLen; - UCHAR au8EthCSEtherType[NUM_ETHERTYPE_BYTES]; - UCHAR usUserPriority[2]; - USHORT usVLANID; - USHORT usValidityBitMap; -}; - -struct bcm_fragmented_packet_info { - bool bUsed; - ULONG ulSrcIpAddress; - USHORT usIpIdentification; - struct bcm_classifier_rule *pstMatchedClassifierEntry; - bool bOutOfOrderFragment; -}; - -struct bcm_packet_info { - /* classification extension Rule */ - ULONG ulSFID; - USHORT usVCID_Value; - UINT uiThreshold; - /* This field determines the priority of the SF Queues */ - B_UINT8 u8TrafficPriority; - - bool bValid; - bool bActive; - bool bActivateRequestSent; - - B_UINT8 u8QueueType; /* BE or rtPS */ - - /* maximum size of the bucket for the queue */ - UINT uiMaxBucketSize; - UINT uiCurrentQueueDepthOnTarget; - UINT uiCurrentBytesOnHost; - UINT uiCurrentPacketsOnHost; - UINT uiDroppedCountBytes; - UINT uiDroppedCountPackets; - UINT uiSentBytes; - UINT uiSentPackets; - UINT uiCurrentDrainRate; - UINT uiThisPeriodSentBytes; - LARGE_INTEGER liDrainCalculated; - UINT uiCurrentTokenCount; - LARGE_INTEGER liLastUpdateTokenAt; - UINT uiMaxAllowedRate; - UINT NumOfPacketsSent; - UCHAR ucDirection; - USHORT usCID; - struct bcm_mibs_parameters stMibsExtServiceFlowTable; - UINT uiCurrentRxRate; - UINT uiThisPeriodRxBytes; - UINT uiTotalRxBytes; - UINT uiTotalTxBytes; - UINT uiPendedLast; - UCHAR ucIpVersion; - - union { - struct { - struct sk_buff *FirstTxQueue; - struct sk_buff *LastTxQueue; - }; - struct { - struct sk_buff *ControlHead; - struct sk_buff *ControlTail; - }; - }; - - bool bProtocolValid; - bool bTOSValid; - bool bDestIpValid; - bool bSrcIpValid; - - bool bActiveSet; - bool bAdmittedSet; - bool bAuthorizedSet; - bool bClassifierPriority; - UCHAR ucServiceClassName[MAX_CLASS_NAME_LENGTH]; - bool bHeaderSuppressionEnabled; - spinlock_t SFQueueLock; - void *pstSFIndication; - struct timeval stLastUpdateTokenAt; - atomic_t uiPerSFTxResourceCount; - UINT uiMaxLatency; - UCHAR bIPCSSupport; - UCHAR bEthCSSupport; -}; - -struct bcm_tarang_data { - struct bcm_tarang_data *next; - struct bcm_mini_adapter *Adapter; - struct sk_buff *RxAppControlHead; - struct sk_buff *RxAppControlTail; - int AppCtrlQueueLen; - bool MacTracingEnabled; - bool bApplicationToExit; - struct bcm_mibs_dropped_cntrl_msg stDroppedAppCntrlMsgs; - ULONG RxCntrlMsgBitMask; -}; - -struct bcm_targetdsx_buffer { - ULONG ulTargetDsxBuffer; - B_UINT16 tid; - bool valid; -}; - -typedef int (*FP_FLASH_WRITE)(struct bcm_mini_adapter *, UINT, PVOID); - -typedef int (*FP_FLASH_WRITE_STATUS)(struct bcm_mini_adapter *, UINT, PVOID); - -/* - * Driver adapter data structure - */ -struct bcm_mini_adapter { - struct bcm_mini_adapter *next; - struct net_device *dev; - u32 msg_enable; - CHAR *caDsxReqResp; - atomic_t ApplicationRunning; - bool AppCtrlQueueOverFlow; - atomic_t CurrentApplicationCount; - atomic_t RegisteredApplicationCount; - bool LinkUpStatus; - bool TimerActive; - u32 StatisticsPointer; - struct sk_buff *RxControlHead; - struct sk_buff *RxControlTail; - struct semaphore RxAppControlQueuelock; - struct semaphore fw_download_sema; - struct bcm_tarang_data *pTarangs; - spinlock_t control_queue_lock; - wait_queue_head_t process_read_wait_queue; - - /* the pointer to the first packet we have queued in send - * deserialized miniport support variables - */ - atomic_t TotalPacketCount; - atomic_t TxPktAvail; - - /* this to keep track of the Tx and Rx MailBox Registers. */ - atomic_t CurrNumFreeTxDesc; - /* to keep track the no of byte received */ - USHORT PrevNumRecvDescs; - USHORT CurrNumRecvDescs; - UINT u32TotalDSD; - struct bcm_packet_info PackInfo[NO_OF_QUEUES]; - struct bcm_classifier_rule astClassifierTable[MAX_CLASSIFIERS]; - bool TransferMode; - - /*************** qos ******************/ - bool bETHCSEnabled; - ULONG BEBucketSize; - ULONG rtPSBucketSize; - UCHAR LinkStatus; - bool AutoLinkUp; - bool AutoSyncup; - - int major; - int minor; - wait_queue_head_t tx_packet_wait_queue; - wait_queue_head_t process_rx_cntrlpkt; - atomic_t process_waiting; - bool fw_download_done; - - char *txctlpacket[MAX_CNTRL_PKTS]; - atomic_t cntrlpktCnt; - atomic_t index_app_read_cntrlpkt; - atomic_t index_wr_txcntrlpkt; - atomic_t index_rd_txcntrlpkt; - UINT index_datpkt; - struct semaphore rdmwrmsync; - - struct bcm_targetdsx_buffer astTargetDsxBuffer[MAX_TARGET_DSX_BUFFERS]; - ULONG ulFreeTargetBufferCnt; - ULONG ulCurrentTargetBuffer; - ULONG ulTotalTargetBuffersAvailable; - unsigned long chip_id; - wait_queue_head_t lowpower_mode_wait_queue; - bool bFlashBoot; - bool bBinDownloaded; - bool bCfgDownloaded; - bool bSyncUpRequestSent; - USHORT usBestEffortQueueIndex; - wait_queue_head_t ioctl_fw_dnld_wait_queue; - bool waiting_to_fw_download_done; - pid_t fw_download_process_pid; - struct bcm_target_params *pstargetparams; - bool device_removed; - bool DeviceAccess; - bool bIsAutoCorrectEnabled; - bool bDDRInitDone; - int DDRSetting; - ULONG ulPowerSaveMode; - spinlock_t txtransmitlock; - B_UINT8 txtransmit_running; - /* Thread for control packet handling */ - struct task_struct *control_packet_handler; - /* thread for transmitting packets. */ - struct task_struct *transmit_packet_thread; - - /* LED Related Structures */ - struct bcm_led_info LEDInfo; - - /* Driver State for LED Blinking */ - enum bcm_led_events DriverState; - /* Interface Specific */ - PVOID pvInterfaceAdapter; - int (*bcm_file_download)(PVOID, - struct file *, - unsigned int); - int (*bcm_file_readback_from_chip)(PVOID, - struct file *, - unsigned int); - int (*interface_rdm)(PVOID, - UINT, - PVOID, - int); - int (*interface_wrm)(PVOID, - UINT, - PVOID, - int); - int (*interface_transmit)(PVOID, PVOID , UINT); - bool IdleMode; - bool bDregRequestSentInIdleMode; - bool bTriedToWakeUpFromlowPowerMode; - bool bShutStatus; - bool bWakeUpDevice; - unsigned int usIdleModePattern; - /* BOOLEAN bTriedToWakeUpFromShutdown; */ - bool bLinkDownRequested; - int downloadDDR; - struct bcm_phs_extension stBCMPhsContext; - struct bcm_hdr_suppression_contextinfo stPhsTxContextInfo; - uint8_t ucaPHSPktRestoreBuf[2048]; - uint8_t bPHSEnabled; - bool AutoFirmDld; - bool bMipsConfig; - bool bDPLLConfig; - UINT32 aTxPktSizeHist[MIBS_MAX_HIST_ENTRIES]; - UINT32 aRxPktSizeHist[MIBS_MAX_HIST_ENTRIES]; - struct bcm_fragmented_packet_info - astFragmentedPktClassifierTable[MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES]; - atomic_t uiMBupdate; - UINT32 PmuMode; - enum bcm_nvm_type eNVMType; - UINT uiSectorSize; - UINT uiSectorSizeInCFG; - bool bSectorSizeOverride; - bool bStatusWrite; - UINT uiNVMDSDSize; - UINT uiVendorExtnFlag; - /* it will always represent chosen DSD at any point of time. - * Generally it is Active DSD but in case of NVM RD/WR it - * might be different. - */ - UINT ulFlashCalStart; - ULONG ulFlashControlSectionStart; - ULONG ulFlashWriteSize; - ULONG ulFlashID; - FP_FLASH_WRITE fpFlashWrite; - FP_FLASH_WRITE_STATUS fpFlashWriteWithStatusCheck; - - struct semaphore NVMRdmWrmLock; - struct device *pstCreatedClassDevice; - - /* BOOLEAN InterfaceUpStatus; */ - struct bcm_flash2x_cs_info *psFlash2xCSInfo; - struct bcm_flash_cs_info *psFlashCSInfo; - struct bcm_flash2x_vendor_info *psFlash2xVendorInfo; - UINT uiFlashBaseAdd; /* Flash start address */ - /* Active ISO offset chosen before f/w download */ - UINT uiActiveISOOffset; - enum bcm_flash2x_section_val eActiveISO; /* Active ISO section val */ - /* Active DSD val chosen before f/w download */ - enum bcm_flash2x_section_val eActiveDSD; - /* For accessing Active DSD chosen before f/w download */ - UINT uiActiveDSDOffsetAtFwDld; - UINT uiFlashLayoutMajorVersion; - UINT uiFlashLayoutMinorVersion; - bool bAllDSDWriteAllow; - bool bSigCorrupted; - /* this should be set who so ever want to change the Headers. - * after Write it should be reset immediately. - */ - bool bHeaderChangeAllowed; - int SelectedChip; - bool bEndPointHalted; - /* while bFlashRawRead will be true, Driver - * ignore map lay out and consider flash as of without any map. - */ - bool bFlashRawRead; - bool bPreparingForLowPowerMode; - bool bDoSuspend; - UINT syscfgBefFwDld; - bool StopAllXaction; - /* Used to Support extended CAPI requirements from */ - UINT32 liTimeSinceLastNetEntry; - struct semaphore LowPowerModeSync; - ULONG liDrainCalculated; - UINT gpioBitMap; - struct bcm_debug_state stDebugState; -}; - -#define GET_BCM_ADAPTER(net_dev) netdev_priv(net_dev) - -struct bcm_eth_header { - UCHAR au8DestinationAddress[6]; - UCHAR au8SourceAddress[6]; - USHORT u16Etype; -} __packed; - -struct bcm_firmware_info { - void __user *pvMappedFirmwareAddress; - ULONG u32FirmwareLength; - ULONG u32StartingAddress; -} __packed; - -/* holds the value of net_device structure.. */ -extern struct net_device *gblpnetdev; - -struct bcm_ddr_setting { - UINT ulRegAddress; - UINT ulRegValue; -}; -int InitAdapter(struct bcm_mini_adapter *psAdapter); - -/* ===================================================================== - * Beceem vendor request codes for EP0 - * ===================================================================== - */ - -#define BCM_REQUEST_READ 0x2 -#define BCM_REQUEST_WRITE 0x1 -#define EP2_MPS_REG 0x0F0110A0 -#define EP2_MPS 0x40 - -#define EP2_CFG_REG 0x0F0110A8 -#define EP2_CFG_INT 0x27 -#define EP2_CFG_BULK 0x25 - -#define EP4_MPS_REG 0x0F0110F0 -#define EP4_MPS 0x8C - -#define EP4_CFG_REG 0x0F0110F8 - -#define ISO_MPS_REG 0x0F0110C8 -#define ISO_MPS 0x00000000 - -#define EP1 0 -#define EP2 1 -#define EP3 2 -#define EP4 3 -#define EP5 4 -#define EP6 5 - -enum bcm_einterface_setting { - DEFAULT_SETTING_0 = 0, - ALTERNATE_SETTING_1 = 1, -}; - -#endif /* __ADAPTER_H__ */ diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c deleted file mode 100644 index 88ce2da531c6..000000000000 --- a/drivers/staging/bcm/Bcmchar.c +++ /dev/null @@ -1,2652 +0,0 @@ -#include <linux/fs.h> - -#include "headers.h" - -static int bcm_handle_nvm_read_cmd(struct bcm_mini_adapter *ad, - PUCHAR read_data, - struct bcm_nvm_readwrite *nvm_rw) -{ - INT status = STATUS_FAILURE; - - down(&ad->NVMRdmWrmLock); - - if ((ad->IdleMode == TRUE) || (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, - DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Device is in Idle/Shutdown Mode\n"); - up(&ad->NVMRdmWrmLock); - kfree(read_data); - return -EACCES; - } - - status = BeceemNVMRead(ad, (PUINT)read_data, - nvm_rw->uiOffset, - nvm_rw->uiNumBytes); - up(&ad->NVMRdmWrmLock); - - if (status != STATUS_SUCCESS) { - kfree(read_data); - return status; - } - - if (copy_to_user(nvm_rw->pBuffer, read_data, nvm_rw->uiNumBytes)) { - kfree(read_data); - return -EFAULT; - } - - return STATUS_SUCCESS; -} - -static int handle_flash2x_adapter(struct bcm_mini_adapter *ad, - PUCHAR read_data, - struct bcm_nvm_readwrite *nvm_rw) -{ - /* - * New Requirement:- - * DSD section updation will be allowed in two case:- - * 1. if DSD sig is present in DSD header means dongle - * is ok and updation is fruitfull - * 2. if point 1 failes then user buff should have - * DSD sig. this point ensures that if dongle is - * corrupted then user space program first modify - * the DSD header with valid DSD sig so that this - * as well as further write may be worthwhile. - * - * This restriction has been put assuming that - * if DSD sig is corrupted, DSD data won't be - * considered valid. - */ - INT status; - ULONG dsd_magic_num_in_usr_buff = 0; - - status = BcmFlash2xCorruptSig(ad, ad->eActiveDSD); - if (status == STATUS_SUCCESS) - return STATUS_SUCCESS; - - if (((nvm_rw->uiOffset + nvm_rw->uiNumBytes) != - ad->uiNVMDSDSize) || - (nvm_rw->uiNumBytes < SIGNATURE_SIZE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "DSD Sig is present neither in Flash nor User provided Input.."); - up(&ad->NVMRdmWrmLock); - kfree(read_data); - return status; - } - - dsd_magic_num_in_usr_buff = - ntohl(*(PUINT)(read_data + nvm_rw->uiNumBytes - - SIGNATURE_SIZE)); - if (dsd_magic_num_in_usr_buff != DSD_IMAGE_MAGIC_NUMBER) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "DSD Sig is present neither in Flash nor User provided Input.."); - up(&ad->NVMRdmWrmLock); - kfree(read_data); - return status; - } - - return STATUS_SUCCESS; -} - -/*************************************************************** -* Function - bcm_char_open() -* -* Description - This is the "open" entry point for the character -* driver. -* -* Parameters - inode: Pointer to the Inode structure of char device -* filp : File pointer of the char device -* -* Returns - Zero(Success) -****************************************************************/ - -static int bcm_char_open(struct inode *inode, struct file *filp) -{ - struct bcm_mini_adapter *ad = NULL; - struct bcm_tarang_data *tarang = NULL; - - ad = GET_BCM_ADAPTER(gblpnetdev); - tarang = kzalloc(sizeof(struct bcm_tarang_data), GFP_KERNEL); - if (!tarang) - return -ENOMEM; - - tarang->Adapter = ad; - tarang->RxCntrlMsgBitMask = 0xFFFFFFFF & ~(1 << 0xB); - - down(&ad->RxAppControlQueuelock); - tarang->next = ad->pTarangs; - ad->pTarangs = tarang; - up(&ad->RxAppControlQueuelock); - - /* Store the Adapter structure */ - filp->private_data = tarang; - - /* Start Queuing the control response Packets */ - atomic_inc(&ad->ApplicationRunning); - - nonseekable_open(inode, filp); - return 0; -} - -static int bcm_char_release(struct inode *inode, struct file *filp) -{ - struct bcm_tarang_data *tarang, *tmp, *ptmp; - struct bcm_mini_adapter *ad = NULL; - struct sk_buff *pkt, *npkt; - - tarang = (struct bcm_tarang_data *)filp->private_data; - - if (tarang == NULL) - return 0; - - ad = tarang->Adapter; - - down(&ad->RxAppControlQueuelock); - - tmp = ad->pTarangs; - for (ptmp = NULL; tmp; ptmp = tmp, tmp = tmp->next) { - if (tmp == tarang) - break; - } - - if (tmp) { - if (!ptmp) - ad->pTarangs = tmp->next; - else - ptmp->next = tmp->next; - } else { - up(&ad->RxAppControlQueuelock); - return 0; - } - - pkt = tarang->RxAppControlHead; - while (pkt) { - npkt = pkt->next; - kfree_skb(pkt); - pkt = npkt; - } - - up(&ad->RxAppControlQueuelock); - - /* Stop Queuing the control response Packets */ - atomic_dec(&ad->ApplicationRunning); - - kfree(tarang); - - /* remove this filp from the asynchronously notified filp's */ - filp->private_data = NULL; - return 0; -} - -static ssize_t bcm_char_read(struct file *filp, - char __user *buf, - size_t size, - loff_t *f_pos) -{ - struct bcm_tarang_data *tarang = filp->private_data; - struct bcm_mini_adapter *ad = tarang->Adapter; - struct sk_buff *packet = NULL; - ssize_t pkt_len = 0; - int wait_ret_val = 0; - unsigned long ret = 0; - - wait_ret_val = wait_event_interruptible( - ad->process_read_wait_queue, - (tarang->RxAppControlHead || - ad->device_removed)); - - if ((wait_ret_val == -ERESTARTSYS)) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Exiting as i've been asked to exit!!!\n"); - return wait_ret_val; - } - - if (ad->device_removed) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Device Removed... Killing the Apps...\n"); - return -ENODEV; - } - - if (false == ad->fw_download_done) - return -EACCES; - - down(&ad->RxAppControlQueuelock); - - if (tarang->RxAppControlHead) { - packet = tarang->RxAppControlHead; - DEQUEUEPACKET(tarang->RxAppControlHead, - tarang->RxAppControlTail); - tarang->AppCtrlQueueLen--; - } - - up(&ad->RxAppControlQueuelock); - - if (packet) { - pkt_len = packet->len; - ret = copy_to_user(buf, packet->data, - min_t(size_t, pkt_len, size)); - if (ret) { - dev_kfree_skb(packet); - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Returning from copy to user failure\n"); - return -EFAULT; - } - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Read %zd Bytes From Adapter packet = %p by process %d!\n", - pkt_len, packet, current->pid); - dev_kfree_skb(packet); - } - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "<\n"); - return pkt_len; -} - -static int bcm_char_ioctl_reg_read_private(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_rdm_buffer rdm_buff = {0}; - struct bcm_ioctl_buffer io_buff; - PCHAR temp_buff; - INT status = STATUS_FAILURE; - UINT buff_len; - u16 temp_value; - int bytes; - - /* Copy Ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength > sizeof(rdm_buff)) - return -EINVAL; - - if (copy_from_user(&rdm_buff, io_buff.InputBuffer, - io_buff.InputLength)) - return -EFAULT; - - if (io_buff.OutputLength > USHRT_MAX || - io_buff.OutputLength == 0) { - return -EINVAL; - } - - buff_len = io_buff.OutputLength; - temp_value = 4 - (buff_len % 4); - buff_len += temp_value % 4; - - temp_buff = kmalloc(buff_len, GFP_KERNEL); - if (!temp_buff) - return -ENOMEM; - - bytes = rdmalt(ad, (UINT)rdm_buff.Register, - (PUINT)temp_buff, buff_len); - if (bytes > 0) { - status = STATUS_SUCCESS; - if (copy_to_user(io_buff.OutputBuffer, temp_buff, bytes)) { - kfree(temp_buff); - return -EFAULT; - } - } else { - status = bytes; - } - - kfree(temp_buff); - return status; -} - -static int bcm_char_ioctl_reg_write_private(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_wrm_buffer wrm_buff = {0}; - struct bcm_ioctl_buffer io_buff; - UINT tmp = 0; - INT status; - - /* Copy Ioctl Buffer structure */ - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength > sizeof(wrm_buff)) - return -EINVAL; - - /* Get WrmBuffer structure */ - if (copy_from_user(&wrm_buff, io_buff.InputBuffer, - io_buff.InputLength)) - return -EFAULT; - - tmp = wrm_buff.Register & EEPROM_REJECT_MASK; - if (!((ad->pstargetparams->m_u32Customize) & VSG_MODE) && - ((tmp == EEPROM_REJECT_REG_1) || - (tmp == EEPROM_REJECT_REG_2) || - (tmp == EEPROM_REJECT_REG_3) || - (tmp == EEPROM_REJECT_REG_4))) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "EEPROM Access Denied, not in VSG Mode\n"); - return -EFAULT; - } - - status = wrmalt(ad, (UINT)wrm_buff.Register, - (PUINT)wrm_buff.Data, sizeof(ULONG)); - - if (status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, "WRM Done\n"); - } else { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, "WRM Failed\n"); - status = -EFAULT; - } - return status; -} - -static int bcm_char_ioctl_eeprom_reg_read(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_rdm_buffer rdm_buff = {0}; - struct bcm_ioctl_buffer io_buff; - PCHAR temp_buff = NULL; - UINT tmp = 0; - INT status; - int bytes; - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Device in Idle Mode, Blocking Rdms\n"); - return -EACCES; - } - - /* Copy Ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength > sizeof(rdm_buff)) - return -EINVAL; - - if (copy_from_user(&rdm_buff, io_buff.InputBuffer, - io_buff.InputLength)) - return -EFAULT; - - if (io_buff.OutputLength > USHRT_MAX || - io_buff.OutputLength == 0) { - return -EINVAL; - } - - temp_buff = kmalloc(io_buff.OutputLength, GFP_KERNEL); - if (!temp_buff) - return STATUS_FAILURE; - - if ((((ULONG)rdm_buff.Register & 0x0F000000) != 0x0F000000) || - ((ULONG)rdm_buff.Register & 0x3)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "RDM Done On invalid Address : %x Access Denied.\n", - (int)rdm_buff.Register); - - kfree(temp_buff); - return -EINVAL; - } - - tmp = rdm_buff.Register & EEPROM_REJECT_MASK; - bytes = rdmaltWithLock(ad, (UINT)rdm_buff.Register, - (PUINT)temp_buff, io_buff.OutputLength); - - if (bytes > 0) { - status = STATUS_SUCCESS; - if (copy_to_user(io_buff.OutputBuffer, temp_buff, bytes)) { - kfree(temp_buff); - return -EFAULT; - } - } else { - status = bytes; - } - - kfree(temp_buff); - return status; -} - -static int bcm_char_ioctl_eeprom_reg_write(void __user *argp, - struct bcm_mini_adapter *ad, - UINT cmd) -{ - struct bcm_wrm_buffer wrm_buff = {0}; - struct bcm_ioctl_buffer io_buff; - UINT tmp = 0; - INT status; - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Device in Idle Mode, Blocking Wrms\n"); - return -EACCES; - } - - /* Copy Ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength > sizeof(wrm_buff)) - return -EINVAL; - - /* Get WrmBuffer structure */ - if (copy_from_user(&wrm_buff, io_buff.InputBuffer, - io_buff.InputLength)) - return -EFAULT; - - if ((((ULONG)wrm_buff.Register & 0x0F000000) != 0x0F000000) || - ((ULONG)wrm_buff.Register & 0x3)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "WRM Done On invalid Address : %x Access Denied.\n", - (int)wrm_buff.Register); - return -EINVAL; - } - - tmp = wrm_buff.Register & EEPROM_REJECT_MASK; - if (!((ad->pstargetparams->m_u32Customize) & VSG_MODE) && - ((tmp == EEPROM_REJECT_REG_1) || - (tmp == EEPROM_REJECT_REG_2) || - (tmp == EEPROM_REJECT_REG_3) || - (tmp == EEPROM_REJECT_REG_4)) && - (cmd == IOCTL_BCM_REGISTER_WRITE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "EEPROM Access Denied, not in VSG Mode\n"); - return -EFAULT; - } - - status = wrmaltWithLock(ad, (UINT)wrm_buff.Register, - (PUINT)wrm_buff.Data, - wrm_buff.Length); - - if (status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, OSAL_DBG, - DBG_LVL_ALL, "WRM Done\n"); - } else { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, "WRM Failed\n"); - status = -EFAULT; - } - return status; -} - -static int bcm_char_ioctl_gpio_set_request(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_gpio_info gpio_info = {0}; - struct bcm_ioctl_buffer io_buff; - UCHAR reset_val[4]; - UINT value = 0; - UINT bit = 0; - UINT operation = 0; - INT status; - int bytes; - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, - "GPIO Can't be set/clear in Low power Mode"); - return -EACCES; - } - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength > sizeof(gpio_info)) - return -EINVAL; - - if (copy_from_user(&gpio_info, io_buff.InputBuffer, - io_buff.InputLength)) - return -EFAULT; - - bit = gpio_info.uiGpioNumber; - operation = gpio_info.uiGpioValue; - value = (1<<bit); - - if (IsReqGpioIsLedInNVM(ad, value) == false) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, - "Sorry, Requested GPIO<0x%X> is not correspond to LED !!!", - value); - return -EINVAL; - } - - /* Set - setting 1 */ - if (operation) { - /* Set the gpio output register */ - status = wrmaltWithLock(ad, - BCM_GPIO_OUTPUT_SET_REG, - (PUINT)(&value), sizeof(UINT)); - - if (status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, - OSAL_DBG, DBG_LVL_ALL, - "Set the GPIO bit\n"); - } else { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, - OSAL_DBG, DBG_LVL_ALL, - "Failed to set the %dth GPIO\n", - bit); - return status; - } - } else { - /* Set the gpio output register */ - status = wrmaltWithLock(ad, - BCM_GPIO_OUTPUT_CLR_REG, - (PUINT)(&value), sizeof(UINT)); - - if (status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, - OSAL_DBG, DBG_LVL_ALL, - "Set the GPIO bit\n"); - } else { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, - OSAL_DBG, DBG_LVL_ALL, - "Failed to clear the %dth GPIO\n", - bit); - return status; - } - } - - bytes = rdmaltWithLock(ad, (UINT)GPIO_MODE_REGISTER, - (PUINT)reset_val, sizeof(UINT)); - if (bytes < 0) { - status = bytes; - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "GPIO_MODE_REGISTER read failed"); - return status; - } - status = STATUS_SUCCESS; - - /* Set the gpio mode register to output */ - *(UINT *)reset_val |= (1<<bit); - status = wrmaltWithLock(ad, GPIO_MODE_REGISTER, - (PUINT)reset_val, sizeof(UINT)); - - if (status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, - "Set the GPIO to output Mode\n"); - } else { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, - "Failed to put GPIO in Output Mode\n"); - } - - return status; -} - -static int bcm_char_ioctl_led_thread_state_change_req(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_user_thread_req thread_req = {0}; - struct bcm_ioctl_buffer io_buff; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "User made LED thread InActive"); - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, - "GPIO Can't be set/clear in Low power Mode"); - return -EACCES; - } - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength > sizeof(thread_req)) - return -EINVAL; - - if (copy_from_user(&thread_req, io_buff.InputBuffer, - io_buff.InputLength)) - return -EFAULT; - - /* if LED thread is running(Actively or Inactively) - * set it state to make inactive - */ - if (ad->LEDInfo.led_thread_running) { - if (thread_req.ThreadState == LED_THREAD_ACTIVATION_REQ) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, - OSAL_DBG, DBG_LVL_ALL, - "Activating thread req"); - ad->DriverState = LED_THREAD_ACTIVE; - } else { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, - OSAL_DBG, DBG_LVL_ALL, - "DeActivating Thread req....."); - ad->DriverState = LED_THREAD_INACTIVE; - } - - /* signal thread. */ - wake_up(&ad->LEDInfo.notify_led_event); - } - return STATUS_SUCCESS; -} - -static int bcm_char_ioctl_gpio_status_request(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_gpio_info gpio_info = {0}; - struct bcm_ioctl_buffer io_buff; - ULONG bit = 0; - UCHAR read[4]; - INT status; - int bytes; - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) - return -EACCES; - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength > sizeof(gpio_info)) - return -EINVAL; - - if (copy_from_user(&gpio_info, io_buff.InputBuffer, - io_buff.InputLength)) - return -EFAULT; - - bit = gpio_info.uiGpioNumber; - - /* Set the gpio output register */ - bytes = rdmaltWithLock(ad, (UINT)GPIO_PIN_STATE_REGISTER, - (PUINT)read, sizeof(UINT)); - - if (bytes < 0) { - status = bytes; - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "RDM Failed\n"); - return status; - } - status = STATUS_SUCCESS; - return status; -} - -static int bcm_char_ioctl_gpio_multi_request(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_gpio_multi_info gpio_multi_info[MAX_IDX]; - struct bcm_gpio_multi_info *pgpio_multi_info = - (struct bcm_gpio_multi_info *)gpio_multi_info; - struct bcm_ioctl_buffer io_buff; - UCHAR reset_val[4]; - INT status = STATUS_FAILURE; - int bytes; - - memset(pgpio_multi_info, 0, - MAX_IDX * sizeof(struct bcm_gpio_multi_info)); - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) - return -EINVAL; - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength > sizeof(gpio_multi_info)) - return -EINVAL; - if (io_buff.OutputLength > sizeof(gpio_multi_info)) - io_buff.OutputLength = sizeof(gpio_multi_info); - - if (copy_from_user(&gpio_multi_info, io_buff.InputBuffer, - io_buff.InputLength)) - return -EFAULT; - - if (IsReqGpioIsLedInNVM(ad, pgpio_multi_info[WIMAX_IDX].uiGPIOMask) - == false) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, - "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!", - pgpio_multi_info[WIMAX_IDX].uiGPIOMask, - ad->gpioBitMap); - return -EINVAL; - } - - /* Set the gpio output register */ - if ((pgpio_multi_info[WIMAX_IDX].uiGPIOMask) & - (pgpio_multi_info[WIMAX_IDX].uiGPIOCommand)) { - /* Set 1's in GPIO OUTPUT REGISTER */ - *(UINT *)reset_val = pgpio_multi_info[WIMAX_IDX].uiGPIOMask & - pgpio_multi_info[WIMAX_IDX].uiGPIOCommand & - pgpio_multi_info[WIMAX_IDX].uiGPIOValue; - - if (*(UINT *) reset_val) - status = wrmaltWithLock(ad, - BCM_GPIO_OUTPUT_SET_REG, - (PUINT)reset_val, sizeof(ULONG)); - - if (status != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "WRM to BCM_GPIO_OUTPUT_SET_REG Failed."); - return status; - } - - /* Clear to 0's in GPIO OUTPUT REGISTER */ - *(UINT *)reset_val = - (pgpio_multi_info[WIMAX_IDX].uiGPIOMask & - pgpio_multi_info[WIMAX_IDX].uiGPIOCommand & - (~(pgpio_multi_info[WIMAX_IDX].uiGPIOValue))); - - if (*(UINT *) reset_val) - status = wrmaltWithLock(ad, - BCM_GPIO_OUTPUT_CLR_REG, (PUINT)reset_val, - sizeof(ULONG)); - - if (status != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "WRM to BCM_GPIO_OUTPUT_CLR_REG Failed."); - return status; - } - } - - if (pgpio_multi_info[WIMAX_IDX].uiGPIOMask) { - bytes = rdmaltWithLock(ad, (UINT)GPIO_PIN_STATE_REGISTER, - (PUINT)reset_val, sizeof(UINT)); - - if (bytes < 0) { - status = bytes; - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "RDM to GPIO_PIN_STATE_REGISTER Failed."); - return status; - } - status = STATUS_SUCCESS; - - pgpio_multi_info[WIMAX_IDX].uiGPIOValue = - (*(UINT *)reset_val & - pgpio_multi_info[WIMAX_IDX].uiGPIOMask); - } - - status = copy_to_user(io_buff.OutputBuffer, &gpio_multi_info, - io_buff.OutputLength); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Failed while copying Content to IOBufer for user space err:%d", - status); - return -EFAULT; - } - return status; -} - -static int bcm_char_ioctl_gpio_mode_request(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_gpio_multi_mode gpio_multi_mode[MAX_IDX]; - struct bcm_gpio_multi_mode *pgpio_multi_mode = - (struct bcm_gpio_multi_mode *)gpio_multi_mode; - struct bcm_ioctl_buffer io_buff; - UCHAR reset_val[4]; - INT status; - int bytes; - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) - return -EINVAL; - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength > sizeof(gpio_multi_mode)) - return -EINVAL; - if (io_buff.OutputLength > sizeof(gpio_multi_mode)) - io_buff.OutputLength = sizeof(gpio_multi_mode); - - if (copy_from_user(&gpio_multi_mode, io_buff.InputBuffer, - io_buff.InputLength)) - return -EFAULT; - - bytes = rdmaltWithLock(ad, (UINT)GPIO_MODE_REGISTER, - (PUINT)reset_val, sizeof(UINT)); - - if (bytes < 0) { - status = bytes; - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Read of GPIO_MODE_REGISTER failed"); - return status; - } - status = STATUS_SUCCESS; - - /* Validating the request */ - if (IsReqGpioIsLedInNVM(ad, pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) - == false) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!", - pgpio_multi_mode[WIMAX_IDX].uiGPIOMask, - ad->gpioBitMap); - return -EINVAL; - } - - if (pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) { - /* write all OUT's (1's) */ - *(UINT *) reset_val |= - (pgpio_multi_mode[WIMAX_IDX].uiGPIOMode & - pgpio_multi_mode[WIMAX_IDX].uiGPIOMask); - - /* write all IN's (0's) */ - *(UINT *) reset_val &= - ~((~pgpio_multi_mode[WIMAX_IDX].uiGPIOMode) & - pgpio_multi_mode[WIMAX_IDX].uiGPIOMask); - - /* Currently implemented return the modes of all GPIO's - * else needs to bit AND with mask - */ - pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT *)reset_val; - - status = wrmaltWithLock(ad, GPIO_MODE_REGISTER, - (PUINT)reset_val, sizeof(ULONG)); - if (status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(ad, - DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "WRM to GPIO_MODE_REGISTER Done"); - } else { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "WRM to GPIO_MODE_REGISTER Failed"); - return -EFAULT; - } - } else { - /* if uiGPIOMask is 0 then return mode register configuration */ - pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT *)reset_val; - } - - status = copy_to_user(io_buff.OutputBuffer, &gpio_multi_mode, - io_buff.OutputLength); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Failed while copying Content to IOBufer for user space err:%d", - status); - return -EFAULT; - } - return status; -} - -static int bcm_char_ioctl_misc_request(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_ioctl_buffer io_buff; - PVOID buff = NULL; - INT status; - - /* Copy Ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength < sizeof(struct bcm_link_request)) - return -EINVAL; - - if (io_buff.InputLength > MAX_CNTL_PKT_SIZE) - return -EINVAL; - - buff = memdup_user(io_buff.InputBuffer, - io_buff.InputLength); - if (IS_ERR(buff)) - return PTR_ERR(buff); - - down(&ad->LowPowerModeSync); - status = wait_event_interruptible_timeout( - ad->lowpower_mode_wait_queue, - !ad->bPreparingForLowPowerMode, - (1 * HZ)); - - if (status == -ERESTARTSYS) - goto cntrlEnd; - - if (ad->bPreparingForLowPowerMode) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Preparing Idle Mode is still True - Hence Rejecting control message\n"); - status = STATUS_FAILURE; - goto cntrlEnd; - } - status = CopyBufferToControlPacket(ad, (PVOID)buff); - -cntrlEnd: - up(&ad->LowPowerModeSync); - kfree(buff); - return status; -} - -static int bcm_char_ioctl_buffer_download_start( - struct bcm_mini_adapter *ad) -{ - INT status; - - if (down_trylock(&ad->NVMRdmWrmLock)) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n"); - return -EACCES; - } - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Starting the firmware download PID =0x%x!!!!\n", - current->pid); - - if (down_trylock(&ad->fw_download_sema)) - return -EBUSY; - - ad->bBinDownloaded = false; - ad->fw_download_process_pid = current->pid; - ad->bCfgDownloaded = false; - ad->fw_download_done = false; - netif_carrier_off(ad->dev); - netif_stop_queue(ad->dev); - status = reset_card_proc(ad); - if (status) { - pr_err(PFX "%s: reset_card_proc Failed!\n", ad->dev->name); - up(&ad->fw_download_sema); - up(&ad->NVMRdmWrmLock); - return status; - } - mdelay(10); - - up(&ad->NVMRdmWrmLock); - return status; -} - -static int bcm_char_ioctl_buffer_download(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_firmware_info *fw_info = NULL; - struct bcm_ioctl_buffer io_buff; - INT status; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Starting the firmware download PID =0x%x!!!!\n", current->pid); - - if (!down_trylock(&ad->fw_download_sema)) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Invalid way to download buffer. Use Start and then call this!!!\n"); - up(&ad->fw_download_sema); - return -EINVAL; - } - - /* Copy Ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) { - up(&ad->fw_download_sema); - return -EFAULT; - } - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Length for FW DLD is : %lx\n", io_buff.InputLength); - - if (io_buff.InputLength > sizeof(struct bcm_firmware_info)) { - up(&ad->fw_download_sema); - return -EINVAL; - } - - fw_info = kmalloc(sizeof(*fw_info), GFP_KERNEL); - if (!fw_info) { - up(&ad->fw_download_sema); - return -ENOMEM; - } - - if (copy_from_user(fw_info, io_buff.InputBuffer, - io_buff.InputLength)) { - up(&ad->fw_download_sema); - kfree(fw_info); - return -EFAULT; - } - - if (!fw_info->pvMappedFirmwareAddress || - (fw_info->u32FirmwareLength == 0)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Something else is wrong %lu\n", - fw_info->u32FirmwareLength); - up(&ad->fw_download_sema); - kfree(fw_info); - status = -EINVAL; - return status; - } - - status = bcm_ioctl_fw_download(ad, fw_info); - - if (status != STATUS_SUCCESS) { - if (fw_info->u32StartingAddress == CONFIG_BEGIN_ADDR) - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "IOCTL: Configuration File Upload Failed\n"); - else - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "IOCTL: Firmware File Upload Failed\n"); - - /* up(&ad->fw_download_sema); */ - - if (ad->LEDInfo.led_thread_running & - BCM_LED_THREAD_RUNNING_ACTIVELY) { - ad->DriverState = DRIVER_INIT; - ad->LEDInfo.bLedInitDone = false; - wake_up(&ad->LEDInfo.notify_led_event); - } - } - - if (status != STATUS_SUCCESS) - up(&ad->fw_download_sema); - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, - "IOCTL: Firmware File Uploaded\n"); - kfree(fw_info); - return status; -} - -static int bcm_char_ioctl_buffer_download_stop(void __user *argp, - struct bcm_mini_adapter *ad) -{ - INT status; - int timeout = 0; - - if (!down_trylock(&ad->fw_download_sema)) { - up(&ad->fw_download_sema); - return -EINVAL; - } - - if (down_trylock(&ad->NVMRdmWrmLock)) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "FW download blocked as EEPROM Read/Write is in progress\n"); - up(&ad->fw_download_sema); - return -EACCES; - } - - ad->bBinDownloaded = TRUE; - ad->bCfgDownloaded = TRUE; - atomic_set(&ad->CurrNumFreeTxDesc, 0); - ad->CurrNumRecvDescs = 0; - ad->downloadDDR = 0; - - /* setting the Mips to Run */ - status = run_card_proc(ad); - - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Firm Download Failed\n"); - up(&ad->fw_download_sema); - up(&ad->NVMRdmWrmLock); - return status; - } - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, "Firm Download Over...\n"); - - mdelay(10); - - /* Wait for MailBox Interrupt */ - if (StartInterruptUrb((struct bcm_interface_adapter *)ad->pvInterfaceAdapter)) - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Unable to send interrupt...\n"); - - timeout = 5*HZ; - ad->waiting_to_fw_download_done = false; - wait_event_timeout(ad->ioctl_fw_dnld_wait_queue, - ad->waiting_to_fw_download_done, timeout); - ad->fw_download_process_pid = INVALID_PID; - ad->fw_download_done = TRUE; - atomic_set(&ad->CurrNumFreeTxDesc, 0); - ad->CurrNumRecvDescs = 0; - ad->PrevNumRecvDescs = 0; - atomic_set(&ad->cntrlpktCnt, 0); - ad->LinkUpStatus = 0; - ad->LinkStatus = 0; - - if (ad->LEDInfo.led_thread_running & - BCM_LED_THREAD_RUNNING_ACTIVELY) { - ad->DriverState = FW_DOWNLOAD_DONE; - wake_up(&ad->LEDInfo.notify_led_event); - } - - if (!timeout) - status = -ENODEV; - - up(&ad->fw_download_sema); - up(&ad->NVMRdmWrmLock); - return status; -} - -static int bcm_char_ioctl_chip_reset(struct bcm_mini_adapter *ad) -{ - INT status; - INT nvm_access; - - nvm_access = down_trylock(&ad->NVMRdmWrmLock); - if (nvm_access) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - " IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n"); - return -EACCES; - } - - down(&ad->RxAppControlQueuelock); - status = reset_card_proc(ad); - flushAllAppQ(); - up(&ad->RxAppControlQueuelock); - up(&ad->NVMRdmWrmLock); - ResetCounters(ad); - return status; -} - -static int bcm_char_ioctl_qos_threshold(ULONG arg, - struct bcm_mini_adapter *ad) -{ - USHORT i; - - for (i = 0; i < NO_OF_QUEUES; i++) { - if (get_user(ad->PackInfo[i].uiThreshold, - (unsigned long __user *)arg)) { - return -EFAULT; - } - } - return 0; -} - -static int bcm_char_ioctl_switch_transfer_mode(void __user *argp, - struct bcm_mini_adapter *ad) -{ - UINT data = 0; - - if (copy_from_user(&data, argp, sizeof(UINT))) - return -EFAULT; - - if (data) { - /* Allow All Packets */ - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_BCM_SWITCH_TRANSFER_MODE: ETH_PACKET_TUNNELING_MODE\n"); - ad->TransferMode = ETH_PACKET_TUNNELING_MODE; - } else { - /* Allow IP only Packets */ - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_BCM_SWITCH_TRANSFER_MODE: IP_PACKET_ONLY_MODE\n"); - ad->TransferMode = IP_PACKET_ONLY_MODE; - } - return STATUS_SUCCESS; -} - -static int bcm_char_ioctl_get_driver_version(void __user *argp) -{ - struct bcm_ioctl_buffer io_buff; - ulong len; - - /* Copy Ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - len = min_t(ulong, io_buff.OutputLength, strlen(DRV_VERSION) + 1); - - if (copy_to_user(io_buff.OutputBuffer, DRV_VERSION, len)) - return -EFAULT; - - return STATUS_SUCCESS; -} - -static int bcm_char_ioctl_get_current_status(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_link_state link_state; - struct bcm_ioctl_buffer io_buff; - - /* Copy Ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "copy_from_user failed..\n"); - return -EFAULT; - } - - if (io_buff.OutputLength != sizeof(link_state)) - return -EINVAL; - - memset(&link_state, 0, sizeof(link_state)); - link_state.bIdleMode = ad->IdleMode; - link_state.bShutdownMode = ad->bShutStatus; - link_state.ucLinkStatus = ad->LinkStatus; - - if (copy_to_user(io_buff.OutputBuffer, &link_state, min_t(size_t, - sizeof(link_state), io_buff.OutputLength))) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Copy_to_user Failed..\n"); - return -EFAULT; - } - return STATUS_SUCCESS; -} - - -static int bcm_char_ioctl_set_mac_tracing(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_ioctl_buffer io_buff; - UINT tracing_flag; - - /* copy ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (copy_from_user(&tracing_flag, io_buff.InputBuffer, sizeof(UINT))) - return -EFAULT; - - if (tracing_flag) - ad->pTarangs->MacTracingEnabled = TRUE; - else - ad->pTarangs->MacTracingEnabled = false; - - return STATUS_SUCCESS; -} - -static int bcm_char_ioctl_get_dsx_indication(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_ioctl_buffer io_buff; - ULONG sf_id = 0; - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.OutputLength < sizeof(struct bcm_add_indication_alt)) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Mismatch req: %lx needed is =0x%zx!!!", - io_buff.OutputLength, - sizeof(struct bcm_add_indication_alt)); - return -EINVAL; - } - - if (copy_from_user(&sf_id, io_buff.InputBuffer, sizeof(sf_id))) - return -EFAULT; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Get DSX Data SF ID is =%lx\n", sf_id); - get_dsx_sf_data_to_application(ad, sf_id, io_buff.OutputBuffer); - return STATUS_SUCCESS; -} - -static int bcm_char_ioctl_get_host_mibs(void __user *argp, - struct bcm_mini_adapter *ad, - struct bcm_tarang_data *tarang) -{ - struct bcm_ioctl_buffer io_buff; - INT status = STATUS_FAILURE; - PVOID temp_buff; - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.OutputLength != sizeof(struct bcm_host_stats_mibs)) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Length Check failed %lu %zd\n", io_buff.OutputLength, - sizeof(struct bcm_host_stats_mibs)); - return -EINVAL; - } - - /* FIXME: HOST_STATS are too big for kmalloc (122048)! */ - temp_buff = kzalloc(sizeof(struct bcm_host_stats_mibs), GFP_KERNEL); - if (!temp_buff) - return STATUS_FAILURE; - - status = ProcessGetHostMibs(ad, temp_buff); - GetDroppedAppCntrlPktMibs(temp_buff, tarang); - - if (status != STATUS_FAILURE) { - if (copy_to_user(io_buff.OutputBuffer, temp_buff, - sizeof(struct bcm_host_stats_mibs))) { - kfree(temp_buff); - return -EFAULT; - } - } - - kfree(temp_buff); - return status; -} - -static int bcm_char_ioctl_bulk_wrm(void __user *argp, - struct bcm_mini_adapter *ad, UINT cmd) -{ - struct bcm_bulk_wrm_buffer *bulk_buff; - struct bcm_ioctl_buffer io_buff; - UINT tmp = 0; - INT status = STATUS_FAILURE; - PCHAR buff = NULL; - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT (ad, DBG_TYPE_PRINTK, 0, 0, - "Device in Idle/Shutdown Mode, Blocking Wrms\n"); - return -EACCES; - } - - /* Copy Ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength < sizeof(ULONG) * 2) - return -EINVAL; - - buff = memdup_user(io_buff.InputBuffer, - io_buff.InputLength); - if (IS_ERR(buff)) - return PTR_ERR(buff); - - bulk_buff = (struct bcm_bulk_wrm_buffer *)buff; - - if (((ULONG)bulk_buff->Register & 0x0F000000) != 0x0F000000 || - ((ULONG)bulk_buff->Register & 0x3)) { - BCM_DEBUG_PRINT (ad, DBG_TYPE_PRINTK, 0, 0, - "WRM Done On invalid Address : %x Access Denied.\n", - (int)bulk_buff->Register); - kfree(buff); - return -EINVAL; - } - - tmp = bulk_buff->Register & EEPROM_REJECT_MASK; - if (!((ad->pstargetparams->m_u32Customize)&VSG_MODE) && - ((tmp == EEPROM_REJECT_REG_1) || - (tmp == EEPROM_REJECT_REG_2) || - (tmp == EEPROM_REJECT_REG_3) || - (tmp == EEPROM_REJECT_REG_4)) && - (cmd == IOCTL_BCM_REGISTER_WRITE)) { - - kfree(buff); - BCM_DEBUG_PRINT (ad, DBG_TYPE_PRINTK, 0, 0, - "EEPROM Access Denied, not in VSG Mode\n"); - return -EFAULT; - } - - if (bulk_buff->SwapEndian == false) - status = wrmWithLock(ad, (UINT)bulk_buff->Register, - (PCHAR)bulk_buff->Values, - io_buff.InputLength - 2*sizeof(ULONG)); - else - status = wrmaltWithLock(ad, (UINT)bulk_buff->Register, - (PUINT)bulk_buff->Values, - io_buff.InputLength - 2*sizeof(ULONG)); - - if (status != STATUS_SUCCESS) - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, "WRM Failed\n"); - - kfree(buff); - return status; -} - -static int bcm_char_ioctl_get_nvm_size(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_ioctl_buffer io_buff; - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (ad->eNVMType == NVM_EEPROM || ad->eNVMType == NVM_FLASH) { - if (copy_to_user(io_buff.OutputBuffer, &ad->uiNVMDSDSize, - sizeof(UINT))) - return -EFAULT; - } - - return STATUS_SUCCESS; -} - -static int bcm_char_ioctl_cal_init(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_ioctl_buffer io_buff; - UINT sector_size = 0; - INT status = STATUS_FAILURE; - - if (ad->eNVMType == NVM_FLASH) { - if (copy_from_user(&io_buff, argp, - sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (copy_from_user(§or_size, io_buff.InputBuffer, - sizeof(UINT))) - return -EFAULT; - - if ((sector_size < MIN_SECTOR_SIZE) || - (sector_size > MAX_SECTOR_SIZE)) { - if (copy_to_user(io_buff.OutputBuffer, - &ad->uiSectorSize, sizeof(UINT))) - return -EFAULT; - } else { - if (IsFlash2x(ad)) { - if (copy_to_user(io_buff.OutputBuffer, - &ad->uiSectorSize, sizeof(UINT))) - return -EFAULT; - } else { - if ((TRUE == ad->bShutStatus) || - (TRUE == ad->IdleMode)) { - BCM_DEBUG_PRINT(ad, - DBG_TYPE_PRINTK, 0, 0, - "Device is in Idle/Shutdown Mode\n"); - return -EACCES; - } - - ad->uiSectorSize = sector_size; - BcmUpdateSectorSize(ad, - ad->uiSectorSize); - } - } - status = STATUS_SUCCESS; - } else { - status = STATUS_FAILURE; - } - return status; -} - -static int bcm_char_ioctl_set_debug(void __user *argp, - struct bcm_mini_adapter *ad) -{ -#ifdef DEBUG - struct bcm_ioctl_buffer io_buff; - struct bcm_user_debug_state user_debug_state; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "In SET_DEBUG ioctl\n"); - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (copy_from_user(&user_debug_state, io_buff.InputBuffer, - sizeof(struct bcm_user_debug_state))) - return -EFAULT; - - BCM_DEBUG_PRINT (ad, DBG_TYPE_PRINTK, 0, 0, - "IOCTL_BCM_SET_DEBUG: OnOff=%d Type = 0x%x ", - user_debug_state.OnOff, user_debug_state.Type); - /* user_debug_state.Subtype <<= 1; */ - user_debug_state.Subtype = 1 << user_debug_state.Subtype; - BCM_DEBUG_PRINT (ad, DBG_TYPE_PRINTK, 0, 0, - "actual Subtype=0x%x\n", user_debug_state.Subtype); - - /* Update new 'DebugState' in the ad */ - ad->stDebugState.type |= user_debug_state.Type; - /* Subtype: A bitmap of 32 bits for Subtype per Type. - * Valid indexes in 'subtype' array: 1,2,4,8 - * corresponding to valid Type values. Hence we can use the 'Type' field - * as the index value, ignoring the array entries 0,3,5,6,7 ! - */ - if (user_debug_state.OnOff) - ad->stDebugState.subtype[user_debug_state.Type] |= - user_debug_state.Subtype; - else - ad->stDebugState.subtype[user_debug_state.Type] &= - ~user_debug_state.Subtype; - - BCM_SHOW_DEBUG_BITMAP(ad); -#endif - return STATUS_SUCCESS; -} - -static int bcm_char_ioctl_nvm_rw(void __user *argp, - struct bcm_mini_adapter *ad, UINT cmd) -{ - struct bcm_nvm_readwrite nvm_rw; - struct timeval tv0, tv1; - struct bcm_ioctl_buffer io_buff; - PUCHAR read_data = NULL; - INT status = STATUS_FAILURE; - - memset(&tv0, 0, sizeof(struct timeval)); - memset(&tv1, 0, sizeof(struct timeval)); - if ((ad->eNVMType == NVM_FLASH) && - (ad->uiFlashLayoutMajorVersion == 0)) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "The Flash Control Section is Corrupted. Hence Rejection on NVM Read/Write\n"); - return -EFAULT; - } - - if (IsFlash2x(ad)) { - if ((ad->eActiveDSD != DSD0) && - (ad->eActiveDSD != DSD1) && - (ad->eActiveDSD != DSD2)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "No DSD is active..hence NVM Command is blocked"); - return STATUS_FAILURE; - } - } - - /* Copy Ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (copy_from_user(&nvm_rw, - (IOCTL_BCM_NVM_READ == cmd) ? - io_buff.OutputBuffer : io_buff.InputBuffer, - sizeof(struct bcm_nvm_readwrite))) - return -EFAULT; - - /* - * Deny the access if the offset crosses the cal area limit. - */ - if (nvm_rw.uiNumBytes > ad->uiNVMDSDSize) - return STATUS_FAILURE; - - if (nvm_rw.uiOffset > - ad->uiNVMDSDSize - nvm_rw.uiNumBytes) - return STATUS_FAILURE; - - read_data = memdup_user(nvm_rw.pBuffer, - nvm_rw.uiNumBytes); - if (IS_ERR(read_data)) - return PTR_ERR(read_data); - - do_gettimeofday(&tv0); - if (IOCTL_BCM_NVM_READ == cmd) { - int ret = bcm_handle_nvm_read_cmd(ad, read_data, - &nvm_rw); - if (ret != STATUS_SUCCESS) - return ret; - } else { - down(&ad->NVMRdmWrmLock); - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, - DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Device is in Idle/Shutdown Mode\n"); - up(&ad->NVMRdmWrmLock); - kfree(read_data); - return -EACCES; - } - - ad->bHeaderChangeAllowed = TRUE; - if (IsFlash2x(ad)) { - int ret = handle_flash2x_adapter(ad, - read_data, - &nvm_rw); - if (ret != STATUS_SUCCESS) - return ret; - } - - status = BeceemNVMWrite(ad, (PUINT)read_data, - nvm_rw.uiOffset, nvm_rw.uiNumBytes, - nvm_rw.bVerify); - if (IsFlash2x(ad)) - BcmFlash2xWriteSig(ad, ad->eActiveDSD); - - ad->bHeaderChangeAllowed = false; - - up(&ad->NVMRdmWrmLock); - - if (status != STATUS_SUCCESS) { - kfree(read_data); - return status; - } - } - - do_gettimeofday(&tv1); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - " timetaken by Write/read :%ld msec\n", - (tv1.tv_sec - tv0.tv_sec)*1000 + - (tv1.tv_usec - tv0.tv_usec)/1000); - - kfree(read_data); - return STATUS_SUCCESS; -} - -static int bcm_char_ioctl_flash2x_section_read(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_flash2x_readwrite flash_2x_read = {0}; - struct bcm_ioctl_buffer io_buff; - PUCHAR read_buff = NULL; - UINT nob = 0; - UINT buff_size = 0; - UINT read_bytes = 0; - UINT read_offset = 0; - INT status = STATUS_FAILURE; - void __user *OutPutBuff; - - if (IsFlash2x(ad) != TRUE) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Flash Does not have 2.x map"); - return -EINVAL; - } - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_READ Called"); - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - /* Reading FLASH 2.x READ structure */ - if (copy_from_user(&flash_2x_read, io_buff.InputBuffer, - sizeof(struct bcm_flash2x_readwrite))) - return -EFAULT; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "\nflash_2x_read.Section :%x", - flash_2x_read.Section); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "\nflash_2x_read.offset :%x", - flash_2x_read.offset); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "\nflash_2x_read.numOfBytes :%x", - flash_2x_read.numOfBytes); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "\nflash_2x_read.bVerify :%x\n", - flash_2x_read.bVerify); - - /* This was internal to driver for raw read. - * now it has ben exposed to user space app. - */ - if (validateFlash2xReadWrite(ad, &flash_2x_read) == false) - return STATUS_FAILURE; - - nob = flash_2x_read.numOfBytes; - if (nob > ad->uiSectorSize) - buff_size = ad->uiSectorSize; - else - buff_size = nob; - - read_offset = flash_2x_read.offset; - OutPutBuff = io_buff.OutputBuffer; - read_buff = kzalloc(buff_size , GFP_KERNEL); - - if (read_buff == NULL) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Memory allocation failed for Flash 2.x Read Structure"); - return -ENOMEM; - } - down(&ad->NVMRdmWrmLock); - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, - "Device is in Idle/Shutdown Mode\n"); - up(&ad->NVMRdmWrmLock); - kfree(read_buff); - return -EACCES; - } - - while (nob) { - if (nob > ad->uiSectorSize) - read_bytes = ad->uiSectorSize; - else - read_bytes = nob; - - /* Reading the data from Flash 2.x */ - status = BcmFlash2xBulkRead(ad, (PUINT)read_buff, - flash_2x_read.Section, read_offset, read_bytes); - if (status) { - BCM_DEBUG_PRINT(ad, - DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Flash 2x read err with status :%d", - status); - break; - } - - BCM_DEBUG_PRINT_BUFFER(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, read_buff, read_bytes); - - status = copy_to_user(OutPutBuff, read_buff, read_bytes); - if (status) { - BCM_DEBUG_PRINT(ad, - DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Copy to use failed with status :%d", status); - up(&ad->NVMRdmWrmLock); - kfree(read_buff); - return -EFAULT; - } - nob = nob - read_bytes; - if (nob) { - read_offset = read_offset + read_bytes; - OutPutBuff = OutPutBuff + read_bytes; - } - } - - up(&ad->NVMRdmWrmLock); - kfree(read_buff); - return status; -} - -static int bcm_char_ioctl_flash2x_section_write(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_flash2x_readwrite sFlash2xWrite = {0}; - struct bcm_ioctl_buffer io_buff; - PUCHAR write_buff; - void __user *input_addr; - UINT nob = 0; - UINT buff_size = 0; - UINT write_off = 0; - UINT write_bytes = 0; - INT status = STATUS_FAILURE; - - if (IsFlash2x(ad) != TRUE) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Flash Does not have 2.x map"); - return -EINVAL; - } - - /* First make this False so that we can enable the Sector - * Permission Check in BeceemFlashBulkWrite - */ - ad->bAllDSDWriteAllow = false; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_BCM_FLASH2X_SECTION_WRITE Called"); - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - /* Reading FLASH 2.x READ structure */ - if (copy_from_user(&sFlash2xWrite, io_buff.InputBuffer, - sizeof(struct bcm_flash2x_readwrite))) - return -EFAULT; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "\nsFlash2xWrite.Section :%x", sFlash2xWrite.Section); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "\nsFlash2xWrite.offset :%d", sFlash2xWrite.offset); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "\nsFlash2xWrite.numOfBytes :%x", sFlash2xWrite.numOfBytes); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "\nsFlash2xWrite.bVerify :%x\n", sFlash2xWrite.bVerify); - - if ((sFlash2xWrite.Section != VSA0) && (sFlash2xWrite.Section != VSA1) - && (sFlash2xWrite.Section != VSA2)) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Only VSA write is allowed"); - return -EINVAL; - } - - if (validateFlash2xReadWrite(ad, &sFlash2xWrite) == false) - return STATUS_FAILURE; - - input_addr = sFlash2xWrite.pDataBuff; - write_off = sFlash2xWrite.offset; - nob = sFlash2xWrite.numOfBytes; - - if (nob > ad->uiSectorSize) - buff_size = ad->uiSectorSize; - else - buff_size = nob; - - write_buff = kmalloc(buff_size, GFP_KERNEL); - - if (write_buff == NULL) - return -ENOMEM; - - /* extracting the remainder of the given offset. */ - write_bytes = ad->uiSectorSize; - if (write_off % ad->uiSectorSize) { - write_bytes = ad->uiSectorSize - - (write_off % ad->uiSectorSize); - } - - if (nob < write_bytes) - write_bytes = nob; - - down(&ad->NVMRdmWrmLock); - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Device is in Idle/Shutdown Mode\n"); - up(&ad->NVMRdmWrmLock); - kfree(write_buff); - return -EACCES; - } - - BcmFlash2xCorruptSig(ad, sFlash2xWrite.Section); - do { - status = copy_from_user(write_buff, input_addr, write_bytes); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Copy to user failed with status :%d", status); - up(&ad->NVMRdmWrmLock); - kfree(write_buff); - return -EFAULT; - } - BCM_DEBUG_PRINT_BUFFER(ad, DBG_TYPE_OTHERS, - OSAL_DBG, DBG_LVL_ALL, write_buff, write_bytes); - - /* Writing the data from Flash 2.x */ - status = BcmFlash2xBulkWrite(ad, (PUINT)write_buff, - sFlash2xWrite.Section, - write_off, - write_bytes, - sFlash2xWrite.bVerify); - - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Flash 2x read err with status :%d", status); - break; - } - - nob = nob - write_bytes; - if (nob) { - write_off = write_off + write_bytes; - input_addr = input_addr + write_bytes; - if (nob > ad->uiSectorSize) - write_bytes = ad->uiSectorSize; - else - write_bytes = nob; - } - } while (nob > 0); - - BcmFlash2xWriteSig(ad, sFlash2xWrite.Section); - up(&ad->NVMRdmWrmLock); - kfree(write_buff); - return status; -} - -static int bcm_char_ioctl_flash2x_section_bitmap(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_flash2x_bitmap *flash_2x_bit_map; - struct bcm_ioctl_buffer io_buff; - -BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP Called"); - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.OutputLength != sizeof(struct bcm_flash2x_bitmap)) - return -EINVAL; - - flash_2x_bit_map = kzalloc(sizeof(struct bcm_flash2x_bitmap), - GFP_KERNEL); - - if (flash_2x_bit_map == NULL) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Memory is not available"); - return -ENOMEM; - } - - /* Reading the Flash Sectio Bit map */ - down(&ad->NVMRdmWrmLock); - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Device is in Idle/Shutdown Mode\n"); - up(&ad->NVMRdmWrmLock); - kfree(flash_2x_bit_map); - return -EACCES; - } - - BcmGetFlash2xSectionalBitMap(ad, flash_2x_bit_map); - up(&ad->NVMRdmWrmLock); - if (copy_to_user(io_buff.OutputBuffer, flash_2x_bit_map, - sizeof(struct bcm_flash2x_bitmap))) { - kfree(flash_2x_bit_map); - return -EFAULT; - } - - kfree(flash_2x_bit_map); - return STATUS_FAILURE; -} - -static int bcm_char_ioctl_set_active_section(void __user *argp, - struct bcm_mini_adapter *ad) -{ - enum bcm_flash2x_section_val flash_2x_section_val = 0; - INT status = STATUS_FAILURE; - struct bcm_ioctl_buffer io_buff; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_BCM_SET_ACTIVE_SECTION Called"); - - if (IsFlash2x(ad) != TRUE) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Flash Does not have 2.x map"); - return -EINVAL; - } - - status = copy_from_user(&io_buff, argp, - sizeof(struct bcm_ioctl_buffer)); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Copy of IOCTL BUFFER failed"); - return -EFAULT; - } - - status = copy_from_user(&flash_2x_section_val, - io_buff.InputBuffer, sizeof(INT)); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Copy of flash section val failed"); - return -EFAULT; - } - - down(&ad->NVMRdmWrmLock); - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Device is in Idle/Shutdown Mode\n"); - up(&ad->NVMRdmWrmLock); - return -EACCES; - } - - status = BcmSetActiveSection(ad, flash_2x_section_val); - if (status) - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Failed to make it's priority Highest. status %d", - status); - - up(&ad->NVMRdmWrmLock); - - return status; -} - -static int bcm_char_ioctl_copy_section(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_flash2x_copy_section copy_sect_strut = {0}; - struct bcm_ioctl_buffer io_buff; - INT status = STATUS_SUCCESS; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_BCM_COPY_SECTION Called"); - - ad->bAllDSDWriteAllow = false; - if (IsFlash2x(ad) != TRUE) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Flash Does not have 2.x map"); - return -EINVAL; - } - - status = copy_from_user(&io_buff, argp, - sizeof(struct bcm_ioctl_buffer)); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Copy of IOCTL BUFFER failed status :%d", - status); - return -EFAULT; - } - - status = copy_from_user(©_sect_strut, io_buff.InputBuffer, - sizeof(struct bcm_flash2x_copy_section)); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Copy of Copy_Section_Struct failed with status :%d", - status); - return -EFAULT; - } - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Source SEction :%x", copy_sect_strut.SrcSection); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Destination SEction :%x", copy_sect_strut.DstSection); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "offset :%x", copy_sect_strut.offset); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "nob :%x", copy_sect_strut.numOfBytes); - - if (IsSectionExistInFlash(ad, copy_sect_strut.SrcSection) == false) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Source Section<%x> does not exist in Flash ", - copy_sect_strut.SrcSection); - return -EINVAL; - } - - if (IsSectionExistInFlash(ad, copy_sect_strut.DstSection) == false) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Destinatio Section<%x> does not exist in Flash ", - copy_sect_strut.DstSection); - return -EINVAL; - } - - if (copy_sect_strut.SrcSection == copy_sect_strut.DstSection) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Source and Destination section should be different"); - return -EINVAL; - } - - down(&ad->NVMRdmWrmLock); - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Device is in Idle/Shutdown Mode\n"); - up(&ad->NVMRdmWrmLock); - return -EACCES; - } - - if (copy_sect_strut.SrcSection == ISO_IMAGE1 || - copy_sect_strut.SrcSection == ISO_IMAGE2) { - if (IsNonCDLessDevice(ad)) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Device is Non-CDLess hence won't have ISO !!"); - status = -EINVAL; - } else if (copy_sect_strut.numOfBytes == 0) { - status = BcmCopyISO(ad, copy_sect_strut); - } else { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Partial Copy of ISO section is not Allowed.."); - status = STATUS_FAILURE; - } - up(&ad->NVMRdmWrmLock); - return status; - } - - status = BcmCopySection(ad, copy_sect_strut.SrcSection, - copy_sect_strut.DstSection, - copy_sect_strut.offset, - copy_sect_strut.numOfBytes); - up(&ad->NVMRdmWrmLock); - return status; -} - -static int bcm_char_ioctl_get_flash_cs_info(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_ioctl_buffer io_buff; - INT status = STATUS_SUCCESS; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - " IOCTL_BCM_GET_FLASH_CS_INFO Called"); - - status = copy_from_user(&io_buff, argp, - sizeof(struct bcm_ioctl_buffer)); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Copy of IOCTL BUFFER failed"); - return -EFAULT; - } - - if (ad->eNVMType != NVM_FLASH) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Connected device does not have flash"); - return -EINVAL; - } - - if (IsFlash2x(ad) == TRUE) { - if (io_buff.OutputLength < sizeof(struct bcm_flash2x_cs_info)) - return -EINVAL; - - if (copy_to_user(io_buff.OutputBuffer, - ad->psFlash2xCSInfo, - sizeof(struct bcm_flash2x_cs_info))) - return -EFAULT; - } else { - if (io_buff.OutputLength < sizeof(struct bcm_flash_cs_info)) - return -EINVAL; - - if (copy_to_user(io_buff.OutputBuffer, ad->psFlashCSInfo, - sizeof(struct bcm_flash_cs_info))) - return -EFAULT; - } - return status; -} - -static int bcm_char_ioctl_select_dsd(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_ioctl_buffer io_buff; - INT status = STATUS_FAILURE; - UINT sect_offset = 0; - enum bcm_flash2x_section_val flash_2x_section_val; - - flash_2x_section_val = NO_SECTION_VAL; - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_BCM_SELECT_DSD Called"); - - if (IsFlash2x(ad) != TRUE) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Flash Does not have 2.x map"); - return -EINVAL; - } - - status = copy_from_user(&io_buff, argp, - sizeof(struct bcm_ioctl_buffer)); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Copy of IOCTL BUFFER failed"); - return -EFAULT; - } - status = copy_from_user(&flash_2x_section_val, io_buff.InputBuffer, - sizeof(INT)); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Copy of flash section val failed"); - return -EFAULT; - } - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Read Section :%d", flash_2x_section_val); - if ((flash_2x_section_val != DSD0) && - (flash_2x_section_val != DSD1) && - (flash_2x_section_val != DSD2)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Passed section<%x> is not DSD section", - flash_2x_section_val); - return STATUS_FAILURE; - } - - sect_offset = BcmGetSectionValStartOffset(ad, flash_2x_section_val); - if (sect_offset == INVALID_OFFSET) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Provided Section val <%d> does not exist in Flash 2.x", - flash_2x_section_val); - return -EINVAL; - } - - ad->bAllDSDWriteAllow = TRUE; - ad->ulFlashCalStart = sect_offset; - ad->eActiveDSD = flash_2x_section_val; - - return STATUS_SUCCESS; -} - -static int bcm_char_ioctl_nvm_raw_read(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_nvm_readwrite nvm_read; - struct bcm_ioctl_buffer io_buff; - unsigned int nob; - INT buff_size; - INT read_offset = 0; - UINT read_bytes = 0; - PUCHAR read_buff; - void __user *OutPutBuff; - INT status = STATUS_FAILURE; - - if (ad->eNVMType != NVM_FLASH) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "NVM TYPE is not Flash"); - return -EINVAL; - } - - /* Copy Ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "copy_from_user 1 failed\n"); - return -EFAULT; - } - - if (copy_from_user(&nvm_read, io_buff.OutputBuffer, - sizeof(struct bcm_nvm_readwrite))) - return -EFAULT; - - nob = nvm_read.uiNumBytes; - /* In Raw-Read max Buff size : 64MB */ - - if (nob > DEFAULT_BUFF_SIZE) - buff_size = DEFAULT_BUFF_SIZE; - else - buff_size = nob; - - read_offset = nvm_read.uiOffset; - OutPutBuff = nvm_read.pBuffer; - - read_buff = kzalloc(buff_size , GFP_KERNEL); - if (read_buff == NULL) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Memory allocation failed for Flash 2.x Read Structure"); - return -ENOMEM; - } - down(&ad->NVMRdmWrmLock); - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Device is in Idle/Shutdown Mode\n"); - kfree(read_buff); - up(&ad->NVMRdmWrmLock); - return -EACCES; - } - - ad->bFlashRawRead = TRUE; - - while (nob) { - if (nob > DEFAULT_BUFF_SIZE) - read_bytes = DEFAULT_BUFF_SIZE; - else - read_bytes = nob; - - /* Reading the data from Flash 2.x */ - status = BeceemNVMRead(ad, (PUINT)read_buff, - read_offset, read_bytes); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Flash 2x read err with status :%d", - status); - break; - } - - BCM_DEBUG_PRINT_BUFFER(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, read_buff, read_bytes); - - status = copy_to_user(OutPutBuff, read_buff, read_bytes); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Copy to use failed with status :%d", - status); - up(&ad->NVMRdmWrmLock); - kfree(read_buff); - return -EFAULT; - } - nob = nob - read_bytes; - if (nob) { - read_offset = read_offset + read_bytes; - OutPutBuff = OutPutBuff + read_bytes; - } - } - ad->bFlashRawRead = false; - up(&ad->NVMRdmWrmLock); - kfree(read_buff); - return status; -} - -static int bcm_char_ioctl_cntrlmsg_mask(void __user *argp, - struct bcm_mini_adapter *ad, - struct bcm_tarang_data *tarang) -{ - struct bcm_ioctl_buffer io_buff; - INT status = STATUS_FAILURE; - ULONG rx_cntrl_msg_bit_mask = 0; - - /* Copy Ioctl Buffer structure */ - status = copy_from_user(&io_buff, argp, - sizeof(struct bcm_ioctl_buffer)); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "copy of Ioctl buffer is failed from user space"); - return -EFAULT; - } - - if (io_buff.InputLength != sizeof(unsigned long)) - return -EINVAL; - - status = copy_from_user(&rx_cntrl_msg_bit_mask, io_buff.InputBuffer, - io_buff.InputLength); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "copy of control bit mask failed from user space"); - return -EFAULT; - } - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "\n Got user defined cntrl msg bit mask :%lx", - rx_cntrl_msg_bit_mask); - tarang->RxCntrlMsgBitMask = rx_cntrl_msg_bit_mask; - - return status; -} - -static int bcm_char_ioctl_get_device_driver_info(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_driver_info dev_info; - struct bcm_ioctl_buffer io_buff; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n"); - - memset(&dev_info, 0, sizeof(dev_info)); - dev_info.MaxRDMBufferSize = BUFFER_4K; - dev_info.u32DSDStartOffset = EEPROM_CALPARAM_START; - dev_info.u32RxAlignmentCorrection = 0; - dev_info.u32NVMType = ad->eNVMType; - dev_info.u32InterfaceType = BCM_USB; - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.OutputLength < sizeof(dev_info)) - return -EINVAL; - - if (copy_to_user(io_buff.OutputBuffer, &dev_info, sizeof(dev_info))) - return -EFAULT; - - return STATUS_SUCCESS; -} - -static int bcm_char_ioctl_time_since_net_entry(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_time_elapsed time_elapsed_since_net_entry = {0}; - struct bcm_ioctl_buffer io_buff; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_BCM_TIME_SINCE_NET_ENTRY called"); - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.OutputLength < sizeof(struct bcm_time_elapsed)) - return -EINVAL; - - time_elapsed_since_net_entry.ul64TimeElapsedSinceNetEntry = - get_seconds() - ad->liTimeSinceLastNetEntry; - - if (copy_to_user(io_buff.OutputBuffer, &time_elapsed_since_net_entry, - sizeof(struct bcm_time_elapsed))) - return -EFAULT; - - return STATUS_SUCCESS; -} - - -static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) -{ - struct bcm_tarang_data *tarang = filp->private_data; - void __user *argp = (void __user *)arg; - struct bcm_mini_adapter *ad = tarang->Adapter; - INT status = STATUS_FAILURE; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX", - cmd, arg); - - if (_IOC_TYPE(cmd) != BCM_IOCTL) - return -EFAULT; - if (_IOC_DIR(cmd) & _IOC_READ) - status = !access_ok(VERIFY_WRITE, argp, _IOC_SIZE(cmd)); - else if (_IOC_DIR(cmd) & _IOC_WRITE) - status = !access_ok(VERIFY_READ, argp, _IOC_SIZE(cmd)); - else if (_IOC_NONE == (_IOC_DIR(cmd) & _IOC_NONE)) - status = STATUS_SUCCESS; - - if (status) - return -EFAULT; - - if (ad->device_removed) - return -EFAULT; - - if (false == ad->fw_download_done) { - switch (cmd) { - case IOCTL_MAC_ADDR_REQ: - case IOCTL_LINK_REQ: - case IOCTL_CM_REQUEST: - case IOCTL_SS_INFO_REQ: - case IOCTL_SEND_CONTROL_MESSAGE: - case IOCTL_IDLE_REQ: - case IOCTL_BCM_GPIO_SET_REQUEST: - case IOCTL_BCM_GPIO_STATUS_REQUEST: - return -EACCES; - default: - break; - } - } - - status = vendorextnIoctl(ad, cmd, arg); - if (status != CONTINUE_COMMON_PATH) - return status; - - switch (cmd) { - /* Rdms for Swin Idle... */ - case IOCTL_BCM_REGISTER_READ_PRIVATE: - status = bcm_char_ioctl_reg_read_private(argp, ad); - return status; - - case IOCTL_BCM_REGISTER_WRITE_PRIVATE: - status = bcm_char_ioctl_reg_write_private(argp, ad); - return status; - - case IOCTL_BCM_REGISTER_READ: - case IOCTL_BCM_EEPROM_REGISTER_READ: - status = bcm_char_ioctl_eeprom_reg_read(argp, ad); - return status; - - case IOCTL_BCM_REGISTER_WRITE: - case IOCTL_BCM_EEPROM_REGISTER_WRITE: - status = bcm_char_ioctl_eeprom_reg_write(argp, ad, cmd); - return status; - - case IOCTL_BCM_GPIO_SET_REQUEST: - status = bcm_char_ioctl_gpio_set_request(argp, ad); - return status; - - case BCM_LED_THREAD_STATE_CHANGE_REQ: - status = bcm_char_ioctl_led_thread_state_change_req(argp, - ad); - return status; - - case IOCTL_BCM_GPIO_STATUS_REQUEST: - status = bcm_char_ioctl_gpio_status_request(argp, ad); - return status; - - case IOCTL_BCM_GPIO_MULTI_REQUEST: - status = bcm_char_ioctl_gpio_multi_request(argp, ad); - return status; - - case IOCTL_BCM_GPIO_MODE_REQUEST: - status = bcm_char_ioctl_gpio_mode_request(argp, ad); - return status; - - case IOCTL_MAC_ADDR_REQ: - case IOCTL_LINK_REQ: - case IOCTL_CM_REQUEST: - case IOCTL_SS_INFO_REQ: - case IOCTL_SEND_CONTROL_MESSAGE: - case IOCTL_IDLE_REQ: - status = bcm_char_ioctl_misc_request(argp, ad); - return status; - - case IOCTL_BCM_BUFFER_DOWNLOAD_START: - status = bcm_char_ioctl_buffer_download_start(ad); - return status; - - case IOCTL_BCM_BUFFER_DOWNLOAD: - status = bcm_char_ioctl_buffer_download(argp, ad); - return status; - - case IOCTL_BCM_BUFFER_DOWNLOAD_STOP: - status = bcm_char_ioctl_buffer_download_stop(argp, ad); - return status; - - - case IOCTL_BE_BUCKET_SIZE: - status = 0; - if (get_user(ad->BEBucketSize, - (unsigned long __user *)arg)) - status = -EFAULT; - break; - - case IOCTL_RTPS_BUCKET_SIZE: - status = 0; - if (get_user(ad->rtPSBucketSize, - (unsigned long __user *)arg)) - status = -EFAULT; - break; - - case IOCTL_CHIP_RESET: - status = bcm_char_ioctl_chip_reset(ad); - return status; - - case IOCTL_QOS_THRESHOLD: - status = bcm_char_ioctl_qos_threshold(arg, ad); - return status; - - case IOCTL_DUMP_PACKET_INFO: - DumpPackInfo(ad); - DumpPhsRules(&ad->stBCMPhsContext); - status = STATUS_SUCCESS; - break; - - case IOCTL_GET_PACK_INFO: - if (copy_to_user(argp, &ad->PackInfo, - sizeof(struct bcm_packet_info)*NO_OF_QUEUES)) - return -EFAULT; - status = STATUS_SUCCESS; - break; - - case IOCTL_BCM_SWITCH_TRANSFER_MODE: - status = bcm_char_ioctl_switch_transfer_mode(argp, ad); - return status; - - case IOCTL_BCM_GET_DRIVER_VERSION: - status = bcm_char_ioctl_get_driver_version(argp); - return status; - - case IOCTL_BCM_GET_CURRENT_STATUS: - status = bcm_char_ioctl_get_current_status(argp, ad); - return status; - - case IOCTL_BCM_SET_MAC_TRACING: - status = bcm_char_ioctl_set_mac_tracing(argp, ad); - return status; - - case IOCTL_BCM_GET_DSX_INDICATION: - status = bcm_char_ioctl_get_dsx_indication(argp, ad); - return status; - - case IOCTL_BCM_GET_HOST_MIBS: - status = bcm_char_ioctl_get_host_mibs(argp, ad, tarang); - return status; - - case IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE: - if ((false == ad->bTriedToWakeUpFromlowPowerMode) && - (TRUE == ad->IdleMode)) { - ad->usIdleModePattern = ABORT_IDLE_MODE; - ad->bWakeUpDevice = TRUE; - wake_up(&ad->process_rx_cntrlpkt); - } - - status = STATUS_SUCCESS; - break; - - case IOCTL_BCM_BULK_WRM: - status = bcm_char_ioctl_bulk_wrm(argp, ad, cmd); - return status; - - case IOCTL_BCM_GET_NVM_SIZE: - status = bcm_char_ioctl_get_nvm_size(argp, ad); - return status; - - case IOCTL_BCM_CAL_INIT: - status = bcm_char_ioctl_cal_init(argp, ad); - return status; - - case IOCTL_BCM_SET_DEBUG: - status = bcm_char_ioctl_set_debug(argp, ad); - return status; - - case IOCTL_BCM_NVM_READ: - case IOCTL_BCM_NVM_WRITE: - status = bcm_char_ioctl_nvm_rw(argp, ad, cmd); - return status; - - case IOCTL_BCM_FLASH2X_SECTION_READ: - status = bcm_char_ioctl_flash2x_section_read(argp, ad); - return status; - - case IOCTL_BCM_FLASH2X_SECTION_WRITE: - status = bcm_char_ioctl_flash2x_section_write(argp, ad); - return status; - - case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP: - status = bcm_char_ioctl_flash2x_section_bitmap(argp, ad); - return status; - - case IOCTL_BCM_SET_ACTIVE_SECTION: - status = bcm_char_ioctl_set_active_section(argp, ad); - return status; - - case IOCTL_BCM_IDENTIFY_ACTIVE_SECTION: - /* Right Now we are taking care of only DSD */ - ad->bAllDSDWriteAllow = false; - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_BCM_IDENTIFY_ACTIVE_SECTION called"); - status = STATUS_SUCCESS; - break; - - case IOCTL_BCM_COPY_SECTION: - status = bcm_char_ioctl_copy_section(argp, ad); - return status; - - case IOCTL_BCM_GET_FLASH_CS_INFO: - status = bcm_char_ioctl_get_flash_cs_info(argp, ad); - return status; - - case IOCTL_BCM_SELECT_DSD: - status = bcm_char_ioctl_select_dsd(argp, ad); - return status; - - case IOCTL_BCM_NVM_RAW_READ: - status = bcm_char_ioctl_nvm_raw_read(argp, ad); - return status; - - case IOCTL_BCM_CNTRLMSG_MASK: - status = bcm_char_ioctl_cntrlmsg_mask(argp, ad, tarang); - return status; - - case IOCTL_BCM_GET_DEVICE_DRIVER_INFO: - status = bcm_char_ioctl_get_device_driver_info(argp, ad); - return status; - - case IOCTL_BCM_TIME_SINCE_NET_ENTRY: - status = bcm_char_ioctl_time_since_net_entry(argp, ad); - return status; - - case IOCTL_CLOSE_NOTIFICATION: - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_CLOSE_NOTIFICATION"); - break; - - default: - pr_info(DRV_NAME ": unknown ioctl cmd=%#x\n", cmd); - status = STATUS_FAILURE; - break; - } - return status; -} - - -static const struct file_operations bcm_fops = { - .owner = THIS_MODULE, - .open = bcm_char_open, - .release = bcm_char_release, - .read = bcm_char_read, - .unlocked_ioctl = bcm_char_ioctl, - .llseek = no_llseek, -}; - -int register_control_device_interface(struct bcm_mini_adapter *ad) -{ - - if (ad->major > 0) - return ad->major; - - ad->major = register_chrdev(0, DEV_NAME, &bcm_fops); - if (ad->major < 0) { - pr_err(DRV_NAME ": could not created character device\n"); - return ad->major; - } - - ad->pstCreatedClassDevice = device_create(bcm_class, NULL, - MKDEV(ad->major, 0), - ad, DEV_NAME); - - if (IS_ERR(ad->pstCreatedClassDevice)) { - pr_err(DRV_NAME ": class device create failed\n"); - unregister_chrdev(ad->major, DEV_NAME); - return PTR_ERR(ad->pstCreatedClassDevice); - } - - return 0; -} - -void unregister_control_device_interface(struct bcm_mini_adapter *ad) -{ - if (ad->major > 0) { - device_destroy(bcm_class, MKDEV(ad->major, 0)); - unregister_chrdev(ad->major, DEV_NAME); - } -} - diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c deleted file mode 100644 index e57767684cee..000000000000 --- a/drivers/staging/bcm/Bcmnet.c +++ /dev/null @@ -1,240 +0,0 @@ -#include "headers.h" - -struct net_device *gblpnetdev; - -static INT bcm_open(struct net_device *dev) -{ - struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev); - - if (ad->fw_download_done == false) { - pr_notice(PFX "%s: link up failed (download in progress)\n", - dev->name); - return -EBUSY; - } - - if (netif_msg_ifup(ad)) - pr_info(PFX "%s: enabling interface\n", dev->name); - - if (ad->LinkUpStatus) { - if (netif_msg_link(ad)) - pr_info(PFX "%s: link up\n", dev->name); - - netif_carrier_on(ad->dev); - netif_start_queue(ad->dev); - } - - return 0; -} - -static INT bcm_close(struct net_device *dev) -{ - struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev); - - if (netif_msg_ifdown(ad)) - pr_info(PFX "%s: disabling interface\n", dev->name); - - netif_carrier_off(dev); - netif_stop_queue(dev); - - return 0; -} - -static u16 bcm_select_queue(struct net_device *dev, struct sk_buff *skb, - void *accel_priv, select_queue_fallback_t fallback) -{ - return ClassifyPacket(netdev_priv(dev), skb); -} - -/******************************************************************* -* Function - bcm_transmit() -* -* Description - This is the main transmit function for our virtual -* interface(eth0). It handles the ARP packets. It -* clones this packet and then Queue it to a suitable -* Queue. Then calls the transmit_packet(). -* -* Parameter - skb - Pointer to the socket buffer structure -* dev - Pointer to the virtual net device structure -* -*********************************************************************/ - -static netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev) -{ - struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev); - u16 qindex = skb_get_queue_mapping(skb); - - - if (ad->device_removed || !ad->LinkUpStatus) - goto drop; - - if (ad->TransferMode != IP_PACKET_ONLY_MODE) - goto drop; - - if (INVALID_QUEUE_INDEX == qindex) - goto drop; - - if (ad->PackInfo[qindex].uiCurrentPacketsOnHost >= - SF_MAX_ALLOWED_PACKETS_TO_BACKUP) - return NETDEV_TX_BUSY; - - /* Now Enqueue the packet */ - if (netif_msg_tx_queued(ad)) - pr_info(PFX "%s: enqueueing packet to queue %d\n", - dev->name, qindex); - - spin_lock(&ad->PackInfo[qindex].SFQueueLock); - ad->PackInfo[qindex].uiCurrentBytesOnHost += skb->len; - ad->PackInfo[qindex].uiCurrentPacketsOnHost++; - - *((B_UINT32 *) skb->cb + SKB_CB_LATENCY_OFFSET) = jiffies; - ENQUEUEPACKET(ad->PackInfo[qindex].FirstTxQueue, - ad->PackInfo[qindex].LastTxQueue, skb); - atomic_inc(&ad->TotalPacketCount); - spin_unlock(&ad->PackInfo[qindex].SFQueueLock); - - /* FIXME - this is racy and incorrect, replace with work queue */ - if (!atomic_read(&ad->TxPktAvail)) { - atomic_set(&ad->TxPktAvail, 1); - wake_up(&ad->tx_packet_wait_queue); - } - return NETDEV_TX_OK; - - drop: - dev_kfree_skb(skb); - return NETDEV_TX_OK; -} - - - -/** -@ingroup init_functions -Register other driver entry points with the kernel -*/ -static const struct net_device_ops bcmNetDevOps = { - .ndo_open = bcm_open, - .ndo_stop = bcm_close, - .ndo_start_xmit = bcm_transmit, - .ndo_change_mtu = eth_change_mtu, - .ndo_set_mac_address = eth_mac_addr, - .ndo_validate_addr = eth_validate_addr, - .ndo_select_queue = bcm_select_queue, -}; - -static struct device_type wimax_type = { - .name = "wimax", -}; - -static int bcm_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - cmd->supported = 0; - cmd->advertising = 0; - cmd->speed = SPEED_10000; - cmd->duplex = DUPLEX_FULL; - cmd->port = PORT_TP; - cmd->phy_address = 0; - cmd->transceiver = XCVR_INTERNAL; - cmd->autoneg = AUTONEG_DISABLE; - cmd->maxtxpkt = 0; - cmd->maxrxpkt = 0; - return 0; -} - -static void bcm_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev); - struct bcm_interface_adapter *intf_ad = ad->pvInterfaceAdapter; - struct usb_device *udev = interface_to_usbdev(intf_ad->interface); - - strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); - strlcpy(info->version, DRV_VERSION, sizeof(info->version)); - snprintf(info->fw_version, sizeof(info->fw_version), "%u.%u", - ad->uiFlashLayoutMajorVersion, - ad->uiFlashLayoutMinorVersion); - - usb_make_path(udev, info->bus_info, sizeof(info->bus_info)); -} - -static u32 bcm_get_link(struct net_device *dev) -{ - struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev); - - return ad->LinkUpStatus; -} - -static u32 bcm_get_msglevel(struct net_device *dev) -{ - struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev); - - return ad->msg_enable; -} - -static void bcm_set_msglevel(struct net_device *dev, u32 level) -{ - struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev); - - ad->msg_enable = level; -} - -static const struct ethtool_ops bcm_ethtool_ops = { - .get_settings = bcm_get_settings, - .get_drvinfo = bcm_get_drvinfo, - .get_link = bcm_get_link, - .get_msglevel = bcm_get_msglevel, - .set_msglevel = bcm_set_msglevel, -}; - -int register_networkdev(struct bcm_mini_adapter *ad) -{ - struct net_device *net = ad->dev; - struct bcm_interface_adapter *intf_ad = ad->pvInterfaceAdapter; - struct usb_interface *udev = intf_ad->interface; - struct usb_device *xdev = intf_ad->udev; - - int result; - - net->netdev_ops = &bcmNetDevOps; - net->ethtool_ops = &bcm_ethtool_ops; - net->mtu = MTU_SIZE; /* 1400 Bytes */ - net->tx_queue_len = TX_QLEN; - net->flags |= IFF_NOARP; - - netif_carrier_off(net); - - SET_NETDEV_DEVTYPE(net, &wimax_type); - - /* Read the MAC Address from EEPROM */ - result = ReadMacAddressFromNVM(ad); - if (result != STATUS_SUCCESS) { - dev_err(&udev->dev, - PFX "Error in Reading the mac Address: %d", result); - return -EIO; - } - - result = register_netdev(net); - if (result) - return result; - - gblpnetdev = ad->dev; - - if (netif_msg_probe(ad)) - dev_info(&udev->dev, PFX "%s: register usb-%s-%s %pM\n", - net->name, xdev->bus->bus_name, xdev->devpath, - net->dev_addr); - - return 0; -} - -void unregister_networkdev(struct bcm_mini_adapter *ad) -{ - struct net_device *net = ad->dev; - struct bcm_interface_adapter *intf_ad = ad->pvInterfaceAdapter; - struct usb_interface *udev = intf_ad->interface; - struct usb_device *xdev = intf_ad->udev; - - if (netif_msg_probe(ad)) - dev_info(&udev->dev, PFX "%s: unregister usb-%s%s\n", - net->name, xdev->bus->bus_name, xdev->devpath); - - unregister_netdev(ad->dev); -} diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c deleted file mode 100644 index adca0ce4d05f..000000000000 --- a/drivers/staging/bcm/CmHost.c +++ /dev/null @@ -1,2254 +0,0 @@ -/************************************************************ - * CMHOST.C - * This file contains the routines for handling Connection - * Management. - ************************************************************/ - -#include "headers.h" - -enum E_CLASSIFIER_ACTION { - eInvalidClassifierAction, - eAddClassifier, - eReplaceClassifier, - eDeleteClassifier -}; - -static ULONG GetNextTargetBufferLocation(struct bcm_mini_adapter *Adapter, - B_UINT16 tid); -static void restore_endianess_of_pstClassifierEntry( - struct bcm_classifier_rule *pstClassifierEntry, - enum bcm_ipaddr_context eIpAddrContext); - -static void apply_phs_rule_to_all_classifiers( - register struct bcm_mini_adapter *Adapter, - register UINT uiSearchRuleIndex, - USHORT uVCID, - struct bcm_phs_rule *sPhsRule, - struct bcm_phs_rules *cPhsRule, - struct bcm_add_indication_alt *pstAddIndication); - -/************************************************************ - * Function - SearchSfid - * - * Description - This routinue would search QOS queues having - * specified SFID as input parameter. - * - * Parameters - Adapter: Pointer to the Adapter structure - * uiSfid : Given SFID for matching - * - * Returns - Queue index for this SFID(If matched) - * Else Invalid Queue Index(If Not matched) - ************************************************************/ -int SearchSfid(struct bcm_mini_adapter *Adapter, UINT uiSfid) -{ - int i; - - for (i = (NO_OF_QUEUES-1); i >= 0; i--) - if (Adapter->PackInfo[i].ulSFID == uiSfid) - return i; - - return NO_OF_QUEUES+1; -} - -/*************************************************************** - * Function -SearchFreeSfid - * - * Description - This routinue would search Free available SFID. - * - * Parameter - Adapter: Pointer to the Adapter structure - * - * Returns - Queue index for the free SFID - * Else returns Invalid Index. - ****************************************************************/ -static int SearchFreeSfid(struct bcm_mini_adapter *Adapter) -{ - int i; - - for (i = 0; i < (NO_OF_QUEUES-1); i++) - if (Adapter->PackInfo[i].ulSFID == 0) - return i; - - return NO_OF_QUEUES+1; -} - -/* - * Function: SearchClsid - * Description: This routinue would search Classifier having specified ClassifierID as input parameter - * Input parameters: struct bcm_mini_adapter *Adapter - Adapter Context - * unsigned int uiSfid - The SF in which the classifier is to searched - * B_UINT16 uiClassifierID - The classifier ID to be searched - * Return: int :Classifier table index of matching entry - */ -static int SearchClsid(struct bcm_mini_adapter *Adapter, - ULONG ulSFID, - B_UINT16 uiClassifierID) -{ - int i; - - for (i = 0; i < MAX_CLASSIFIERS; i++) { - if ((Adapter->astClassifierTable[i].bUsed) && - (Adapter->astClassifierTable[i].uiClassifierRuleIndex - == uiClassifierID) && - (Adapter->astClassifierTable[i].ulSFID == ulSFID)) - return i; - } - - return MAX_CLASSIFIERS+1; -} - -/* - * @ingroup ctrl_pkt_functions - * This routinue would search Free available Classifier entry in classifier table. - * @return free Classifier Entry index in classifier table for specified SF - */ -static int SearchFreeClsid(struct bcm_mini_adapter *Adapter /**Adapter Context*/) -{ - int i; - - for (i = 0; i < MAX_CLASSIFIERS; i++) { - if (!Adapter->astClassifierTable[i].bUsed) - return i; - } - - return MAX_CLASSIFIERS+1; -} - -static VOID deleteSFBySfid(struct bcm_mini_adapter *Adapter, - UINT uiSearchRuleIndex) -{ - /* deleting all the packet held in the SF */ - flush_queue(Adapter, uiSearchRuleIndex); - - /* Deleting the all classifiers for this SF */ - DeleteAllClassifiersForSF(Adapter, uiSearchRuleIndex); - - /* Resetting only MIBS related entries in the SF */ - memset((PVOID)&Adapter->PackInfo[uiSearchRuleIndex], 0, - sizeof(struct bcm_mibs_table)); -} - -static inline VOID -CopyIpAddrToClassifier(struct bcm_classifier_rule *pstClassifierEntry, - B_UINT8 u8IpAddressLen, B_UINT8 *pu8IpAddressMaskSrc, - bool bIpVersion6, enum bcm_ipaddr_context eIpAddrContext) -{ - int i = 0; - UINT nSizeOfIPAddressInBytes = IP_LENGTH_OF_ADDRESS; - UCHAR *ptrClassifierIpAddress = NULL; - UCHAR *ptrClassifierIpMask = NULL; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if (bIpVersion6) - nSizeOfIPAddressInBytes = IPV6_ADDRESS_SIZEINBYTES; - - /* Destination Ip Address */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Ip Address Range Length:0x%X ", u8IpAddressLen); - if ((bIpVersion6 ? (IPV6_ADDRESS_SIZEINBYTES * MAX_IP_RANGE_LENGTH * 2) : - (TOTAL_MASKED_ADDRESS_IN_BYTES)) >= u8IpAddressLen) { - - union u_ip_address *st_dest_ip = - &pstClassifierEntry->stDestIpAddress; - - union u_ip_address *st_src_ip = - &pstClassifierEntry->stSrcIpAddress; - - /* - * checking both the mask and address togethor in Classification. - * So length will be : TotalLengthInBytes/nSizeOfIPAddressInBytes * 2 - * (nSizeOfIPAddressInBytes for address and nSizeOfIPAddressInBytes for mask) - */ - if (eIpAddrContext == eDestIpAddress) { - pstClassifierEntry->ucIPDestinationAddressLength = - u8IpAddressLen/(nSizeOfIPAddressInBytes * 2); - if (bIpVersion6) { - ptrClassifierIpAddress = - st_dest_ip->ucIpv6Address; - ptrClassifierIpMask = - st_dest_ip->ucIpv6Mask; - } else { - ptrClassifierIpAddress = - st_dest_ip->ucIpv4Address; - ptrClassifierIpMask = - st_dest_ip->ucIpv4Mask; - } - } else if (eIpAddrContext == eSrcIpAddress) { - pstClassifierEntry->ucIPSourceAddressLength = - u8IpAddressLen/(nSizeOfIPAddressInBytes * 2); - if (bIpVersion6) { - ptrClassifierIpAddress = - st_src_ip->ucIpv6Address; - ptrClassifierIpMask = st_src_ip->ucIpv6Mask; - } else { - ptrClassifierIpAddress = - st_src_ip->ucIpv4Address; - ptrClassifierIpMask = st_src_ip->ucIpv4Mask; - } - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Address Length:0x%X\n", - pstClassifierEntry->ucIPDestinationAddressLength); - while ((u8IpAddressLen >= nSizeOfIPAddressInBytes) - && (i < MAX_IP_RANGE_LENGTH)) { - memcpy(ptrClassifierIpAddress + - (i * nSizeOfIPAddressInBytes), - (pu8IpAddressMaskSrc - + (i * nSizeOfIPAddressInBytes * 2)), - nSizeOfIPAddressInBytes); - - if (!bIpVersion6) { - if (eIpAddrContext == eSrcIpAddress) { - st_src_ip->ulIpv4Addr[i] = - ntohl(st_src_ip->ulIpv4Addr[i]); - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - CONN_MSG, - DBG_LVL_ALL, - "Src Ip Address:0x%luX ", - st_src_ip->ulIpv4Addr[i]); - } else if (eIpAddrContext == eDestIpAddress) { - st_dest_ip->ulIpv4Addr[i] = - ntohl(st_dest_ip->ulIpv4Addr[i]); - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - CONN_MSG, - DBG_LVL_ALL, - "Dest Ip Address:0x%luX ", - st_dest_ip->ulIpv4Addr[i]); - } - } - u8IpAddressLen -= nSizeOfIPAddressInBytes; - if (u8IpAddressLen >= nSizeOfIPAddressInBytes) { - memcpy(ptrClassifierIpMask + - (i * nSizeOfIPAddressInBytes), - (pu8IpAddressMaskSrc - + nSizeOfIPAddressInBytes - + (i * nSizeOfIPAddressInBytes * 2)), - nSizeOfIPAddressInBytes); - - if (!bIpVersion6) { - if (eIpAddrContext == eSrcIpAddress) { - st_src_ip->ulIpv4Mask[i] = - ntohl(st_src_ip->ulIpv4Mask[i]); - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - CONN_MSG, - DBG_LVL_ALL, - "Src Ip Mask Address:0x%luX ", - st_src_ip->ulIpv4Mask[i]); - } else if (eIpAddrContext == eDestIpAddress) { - st_dest_ip->ulIpv4Mask[i] = - ntohl(st_dest_ip->ulIpv4Mask[i]); - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - CONN_MSG, - DBG_LVL_ALL, - "Dest Ip Mask Address:0x%luX ", - st_dest_ip->ulIpv4Mask[i]); - } - } - u8IpAddressLen -= nSizeOfIPAddressInBytes; - } - if (u8IpAddressLen == 0) - pstClassifierEntry->bDestIpValid = TRUE; - - i++; - } - if (bIpVersion6) { - /* Restore EndianNess of Struct */ - restore_endianess_of_pstClassifierEntry( - pstClassifierEntry, - eIpAddrContext - ); - } - } -} - -void ClearTargetDSXBuffer(struct bcm_mini_adapter *Adapter, B_UINT16 TID, bool bFreeAll) -{ - int i; - struct bcm_targetdsx_buffer *curr_buf; - - for (i = 0; i < Adapter->ulTotalTargetBuffersAvailable; i++) { - curr_buf = &Adapter->astTargetDsxBuffer[i]; - - if (curr_buf->valid) - continue; - - if ((bFreeAll) || (curr_buf->tid == TID)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, - "ClearTargetDSXBuffer: found tid %d buffer cleared %lx\n", - TID, curr_buf->ulTargetDsxBuffer); - curr_buf->valid = 1; - curr_buf->tid = 0; - Adapter->ulFreeTargetBufferCnt++; - } - } -} - -/* - * @ingroup ctrl_pkt_functions - * copy classifier rule into the specified SF index - */ -static inline VOID CopyClassifierRuleToSF(struct bcm_mini_adapter *Adapter, - struct bcm_convergence_types *psfCSType, - UINT uiSearchRuleIndex, - UINT nClassifierIndex) -{ - struct bcm_classifier_rule *pstClassifierEntry = NULL; - /* VOID *pvPhsContext = NULL; */ - int i; - /* UCHAR ucProtocolLength=0; */ - /* ULONG ulPhsStatus; */ - - struct bcm_packet_class_rules *pack_class_rule = - &psfCSType->cCPacketClassificationRule; - - if (Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value == 0 || - nClassifierIndex > (MAX_CLASSIFIERS-1)) - return; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Storing Classifier Rule Index : %X", - ntohs(pack_class_rule->u16PacketClassificationRuleIndex)); - - if (nClassifierIndex > MAX_CLASSIFIERS-1) - return; - - pstClassifierEntry = &Adapter->astClassifierTable[nClassifierIndex]; - if (pstClassifierEntry) { - /* Store if Ipv6 */ - pstClassifierEntry->bIpv6Protocol = - (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6) ? TRUE : false; - - /* Destinaiton Port */ - pstClassifierEntry->ucDestPortRangeLength = - pack_class_rule->u8ProtocolDestPortRangeLength / 4; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Destination Port Range Length:0x%X ", - pstClassifierEntry->ucDestPortRangeLength); - - if (pack_class_rule->u8ProtocolDestPortRangeLength <= MAX_PORT_RANGE) { - for (i = 0; i < (pstClassifierEntry->ucDestPortRangeLength); i++) { - pstClassifierEntry->usDestPortRangeLo[i] = - *((PUSHORT)(pack_class_rule->u8ProtocolDestPortRange+i)); - pstClassifierEntry->usDestPortRangeHi[i] = - *((PUSHORT)(pack_class_rule->u8ProtocolDestPortRange+2+i)); - pstClassifierEntry->usDestPortRangeLo[i] = - ntohs(pstClassifierEntry->usDestPortRangeLo[i]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - CONN_MSG, DBG_LVL_ALL, - "Destination Port Range Lo:0x%X ", - pstClassifierEntry->usDestPortRangeLo[i]); - pstClassifierEntry->usDestPortRangeHi[i] = - ntohs(pstClassifierEntry->usDestPortRangeHi[i]); - } - } else { - pstClassifierEntry->ucDestPortRangeLength = 0; - } - - /* Source Port */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Source Port Range Length:0x%X ", - pack_class_rule->u8ProtocolSourcePortRangeLength); - if (pack_class_rule->u8ProtocolSourcePortRangeLength <= MAX_PORT_RANGE) { - pstClassifierEntry->ucSrcPortRangeLength = - pack_class_rule->u8ProtocolSourcePortRangeLength/4; - for (i = 0; i < (pstClassifierEntry->ucSrcPortRangeLength); i++) { - pstClassifierEntry->usSrcPortRangeLo[i] = - *((PUSHORT)(pack_class_rule-> - u8ProtocolSourcePortRange+i)); - pstClassifierEntry->usSrcPortRangeHi[i] = - *((PUSHORT)(pack_class_rule-> - u8ProtocolSourcePortRange+2+i)); - pstClassifierEntry->usSrcPortRangeLo[i] = - ntohs(pstClassifierEntry->usSrcPortRangeLo[i]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - CONN_MSG, DBG_LVL_ALL, - "Source Port Range Lo:0x%X ", - pstClassifierEntry->usSrcPortRangeLo[i]); - pstClassifierEntry->usSrcPortRangeHi[i] = - ntohs(pstClassifierEntry->usSrcPortRangeHi[i]); - } - } - /* Destination Ip Address and Mask */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Ip Destination Parameters : "); - CopyIpAddrToClassifier(pstClassifierEntry, - pack_class_rule->u8IPDestinationAddressLength, - pack_class_rule->u8IPDestinationAddress, - (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6) ? - TRUE : false, eDestIpAddress); - - /* Source Ip Address and Mask */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Ip Source Parameters : "); - - CopyIpAddrToClassifier(pstClassifierEntry, - pack_class_rule->u8IPMaskedSourceAddressLength, - pack_class_rule->u8IPMaskedSourceAddress, - (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6) ? TRUE : false, - eSrcIpAddress); - - /* TOS */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "TOS Length:0x%X ", - pack_class_rule->u8IPTypeOfServiceLength); - if (pack_class_rule->u8IPTypeOfServiceLength == 3) { - pstClassifierEntry->ucIPTypeOfServiceLength = - pack_class_rule->u8IPTypeOfServiceLength; - pstClassifierEntry->ucTosLow = - pack_class_rule->u8IPTypeOfService[0]; - pstClassifierEntry->ucTosHigh = - pack_class_rule->u8IPTypeOfService[1]; - pstClassifierEntry->ucTosMask = - pack_class_rule->u8IPTypeOfService[2]; - pstClassifierEntry->bTOSValid = TRUE; - } - if (pack_class_rule->u8Protocol == 0) { - /* we didn't get protocol field filled in by the BS */ - pstClassifierEntry->ucProtocolLength = 0; - } else { - pstClassifierEntry->ucProtocolLength = 1; /* 1 valid protocol */ - } - - pstClassifierEntry->ucProtocol[0] = pack_class_rule->u8Protocol; - pstClassifierEntry->u8ClassifierRulePriority = - pack_class_rule->u8ClassifierRulePriority; - - /* store the classifier rule ID and set this classifier entry as valid */ - pstClassifierEntry->ucDirection = - Adapter->PackInfo[uiSearchRuleIndex].ucDirection; - pstClassifierEntry->uiClassifierRuleIndex = - ntohs(pack_class_rule->u16PacketClassificationRuleIndex); - pstClassifierEntry->usVCID_Value = - Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value; - pstClassifierEntry->ulSFID = - Adapter->PackInfo[uiSearchRuleIndex].ulSFID; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Search Index %d Dir: %d, Index: %d, Vcid: %d\n", - uiSearchRuleIndex, - pstClassifierEntry->ucDirection, - pstClassifierEntry->uiClassifierRuleIndex, - pstClassifierEntry->usVCID_Value); - - if (pack_class_rule->u8AssociatedPHSI) - pstClassifierEntry->u8AssociatedPHSI = - pack_class_rule->u8AssociatedPHSI; - - /* Copy ETH CS Parameters */ - pstClassifierEntry->ucEthCSSrcMACLen = - (pack_class_rule->u8EthernetSourceMACAddressLength); - memcpy(pstClassifierEntry->au8EThCSSrcMAC, - pack_class_rule->u8EthernetSourceMACAddress, - MAC_ADDRESS_SIZE); - memcpy(pstClassifierEntry->au8EThCSSrcMACMask, - pack_class_rule->u8EthernetSourceMACAddress - + MAC_ADDRESS_SIZE, MAC_ADDRESS_SIZE); - pstClassifierEntry->ucEthCSDestMACLen = - (pack_class_rule->u8EthernetDestMacAddressLength); - memcpy(pstClassifierEntry->au8EThCSDestMAC, - pack_class_rule->u8EthernetDestMacAddress, - MAC_ADDRESS_SIZE); - memcpy(pstClassifierEntry->au8EThCSDestMACMask, - pack_class_rule->u8EthernetDestMacAddress - + MAC_ADDRESS_SIZE, MAC_ADDRESS_SIZE); - pstClassifierEntry->ucEtherTypeLen = - (pack_class_rule->u8EthertypeLength); - memcpy(pstClassifierEntry->au8EthCSEtherType, - pack_class_rule->u8Ethertype, - NUM_ETHERTYPE_BYTES); - memcpy(pstClassifierEntry->usUserPriority, - &pack_class_rule->u16UserPriority, 2); - pstClassifierEntry->usVLANID = - ntohs(pack_class_rule->u16VLANID); - pstClassifierEntry->usValidityBitMap = - ntohs(pack_class_rule->u16ValidityBitMap); - - pstClassifierEntry->bUsed = TRUE; - } -} - -/* - * @ingroup ctrl_pkt_functions - */ -static inline VOID DeleteClassifierRuleFromSF(struct bcm_mini_adapter *Adapter, - UINT uiSearchRuleIndex, UINT nClassifierIndex) -{ - struct bcm_classifier_rule *pstClassifierEntry = NULL; - B_UINT16 u16PacketClassificationRuleIndex; - USHORT usVCID; - /* VOID *pvPhsContext = NULL; */ - /*ULONG ulPhsStatus; */ - - usVCID = Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value; - - if (nClassifierIndex > MAX_CLASSIFIERS-1) - return; - - if (usVCID == 0) - return; - - u16PacketClassificationRuleIndex = - Adapter->astClassifierTable[nClassifierIndex].uiClassifierRuleIndex; - pstClassifierEntry = &Adapter->astClassifierTable[nClassifierIndex]; - if (pstClassifierEntry) { - pstClassifierEntry->bUsed = false; - pstClassifierEntry->uiClassifierRuleIndex = 0; - memset(pstClassifierEntry, 0, - sizeof(struct bcm_classifier_rule)); - - /* Delete the PHS Rule for this classifier */ - PhsDeleteClassifierRule(&Adapter->stBCMPhsContext, usVCID, - u16PacketClassificationRuleIndex); - } -} - -/* - * @ingroup ctrl_pkt_functions - */ -VOID DeleteAllClassifiersForSF(struct bcm_mini_adapter *Adapter, - UINT uiSearchRuleIndex) -{ - struct bcm_classifier_rule *pstClassifierEntry = NULL; - int i; - /* B_UINT16 u16PacketClassificationRuleIndex; */ - USHORT ulVCID; - /* VOID *pvPhsContext = NULL; */ - /* ULONG ulPhsStatus; */ - - ulVCID = Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value; - - if (ulVCID == 0) - return; - - for (i = 0; i < MAX_CLASSIFIERS; i++) { - if (Adapter->astClassifierTable[i].usVCID_Value == ulVCID) { - pstClassifierEntry = &Adapter->astClassifierTable[i]; - - if (pstClassifierEntry->bUsed) - DeleteClassifierRuleFromSF(Adapter, - uiSearchRuleIndex, i); - } - } - - /* Delete All Phs Rules Associated with this SF */ - PhsDeleteSFRules(&Adapter->stBCMPhsContext, ulVCID); -} - -/* - * This routinue copies the Connection Management - * related data into the Adapter structure. - * @ingroup ctrl_pkt_functions - */ -static VOID CopyToAdapter(register struct bcm_mini_adapter *Adapter, /* <Pointer to the Adapter structure */ - register struct bcm_connect_mgr_params *psfLocalSet, /* Pointer to the connection manager parameters structure */ - register UINT uiSearchRuleIndex, /* <Index of Queue, to which this data belongs */ - register UCHAR ucDsxType, - struct bcm_add_indication_alt *pstAddIndication) { - - /* UCHAR ucProtocolLength = 0; */ - ULONG ulSFID; - UINT nClassifierIndex = 0; - enum E_CLASSIFIER_ACTION eClassifierAction = eInvalidClassifierAction; - B_UINT16 u16PacketClassificationRuleIndex = 0; - int i; - struct bcm_convergence_types *psfCSType = NULL; - struct bcm_phs_rule sPhsRule; - struct bcm_packet_info *curr_packinfo = - &Adapter->PackInfo[uiSearchRuleIndex]; - USHORT uVCID = curr_packinfo->usVCID_Value; - UINT UGIValue = 0; - - curr_packinfo->bValid = TRUE; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Search Rule Index = %d\n", uiSearchRuleIndex); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "%s: SFID= %x ", __func__, ntohl(psfLocalSet->u32SFID)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Updating Queue %d", uiSearchRuleIndex); - - ulSFID = ntohl(psfLocalSet->u32SFID); - /* Store IP Version used */ - /* Get The Version Of IP used (IPv6 or IPv4) from CSSpecification field of SF */ - - curr_packinfo->bIPCSSupport = 0; - curr_packinfo->bEthCSSupport = 0; - - /* Enable IP/ETh CS Support As Required */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "CopyToAdapter : u8CSSpecification : %X\n", - psfLocalSet->u8CSSpecification); - switch (psfLocalSet->u8CSSpecification) { - case eCSPacketIPV4: - curr_packinfo->bIPCSSupport = IPV4_CS; - break; - case eCSPacketIPV6: - curr_packinfo->bIPCSSupport = IPV6_CS; - break; - case eCS802_3PacketEthernet: - case eCS802_1QPacketVLAN: - curr_packinfo->bEthCSSupport = ETH_CS_802_3; - break; - case eCSPacketIPV4Over802_1QVLAN: - case eCSPacketIPV4Over802_3Ethernet: - curr_packinfo->bIPCSSupport = IPV4_CS; - curr_packinfo->bEthCSSupport = ETH_CS_802_3; - break; - case eCSPacketIPV6Over802_1QVLAN: - case eCSPacketIPV6Over802_3Ethernet: - curr_packinfo->bIPCSSupport = IPV6_CS; - curr_packinfo->bEthCSSupport = ETH_CS_802_3; - break; - default: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Error in value of CS Classification.. setting default to IP CS\n"); - curr_packinfo->bIPCSSupport = IPV4_CS; - break; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "CopyToAdapter : Queue No : %X ETH CS Support : %X , IP CS Support : %X\n", - uiSearchRuleIndex, - curr_packinfo->bEthCSSupport, - curr_packinfo->bIPCSSupport); - - /* Store IP Version used */ - /* Get The Version Of IP used (IPv6 or IPv4) from CSSpecification field of SF */ - if (curr_packinfo->bIPCSSupport == IPV6_CS) - curr_packinfo->ucIpVersion = IPV6; - else - curr_packinfo->ucIpVersion = IPV4; - - /* To ensure that the ETH CS code doesn't gets executed if the BS doesn't supports ETH CS */ - if (!Adapter->bETHCSEnabled) - curr_packinfo->bEthCSSupport = 0; - - if (psfLocalSet->u8ServiceClassNameLength > 0 && psfLocalSet->u8ServiceClassNameLength < 32) - memcpy(curr_packinfo->ucServiceClassName, - psfLocalSet->u8ServiceClassName, - psfLocalSet->u8ServiceClassNameLength); - - curr_packinfo->u8QueueType = psfLocalSet->u8ServiceFlowSchedulingType; - - if (curr_packinfo->u8QueueType == BE && curr_packinfo->ucDirection) - Adapter->usBestEffortQueueIndex = uiSearchRuleIndex; - - curr_packinfo->ulSFID = ntohl(psfLocalSet->u32SFID); - - curr_packinfo->u8TrafficPriority = psfLocalSet->u8TrafficPriority; - - /* copy all the classifier in the Service Flow param structure */ - for (i = 0; i < psfLocalSet->u8TotalClassifiers; i++) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Classifier index =%d", i); - psfCSType = &psfLocalSet->cConvergenceSLTypes[i]; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Classifier index =%d", i); - - if (psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority) - curr_packinfo->bClassifierPriority = TRUE; - - if (psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority) - curr_packinfo->bClassifierPriority = TRUE; - - if (ucDsxType == DSA_ACK) { - eClassifierAction = eAddClassifier; - } else if (ucDsxType == DSC_ACK) { - switch (psfCSType->u8ClassfierDSCAction) { - case 0: /* DSC Add Classifier */ - eClassifierAction = eAddClassifier; - break; - case 1: /* DSC Replace Classifier */ - eClassifierAction = eReplaceClassifier; - break; - case 2: /* DSC Delete Classifier */ - eClassifierAction = eDeleteClassifier; - break; - default: - eClassifierAction = eInvalidClassifierAction; - } - } - - u16PacketClassificationRuleIndex = ntohs(psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex); - - switch (eClassifierAction) { - case eAddClassifier: - /* Get a Free Classifier Index From Classifier table for this SF to add the Classifier */ - /* Contained in this message */ - nClassifierIndex = SearchClsid(Adapter, - ulSFID, - u16PacketClassificationRuleIndex); - - if (nClassifierIndex > MAX_CLASSIFIERS) { - nClassifierIndex = SearchFreeClsid(Adapter); - if (nClassifierIndex > MAX_CLASSIFIERS) { - /* Failed To get a free Entry */ - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - CONN_MSG, - DBG_LVL_ALL, - "Error Failed To get a free Classifier Entry"); - break; - } - /* Copy the Classifier Rule for this service flow into our Classifier table maintained per SF. */ - CopyClassifierRuleToSF(Adapter, psfCSType, - uiSearchRuleIndex, - nClassifierIndex); - } else { - /* This Classifier Already Exists and it is invalid to Add Classifier with existing PCRI */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - CONN_MSG, - DBG_LVL_ALL, - "CopyToAdapter: Error The Specified Classifier Already Exists and attempted To Add Classifier with Same PCRI : 0x%x\n", - u16PacketClassificationRuleIndex); - } - break; - case eReplaceClassifier: - /* Get the Classifier Index From Classifier table for this SF and replace existing Classifier */ - /* with the new classifier Contained in this message */ - nClassifierIndex = SearchClsid(Adapter, ulSFID, - u16PacketClassificationRuleIndex); - if (nClassifierIndex > MAX_CLASSIFIERS) { - /* Failed To search the classifier */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - CONN_MSG, DBG_LVL_ALL, - "Error Search for Classifier To be replaced failed"); - break; - } - /* Copy the Classifier Rule for this service flow into our Classifier table maintained per SF. */ - CopyClassifierRuleToSF(Adapter, psfCSType, - uiSearchRuleIndex, nClassifierIndex); - break; - case eDeleteClassifier: - /* Get the Classifier Index From Classifier table for this SF and replace existing Classifier */ - /* with the new classifier Contained in this message */ - nClassifierIndex = SearchClsid(Adapter, ulSFID, - u16PacketClassificationRuleIndex); - if (nClassifierIndex > MAX_CLASSIFIERS) { - /* Failed To search the classifier */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - CONN_MSG, DBG_LVL_ALL, - "Error Search for Classifier To be deleted failed"); - break; - } - - /* Delete This classifier */ - DeleteClassifierRuleFromSF(Adapter, uiSearchRuleIndex, - nClassifierIndex); - break; - default: - /* Invalid Action for classifier */ - break; - } - } - - /* Repeat parsing Classification Entries to process PHS Rules */ - for (i = 0; i < psfLocalSet->u8TotalClassifiers; i++) { - psfCSType = &psfLocalSet->cConvergenceSLTypes[i]; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "psfCSType->u8PhsDSCAction : 0x%x\n", - psfCSType->u8PhsDSCAction); - - switch (psfCSType->u8PhsDSCAction) { - case eDeleteAllPHSRules: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, - DBG_LVL_ALL, - "Deleting All PHS Rules For VCID: 0x%X\n", - uVCID); - - /* Delete All the PHS rules for this Service flow */ - PhsDeleteSFRules(&Adapter->stBCMPhsContext, uVCID); - break; - case eDeletePHSRule: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, - DBG_LVL_ALL, - "PHS DSC Action = Delete PHS Rule\n"); - - if (psfCSType->cPhsRule.u8PHSI) - PhsDeletePHSRule(&Adapter->stBCMPhsContext, - uVCID, - psfCSType->cCPacketClassificationRule.u8AssociatedPHSI); - - break; - default: - if (ucDsxType == DSC_ACK) { - /* BCM_DEBUG_PRINT(CONN_MSG,("Invalid PHS DSC Action For DSC\n",psfCSType->cPhsRule.u8PHSI)); */ - break; /* FOr DSC ACK Case PHS DSC Action must be in valid set */ - } - /* Proceed To Add PHS rule for DSA_ACK case even if PHS DSC action is unspecified */ - /* No Break Here . Intentionally! */ - - case eAddPHSRule: - case eSetPHSRule: - if (psfCSType->cPhsRule.u8PHSI) { - /* Apply This PHS Rule to all classifiers whose Associated PHSI Match */ - apply_phs_rule_to_all_classifiers(Adapter, - uiSearchRuleIndex, - uVCID, - &sPhsRule, - &psfCSType->cPhsRule, - pstAddIndication); - } - break; - } - } - - if (psfLocalSet->u32MaxSustainedTrafficRate == 0) { - /* No Rate Limit . Set Max Sustained Traffic Rate to Maximum */ - curr_packinfo->uiMaxAllowedRate = WIMAX_MAX_ALLOWED_RATE; - } else if (ntohl(psfLocalSet->u32MaxSustainedTrafficRate) > WIMAX_MAX_ALLOWED_RATE) { - /* Too large Allowed Rate specified. Limiting to Wi Max Allowed rate */ - curr_packinfo->uiMaxAllowedRate = WIMAX_MAX_ALLOWED_RATE; - } else { - curr_packinfo->uiMaxAllowedRate = - ntohl(psfLocalSet->u32MaxSustainedTrafficRate); - } - - curr_packinfo->uiMaxLatency = ntohl(psfLocalSet->u32MaximumLatency); - if (curr_packinfo->uiMaxLatency == 0) /* 0 should be treated as infinite */ - curr_packinfo->uiMaxLatency = MAX_LATENCY_ALLOWED; - - if ((curr_packinfo->u8QueueType == ERTPS || - curr_packinfo->u8QueueType == UGS)) - UGIValue = ntohs(psfLocalSet->u16UnsolicitedGrantInterval); - - if (UGIValue == 0) - UGIValue = DEFAULT_UG_INTERVAL; - - /* - * For UGI based connections... - * DEFAULT_UGI_FACTOR*UGIInterval worth of data is the max token count at host... - * The extra amount of token is to ensure that a large amount of jitter won't have loss in throughput... - * In case of non-UGI based connection, 200 frames worth of data is the max token count at host... - */ - curr_packinfo->uiMaxBucketSize = - (DEFAULT_UGI_FACTOR*curr_packinfo->uiMaxAllowedRate*UGIValue)/1000; - - if (curr_packinfo->uiMaxBucketSize < WIMAX_MAX_MTU*8) { - UINT UGIFactor = 0; - /* Special Handling to ensure the biggest size of packet can go out from host to FW as follows: - * 1. Any packet from Host to FW can go out in different packet size. - * 2. So in case the Bucket count is smaller than MTU, the packets of size (Size > TokenCount), will get dropped. - * 3. We can allow packets of MaxSize from Host->FW that can go out from FW in multiple SDUs by fragmentation at Wimax Layer - */ - UGIFactor = (curr_packinfo->uiMaxLatency/UGIValue + 1); - - if (UGIFactor > DEFAULT_UGI_FACTOR) - curr_packinfo->uiMaxBucketSize = - (UGIFactor*curr_packinfo->uiMaxAllowedRate*UGIValue)/1000; - - if (curr_packinfo->uiMaxBucketSize > WIMAX_MAX_MTU*8) - curr_packinfo->uiMaxBucketSize = WIMAX_MAX_MTU*8; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "LAT: %d, UGI: %d\n", curr_packinfo->uiMaxLatency, - UGIValue); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "uiMaxAllowedRate: 0x%x, u32MaxSustainedTrafficRate: 0x%x ,uiMaxBucketSize: 0x%x", - curr_packinfo->uiMaxAllowedRate, - ntohl(psfLocalSet->u32MaxSustainedTrafficRate), - curr_packinfo->uiMaxBucketSize); - - /* copy the extended SF Parameters to Support MIBS */ - CopyMIBSExtendedSFParameters(Adapter, psfLocalSet, uiSearchRuleIndex); - - /* store header suppression enabled flag per SF */ - curr_packinfo->bHeaderSuppressionEnabled = - !(psfLocalSet->u8RequesttransmissionPolicy & - MASK_DISABLE_HEADER_SUPPRESSION); - - kfree(curr_packinfo->pstSFIndication); - curr_packinfo->pstSFIndication = pstAddIndication; - - /* Re Sort the SF list in PackInfo according to Traffic Priority */ - SortPackInfo(Adapter); - - /* Re Sort the Classifier Rules table and re - arrange - * according to Classifier Rule Priority - */ - SortClassifiers(Adapter); - DumpPhsRules(&Adapter->stBCMPhsContext); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "%s <=====", __func__); -} - -/*********************************************************************** - * Function - DumpCmControlPacket - * - * Description - This routinue Dumps the Contents of the AddIndication - * Structure in the Connection Management Control Packet - * - * Parameter - pvBuffer: Pointer to the buffer containing the - * AddIndication data. - * - * Returns - None - *************************************************************************/ -static VOID DumpCmControlPacket(PVOID pvBuffer) -{ - int uiLoopIndex; - int nIndex; - struct bcm_add_indication_alt *pstAddIndication; - UINT nCurClassifierCnt; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - pstAddIndication = pvBuffer; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "======>"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Type: 0x%X", pstAddIndication->u8Type); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Direction: 0x%X", pstAddIndication->u8Direction); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TID: 0x%X", ntohs(pstAddIndication->u16TID)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", ntohs(pstAddIndication->u16CID)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VCID: 0x%X", ntohs(pstAddIndication->u16VCID)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " AuthorizedSet--->"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID: 0x%X", htonl(pstAddIndication->sfAuthorizedSet.u32SFID)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", htons(pstAddIndication->sfAuthorizedSet.u16CID)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength: 0x%X", - pstAddIndication->sfAuthorizedSet.u8ServiceClassNameLength); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName: 0x%X ,0x%X , 0x%X, 0x%X, 0x%X, 0x%X", - pstAddIndication->sfAuthorizedSet.u8ServiceClassName[0], - pstAddIndication->sfAuthorizedSet.u8ServiceClassName[1], - pstAddIndication->sfAuthorizedSet.u8ServiceClassName[2], - pstAddIndication->sfAuthorizedSet.u8ServiceClassName[3], - pstAddIndication->sfAuthorizedSet.u8ServiceClassName[4], - pstAddIndication->sfAuthorizedSet.u8ServiceClassName[5]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService: 0x%X", pstAddIndication->sfAuthorizedSet.u8MBSService); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet: 0x%X", pstAddIndication->sfAuthorizedSet.u8QosParamSet); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority: 0x%X, %p", - pstAddIndication->sfAuthorizedSet.u8TrafficPriority, &pstAddIndication->sfAuthorizedSet.u8TrafficPriority); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxSustainedTrafficRate: 0x%X 0x%p", - pstAddIndication->sfAuthorizedSet.u32MaxSustainedTrafficRate, - &pstAddIndication->sfAuthorizedSet.u32MaxSustainedTrafficRate); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst: 0x%X", pstAddIndication->sfAuthorizedSet.u32MaxTrafficBurst); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X", - pstAddIndication->sfAuthorizedSet.u32MinReservedTrafficRate); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength: 0x%X", - pstAddIndication->sfAuthorizedSet.u8VendorSpecificQoSParamLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam: 0x%X", - pstAddIndication->sfAuthorizedSet.u8VendorSpecificQoSParam[0]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType: 0x%X", - pstAddIndication->sfAuthorizedSet.u8ServiceFlowSchedulingType); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter: 0x%X", pstAddIndication->sfAuthorizedSet.u32ToleratedJitter); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaximumLatency: 0x%X", pstAddIndication->sfAuthorizedSet.u32MaximumLatency); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%X", - pstAddIndication->sfAuthorizedSet.u8FixedLengthVSVariableLengthSDUIndicator); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize: 0x%X", pstAddIndication->sfAuthorizedSet.u8SDUSize); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TargetSAID: 0x%X", pstAddIndication->sfAuthorizedSet.u16TargetSAID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQEnable: 0x%X", pstAddIndication->sfAuthorizedSet.u8ARQEnable); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQWindowSize: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQWindowSize); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryTxTimeOut: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQRetryTxTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryRxTimeOut: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQRetryRxTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockLifeTime: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQBlockLifeTime); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQSyncLossTimeOut: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQSyncLossTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQDeliverInOrder: 0x%X", pstAddIndication->sfAuthorizedSet.u8ARQDeliverInOrder); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRxPurgeTimeOut: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQRxPurgeTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockSize: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQBlockSize); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8CSSpecification: 0x%X", pstAddIndication->sfAuthorizedSet.u8CSSpecification); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TypeOfDataDeliveryService: 0x%X", - pstAddIndication->sfAuthorizedSet.u8TypeOfDataDeliveryService); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16SDUInterArrivalTime: 0x%X", pstAddIndication->sfAuthorizedSet.u16SDUInterArrivalTime); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TimeBase: 0x%X", pstAddIndication->sfAuthorizedSet.u16TimeBase); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8PagingPreference: 0x%X", pstAddIndication->sfAuthorizedSet.u8PagingPreference); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UnsolicitedPollingInterval: 0x%X", - pstAddIndication->sfAuthorizedSet.u16UnsolicitedPollingInterval); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "sfAuthorizedSet.u8HARQChannelMapping %x %x %x ", - *(unsigned int *)pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping, - *(unsigned int *)&pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping[4], - *(USHORT *)&pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping[8]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficIndicationPreference: 0x%X", - pstAddIndication->sfAuthorizedSet.u8TrafficIndicationPreference); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Received: 0x%X", pstAddIndication->sfAuthorizedSet.u8TotalClassifiers); - - nCurClassifierCnt = pstAddIndication->sfAuthorizedSet.u8TotalClassifiers; - if (nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF) - nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "pstAddIndication->sfAuthorizedSet.bValid %d", pstAddIndication->sfAuthorizedSet.bValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "pstAddIndication->sfAuthorizedSet.u16MacOverhead %x", pstAddIndication->sfAuthorizedSet.u16MacOverhead); - if (!pstAddIndication->sfAuthorizedSet.bValid) - pstAddIndication->sfAuthorizedSet.bValid = 1; - for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++) { - struct bcm_convergence_types *psfCSType = NULL; - - psfCSType = &pstAddIndication->sfAuthorizedSet.cConvergenceSLTypes[nIndex]; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "psfCSType = %p", psfCSType); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "CCPacketClassificationRuleSI====>"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ClassifierRulePriority: 0x%X ", - psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfServiceLength: 0x%X ", - psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfService[3]: 0x%X ,0x%X ,0x%X ", - psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0], - psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1], - psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]); - - for (uiLoopIndex = 0; uiLoopIndex < 1; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8Protocol); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddressLength: 0x%X ", - psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength); - - for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddress[32]: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddressLength: 0x%X ", - psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength); - - for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddress[32]: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRangeLength:0x%X ", - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRange[4]: 0x%02X ,0x%02X ,0x%02X ,0x%02X ", - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0], - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1], - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2], - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRangeLength: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRange[4]: 0x%02X ,0x%02X ,0x%02X ,0x%02X ", - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0], - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1], - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2], - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddressLength: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, "u8EthernetDestMacAddress[6]: %pM", - psfCSType->cCPacketClassificationRule. - u8EthernetDestMacAddress); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddressLength: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, "u8EthernetSourceMACAddress[6]: %pM", - psfCSType->cCPacketClassificationRule. - u8EthernetSourceMACAddress); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthertypeLength: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8EthertypeLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Ethertype[3]: 0x%02X ,0x%02X ,0x%02X ", - psfCSType->cCPacketClassificationRule.u8Ethertype[0], - psfCSType->cCPacketClassificationRule.u8Ethertype[1], - psfCSType->cCPacketClassificationRule.u8Ethertype[2]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UserPriority: 0x%X ", psfCSType->cCPacketClassificationRule.u16UserPriority); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VLANID: 0x%X ", psfCSType->cCPacketClassificationRule.u16VLANID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8AssociatedPHSI: 0x%02X ", psfCSType->cCPacketClassificationRule.u8AssociatedPHSI); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16PacketClassificationRuleIndex: 0x%X ", - psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParamLength: 0x%X ", - psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParam[1]: 0x%X ", - psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]); -#ifdef VERSION_D5 - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLableLength: 0x%X ", - psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, "u8IPv6FlowLable[6]: 0x%*ph ", - 6, psfCSType->cCPacketClassificationRule. - u8IPv6FlowLable); -#endif - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "bValid: 0x%02X", pstAddIndication->sfAuthorizedSet.bValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "AdmittedSet--->"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID: 0x%X", pstAddIndication->sfAdmittedSet.u32SFID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", pstAddIndication->sfAdmittedSet.u16CID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength: 0x%X", - pstAddIndication->sfAdmittedSet.u8ServiceClassNameLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, - "u8ServiceClassName: 0x%*ph", - 6, pstAddIndication->sfAdmittedSet.u8ServiceClassName); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService: 0x%02X", pstAddIndication->sfAdmittedSet.u8MBSService); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet: 0x%02X", pstAddIndication->sfAdmittedSet.u8QosParamSet); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority: 0x%02X", pstAddIndication->sfAdmittedSet.u8TrafficPriority); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst: 0x%X", pstAddIndication->sfAdmittedSet.u32MaxTrafficBurst); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate: 0x%X", - pstAddIndication->sfAdmittedSet.u32MinReservedTrafficRate); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength: 0x%02X", - pstAddIndication->sfAdmittedSet.u8VendorSpecificQoSParamLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam: 0x%02X", - pstAddIndication->sfAdmittedSet.u8VendorSpecificQoSParam[0]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType: 0x%02X", - pstAddIndication->sfAdmittedSet.u8ServiceFlowSchedulingType); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter: 0x%X", pstAddIndication->sfAdmittedSet.u32ToleratedJitter); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaximumLatency: 0x%X", pstAddIndication->sfAdmittedSet.u32MaximumLatency); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%02X", - pstAddIndication->sfAdmittedSet.u8FixedLengthVSVariableLengthSDUIndicator); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize: 0x%02X", pstAddIndication->sfAdmittedSet.u8SDUSize); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TargetSAID: 0x%02X", pstAddIndication->sfAdmittedSet.u16TargetSAID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQEnable: 0x%02X", pstAddIndication->sfAdmittedSet.u8ARQEnable); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQWindowSize: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQWindowSize); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryTxTimeOut: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQRetryTxTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryRxTimeOut: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQRetryRxTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockLifeTime: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQBlockLifeTime); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQSyncLossTimeOut: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQSyncLossTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQDeliverInOrder: 0x%02X", pstAddIndication->sfAdmittedSet.u8ARQDeliverInOrder); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRxPurgeTimeOut: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQRxPurgeTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockSize: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQBlockSize); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8CSSpecification: 0x%02X", pstAddIndication->sfAdmittedSet.u8CSSpecification); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TypeOfDataDeliveryService: 0x%02X", - pstAddIndication->sfAdmittedSet.u8TypeOfDataDeliveryService); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16SDUInterArrivalTime: 0x%X", pstAddIndication->sfAdmittedSet.u16SDUInterArrivalTime); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TimeBase: 0x%X", pstAddIndication->sfAdmittedSet.u16TimeBase); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8PagingPreference: 0x%X", pstAddIndication->sfAdmittedSet.u8PagingPreference); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficIndicationPreference: 0x%02X", - pstAddIndication->sfAdmittedSet.u8TrafficIndicationPreference); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Received: 0x%X", pstAddIndication->sfAdmittedSet.u8TotalClassifiers); - - nCurClassifierCnt = pstAddIndication->sfAdmittedSet.u8TotalClassifiers; - if (nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF) - nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF; - - for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++) { - struct bcm_convergence_types *psfCSType = NULL; - - psfCSType = &pstAddIndication->sfAdmittedSet.cConvergenceSLTypes[nIndex]; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " CCPacketClassificationRuleSI====>"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ClassifierRulePriority: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfServiceLength: 0x%02X", - psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, "u8IPTypeOfService[3]: 0x%*ph", - 3, psfCSType->cCPacketClassificationRule. - u8IPTypeOfService); - for (uiLoopIndex = 0; uiLoopIndex < 1; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol: 0x%02X ", psfCSType->cCPacketClassificationRule.u8Protocol); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddressLength: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength); - - for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddress[32]: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddressLength: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength); - - for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddress[32]: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRangeLength: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, "u8ProtocolSourcePortRange[4]: 0x%*ph ", - 4, psfCSType->cCPacketClassificationRule. - u8ProtocolSourcePortRange); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRangeLength: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, "u8ProtocolDestPortRange[4]: 0x%*ph ", - 4, psfCSType->cCPacketClassificationRule. - u8ProtocolDestPortRange); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddressLength: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, "u8EthernetDestMacAddress[6]: %pM", - psfCSType->cCPacketClassificationRule. - u8EthernetDestMacAddress); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddressLength: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, "u8EthernetSourceMACAddress[6]: %pM", - psfCSType->cCPacketClassificationRule. - u8EthernetSourceMACAddress); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthertypeLength: 0x%02X ", psfCSType->cCPacketClassificationRule.u8EthertypeLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, "u8Ethertype[3]: 0x%*ph", - 3, psfCSType->cCPacketClassificationRule. - u8Ethertype); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UserPriority: 0x%X ", psfCSType->cCPacketClassificationRule.u16UserPriority); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VLANID: 0x%X ", psfCSType->cCPacketClassificationRule.u16VLANID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8AssociatedPHSI: 0x%02X ", psfCSType->cCPacketClassificationRule.u8AssociatedPHSI); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16PacketClassificationRuleIndex: 0x%X ", - psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParamLength: 0x%02X", - psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParam[1]: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]); -#ifdef VERSION_D5 - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLableLength: 0x%X ", - psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, "u8IPv6FlowLable[6]: 0x%*ph ", - 6, psfCSType->cCPacketClassificationRule. - u8IPv6FlowLable); -#endif - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "bValid: 0x%X", pstAddIndication->sfAdmittedSet.bValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " ActiveSet--->"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID: 0x%X", pstAddIndication->sfActiveSet.u32SFID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", pstAddIndication->sfActiveSet.u16CID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength: 0x%X", pstAddIndication->sfActiveSet.u8ServiceClassNameLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, - "u8ServiceClassName: 0x%*ph", - 6, pstAddIndication->sfActiveSet.u8ServiceClassName); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService: 0x%02X", pstAddIndication->sfActiveSet.u8MBSService); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet: 0x%02X", pstAddIndication->sfActiveSet.u8QosParamSet); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority: 0x%02X", pstAddIndication->sfActiveSet.u8TrafficPriority); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst: 0x%X", pstAddIndication->sfActiveSet.u32MaxTrafficBurst); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate: 0x%X", - pstAddIndication->sfActiveSet.u32MinReservedTrafficRate); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength: 0x%02X", - pstAddIndication->sfActiveSet.u8VendorSpecificQoSParamLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam: 0x%02X", - pstAddIndication->sfActiveSet.u8VendorSpecificQoSParam[0]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType: 0x%02X", - pstAddIndication->sfActiveSet.u8ServiceFlowSchedulingType); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter: 0x%X", pstAddIndication->sfActiveSet.u32ToleratedJitter); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaximumLatency: 0x%X", pstAddIndication->sfActiveSet.u32MaximumLatency); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%02X", - pstAddIndication->sfActiveSet.u8FixedLengthVSVariableLengthSDUIndicator); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize: 0x%X", pstAddIndication->sfActiveSet.u8SDUSize); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16TargetSAID: 0x%X", pstAddIndication->sfActiveSet.u16TargetSAID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ARQEnable: 0x%X", pstAddIndication->sfActiveSet.u8ARQEnable); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQWindowSize: 0x%X", pstAddIndication->sfActiveSet.u16ARQWindowSize); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQRetryTxTimeOut: 0x%X", pstAddIndication->sfActiveSet.u16ARQRetryTxTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQRetryRxTimeOut: 0x%X", pstAddIndication->sfActiveSet.u16ARQRetryRxTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQBlockLifeTime: 0x%X", pstAddIndication->sfActiveSet.u16ARQBlockLifeTime); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQSyncLossTimeOut: 0x%X", pstAddIndication->sfActiveSet.u16ARQSyncLossTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ARQDeliverInOrder: 0x%X", pstAddIndication->sfActiveSet.u8ARQDeliverInOrder); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQRxPurgeTimeOut: 0x%X", pstAddIndication->sfActiveSet.u16ARQRxPurgeTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQBlockSize: 0x%X", pstAddIndication->sfActiveSet.u16ARQBlockSize); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8CSSpecification: 0x%X", pstAddIndication->sfActiveSet.u8CSSpecification); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8TypeOfDataDeliveryService: 0x%X", - pstAddIndication->sfActiveSet.u8TypeOfDataDeliveryService); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16SDUInterArrivalTime: 0x%X", pstAddIndication->sfActiveSet.u16SDUInterArrivalTime); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16TimeBase: 0x%X", pstAddIndication->sfActiveSet.u16TimeBase); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8PagingPreference: 0x%X", pstAddIndication->sfActiveSet.u8PagingPreference); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8TrafficIndicationPreference: 0x%X", - pstAddIndication->sfActiveSet.u8TrafficIndicationPreference); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Received: 0x%X", pstAddIndication->sfActiveSet.u8TotalClassifiers); - - nCurClassifierCnt = pstAddIndication->sfActiveSet.u8TotalClassifiers; - if (nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF) - nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF; - - for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++) { - struct bcm_convergence_types *psfCSType = NULL; - struct bcm_packet_class_rules *clsRule = NULL; - - psfCSType = &pstAddIndication->sfActiveSet.cConvergenceSLTypes[nIndex]; - clsRule = &psfCSType->cCPacketClassificationRule; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, " CCPacketClassificationRuleSI====>"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, " u8ClassifierRulePriority: 0x%X ", - clsRule->u8ClassifierRulePriority); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, " u8IPTypeOfServiceLength: 0x%X ", - clsRule->u8IPTypeOfServiceLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8IPTypeOfService[3]: 0x%X ,0x%X ,0x%X ", - clsRule->u8IPTypeOfService[0], - clsRule->u8IPTypeOfService[1], - clsRule->u8IPTypeOfService[2]); - - for (uiLoopIndex = 0; uiLoopIndex < 1; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8Protocol: 0x%X ", - clsRule->u8Protocol); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - "u8IPMaskedSourceAddressLength: 0x%X ", - clsRule->u8IPMaskedSourceAddressLength); - - for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - "u8IPMaskedSourceAddress[32]: 0x%X ", - clsRule->u8IPMaskedSourceAddress[uiLoopIndex]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - "u8IPDestinationAddressLength: 0x%02X ", - clsRule->u8IPDestinationAddressLength); - - for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8IPDestinationAddress[32]:0x%X ", - clsRule->u8IPDestinationAddress[uiLoopIndex]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8ProtocolSourcePortRangeLength: 0x%X ", - clsRule->u8ProtocolSourcePortRangeLength); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8ProtocolSourcePortRange[4]: 0x%X ,0x%X ,0x%X ,0x%X ", - clsRule->u8ProtocolSourcePortRange[0], - clsRule->u8ProtocolSourcePortRange[1], - clsRule->u8ProtocolSourcePortRange[2], - clsRule->u8ProtocolSourcePortRange[3]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8ProtocolDestPortRangeLength: 0x%X ", - clsRule->u8ProtocolDestPortRangeLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8ProtocolDestPortRange[4]: 0x%X ,0x%X ,0x%X ,0x%X ", - clsRule->u8ProtocolDestPortRange[0], - clsRule->u8ProtocolDestPortRange[1], - clsRule->u8ProtocolDestPortRange[2], - clsRule->u8ProtocolDestPortRange[3]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8EthernetDestMacAddressLength: 0x%X ", - clsRule->u8EthernetDestMacAddressLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8EthernetDestMacAddress[6]: 0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X", - clsRule->u8EthernetDestMacAddress[0], - clsRule->u8EthernetDestMacAddress[1], - clsRule->u8EthernetDestMacAddress[2], - clsRule->u8EthernetDestMacAddress[3], - clsRule->u8EthernetDestMacAddress[4], - clsRule->u8EthernetDestMacAddress[5]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8EthernetSourceMACAddressLength: 0x%X ", - clsRule->u8EthernetDestMacAddressLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - "u8EthernetSourceMACAddress[6]: 0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X", - clsRule->u8EthernetSourceMACAddress[0], - clsRule->u8EthernetSourceMACAddress[1], - clsRule->u8EthernetSourceMACAddress[2], - clsRule->u8EthernetSourceMACAddress[3], - clsRule->u8EthernetSourceMACAddress[4], - clsRule->u8EthernetSourceMACAddress[5]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, " u8EthertypeLength: 0x%X ", - clsRule->u8EthertypeLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8Ethertype[3]: 0x%X ,0x%X ,0x%X ", - clsRule->u8Ethertype[0], - clsRule->u8Ethertype[1], - clsRule->u8Ethertype[2]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, " u16UserPriority: 0x%X ", - clsRule->u16UserPriority); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, " u16VLANID: 0x%X ", - clsRule->u16VLANID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, " u8AssociatedPHSI: 0x%X ", - clsRule->u8AssociatedPHSI); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u16PacketClassificationRuleIndex:0x%X ", - clsRule->u16PacketClassificationRuleIndex); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8VendorSpecificClassifierParamLength:0x%X ", - clsRule->u8VendorSpecificClassifierParamLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8VendorSpecificClassifierParam[1]:0x%X ", - clsRule->u8VendorSpecificClassifierParam[0]); -#ifdef VERSION_D5 - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, " u8IPv6FlowLableLength: 0x%X ", - clsRule->u8IPv6FlowLableLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8IPv6FlowLable[6]: 0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X ", - clsRule->u8IPv6FlowLable[0], - clsRule->u8IPv6FlowLable[1], - clsRule->u8IPv6FlowLable[2], - clsRule->u8IPv6FlowLable[3], - clsRule->u8IPv6FlowLable[4], - clsRule->u8IPv6FlowLable[5]); -#endif - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, - " bValid: 0x%X", pstAddIndication->sfActiveSet.bValid); -} - -static inline ULONG RestoreSFParam(struct bcm_mini_adapter *Adapter, - ULONG ulAddrSFParamSet, PUCHAR pucDestBuffer) -{ - UINT nBytesToRead = sizeof(struct bcm_connect_mgr_params); - - if (ulAddrSFParamSet == 0 || NULL == pucDestBuffer) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Got Param address as 0!!"); - return 0; - } - ulAddrSFParamSet = ntohl(ulAddrSFParamSet); - - /* Read out the SF Param Set At the indicated Location */ - if (rdm(Adapter, ulAddrSFParamSet, (PUCHAR)pucDestBuffer, nBytesToRead) < 0) - return STATUS_FAILURE; - - return 1; -} - -static ULONG StoreSFParam(struct bcm_mini_adapter *Adapter, PUCHAR pucSrcBuffer, - ULONG ulAddrSFParamSet) -{ - UINT nBytesToWrite = sizeof(struct bcm_connect_mgr_params); - int ret = 0; - - if (ulAddrSFParamSet == 0 || NULL == pucSrcBuffer) - return 0; - - ret = wrm(Adapter, ulAddrSFParamSet, (u8 *)pucSrcBuffer, nBytesToWrite); - if (ret < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "%s:%d WRM failed", __func__, __LINE__); - return ret; - } - return 1; -} - -ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, - PVOID pvBuffer, UINT *puBufferLength) -{ - struct bcm_add_indication_alt *pstAddIndicationAlt = NULL; - struct bcm_add_indication *pstAddIndication = NULL; - struct bcm_del_request *pstDeletionRequest; - UINT uiSearchRuleIndex; - ULONG ulSFID; - - pstAddIndicationAlt = pvBuffer; - - /* - * In case of DSD Req By MS, we should immediately delete this SF so that - * we can stop the further classifying the pkt for this SF. - */ - if (pstAddIndicationAlt->u8Type == DSD_REQ) { - pstDeletionRequest = pvBuffer; - - ulSFID = ntohl(pstDeletionRequest->u32SFID); - uiSearchRuleIndex = SearchSfid(Adapter, ulSFID); - - if (uiSearchRuleIndex < NO_OF_QUEUES) { - deleteSFBySfid(Adapter, uiSearchRuleIndex); - Adapter->u32TotalDSD++; - } - return 1; - } - - if ((pstAddIndicationAlt->u8Type == DSD_RSP) || - (pstAddIndicationAlt->u8Type == DSD_ACK)) { - /* No Special handling send the message as it is */ - return 1; - } - /* For DSA_REQ, only up to "psfAuthorizedSet" parameter should be accessed by driver! */ - - pstAddIndication = kmalloc(sizeof(struct bcm_add_indication), - GFP_KERNEL); - if (pstAddIndication == NULL) - return 0; - - /* AUTHORIZED SET */ - pstAddIndication->psfAuthorizedSet = (struct bcm_connect_mgr_params *) - GetNextTargetBufferLocation(Adapter, - pstAddIndicationAlt->u16TID); - if (!pstAddIndication->psfAuthorizedSet) { - kfree(pstAddIndication); - return 0; - } - - if (StoreSFParam(Adapter, (PUCHAR)&pstAddIndicationAlt->sfAuthorizedSet, - (ULONG)pstAddIndication->psfAuthorizedSet) != 1) { - kfree(pstAddIndication); - return 0; - } - - /* this can't possibly be right */ - pstAddIndication->psfAuthorizedSet = - (struct bcm_connect_mgr_params *) ntohl( - (ULONG)pstAddIndication->psfAuthorizedSet); - - if (pstAddIndicationAlt->u8Type == DSA_REQ) { - struct bcm_add_request AddRequest; - - AddRequest.u8Type = pstAddIndicationAlt->u8Type; - AddRequest.eConnectionDir = pstAddIndicationAlt->u8Direction; - AddRequest.u16TID = pstAddIndicationAlt->u16TID; - AddRequest.u16CID = pstAddIndicationAlt->u16CID; - AddRequest.u16VCID = pstAddIndicationAlt->u16VCID; - AddRequest.psfParameterSet = pstAddIndication->psfAuthorizedSet; - (*puBufferLength) = sizeof(struct bcm_add_request); - memcpy(pvBuffer, &AddRequest, sizeof(struct bcm_add_request)); - kfree(pstAddIndication); - return 1; - } - - /* Since it's not DSA_REQ, we can access all field in pstAddIndicationAlt */ - /* We need to extract the structure from the buffer and pack it differently */ - - pstAddIndication->u8Type = pstAddIndicationAlt->u8Type; - pstAddIndication->eConnectionDir = pstAddIndicationAlt->u8Direction; - pstAddIndication->u16TID = pstAddIndicationAlt->u16TID; - pstAddIndication->u16CID = pstAddIndicationAlt->u16CID; - pstAddIndication->u16VCID = pstAddIndicationAlt->u16VCID; - pstAddIndication->u8CC = pstAddIndicationAlt->u8CC; - - /* ADMITTED SET */ - pstAddIndication->psfAdmittedSet = (struct bcm_connect_mgr_params *) - GetNextTargetBufferLocation(Adapter, - pstAddIndicationAlt->u16TID); - if (!pstAddIndication->psfAdmittedSet) { - kfree(pstAddIndication); - return 0; - } - if (StoreSFParam(Adapter, (PUCHAR)&pstAddIndicationAlt->sfAdmittedSet, - (ULONG)pstAddIndication->psfAdmittedSet) != 1) { - kfree(pstAddIndication); - return 0; - } - - pstAddIndication->psfAdmittedSet = - (struct bcm_connect_mgr_params *) ntohl( - (ULONG) pstAddIndication->psfAdmittedSet); - - /* ACTIVE SET */ - pstAddIndication->psfActiveSet = (struct bcm_connect_mgr_params *) - GetNextTargetBufferLocation(Adapter, - pstAddIndicationAlt->u16TID); - if (!pstAddIndication->psfActiveSet) { - kfree(pstAddIndication); - return 0; - } - if (StoreSFParam(Adapter, (PUCHAR)&pstAddIndicationAlt->sfActiveSet, - (ULONG)pstAddIndication->psfActiveSet) != 1) { - kfree(pstAddIndication); - return 0; - } - - pstAddIndication->psfActiveSet = - (struct bcm_connect_mgr_params *) ntohl( - (ULONG)pstAddIndication->psfActiveSet); - - (*puBufferLength) = sizeof(struct bcm_add_indication); - *(struct bcm_add_indication *)pvBuffer = *pstAddIndication; - kfree(pstAddIndication); - return 1; -} - -static inline struct bcm_add_indication_alt -*RestoreCmControlResponseMessage(register struct bcm_mini_adapter *Adapter, - register PVOID pvBuffer) -{ - ULONG ulStatus = 0; - struct bcm_add_indication *pstAddIndication = NULL; - struct bcm_add_indication_alt *pstAddIndicationDest = NULL; - - pstAddIndication = pvBuffer; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "=====>"); - if ((pstAddIndication->u8Type == DSD_REQ) || - (pstAddIndication->u8Type == DSD_RSP) || - (pstAddIndication->u8Type == DSD_ACK)) - return pvBuffer; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Inside RestoreCmControlResponseMessage "); - /* - * Need to Allocate memory to contain the SUPER Large structures - * Our driver can't create these structures on Stack :( - */ - pstAddIndicationDest = kmalloc(sizeof(struct bcm_add_indication_alt), - GFP_KERNEL); - - if (pstAddIndicationDest) { - memset(pstAddIndicationDest, 0, - sizeof(struct bcm_add_indication_alt)); - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, - DBG_LVL_ALL, - "Failed to allocate memory for SF Add Indication Structure "); - return NULL; - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "AddIndication-u8Type : 0x%X", - pstAddIndication->u8Type); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "AddIndication-u8Direction : 0x%X", - pstAddIndication->eConnectionDir); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "AddIndication-u8TID : 0x%X", - ntohs(pstAddIndication->u16TID)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "AddIndication-u8CID : 0x%X", - ntohs(pstAddIndication->u16CID)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "AddIndication-u16VCID : 0x%X", - ntohs(pstAddIndication->u16VCID)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "AddIndication-autorized set loc : %p", - pstAddIndication->psfAuthorizedSet); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "AddIndication-admitted set loc : %p", - pstAddIndication->psfAdmittedSet); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "AddIndication-Active set loc : %p", - pstAddIndication->psfActiveSet); - - pstAddIndicationDest->u8Type = pstAddIndication->u8Type; - pstAddIndicationDest->u8Direction = pstAddIndication->eConnectionDir; - pstAddIndicationDest->u16TID = pstAddIndication->u16TID; - pstAddIndicationDest->u16CID = pstAddIndication->u16CID; - pstAddIndicationDest->u16VCID = pstAddIndication->u16VCID; - pstAddIndicationDest->u8CC = pstAddIndication->u8CC; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Restoring Active Set "); - ulStatus = RestoreSFParam(Adapter, - (ULONG)pstAddIndication->psfActiveSet, - (PUCHAR)&pstAddIndicationDest->sfActiveSet); - if (ulStatus != 1) - goto failed_restore_sf_param; - - if (pstAddIndicationDest->sfActiveSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF) - pstAddIndicationDest->sfActiveSet.u8TotalClassifiers = - MAX_CLASSIFIERS_IN_SF; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Restoring Admitted Set "); - ulStatus = RestoreSFParam(Adapter, - (ULONG)pstAddIndication->psfAdmittedSet, - (PUCHAR)&pstAddIndicationDest->sfAdmittedSet); - if (ulStatus != 1) - goto failed_restore_sf_param; - - if (pstAddIndicationDest->sfAdmittedSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF) - pstAddIndicationDest->sfAdmittedSet.u8TotalClassifiers = - MAX_CLASSIFIERS_IN_SF; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Restoring Authorized Set "); - ulStatus = RestoreSFParam(Adapter, - (ULONG)pstAddIndication->psfAuthorizedSet, - (PUCHAR)&pstAddIndicationDest->sfAuthorizedSet); - if (ulStatus != 1) - goto failed_restore_sf_param; - - if (pstAddIndicationDest->sfAuthorizedSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF) - pstAddIndicationDest->sfAuthorizedSet.u8TotalClassifiers = - MAX_CLASSIFIERS_IN_SF; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Dumping the whole raw packet"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "============================================================"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - " pstAddIndicationDest->sfActiveSet size %zx %p", - sizeof(*pstAddIndicationDest), pstAddIndicationDest); - /* BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, CONN_MSG, - * DBG_LVL_ALL, (unsigned char *)pstAddIndicationDest, - * sizeof(*pstAddIndicationDest)); - */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "============================================================"); - return pstAddIndicationDest; -failed_restore_sf_param: - kfree(pstAddIndicationDest); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "<====="); - return NULL; -} - -ULONG SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter) -{ - ULONG ulTargetDsxBuffersBase = 0; - ULONG ulCntTargetBuffers; - ULONG i; - int Status; - - if (!Adapter) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Adapter was NULL!!!"); - return 0; - } - - if (Adapter->astTargetDsxBuffer[0].ulTargetDsxBuffer) - return 1; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Size of Each DSX Buffer(Also size of connection manager parameters): %zx ", - sizeof(struct bcm_connect_mgr_params)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Reading DSX buffer From Target location %x ", - DSX_MESSAGE_EXCHANGE_BUFFER); - - Status = rdmalt(Adapter, DSX_MESSAGE_EXCHANGE_BUFFER, - (PUINT)&ulTargetDsxBuffersBase, sizeof(UINT)); - if (Status < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "RDM failed!!"); - return 0; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Base Address Of DSX Target Buffer : 0x%lx", - ulTargetDsxBuffersBase); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Tgt Buffer is Now %lx :", ulTargetDsxBuffersBase); - ulCntTargetBuffers = DSX_MESSAGE_EXCHANGE_BUFFER_SIZE / - sizeof(struct bcm_connect_mgr_params); - - Adapter->ulTotalTargetBuffersAvailable = - ulCntTargetBuffers > MAX_TARGET_DSX_BUFFERS ? - MAX_TARGET_DSX_BUFFERS : ulCntTargetBuffers; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - " Total Target DSX Buffer setup %lx ", - Adapter->ulTotalTargetBuffersAvailable); - - for (i = 0; i < Adapter->ulTotalTargetBuffersAvailable; i++) { - Adapter->astTargetDsxBuffer[i].ulTargetDsxBuffer = ulTargetDsxBuffersBase; - Adapter->astTargetDsxBuffer[i].valid = 1; - Adapter->astTargetDsxBuffer[i].tid = 0; - ulTargetDsxBuffersBase += sizeof(struct bcm_connect_mgr_params); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " Target DSX Buffer %lx setup at 0x%lx", - i, Adapter->astTargetDsxBuffer[i].ulTargetDsxBuffer); - } - Adapter->ulCurrentTargetBuffer = 0; - Adapter->ulFreeTargetBufferCnt = Adapter->ulTotalTargetBuffersAvailable; - return 1; -} - -static ULONG GetNextTargetBufferLocation(struct bcm_mini_adapter *Adapter, - B_UINT16 tid) -{ - ULONG dsx_buf; - ULONG idx, max_try; - - if ((Adapter->ulTotalTargetBuffersAvailable == 0) - || (Adapter->ulFreeTargetBufferCnt == 0)) { - ClearTargetDSXBuffer(Adapter, tid, false); - return 0; - } - - idx = Adapter->ulCurrentTargetBuffer; - max_try = Adapter->ulTotalTargetBuffersAvailable; - while ((max_try) && (Adapter->astTargetDsxBuffer[idx].valid != 1)) { - idx = (idx+1) % Adapter->ulTotalTargetBuffersAvailable; - max_try--; - } - - if (max_try == 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, - "\n GetNextTargetBufferLocation : Error No Free Target DSX Buffers FreeCnt : %lx ", - Adapter->ulFreeTargetBufferCnt); - ClearTargetDSXBuffer(Adapter, tid, false); - return 0; - } - - dsx_buf = Adapter->astTargetDsxBuffer[idx].ulTargetDsxBuffer; - Adapter->astTargetDsxBuffer[idx].valid = 0; - Adapter->astTargetDsxBuffer[idx].tid = tid; - Adapter->ulFreeTargetBufferCnt--; - idx = (idx+1)%Adapter->ulTotalTargetBuffersAvailable; - Adapter->ulCurrentTargetBuffer = idx; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, - "GetNextTargetBufferLocation :Returning address %lx tid %d\n", - dsx_buf, tid); - - return dsx_buf; -} - -int AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter) -{ - /* - * Need to Allocate memory to contain the SUPER Large structures - * Our driver can't create these structures on Stack - */ - Adapter->caDsxReqResp = kmalloc(sizeof(struct bcm_add_indication_alt) - + LEADER_SIZE, GFP_KERNEL); - if (!Adapter->caDsxReqResp) - return -ENOMEM; - - return 0; -} - -int FreeAdapterDsxBuffer(struct bcm_mini_adapter *Adapter) -{ - kfree(Adapter->caDsxReqResp); - return 0; -} - -/* - * @ingroup ctrl_pkt_functions - * This routinue would process the Control responses - * for the Connection Management. - * @return - Queue index for the free SFID else returns Invalid Index. - */ -bool CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* <Pointer to the Adapter structure */ - PVOID pvBuffer /* Starting Address of the Buffer, that contains the AddIndication Data */) -{ - struct bcm_connect_mgr_params *psfLocalSet = NULL; - struct bcm_add_indication_alt *pstAddIndication = NULL; - struct bcm_change_indication *pstChangeIndication = NULL; - struct bcm_leader *pLeader = NULL; - INT uiSearchRuleIndex = 0; - ULONG ulSFID; - - /* - * Otherwise the message contains a target address from where we need to - * read out the rest of the service flow param structure - */ - pstAddIndication = RestoreCmControlResponseMessage(Adapter, pvBuffer); - if (pstAddIndication == NULL) { - ClearTargetDSXBuffer(Adapter, ((struct bcm_add_indication *)pvBuffer)->u16TID, false); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Error in restoring Service Flow param structure from DSx message"); - return false; - } - - DumpCmControlPacket(pstAddIndication); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "====>"); - pLeader = (struct bcm_leader *)Adapter->caDsxReqResp; - - pLeader->Status = CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ; - pLeader->Vcid = 0; - - ClearTargetDSXBuffer(Adapter, pstAddIndication->u16TID, false); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "### TID RECEIVED %d\n", pstAddIndication->u16TID); - switch (pstAddIndication->u8Type) { - case DSA_REQ: - pLeader->PLength = sizeof(struct bcm_add_indication_alt); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Sending DSA Response....\n"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA RESPONSE TO MAC %d", pLeader->PLength); - *((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE])) - = *pstAddIndication; - ((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_RSP; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " VCID = %x", ntohs(pstAddIndication->u16VCID)); - CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp); - kfree(pstAddIndication); - break; - case DSA_RSP: - pLeader->PLength = sizeof(struct bcm_add_indication_alt); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA ACK TO MAC %d", - pLeader->PLength); - *((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE])) - = *pstAddIndication; - ((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_ACK; - /* FALLTHROUGH */ - case DSA_ACK: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "VCID:0x%X", - ntohs(pstAddIndication->u16VCID)); - uiSearchRuleIndex = SearchFreeSfid(Adapter); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "uiSearchRuleIndex:0x%X ", - uiSearchRuleIndex); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Direction:0x%X ", - pstAddIndication->u8Direction); - if (uiSearchRuleIndex < NO_OF_QUEUES) { - Adapter->PackInfo[uiSearchRuleIndex].ucDirection = - pstAddIndication->u8Direction; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "bValid:0x%X ", - pstAddIndication->sfActiveSet.bValid); - if (pstAddIndication->sfActiveSet.bValid == TRUE) - Adapter->PackInfo[uiSearchRuleIndex].bActiveSet = TRUE; - - if (pstAddIndication->sfAuthorizedSet.bValid == TRUE) - Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet = TRUE; - - if (pstAddIndication->sfAdmittedSet.bValid == TRUE) - Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet = TRUE; - - if (pstAddIndication->sfActiveSet.bValid == false) { - Adapter->PackInfo[uiSearchRuleIndex].bActive = false; - Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = false; - if (pstAddIndication->sfAdmittedSet.bValid) - psfLocalSet = &pstAddIndication->sfAdmittedSet; - else if (pstAddIndication->sfAuthorizedSet.bValid) - psfLocalSet = &pstAddIndication->sfAuthorizedSet; - } else { - psfLocalSet = &pstAddIndication->sfActiveSet; - Adapter->PackInfo[uiSearchRuleIndex].bActive = TRUE; - } - - if (!psfLocalSet) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "No set is valid\n"); - Adapter->PackInfo[uiSearchRuleIndex].bActive = false; - Adapter->PackInfo[uiSearchRuleIndex].bValid = false; - Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = 0; - kfree(pstAddIndication); - } else if (psfLocalSet->bValid && (pstAddIndication->u8CC == 0)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSA ACK"); - Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = ntohs(pstAddIndication->u16VCID); - Adapter->PackInfo[uiSearchRuleIndex].usCID = ntohs(pstAddIndication->u16CID); - - if (UPLINK_DIR == pstAddIndication->u8Direction) - atomic_set(&Adapter->PackInfo[uiSearchRuleIndex].uiPerSFTxResourceCount, DEFAULT_PERSFCOUNT); - - CopyToAdapter(Adapter, psfLocalSet, uiSearchRuleIndex, DSA_ACK, pstAddIndication); - /* don't free pstAddIndication */ - - /* Inside CopyToAdapter, Sorting of all the SFs take place. - * Hence any access to the newly added SF through uiSearchRuleIndex is invalid. - * SHOULD BE STRICTLY AVOIDED. - */ - /* *(PULONG)(((PUCHAR)pvBuffer)+1)=psfLocalSet->u32SFID; */ - memcpy((((PUCHAR)pvBuffer)+1), &psfLocalSet->u32SFID, 4); - - if (pstAddIndication->sfActiveSet.bValid == TRUE) { - if (UPLINK_DIR == pstAddIndication->u8Direction) { - if (!Adapter->LinkUpStatus) { - netif_carrier_on(Adapter->dev); - netif_start_queue(Adapter->dev); - Adapter->LinkUpStatus = 1; - if (netif_msg_link(Adapter)) - pr_info(PFX "%s: link up\n", Adapter->dev->name); - atomic_set(&Adapter->TxPktAvail, 1); - wake_up(&Adapter->tx_packet_wait_queue); - Adapter->liTimeSinceLastNetEntry = get_seconds(); - } - } - } - } else { - Adapter->PackInfo[uiSearchRuleIndex].bActive = false; - Adapter->PackInfo[uiSearchRuleIndex].bValid = false; - Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = 0; - kfree(pstAddIndication); - } - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DSA ACK did not get valid SFID"); - kfree(pstAddIndication); - return false; - } - break; - case DSC_REQ: - pLeader->PLength = sizeof(struct bcm_change_indication); - pstChangeIndication = (struct bcm_change_indication *)pstAddIndication; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC RESPONSE TO MAC %d", pLeader->PLength); - - *((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication; - ((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_RSP; - - CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp); - kfree(pstAddIndication); - break; - case DSC_RSP: - pLeader->PLength = sizeof(struct bcm_change_indication); - pstChangeIndication = (struct bcm_change_indication *)pstAddIndication; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC ACK TO MAC %d", pLeader->PLength); - *((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication; - ((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_ACK; - /* FALLTHROUGH */ - case DSC_ACK: - pstChangeIndication = (struct bcm_change_indication *)pstAddIndication; - uiSearchRuleIndex = SearchSfid(Adapter, ntohl(pstChangeIndication->sfActiveSet.u32SFID)); - if (uiSearchRuleIndex > NO_OF_QUEUES-1) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "SF doesn't exist for which DSC_ACK is received"); - - if (uiSearchRuleIndex < NO_OF_QUEUES) { - Adapter->PackInfo[uiSearchRuleIndex].ucDirection = pstChangeIndication->u8Direction; - if (pstChangeIndication->sfActiveSet.bValid == TRUE) - Adapter->PackInfo[uiSearchRuleIndex].bActiveSet = TRUE; - - if (pstChangeIndication->sfAuthorizedSet.bValid == TRUE) - Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet = TRUE; - - if (pstChangeIndication->sfAdmittedSet.bValid == TRUE) - Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet = TRUE; - - if (pstChangeIndication->sfActiveSet.bValid == false) { - Adapter->PackInfo[uiSearchRuleIndex].bActive = false; - Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = false; - - if (pstChangeIndication->sfAdmittedSet.bValid) - psfLocalSet = &pstChangeIndication->sfAdmittedSet; - else if (pstChangeIndication->sfAuthorizedSet.bValid) - psfLocalSet = &pstChangeIndication->sfAuthorizedSet; - } else { - psfLocalSet = &pstChangeIndication->sfActiveSet; - Adapter->PackInfo[uiSearchRuleIndex].bActive = TRUE; - } - - if (!psfLocalSet) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "No set is valid\n"); - Adapter->PackInfo[uiSearchRuleIndex].bActive = false; - Adapter->PackInfo[uiSearchRuleIndex].bValid = false; - Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = 0; - kfree(pstAddIndication); - } else if (psfLocalSet->bValid && (pstChangeIndication->u8CC == 0)) { - Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = ntohs(pstChangeIndication->u16VCID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "CC field is %d bvalid = %d\n", - pstChangeIndication->u8CC, psfLocalSet->bValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "VCID= %d\n", ntohs(pstChangeIndication->u16VCID)); - Adapter->PackInfo[uiSearchRuleIndex].usCID = ntohs(pstChangeIndication->u16CID); - CopyToAdapter(Adapter, psfLocalSet, uiSearchRuleIndex, DSC_ACK, pstAddIndication); - - *(PULONG)(((PUCHAR)pvBuffer)+1) = psfLocalSet->u32SFID; - } else if (pstChangeIndication->u8CC == 6) { - deleteSFBySfid(Adapter, uiSearchRuleIndex); - kfree(pstAddIndication); - } - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DSC ACK did not get valid SFID"); - kfree(pstAddIndication); - return false; - } - break; - case DSD_REQ: - pLeader->PLength = sizeof(struct bcm_del_indication); - *((struct bcm_del_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *((struct bcm_del_indication *)pstAddIndication); - - ulSFID = ntohl(((struct bcm_del_indication *)pstAddIndication)->u32SFID); - uiSearchRuleIndex = SearchSfid(Adapter, ulSFID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD - Removing connection %x", uiSearchRuleIndex); - - if (uiSearchRuleIndex < NO_OF_QUEUES) { - /* Delete All Classifiers Associated with this SFID */ - deleteSFBySfid(Adapter, uiSearchRuleIndex); - Adapter->u32TotalDSD++; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSD RESPONSE TO MAC"); - ((struct bcm_del_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSD_RSP; - CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp); - /* FALLTHROUGH */ - case DSD_RSP: - /* Do nothing as SF has already got Deleted */ - break; - case DSD_ACK: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD ACK Rcd, let App handle it\n"); - break; - default: - kfree(pstAddIndication); - return false; - } - return TRUE; -} - -int get_dsx_sf_data_to_application(struct bcm_mini_adapter *Adapter, - UINT uiSFId, void __user *user_buffer) -{ - int status = 0; - struct bcm_packet_info *psSfInfo = NULL; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "status =%d", status); - status = SearchSfid(Adapter, uiSFId); - if (status >= NO_OF_QUEUES) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "SFID %d not present in queue !!!", uiSFId); - return -EINVAL; - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "status =%d", status); - psSfInfo = &Adapter->PackInfo[status]; - if (psSfInfo->pstSFIndication - && copy_to_user(user_buffer, psSfInfo->pstSFIndication, - sizeof(struct bcm_add_indication_alt))) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, - "copy to user failed SFID %d, present in queue !!!", - uiSFId); - status = -EFAULT; - return status; - } - return STATUS_SUCCESS; -} - -VOID OverrideServiceFlowParams(struct bcm_mini_adapter *Adapter, - PUINT puiBuffer) -{ - B_UINT32 u32NumofSFsinMsg = ntohl(*(puiBuffer + 1)); - struct bcm_stim_sfhostnotify *pHostInfo = NULL; - UINT uiSearchRuleIndex = 0; - ULONG ulSFID = 0; - - puiBuffer += 2; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "u32NumofSFsinMsg: 0x%x\n", u32NumofSFsinMsg); - - while (u32NumofSFsinMsg != 0 && u32NumofSFsinMsg < NO_OF_QUEUES) { - u32NumofSFsinMsg--; - pHostInfo = (struct bcm_stim_sfhostnotify *)puiBuffer; - puiBuffer = (PUINT)(pHostInfo + 1); - - ulSFID = ntohl(pHostInfo->SFID); - uiSearchRuleIndex = SearchSfid(Adapter, ulSFID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "SFID: 0x%lx\n", ulSFID); - - if (uiSearchRuleIndex >= NO_OF_QUEUES - || uiSearchRuleIndex == HiPriority) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, - DBG_LVL_ALL, - "The SFID <%lx> doesn't exist in host entry or is Invalid\n", - ulSFID); - continue; - } - - if (pHostInfo->RetainSF == false) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, - DBG_LVL_ALL, "Going to Delete SF"); - deleteSFBySfid(Adapter, uiSearchRuleIndex); - } else { - struct bcm_packet_info *packinfo = - &Adapter->PackInfo[uiSearchRuleIndex]; - - packinfo->usVCID_Value = ntohs(pHostInfo->VCID); - packinfo->usCID = ntohs(pHostInfo->newCID); - packinfo->bActive = false; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, - DBG_LVL_ALL, - "pHostInfo->QoSParamSet: 0x%x\n", - pHostInfo->QoSParamSet); - - if (pHostInfo->QoSParamSet & 0x1) - packinfo->bAuthorizedSet = TRUE; - if (pHostInfo->QoSParamSet & 0x2) - packinfo->bAdmittedSet = TRUE; - if (pHostInfo->QoSParamSet & 0x4) { - packinfo->bActiveSet = TRUE; - packinfo->bActive = TRUE; - } - } - } -} - -static void restore_endianess_of_pstClassifierEntry( - struct bcm_classifier_rule *pstClassifierEntry, - enum bcm_ipaddr_context eIpAddrContext) -{ - int i; - union u_ip_address *stSrc = &pstClassifierEntry->stSrcIpAddress; - union u_ip_address *stDest = &pstClassifierEntry->stDestIpAddress; - - for (i = 0; i < MAX_IP_RANGE_LENGTH * 4; i++) { - if (eIpAddrContext == eSrcIpAddress) { - stSrc->ulIpv6Addr[i] = ntohl(stSrc->ulIpv6Addr[i]); - stSrc->ulIpv6Mask[i] = ntohl(stSrc->ulIpv6Mask[i]); - } else if (eIpAddrContext == eDestIpAddress) { - stDest->ulIpv6Addr[i] = ntohl(stDest->ulIpv6Addr[i]); - stDest->ulIpv6Mask[i] = ntohl(stDest->ulIpv6Mask[i]); - } - } -} - -static void apply_phs_rule_to_all_classifiers( - register struct bcm_mini_adapter *Adapter, /* <Pointer to the Adapter structure */ - register UINT uiSearchRuleIndex, /* <Index of Queue, to which this data belongs */ - USHORT uVCID, - struct bcm_phs_rule *sPhsRule, - struct bcm_phs_rules *cPhsRule, - struct bcm_add_indication_alt *pstAddIndication) -{ - unsigned int uiClassifierIndex = 0; - struct bcm_classifier_rule *curr_classifier = NULL; - - if (pstAddIndication->u8Direction == UPLINK_DIR) { - for (uiClassifierIndex = 0; uiClassifierIndex < MAX_CLASSIFIERS; uiClassifierIndex++) { - curr_classifier = - &Adapter->astClassifierTable[uiClassifierIndex]; - if ((curr_classifier->bUsed) && - (curr_classifier->ulSFID == Adapter->PackInfo[uiSearchRuleIndex].ulSFID) && - (curr_classifier->u8AssociatedPHSI == cPhsRule->u8PHSI)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Adding PHS Rule For Classifier: 0x%x cPhsRule.u8PHSI: 0x%x\n", - curr_classifier->uiClassifierRuleIndex, - cPhsRule->u8PHSI); - /* Update The PHS Rule for this classifier as Associated PHSI id defined */ - - /* Copy the PHS Rule */ - sPhsRule->u8PHSI = cPhsRule->u8PHSI; - sPhsRule->u8PHSFLength = cPhsRule->u8PHSFLength; - sPhsRule->u8PHSMLength = cPhsRule->u8PHSMLength; - sPhsRule->u8PHSS = cPhsRule->u8PHSS; - sPhsRule->u8PHSV = cPhsRule->u8PHSV; - memcpy(sPhsRule->u8PHSF, cPhsRule->u8PHSF, MAX_PHS_LENGTHS); - memcpy(sPhsRule->u8PHSM, cPhsRule->u8PHSM, MAX_PHS_LENGTHS); - sPhsRule->u8RefCnt = 0; - sPhsRule->bUnclassifiedPHSRule = false; - sPhsRule->PHSModifiedBytes = 0; - sPhsRule->PHSModifiedNumPackets = 0; - sPhsRule->PHSErrorNumPackets = 0; - - /* bPHSRuleAssociated = TRUE; */ - /* Store The PHS Rule for this classifier */ - - PhsUpdateClassifierRule( - &Adapter->stBCMPhsContext, - uVCID, - curr_classifier->uiClassifierRuleIndex, - sPhsRule, - curr_classifier->u8AssociatedPHSI); - - /* Update PHS Rule For the Classifier */ - if (sPhsRule->u8PHSI) { - curr_classifier->u32PHSRuleID = sPhsRule->u8PHSI; - memcpy(&curr_classifier->sPhsRule, sPhsRule, sizeof(struct bcm_phs_rule)); - } - } - } - } else { - /* Error PHS Rule specified in signaling could not be applied to any classifier */ - - /* Copy the PHS Rule */ - sPhsRule->u8PHSI = cPhsRule->u8PHSI; - sPhsRule->u8PHSFLength = cPhsRule->u8PHSFLength; - sPhsRule->u8PHSMLength = cPhsRule->u8PHSMLength; - sPhsRule->u8PHSS = cPhsRule->u8PHSS; - sPhsRule->u8PHSV = cPhsRule->u8PHSV; - memcpy(sPhsRule->u8PHSF, cPhsRule->u8PHSF, MAX_PHS_LENGTHS); - memcpy(sPhsRule->u8PHSM, cPhsRule->u8PHSM, MAX_PHS_LENGTHS); - sPhsRule->u8RefCnt = 0; - sPhsRule->bUnclassifiedPHSRule = TRUE; - sPhsRule->PHSModifiedBytes = 0; - sPhsRule->PHSModifiedNumPackets = 0; - sPhsRule->PHSErrorNumPackets = 0; - /* Store The PHS Rule for this classifier */ - - /* - * Passing the argument u8PHSI instead of clsid. Because for DL with no classifier rule, - * clsid will be zero hence we can't have multiple PHS rules for the same SF. - * To support multiple PHS rule, passing u8PHSI. - */ - PhsUpdateClassifierRule( - &Adapter->stBCMPhsContext, - uVCID, - sPhsRule->u8PHSI, - sPhsRule, - sPhsRule->u8PHSI); - } -} diff --git a/drivers/staging/bcm/CmHost.h b/drivers/staging/bcm/CmHost.h deleted file mode 100644 index 0887d3f49e2f..000000000000 --- a/drivers/staging/bcm/CmHost.h +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************** - * (c) Beceem Communications Inc. - * All Rights Reserved - * - * file : CmHost.h - * author: Rajeev Tirumala - * date : September 8 , 2006 - * brief : Definitions for Connection Management Requests structure - * which we will use to setup our connection structures.Its high - * time we had a header file for CmHost.cpp to isolate the way - * f/w sends DSx messages and the way we interpret them in code. - * Revision History - * - * Date Author Version Description - * 08-Sep-06 Rajeev 0.1 Created - ***************************************************************************/ -#ifndef _CM_HOST_H -#define _CM_HOST_H - -#pragma once -#pragma pack(push, 4) - -#define DSX_MESSAGE_EXCHANGE_BUFFER 0xBF60AC84 /* This contains the pointer */ -#define DSX_MESSAGE_EXCHANGE_BUFFER_SIZE 72000 /* 24 K Bytes */ - -struct bcm_add_indication_alt { - u8 u8Type; - u8 u8Direction; - u16 u16TID; - u16 u16CID; - u16 u16VCID; - struct bcm_connect_mgr_params sfAuthorizedSet; - struct bcm_connect_mgr_params sfAdmittedSet; - struct bcm_connect_mgr_params sfActiveSet; - u8 u8CC; /* < Confirmation Code */ - u8 u8Padd; - u16 u16Padd; -}; - -struct bcm_change_indication { - u8 u8Type; - u8 u8Direction; - u16 u16TID; - u16 u16CID; - u16 u16VCID; - struct bcm_connect_mgr_params sfAuthorizedSet; - struct bcm_connect_mgr_params sfAdmittedSet; - struct bcm_connect_mgr_params sfActiveSet; - u8 u8CC; /* < Confirmation Code */ - u8 u8Padd; - u16 u16Padd; -}; - -unsigned long StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, void *pvBuffer, unsigned int *puBufferLength); -int AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter); -int FreeAdapterDsxBuffer(struct bcm_mini_adapter *Adapter); -unsigned long SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter); -bool CmControlResponseMessage(struct bcm_mini_adapter *Adapter, void *pvBuffer); - -#pragma pack(pop) - -#endif diff --git a/drivers/staging/bcm/DDRInit.c b/drivers/staging/bcm/DDRInit.c deleted file mode 100644 index 4226c931cd45..000000000000 --- a/drivers/staging/bcm/DDRInit.c +++ /dev/null @@ -1,1355 +0,0 @@ -#include "headers.h" - - - -#define DDR_DUMP_INTERNAL_DEVICE_MEMORY 0xBFC02B00 -#define MIPS_CLOCK_REG 0x0f000820 - -/* DDR INIT-133Mhz */ -#define T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 12 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3_DDRSetting133MHz[] = { - /* DPLL Clock Setting */ - {0x0F000800, 0x00007212}, - {0x0f000820, 0x07F13FFF}, - {0x0f000810, 0x00000F95}, - {0x0f000860, 0x00000000}, - {0x0f000880, 0x000003DD}, - /* Changed source for X-bar and MIPS clock to APLL */ - {0x0f000840, 0x0FFF1B00}, - {0x0f000870, 0x00000002}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0F00a084, 0x1Cffffff}, - {0x0F00a080, 0x1C000000}, - {0x0F00a04C, 0x0000000C}, - /* Memcontroller Default values */ - {0x0F007000, 0x00010001}, - {0x0F007004, 0x01010100}, - {0x0F007008, 0x01000001}, - {0x0F00700c, 0x00000000}, - {0x0F007010, 0x01000000}, - {0x0F007014, 0x01000100}, - {0x0F007018, 0x01000000}, - {0x0F00701c, 0x01020001}, - {0x0F007020, 0x04030107}, - {0x0F007024, 0x02000007}, - {0x0F007028, 0x02020202}, - {0x0F00702c, 0x0206060a}, - {0x0F007030, 0x05000000}, - {0x0F007034, 0x00000003}, - {0x0F007038, 0x110a0200}, - {0x0F00703C, 0x02101010}, - {0x0F007040, 0x45751200}, - {0x0F007044, 0x110a0d00}, - {0x0F007048, 0x081b0306}, - {0x0F00704c, 0x00000000}, - {0x0F007050, 0x0000001c}, - {0x0F007054, 0x00000000}, - {0x0F007058, 0x00000000}, - {0x0F00705c, 0x00000000}, - {0x0F007060, 0x0010246c}, - {0x0F007064, 0x00000010}, - {0x0F007068, 0x00000000}, - {0x0F00706c, 0x00000001}, - {0x0F007070, 0x00007000}, - {0x0F007074, 0x00000000}, - {0x0F007078, 0x00000000}, - {0x0F00707C, 0x00000000}, - {0x0F007080, 0x00000000}, - {0x0F007084, 0x00000000}, - /* Enable BW improvement within memory controller */ - {0x0F007094, 0x00000104}, - /* Enable 2 ports within X-bar */ - {0x0F00A000, 0x00000016}, - /* Enable start bit within memory controller */ - {0x0F007018, 0x01010000} -}; -/* 80Mhz */ -#define T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 10 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3_DDRSetting80MHz[] = { - /* DPLL Clock Setting */ - {0x0f000810, 0x00000F95}, - {0x0f000820, 0x07f1ffff}, - {0x0f000860, 0x00000000}, - {0x0f000880, 0x000003DD}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0F00a084, 0x1Cffffff}, - {0x0F00a080, 0x1C000000}, - {0x0F00a000, 0x00000016}, - {0x0F00a04C, 0x0000000C}, - /* Memcontroller Default values */ - {0x0F007000, 0x00010001}, - {0x0F007004, 0x01000000}, - {0x0F007008, 0x01000001}, - {0x0F00700c, 0x00000000}, - {0x0F007010, 0x01000000}, - {0x0F007014, 0x01000100}, - {0x0F007018, 0x01000000}, - {0x0F00701c, 0x01020000}, - {0x0F007020, 0x04020107}, - {0x0F007024, 0x00000007}, - {0x0F007028, 0x02020201}, - {0x0F00702c, 0x0204040a}, - {0x0F007030, 0x04000000}, - {0x0F007034, 0x00000002}, - {0x0F007038, 0x1F060200}, - {0x0F00703C, 0x1C22221F}, - {0x0F007040, 0x8A006600}, - {0x0F007044, 0x221a0800}, - {0x0F007048, 0x02690204}, - {0x0F00704c, 0x00000000}, - {0x0F007050, 0x0000001c}, - {0x0F007054, 0x00000000}, - {0x0F007058, 0x00000000}, - {0x0F00705c, 0x00000000}, - {0x0F007060, 0x000A15D6}, - {0x0F007064, 0x0000000A}, - {0x0F007068, 0x00000000}, - {0x0F00706c, 0x00000001}, - {0x0F007070, 0x00004000}, - {0x0F007074, 0x00000000}, - {0x0F007078, 0x00000000}, - {0x0F00707C, 0x00000000}, - {0x0F007080, 0x00000000}, - {0x0F007084, 0x00000000}, - {0x0F007094, 0x00000104}, - /* Enable start bit within memory controller */ - {0x0F007018, 0x01010000} -}; -/* 100Mhz */ -#define T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 13 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3_DDRSetting100MHz[] = { - /* DPLL Clock Setting */ - {0x0F000800, 0x00007008}, - {0x0f000810, 0x00000F95}, - {0x0f000820, 0x07F13E3F}, - {0x0f000860, 0x00000000}, - {0x0f000880, 0x000003DD}, - /* Changed source for X-bar and MIPS clock to APLL */ - {0x0f000840, 0x0FFF1B00}, - {0x0f000870, 0x00000002}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0F00a084, 0x1Cffffff}, - {0x0F00a080, 0x1C000000}, - {0x0F00a04C, 0x0000000C}, - /* Enable 2 ports within X-bar */ - {0x0F00A000, 0x00000016}, - /* Memcontroller Default values */ - {0x0F007000, 0x00010001}, - {0x0F007004, 0x01010100}, - {0x0F007008, 0x01000001}, - {0x0F00700c, 0x00000000}, - {0x0F007010, 0x01000000}, - {0x0F007014, 0x01000100}, - {0x0F007018, 0x01000000}, - {0x0F00701c, 0x01020001}, - {0x0F007020, 0x04020107}, - {0x0F007024, 0x00000007}, - {0x0F007028, 0x01020201}, - {0x0F00702c, 0x0204040A}, - {0x0F007030, 0x06000000}, - {0x0F007034, 0x00000004}, - {0x0F007038, 0x20080200}, - {0x0F00703C, 0x02030320}, - {0x0F007040, 0x6E7F1200}, - {0x0F007044, 0x01190A00}, - {0x0F007048, 0x06120305}, - {0x0F00704c, 0x00000000}, - {0x0F007050, 0x0000001C}, - {0x0F007054, 0x00000000}, - {0x0F007058, 0x00000000}, - {0x0F00705c, 0x00000000}, - {0x0F007060, 0x00082ED6}, - {0x0F007064, 0x0000000A}, - {0x0F007068, 0x00000000}, - {0x0F00706c, 0x00000001}, - {0x0F007070, 0x00005000}, - {0x0F007074, 0x00000000}, - {0x0F007078, 0x00000000}, - {0x0F00707C, 0x00000000}, - {0x0F007080, 0x00000000}, - {0x0F007084, 0x00000000}, - /* Enable BW improvement within memory controller */ - {0x0F007094, 0x00000104}, - /* Enable start bit within memory controller */ - {0x0F007018, 0x01010000} -}; - -/* Net T3B DDR Settings - * DDR INIT-133Mhz - */ -static struct bcm_ddr_setting asDPLL_266MHZ[] = { - {0x0F000800, 0x00007212}, - {0x0f000820, 0x07F13FFF}, - {0x0f000810, 0x00000F95}, - {0x0f000860, 0x00000000}, - {0x0f000880, 0x000003DD}, - /* Changed source for X-bar and MIPS clock to APLL */ - {0x0f000840, 0x0FFF1B00}, - {0x0f000870, 0x00000002} -}; - -#define T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 11 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3B_DDRSetting133MHz[] = { - /* DPLL Clock Setting */ - {0x0f000810, 0x00000F95}, - {0x0f000810, 0x00000F95}, - {0x0f000810, 0x00000F95}, - {0x0f000820, 0x07F13652}, - {0x0f000840, 0x0FFF0800}, - /* Changed source for X-bar and MIPS clock to APLL */ - {0x0f000880, 0x000003DD}, - {0x0f000860, 0x00000000}, - /* Changed source for X-bar and MIPS clock to APLL */ - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0F00a084, 0x1Cffffff}, - {0x0F00a080, 0x1C000000}, - /* Enable 2 ports within X-bar */ - {0x0F00A000, 0x00000016}, - /* Memcontroller Default values */ - {0x0F007000, 0x00010001}, - {0x0F007004, 0x01010100}, - {0x0F007008, 0x01000001}, - {0x0F00700c, 0x00000000}, - {0x0F007010, 0x01000000}, - {0x0F007014, 0x01000100}, - {0x0F007018, 0x01000000}, - {0x0F00701c, 0x01020001}, - {0x0F007020, 0x04030107}, - {0x0F007024, 0x02000007}, - {0x0F007028, 0x02020202}, - {0x0F00702c, 0x0206060a}, - {0x0F007030, 0x05000000}, - {0x0F007034, 0x00000003}, - {0x0F007038, 0x130a0200}, - {0x0F00703C, 0x02101012}, - {0x0F007040, 0x457D1200}, - {0x0F007044, 0x11130d00}, - {0x0F007048, 0x040D0306}, - {0x0F00704c, 0x00000000}, - {0x0F007050, 0x0000001c}, - {0x0F007054, 0x00000000}, - {0x0F007058, 0x00000000}, - {0x0F00705c, 0x00000000}, - {0x0F007060, 0x0010246c}, - {0x0F007064, 0x00000012}, - {0x0F007068, 0x00000000}, - {0x0F00706c, 0x00000001}, - {0x0F007070, 0x00007000}, - {0x0F007074, 0x00000000}, - {0x0F007078, 0x00000000}, - {0x0F00707C, 0x00000000}, - {0x0F007080, 0x00000000}, - {0x0F007084, 0x00000000}, - /* Enable BW improvement within memory controller */ - {0x0F007094, 0x00000104}, - /* Enable start bit within memory controller */ - {0x0F007018, 0x01010000}, - }; - -#define T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 9 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3B_DDRSetting80MHz[] = { - /* DPLL Clock Setting */ - {0x0f000810, 0x00000F95}, - {0x0f000820, 0x07F13FFF}, - {0x0f000840, 0x0FFF1F00}, - {0x0f000880, 0x000003DD}, - {0x0f000860, 0x00000000}, - - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0F00a084, 0x1Cffffff}, - {0x0F00a080, 0x1C000000}, - {0x0F00a000, 0x00000016}, - /* Memcontroller Default values */ - {0x0F007000, 0x00010001}, - {0x0F007004, 0x01000000}, - {0x0F007008, 0x01000001}, - {0x0F00700c, 0x00000000}, - {0x0F007010, 0x01000000}, - {0x0F007014, 0x01000100}, - {0x0F007018, 0x01000000}, - {0x0F00701c, 0x01020000}, - {0x0F007020, 0x04020107}, - {0x0F007024, 0x00000007}, - {0x0F007028, 0x02020201}, - {0x0F00702c, 0x0204040a}, - {0x0F007030, 0x04000000}, - {0x0F007034, 0x02000002}, - {0x0F007038, 0x1F060202}, - {0x0F00703C, 0x1C22221F}, - {0x0F007040, 0x8A006600}, - {0x0F007044, 0x221a0800}, - {0x0F007048, 0x02690204}, - {0x0F00704c, 0x00000000}, - {0x0F007050, 0x0100001c}, - {0x0F007054, 0x00000000}, - {0x0F007058, 0x00000000}, - {0x0F00705c, 0x00000000}, - {0x0F007060, 0x000A15D6}, - {0x0F007064, 0x0000000A}, - {0x0F007068, 0x00000000}, - {0x0F00706c, 0x00000001}, - {0x0F007070, 0x00004000}, - {0x0F007074, 0x00000000}, - {0x0F007078, 0x00000000}, - {0x0F00707C, 0x00000000}, - {0x0F007080, 0x00000000}, - {0x0F007084, 0x00000000}, - {0x0F007094, 0x00000104}, - /* Enable start bit within memory controller */ - {0x0F007018, 0x01010000} -}; - -/* 100Mhz */ -#define T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 9 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3B_DDRSetting100MHz[] = { - /* DPLL Clock Setting */ - {0x0f000810, 0x00000F95}, - {0x0f000820, 0x07F1369B}, - {0x0f000840, 0x0FFF0800}, - {0x0f000880, 0x000003DD}, - {0x0f000860, 0x00000000}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0F00a084, 0x1Cffffff}, - {0x0F00a080, 0x1C000000}, - /* Enable 2 ports within X-bar */ - {0x0F00A000, 0x00000016}, - /* Memcontroller Default values */ - {0x0F007000, 0x00010001}, - {0x0F007004, 0x01010100}, - {0x0F007008, 0x01000001}, - {0x0F00700c, 0x00000000}, - {0x0F007010, 0x01000000}, - {0x0F007014, 0x01000100}, - {0x0F007018, 0x01000000}, - {0x0F00701c, 0x01020000}, - {0x0F007020, 0x04020107}, - {0x0F007024, 0x00000007}, - {0x0F007028, 0x01020201}, - {0x0F00702c, 0x0204040A}, - {0x0F007030, 0x06000000}, - {0x0F007034, 0x02000004}, - {0x0F007038, 0x20080200}, - {0x0F00703C, 0x02030320}, - {0x0F007040, 0x6E7F1200}, - {0x0F007044, 0x01190A00}, - {0x0F007048, 0x06120305}, - {0x0F00704c, 0x00000000}, - {0x0F007050, 0x0100001C}, - {0x0F007054, 0x00000000}, - {0x0F007058, 0x00000000}, - {0x0F00705c, 0x00000000}, - {0x0F007060, 0x00082ED6}, - {0x0F007064, 0x0000000A}, - {0x0F007068, 0x00000000}, - {0x0F00706c, 0x00000001}, - {0x0F007070, 0x00005000}, - {0x0F007074, 0x00000000}, - {0x0F007078, 0x00000000}, - {0x0F00707C, 0x00000000}, - {0x0F007080, 0x00000000}, - {0x0F007084, 0x00000000}, - /* Enable BW improvement within memory controller */ - {0x0F007094, 0x00000104}, - /* Enable start bit within memory controller */ - {0x0F007018, 0x01010000} -}; - - -#define T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 9 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3LP_DDRSetting133MHz[] = { - /* DPLL Clock Setting */ - {0x0f000820, 0x03F1365B}, - {0x0f000810, 0x00002F95}, - {0x0f000880, 0x000003DD}, - /* Changed source for X-bar and MIPS clock to APLL */ - {0x0f000840, 0x0FFF0000}, - {0x0f000860, 0x00000000}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0F00a084, 0x1Cffffff}, - {0x0F00a080, 0x1C000000}, - {0x0F00A000, 0x00000016}, - /* Memcontroller Default values */ - {0x0F007000, 0x00010001}, - {0x0F007004, 0x01010100}, - {0x0F007008, 0x01000001}, - {0x0F00700c, 0x00000000}, - {0x0F007010, 0x01000000}, - {0x0F007014, 0x01000100}, - {0x0F007018, 0x01000000}, - {0x0F00701c, 0x01020001}, - {0x0F007020, 0x04030107}, - {0x0F007024, 0x02000007}, - {0x0F007028, 0x02020200}, - {0x0F00702c, 0x0206060a}, - {0x0F007030, 0x05000000}, - {0x0F007034, 0x00000003}, - {0x0F007038, 0x200a0200}, - {0x0F00703C, 0x02101020}, - {0x0F007040, 0x45711200}, - {0x0F007044, 0x110D0D00}, - {0x0F007048, 0x04080306}, - {0x0F00704c, 0x00000000}, - {0x0F007050, 0x0100001c}, - {0x0F007054, 0x00000000}, - {0x0F007058, 0x00000000}, - {0x0F00705c, 0x00000000}, - {0x0F007060, 0x0010245F}, - {0x0F007064, 0x00000010}, - {0x0F007068, 0x00000000}, - {0x0F00706c, 0x00000001}, - {0x0F007070, 0x00007000}, - {0x0F007074, 0x00000000}, - {0x0F007078, 0x00000000}, - {0x0F00707C, 0x00000000}, - {0x0F007080, 0x00000000}, - {0x0F007084, 0x00000000}, - {0x0F007088, 0x01000001}, - {0x0F00708c, 0x00000101}, - {0x0F007090, 0x00000000}, - /* Enable BW improvement within memory controller */ - {0x0F007094, 0x00040000}, - {0x0F007098, 0x00000000}, - {0x0F0070c8, 0x00000104}, - /* Enable 2 ports within X-bar */ - /* Enable start bit within memory controller */ - {0x0F007018, 0x01010000} -}; - -#define T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 11 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3LP_DDRSetting100MHz[] = { - /* DPLL Clock Setting */ - {0x0f000810, 0x00002F95}, - {0x0f000820, 0x03F1369B}, - {0x0f000840, 0x0fff0000}, - {0x0f000860, 0x00000000}, - {0x0f000880, 0x000003DD}, - /* Changed source for X-bar and MIPS clock to APLL */ - {0x0f000840, 0x0FFF0000}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0F00a084, 0x1Cffffff}, - {0x0F00a080, 0x1C000000}, - /* Memcontroller Default values */ - {0x0F007000, 0x00010001}, - {0x0F007004, 0x01010100}, - {0x0F007008, 0x01000001}, - {0x0F00700c, 0x00000000}, - {0x0F007010, 0x01000000}, - {0x0F007014, 0x01000100}, - {0x0F007018, 0x01000000}, - {0x0F00701c, 0x01020000}, - {0x0F007020, 0x04020107}, - {0x0F007024, 0x00000007}, - {0x0F007028, 0x01020200}, - {0x0F00702c, 0x0204040a}, - {0x0F007030, 0x06000000}, - {0x0F007034, 0x00000004}, - {0x0F007038, 0x1F080200}, - {0x0F00703C, 0x0203031F}, - {0x0F007040, 0x6e001200}, - {0x0F007044, 0x011a0a00}, - {0x0F007048, 0x03000305}, - {0x0F00704c, 0x00000000}, - {0x0F007050, 0x0100001c}, - {0x0F007054, 0x00000000}, - {0x0F007058, 0x00000000}, - {0x0F00705c, 0x00000000}, - {0x0F007060, 0x00082ED6}, - {0x0F007064, 0x0000000A}, - {0x0F007068, 0x00000000}, - {0x0F00706c, 0x00000001}, - {0x0F007070, 0x00005000}, - {0x0F007074, 0x00000000}, - {0x0F007078, 0x00000000}, - {0x0F00707C, 0x00000000}, - {0x0F007080, 0x00000000}, - {0x0F007084, 0x00000000}, - {0x0F007088, 0x01000001}, - {0x0F00708c, 0x00000101}, - {0x0F007090, 0x00000000}, - {0x0F007094, 0x00010000}, - {0x0F007098, 0x00000000}, - {0x0F0070C8, 0x00000104}, - /* Enable 2 ports within X-bar */ - {0x0F00A000, 0x00000016}, - /* Enable start bit within memory controller */ - {0x0F007018, 0x01010000} -}; - -#define T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 9 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3LP_DDRSetting80MHz[] = { - /* DPLL Clock Setting */ - {0x0f000820, 0x07F13FFF}, - {0x0f000810, 0x00002F95}, - {0x0f000860, 0x00000000}, - {0x0f000880, 0x000003DD}, - {0x0f000840, 0x0FFF1F00}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0F00a084, 0x1Cffffff}, - {0x0F00a080, 0x1C000000}, - {0x0F00A000, 0x00000016}, - {0x0f007000, 0x00010001}, - {0x0f007004, 0x01000000}, - {0x0f007008, 0x01000001}, - {0x0f00700c, 0x00000000}, - {0x0f007010, 0x01000000}, - {0x0f007014, 0x01000100}, - {0x0f007018, 0x01000000}, - {0x0f00701c, 0x01020000}, - {0x0f007020, 0x04020107}, - {0x0f007024, 0x00000007}, - {0x0f007028, 0x02020200}, - {0x0f00702c, 0x0204040a}, - {0x0f007030, 0x04000000}, - {0x0f007034, 0x00000002}, - {0x0f007038, 0x1d060200}, - {0x0f00703c, 0x1c22221d}, - {0x0f007040, 0x8A116600}, - {0x0f007044, 0x222d0800}, - {0x0f007048, 0x02690204}, - {0x0f00704c, 0x00000000}, - {0x0f007050, 0x0100001c}, - {0x0f007054, 0x00000000}, - {0x0f007058, 0x00000000}, - {0x0f00705c, 0x00000000}, - {0x0f007060, 0x000A15D6}, - {0x0f007064, 0x0000000A}, - {0x0f007068, 0x00000000}, - {0x0f00706c, 0x00000001}, - {0x0f007070, 0x00004000}, - {0x0f007074, 0x00000000}, - {0x0f007078, 0x00000000}, - {0x0f00707c, 0x00000000}, - {0x0f007080, 0x00000000}, - {0x0f007084, 0x00000000}, - {0x0f007088, 0x01000001}, - {0x0f00708c, 0x00000101}, - {0x0f007090, 0x00000000}, - {0x0f007094, 0x00010000}, - {0x0f007098, 0x00000000}, - {0x0F0070C8, 0x00000104}, - {0x0F007018, 0x01010000} -}; - - - - -/* T3 LP-B (UMA-B) */ - -#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ 7 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3LPB_DDRSetting160MHz[] = { - /* DPLL Clock Setting */ - {0x0f000820, 0x03F137DB}, - {0x0f000810, 0x01842795}, - {0x0f000860, 0x00000000}, - {0x0f000880, 0x000003DD}, - {0x0f000840, 0x0FFF0400}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0f003050, 0x00000021}, /* this is flash/eeprom clock divisor which - * set the flash clock to 20 MHz */ - {0x0F00a084, 0x1Cffffff}, /* Now dump from her in internal memory */ - {0x0F00a080, 0x1C000000}, - {0x0F00A000, 0x00000016}, - {0x0f007000, 0x00010001}, - {0x0f007004, 0x01000001}, - {0x0f007008, 0x01000101}, - {0x0f00700c, 0x00000000}, - {0x0f007010, 0x01000100}, - {0x0f007014, 0x01000100}, - {0x0f007018, 0x01000000}, - {0x0f00701c, 0x01020000}, - {0x0f007020, 0x04030107}, - {0x0f007024, 0x02000007}, - {0x0f007028, 0x02020200}, - {0x0f00702c, 0x0206060a}, - {0x0f007030, 0x050d0d00}, - {0x0f007034, 0x00000003}, - {0x0f007038, 0x170a0200}, - {0x0f00703c, 0x02101012}, - {0x0f007040, 0x45161200}, - {0x0f007044, 0x11250c00}, - {0x0f007048, 0x04da0307}, - {0x0f00704c, 0x00000000}, - {0x0f007050, 0x0000001c}, - {0x0f007054, 0x00000000}, - {0x0f007058, 0x00000000}, - {0x0f00705c, 0x00000000}, - {0x0f007060, 0x00142bb6}, - {0x0f007064, 0x20430014}, - {0x0f007068, 0x00000000}, - {0x0f00706c, 0x00000001}, - {0x0f007070, 0x00009000}, - {0x0f007074, 0x00000000}, - {0x0f007078, 0x00000000}, - {0x0f00707c, 0x00000000}, - {0x0f007080, 0x00000000}, - {0x0f007084, 0x00000000}, - {0x0f007088, 0x01000001}, - {0x0f00708c, 0x00000101}, - {0x0f007090, 0x00000000}, - {0x0f007094, 0x00040000}, - {0x0f007098, 0x00000000}, - {0x0F0070C8, 0x00000104}, - {0x0F007018, 0x01010000} -}; - - -#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 7 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3LPB_DDRSetting133MHz[] = { - /* DPLL Clock Setting */ - {0x0f000820, 0x03F1365B}, - {0x0f000810, 0x00002F95}, - {0x0f000880, 0x000003DD}, - /* Changed source for X-bar and MIPS clock to APLL */ - {0x0f000840, 0x0FFF0000}, - {0x0f000860, 0x00000000}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0f003050, 0x00000021}, /* flash/eeprom clock divisor which - * set the flash clock to 20 MHz */ - {0x0F00a084, 0x1Cffffff}, /* dump from here in internal memory */ - {0x0F00a080, 0x1C000000}, - {0x0F00A000, 0x00000016}, - /* Memcontroller Default values */ - {0x0F007000, 0x00010001}, - {0x0F007004, 0x01010100}, - {0x0F007008, 0x01000001}, - {0x0F00700c, 0x00000000}, - {0x0F007010, 0x01000000}, - {0x0F007014, 0x01000100}, - {0x0F007018, 0x01000000}, - {0x0F00701c, 0x01020001}, - {0x0F007020, 0x04030107}, - {0x0F007024, 0x02000007}, - {0x0F007028, 0x02020200}, - {0x0F00702c, 0x0206060a}, - {0x0F007030, 0x05000000}, - {0x0F007034, 0x00000003}, - {0x0F007038, 0x190a0200}, - {0x0F00703C, 0x02101017}, - {0x0F007040, 0x45171200}, - {0x0F007044, 0x11290D00}, - {0x0F007048, 0x04080306}, - {0x0F00704c, 0x00000000}, - {0x0F007050, 0x0100001c}, - {0x0F007054, 0x00000000}, - {0x0F007058, 0x00000000}, - {0x0F00705c, 0x00000000}, - {0x0F007060, 0x0010245F}, - {0x0F007064, 0x00000010}, - {0x0F007068, 0x00000000}, - {0x0F00706c, 0x00000001}, - {0x0F007070, 0x00007000}, - {0x0F007074, 0x00000000}, - {0x0F007078, 0x00000000}, - {0x0F00707C, 0x00000000}, - {0x0F007080, 0x00000000}, - {0x0F007084, 0x00000000}, - {0x0F007088, 0x01000001}, - {0x0F00708c, 0x00000101}, - {0x0F007090, 0x00000000}, - /* Enable BW improvement within memory controller */ - {0x0F007094, 0x00040000}, - {0x0F007098, 0x00000000}, - {0x0F0070c8, 0x00000104}, - /* Enable 2 ports within X-bar */ - /* Enable start bit within memory controller */ - {0x0F007018, 0x01010000} -}; - -#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 8 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3LPB_DDRSetting100MHz[] = { - /* DPLL Clock Setting */ - {0x0f000810, 0x00002F95}, - {0x0f000820, 0x03F1369B}, - {0x0f000840, 0x0fff0000}, - {0x0f000860, 0x00000000}, - {0x0f000880, 0x000003DD}, - /* Changed source for X-bar and MIPS clock to APLL */ - {0x0f000840, 0x0FFF0000}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0f003050, 0x00000021}, /* flash/eeprom clock divisor which - * set the flash clock to 20 MHz */ - {0x0F00a084, 0x1Cffffff}, /* dump from here in internal memory */ - {0x0F00a080, 0x1C000000}, - /* Memcontroller Default values */ - {0x0F007000, 0x00010001}, - {0x0F007004, 0x01010100}, - {0x0F007008, 0x01000001}, - {0x0F00700c, 0x00000000}, - {0x0F007010, 0x01000000}, - {0x0F007014, 0x01000100}, - {0x0F007018, 0x01000000}, - {0x0F00701c, 0x01020000}, - {0x0F007020, 0x04020107}, - {0x0F007024, 0x00000007}, - {0x0F007028, 0x01020200}, - {0x0F00702c, 0x0204040a}, - {0x0F007030, 0x06000000}, - {0x0F007034, 0x00000004}, - {0x0F007038, 0x1F080200}, - {0x0F00703C, 0x0203031F}, - {0x0F007040, 0x6e001200}, - {0x0F007044, 0x011a0a00}, - {0x0F007048, 0x03000305}, - {0x0F00704c, 0x00000000}, - {0x0F007050, 0x0100001c}, - {0x0F007054, 0x00000000}, - {0x0F007058, 0x00000000}, - {0x0F00705c, 0x00000000}, - {0x0F007060, 0x00082ED6}, - {0x0F007064, 0x0000000A}, - {0x0F007068, 0x00000000}, - {0x0F00706c, 0x00000001}, - {0x0F007070, 0x00005000}, - {0x0F007074, 0x00000000}, - {0x0F007078, 0x00000000}, - {0x0F00707C, 0x00000000}, - {0x0F007080, 0x00000000}, - {0x0F007084, 0x00000000}, - {0x0F007088, 0x01000001}, - {0x0F00708c, 0x00000101}, - {0x0F007090, 0x00000000}, - {0x0F007094, 0x00010000}, - {0x0F007098, 0x00000000}, - {0x0F0070C8, 0x00000104}, - /* Enable 2 ports within X-bar */ - {0x0F00A000, 0x00000016}, - /* Enable start bit within memory controller */ - {0x0F007018, 0x01010000} -}; - -#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 7 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3LPB_DDRSetting80MHz[] = { - /* DPLL Clock Setting */ - {0x0f000820, 0x07F13FFF}, - {0x0f000810, 0x00002F95}, - {0x0f000860, 0x00000000}, - {0x0f000880, 0x000003DD}, - {0x0f000840, 0x0FFF1F00}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0f003050, 0x00000021}, /* flash/eeprom clock divisor - * which set the flash clock to 20 MHz */ - {0x0F00a084, 0x1Cffffff}, /* dump from here in internal memory */ - {0x0F00a080, 0x1C000000}, - {0x0F00A000, 0x00000016}, - {0x0f007000, 0x00010001}, - {0x0f007004, 0x01000000}, - {0x0f007008, 0x01000001}, - {0x0f00700c, 0x00000000}, - {0x0f007010, 0x01000000}, - {0x0f007014, 0x01000100}, - {0x0f007018, 0x01000000}, - {0x0f00701c, 0x01020000}, - {0x0f007020, 0x04020107}, - {0x0f007024, 0x00000007}, - {0x0f007028, 0x02020200}, - {0x0f00702c, 0x0204040a}, - {0x0f007030, 0x04000000}, - {0x0f007034, 0x00000002}, - {0x0f007038, 0x1d060200}, - {0x0f00703c, 0x1c22221d}, - {0x0f007040, 0x8A116600}, - {0x0f007044, 0x222d0800}, - {0x0f007048, 0x02690204}, - {0x0f00704c, 0x00000000}, - {0x0f007050, 0x0100001c}, - {0x0f007054, 0x00000000}, - {0x0f007058, 0x00000000}, - {0x0f00705c, 0x00000000}, - {0x0f007060, 0x000A15D6}, - {0x0f007064, 0x0000000A}, - {0x0f007068, 0x00000000}, - {0x0f00706c, 0x00000001}, - {0x0f007070, 0x00004000}, - {0x0f007074, 0x00000000}, - {0x0f007078, 0x00000000}, - {0x0f00707c, 0x00000000}, - {0x0f007080, 0x00000000}, - {0x0f007084, 0x00000000}, - {0x0f007088, 0x01000001}, - {0x0f00708c, 0x00000101}, - {0x0f007090, 0x00000000}, - {0x0f007094, 0x00010000}, - {0x0f007098, 0x00000000}, - {0x0F0070C8, 0x00000104}, - {0x0F007018, 0x01010000} -}; - - -int ddr_init(struct bcm_mini_adapter *Adapter) -{ - struct bcm_ddr_setting *psDDRSetting = NULL; - ULONG RegCount = 0; - UINT value = 0; - UINT uiResetValue = 0; - UINT uiClockSetting = 0; - int retval = STATUS_SUCCESS; - - switch (Adapter->chip_id) { - case 0xbece3200: - switch (Adapter->DDRSetting) { - case DDR_80_MHZ: - psDDRSetting = asT3LP_DDRSetting80MHz; - RegCount = (sizeof(asT3LP_DDRSetting80MHz) / - sizeof(struct bcm_ddr_setting)); - break; - case DDR_100_MHZ: - psDDRSetting = asT3LP_DDRSetting100MHz; - RegCount = (sizeof(asT3LP_DDRSetting100MHz) / - sizeof(struct bcm_ddr_setting)); - break; - case DDR_133_MHZ: - psDDRSetting = asT3LP_DDRSetting133MHz; - RegCount = (sizeof(asT3LP_DDRSetting133MHz) / - sizeof(struct bcm_ddr_setting)); - if (Adapter->bMipsConfig == MIPS_200_MHZ) - uiClockSetting = 0x03F13652; - else - uiClockSetting = 0x03F1365B; - break; - default: - return -EINVAL; - } - - break; - case T3LPB: - case BCS220_2: - case BCS220_2BC: - case BCS250_BC: - case BCS220_3: - /* Set bit 2 and bit 6 to 1 for BBIC 2mA drive - * (please check current value and additionally set these bits) - */ - if ((Adapter->chip_id != BCS220_2) && - (Adapter->chip_id != BCS220_2BC) && - (Adapter->chip_id != BCS220_3)) { - retval = rdmalt(Adapter, (UINT)0x0f000830, &uiResetValue, - sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, __LINE__); - return retval; - } - uiResetValue |= 0x44; - retval = wrmalt(Adapter, (UINT)0x0f000830, &uiResetValue, - sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, __LINE__); - return retval; - } - } - switch (Adapter->DDRSetting) { - - - - case DDR_80_MHZ: - psDDRSetting = asT3LPB_DDRSetting80MHz; - RegCount = (sizeof(asT3B_DDRSetting80MHz) / - sizeof(struct bcm_ddr_setting)); - break; - case DDR_100_MHZ: - psDDRSetting = asT3LPB_DDRSetting100MHz; - RegCount = (sizeof(asT3B_DDRSetting100MHz) / - sizeof(struct bcm_ddr_setting)); - break; - case DDR_133_MHZ: - psDDRSetting = asT3LPB_DDRSetting133MHz; - RegCount = (sizeof(asT3B_DDRSetting133MHz) / - sizeof(struct bcm_ddr_setting)); - - if (Adapter->bMipsConfig == MIPS_200_MHZ) - uiClockSetting = 0x03F13652; - else - uiClockSetting = 0x03F1365B; - break; - - case DDR_160_MHZ: - psDDRSetting = asT3LPB_DDRSetting160MHz; - RegCount = sizeof(asT3LPB_DDRSetting160MHz) / - sizeof(struct bcm_ddr_setting); - - if (Adapter->bMipsConfig == MIPS_200_MHZ) - uiClockSetting = 0x03F137D2; - else - uiClockSetting = 0x03F137DB; - } - break; - - case 0xbece0110: - case 0xbece0120: - case 0xbece0121: - case 0xbece0130: - case 0xbece0300: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, - "DDR Setting: %x\n", Adapter->DDRSetting); - switch (Adapter->DDRSetting) { - case DDR_80_MHZ: - psDDRSetting = asT3_DDRSetting80MHz; - RegCount = (sizeof(asT3_DDRSetting80MHz) / - sizeof(struct bcm_ddr_setting)); - break; - case DDR_100_MHZ: - psDDRSetting = asT3_DDRSetting100MHz; - RegCount = (sizeof(asT3_DDRSetting100MHz) / - sizeof(struct bcm_ddr_setting)); - break; - case DDR_133_MHZ: - psDDRSetting = asT3_DDRSetting133MHz; - RegCount = (sizeof(asT3_DDRSetting133MHz) / - sizeof(struct bcm_ddr_setting)); - break; - default: - return -EINVAL; - } - case 0xbece0310: - { - switch (Adapter->DDRSetting) { - case DDR_80_MHZ: - psDDRSetting = asT3B_DDRSetting80MHz; - RegCount = (sizeof(asT3B_DDRSetting80MHz) / - sizeof(struct bcm_ddr_setting)); - break; - case DDR_100_MHZ: - psDDRSetting = asT3B_DDRSetting100MHz; - RegCount = (sizeof(asT3B_DDRSetting100MHz) / - sizeof(struct bcm_ddr_setting)); - break; - case DDR_133_MHZ: - - /* 266Mhz PLL selected. */ - if (Adapter->bDPLLConfig == PLL_266_MHZ) { - memcpy(asT3B_DDRSetting133MHz, asDPLL_266MHZ, - sizeof(asDPLL_266MHZ)); - psDDRSetting = asT3B_DDRSetting133MHz; - RegCount = (sizeof(asT3B_DDRSetting133MHz) / - sizeof(struct bcm_ddr_setting)); - } else { - psDDRSetting = asT3B_DDRSetting133MHz; - RegCount = (sizeof(asT3B_DDRSetting133MHz) / - sizeof(struct bcm_ddr_setting)); - if (Adapter->bMipsConfig == MIPS_200_MHZ) - uiClockSetting = 0x07F13652; - else - uiClockSetting = 0x07F1365B; - } - break; - default: - return -EINVAL; - } - break; - - } - default: - return -EINVAL; - } - - value = 0; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, - "Register Count is =%lu\n", RegCount); - while (RegCount && !retval) { - if (uiClockSetting - && psDDRSetting->ulRegAddress == MIPS_CLOCK_REG) - value = uiClockSetting; - else - value = psDDRSetting->ulRegValue; - retval = wrmalt(Adapter, psDDRSetting->ulRegAddress, &value, - sizeof(value)); - if (STATUS_SUCCESS != retval) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, - "%s:%d\n", __func__, __LINE__); - break; - } - - RegCount--; - psDDRSetting++; - } - - if (Adapter->chip_id >= 0xbece3300) { - - mdelay(3); - if ((Adapter->chip_id != BCS220_2) && - (Adapter->chip_id != BCS220_2BC) && - (Adapter->chip_id != BCS220_3)) { - /* drive MDDR to half in case of UMA-B: */ - uiResetValue = 0x01010001; - retval = wrmalt(Adapter, (UINT)0x0F007018, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - uiResetValue = 0x00040020; - retval = wrmalt(Adapter, (UINT)0x0F007094, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - uiResetValue = 0x01020101; - retval = wrmalt(Adapter, (UINT)0x0F00701c, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - uiResetValue = 0x01010000; - retval = wrmalt(Adapter, (UINT)0x0F007018, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - } - mdelay(3); - - /* DC/DC standby change... - * This is to be done only for Hybrid PMU mode. - * with the current h/w there is no way to detect this. - * and since we dont have internal PMU lets do it under - * UMA-B chip id. we will change this when we will have - * internal PMU. - */ - if (Adapter->PmuMode == HYBRID_MODE_7C) { - retval = rdmalt(Adapter, (UINT)0x0f000c00, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - retval = rdmalt(Adapter, (UINT)0x0f000c00, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - uiResetValue = 0x1322a8; - retval = wrmalt(Adapter, (UINT)0x0f000d1c, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - retval = rdmalt(Adapter, (UINT)0x0f000c00, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - retval = rdmalt(Adapter, (UINT)0x0f000c00, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - uiResetValue = 0x132296; - retval = wrmalt(Adapter, (UINT)0x0f000d14, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - } else if (Adapter->PmuMode == HYBRID_MODE_6) { - - retval = rdmalt(Adapter, (UINT)0x0f000c00, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - retval = rdmalt(Adapter, (UINT)0x0f000c00, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - uiResetValue = 0x6003229a; - retval = wrmalt(Adapter, (UINT)0x0f000d14, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - retval = rdmalt(Adapter, (UINT)0x0f000c00, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - retval = rdmalt(Adapter, (UINT)0x0f000c00, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - uiResetValue = 0x1322a8; - retval = wrmalt(Adapter, (UINT)0x0f000d1c, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - } - - } - Adapter->bDDRInitDone = TRUE; - return retval; -} - -int download_ddr_settings(struct bcm_mini_adapter *Adapter) -{ - struct bcm_ddr_setting *psDDRSetting = NULL; - ULONG RegCount = 0; - unsigned long ul_ddr_setting_load_addr = - DDR_DUMP_INTERNAL_DEVICE_MEMORY; - UINT value = 0; - int retval = STATUS_SUCCESS; - bool bOverrideSelfRefresh = false; - - switch (Adapter->chip_id) { - case 0xbece3200: - switch (Adapter->DDRSetting) { - case DDR_80_MHZ: - psDDRSetting = asT3LP_DDRSetting80MHz; - RegCount = ARRAY_SIZE(asT3LP_DDRSetting80MHz); - RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; - psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; - break; - case DDR_100_MHZ: - psDDRSetting = asT3LP_DDRSetting100MHz; - RegCount = ARRAY_SIZE(asT3LP_DDRSetting100MHz); - RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; - psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; - break; - case DDR_133_MHZ: - bOverrideSelfRefresh = TRUE; - psDDRSetting = asT3LP_DDRSetting133MHz; - RegCount = ARRAY_SIZE(asT3LP_DDRSetting133MHz); - RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; - psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; - break; - default: - return -EINVAL; - } - break; - - case T3LPB: - case BCS220_2: - case BCS220_2BC: - case BCS250_BC: - case BCS220_3: - switch (Adapter->DDRSetting) { - case DDR_80_MHZ: - psDDRSetting = asT3LPB_DDRSetting80MHz; - RegCount = ARRAY_SIZE(asT3LPB_DDRSetting80MHz); - RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; - psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; - break; - case DDR_100_MHZ: - psDDRSetting = asT3LPB_DDRSetting100MHz; - RegCount = ARRAY_SIZE(asT3LPB_DDRSetting100MHz); - RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; - psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; - break; - case DDR_133_MHZ: - bOverrideSelfRefresh = TRUE; - psDDRSetting = asT3LPB_DDRSetting133MHz; - RegCount = ARRAY_SIZE(asT3LPB_DDRSetting133MHz); - RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; - psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; - break; - - case DDR_160_MHZ: - bOverrideSelfRefresh = TRUE; - psDDRSetting = asT3LPB_DDRSetting160MHz; - RegCount = ARRAY_SIZE(asT3LPB_DDRSetting160MHz); - RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ; - psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ; - - break; - default: - return -EINVAL; - } - break; - case 0xbece0300: - switch (Adapter->DDRSetting) { - case DDR_80_MHZ: - psDDRSetting = asT3_DDRSetting80MHz; - RegCount = ARRAY_SIZE(asT3_DDRSetting80MHz); - RegCount -= T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; - psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; - break; - case DDR_100_MHZ: - psDDRSetting = asT3_DDRSetting100MHz; - RegCount = ARRAY_SIZE(asT3_DDRSetting100MHz); - RegCount -= T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; - psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; - break; - case DDR_133_MHZ: - psDDRSetting = asT3_DDRSetting133MHz; - RegCount = ARRAY_SIZE(asT3_DDRSetting133MHz); - RegCount -= T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; - psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; - break; - default: - return -EINVAL; - } - break; - case 0xbece0310: - { - switch (Adapter->DDRSetting) { - case DDR_80_MHZ: - psDDRSetting = asT3B_DDRSetting80MHz; - RegCount = ARRAY_SIZE(asT3B_DDRSetting80MHz); - RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; - psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; - break; - case DDR_100_MHZ: - psDDRSetting = asT3B_DDRSetting100MHz; - RegCount = ARRAY_SIZE(asT3B_DDRSetting100MHz); - RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; - psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; - break; - case DDR_133_MHZ: - bOverrideSelfRefresh = TRUE; - psDDRSetting = asT3B_DDRSetting133MHz; - RegCount = ARRAY_SIZE(asT3B_DDRSetting133MHz); - RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; - psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; - break; - } - break; - } - default: - return -EINVAL; - } - /* total number of Register that has to be dumped */ - value = RegCount; - retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, - sizeof(value)); - if (retval) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, - "%s:%d\n", __func__, __LINE__); - - return retval; - } - ul_ddr_setting_load_addr += sizeof(ULONG); - /* signature */ - value = (0x1d1e0dd0); - retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, - sizeof(value)); - if (retval) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, - "%s:%d\n", __func__, __LINE__); - return retval; - } - - ul_ddr_setting_load_addr += sizeof(ULONG); - RegCount *= (sizeof(struct bcm_ddr_setting)/sizeof(ULONG)); - - while (RegCount && !retval) { - value = psDDRSetting->ulRegAddress; - retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, - sizeof(value)); - ul_ddr_setting_load_addr += sizeof(ULONG); - if (!retval) { - if (bOverrideSelfRefresh - && (psDDRSetting->ulRegAddress - == 0x0F007018)) - value = (psDDRSetting->ulRegValue | (1<<8)); - else - value = psDDRSetting->ulRegValue; - - if (STATUS_SUCCESS != wrmalt(Adapter, - ul_ddr_setting_load_addr, - &value, - sizeof(value))) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, - "%s:%d\n", __func__, __LINE__); - break; - } - } - ul_ddr_setting_load_addr += sizeof(ULONG); - RegCount--; - psDDRSetting++; - } - return retval; -} diff --git a/drivers/staging/bcm/DDRInit.h b/drivers/staging/bcm/DDRInit.h deleted file mode 100644 index b0196fce9255..000000000000 --- a/drivers/staging/bcm/DDRInit.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _DDR_INIT_H_ -#define _DDR_INIT_H_ - - - -int ddr_init(struct bcm_mini_adapter *psAdapter); -int download_ddr_settings(struct bcm_mini_adapter *psAdapter); - -#endif diff --git a/drivers/staging/bcm/Debug.h b/drivers/staging/bcm/Debug.h deleted file mode 100644 index 7b331215c1ac..000000000000 --- a/drivers/staging/bcm/Debug.h +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Debug.h - * - * Dynamic (runtime) debug framework implementation. - * -kaiwan. - */ -#ifndef _DEBUG_H -#define _DEBUG_H -#include <linux/string.h> -#define NONE 0xFFFF - -/* TYPE and SUBTYPE - * Define valid TYPE (or category or code-path, however you like to think of it) - * and SUBTYPE s. - * Type and SubType are treated as bitmasks. - */ -#define DBG_TYPE_INITEXIT (1 << 0) /* 1 */ -#define DBG_TYPE_TX (1 << 1) /* 2 */ -#define DBG_TYPE_RX (1 << 2) /* 4 */ -#define DBG_TYPE_OTHERS (1 << 3) /* 8 */ -#define NUMTYPES 4 - -/* -SUBTYPEs for TX : TYPE is DBG_TYPE_TX -----// - * Transmit.c ,Arp.c, LeakyBucket.c, And Qos.c - * total 17 macros - */ -/* Transmit.c */ -#define TX 1 -#define MP_SEND (TX << 0) -#define NEXT_SEND (TX << 1) -#define TX_FIFO (TX << 2) -#define TX_CONTROL (TX << 3) - -/* Arp.c */ -#define IP_ADDR (TX << 4) -#define ARP_REQ (TX << 5) -#define ARP_RESP (TX << 6) - -/* Leakybucket.c */ -#define TOKEN_COUNTS (TX << 8) -#define CHECK_TOKENS (TX << 9) -#define TX_PACKETS (TX << 10) -#define TIMER (TX << 11) - -/* Qos.c */ -#define QOS TX -#define QUEUE_INDEX (QOS << 12) -#define IPV4_DBG (QOS << 13) -#define IPV6_DBG (QOS << 14) -#define PRUNE_QUEUE (QOS << 15) -#define SEND_QUEUE (QOS << 16) - -/* TX_Misc */ -#define TX_OSAL_DBG (TX << 17) - -/* --SUBTYPEs for ------INIT & EXIT--------------------- - * ------------ TYPE is DBG_TYPE_INITEXIT -----// - * DriverEntry.c, bcmfwup.c, ChipDetectTask.c, HaltnReset.c, InterfaceDDR.c - */ -#define MP 1 -#define DRV_ENTRY (MP << 0) -#define MP_INIT (MP << 1) -#define READ_REG (MP << 3) -#define DISPATCH (MP << 2) -#define CLAIM_ADAP (MP << 4) -#define REG_IO_PORT (MP << 5) -#define INIT_DISP (MP << 6) -#define RX_INIT (MP << 7) - -/* -SUBTYPEs for --RX---------------------------------- - * ------------RX : TYPE is DBG_TYPE_RX -----// - * Receive.c - */ -#define RX 1 -#define RX_DPC (RX << 0) -#define RX_CTRL (RX << 3) -#define RX_DATA (RX << 4) -#define MP_RETURN (RX << 1) -#define LINK_MSG (RX << 2) - -/* -SUBTYPEs for ----OTHER ROUTINES------------------ - * ------------OTHERS : TYPE is DBG_TYPE_OTHER -----// - * HaltnReset,CheckForHang,PnP,Misc,CmHost - * total 12 macros - */ -#define OTHERS 1 -#define ISR OTHERS -#define MP_DPC (ISR << 0) - -/* HaltnReset.c */ -#define HALT OTHERS -#define MP_HALT (HALT << 1) -#define CHECK_HANG (HALT << 2) -#define MP_RESET (HALT << 3) -#define MP_SHUTDOWN (HALT << 4) - -/* pnp.c */ -#define PNP OTHERS -#define MP_PNP (PNP << 5) - -/* Misc.c */ -#define MISC OTHERS -#define DUMP_INFO (MISC << 6) -#define CLASSIFY (MISC << 7) -#define LINK_UP_MSG (MISC << 8) -#define CP_CTRL_PKT (MISC << 9) -#define DUMP_CONTROL (MISC << 10) -#define LED_DUMP_INFO (MISC << 11) - -/* CmHost.c */ -#define CMHOST OTHERS -#define SERIAL (OTHERS << 12) -#define IDLE_MODE (OTHERS << 13) -#define WRM (OTHERS << 14) -#define RDM (OTHERS << 15) - -/* TODO - put PHS_SEND in Tx PHS_RECEIVE in Rx path ? */ -#define PHS_SEND (OTHERS << 16) -#define PHS_RECEIVE (OTHERS << 17) -#define PHS_MODULE (OTHERS << 18) - -#define INTF_INIT (OTHERS << 19) -#define INTF_ERR (OTHERS << 20) -#define INTF_WARN (OTHERS << 21) -#define INTF_NORM (OTHERS << 22) - -#define IRP_COMPLETION (OTHERS << 23) -#define SF_DESCRIPTOR_CNTS (OTHERS << 24) -#define PHS_DISPATCH (OTHERS << 25) -#define OSAL_DBG (OTHERS << 26) -#define NVM_RW (OTHERS << 27) - -#define HOST_MIBS (OTHERS << 28) -#define CONN_MSG (CMHOST << 29) - -/* Debug level - * We have 8 debug levels, in (numerical) increasing order of verbosity. - * IMP: Currently implementing ONLY DBG_LVL_ALL , i.e. , all debug prints will - * appear (of course, iff global debug flag is ON and we match the Type and SubType). - * Finer granularity debug levels are currently not in use, although the feature exists. - * - * Another way to say this: - * All the debug prints currently have 'debug_level' set to DBG_LVL_ALL . - * You can compile-time change that to any of the below, if you wish to. However, as of now, there's - * no dynamic facility to have the userspace 'TestApp' set debug_level. Slated for future expansion. - */ -#define BCM_ALL 7 -#define BCM_LOW 6 -#define BCM_PRINT 5 -#define BCM_NORMAL 4 -#define BCM_MEDIUM 3 -#define BCM_SCREAM 2 -#define BCM_ERR 1 -/* Not meant for developer in debug prints. - * To be used to disable all prints by setting the DBG_LVL_CURR to this value - */ -#define BCM_NONE 0 - -/* The current driver logging level. - * Everything at this level and (numerically) lower (meaning higher prio) - * is logged. - * Replace 'BCM_ALL' in the DBG_LVL_CURR macro with the logging level desired. - * For eg. to set the logging level to 'errors only' use: - * #define DBG_LVL_CURR (BCM_ERR) - */ - -#define DBG_LVL_CURR (BCM_ALL) -#define DBG_LVL_ALL BCM_ALL - -/* ---Userspace mapping of Debug State. - * Delibrately matches that of the Windows driver.. - * The TestApp's ioctl passes this struct to us. - */ -struct bcm_user_debug_state { - unsigned int Subtype, Type; - unsigned int OnOff; -/* unsigned int debug_level; future expansion */ -} __packed; - -/* ---Kernel-space mapping of Debug State */ -struct bcm_debug_state { - unsigned int type; - /* A bitmap of 32 bits for Subtype per Type. - * Valid indexes in 'subtype' array are *only* 1,2,4 and 8, - * corresponding to valid Type values. Hence we use the 'Type' field - * as the index value, ignoring the array entries 0,3,5,6,7 ! - */ - unsigned int subtype[(NUMTYPES*2)+1]; - unsigned int debug_level; -}; -/* Instantiated in the Adapter structure - * We'll reuse the debug level parameter to include a bit (the MSB) to indicate whether or not - * we want the function's name printed. - */ -#define DBG_NO_FUNC_PRINT (1 << 31) -#define DBG_LVL_BITMASK 0xFF - -/* --- Only for direct printk's; "hidden" to API. */ -#define DBG_TYPE_PRINTK 3 - -#define BCM_DEBUG_PRINT(Adapter, Type, SubType, dbg_level, string, args...) \ - do { \ - if (DBG_TYPE_PRINTK == Type) \ - pr_info("%s:" string, __func__, ##args); \ - else if (Adapter && \ - (dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level && \ - (Type & Adapter->stDebugState.type) && \ - (SubType & Adapter->stDebugState.subtype[Type])) { \ - if (dbg_level & DBG_NO_FUNC_PRINT) \ - pr_debug("%s:\n", string); \ - else \ - pr_debug("%s:\n" string, __func__, ##args); \ - } \ - } while (0) - -#define BCM_DEBUG_PRINT_BUFFER(Adapter, Type, SubType, dbg_level, buffer, bufferlen) \ - do { \ - if (DBG_TYPE_PRINTK == Type || \ - (Adapter && \ - (dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level && \ - (Type & Adapter->stDebugState.type) && \ - (SubType & Adapter->stDebugState.subtype[Type]))) { \ - pr_debug("%s:\n", __func__); \ - print_hex_dump(KERN_DEBUG, " ", DUMP_PREFIX_OFFSET, \ - 16, 1, buffer, bufferlen, false); \ - } \ - } while (0) - -#define BCM_SHOW_DEBUG_BITMAP(Adapter) do { \ - int i; \ - for (i = 0; i < (NUMTYPES * 2) + 1; i++) { \ - if ((i == 1) || (i == 2) || (i == 4) || (i == 8)) { \ - /* CAUTION! Forcefully turn on ALL debug paths and subpaths! \ - * Adapter->stDebugState.subtype[i] = 0xffffffff; \ - */ \ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "subtype[%d] = 0x%08x\n", \ - i, Adapter->stDebugState.subtype[i]); \ - } \ - } \ -} while (0) - -#endif diff --git a/drivers/staging/bcm/HandleControlPacket.c b/drivers/staging/bcm/HandleControlPacket.c deleted file mode 100644 index dd5d138a6528..000000000000 --- a/drivers/staging/bcm/HandleControlPacket.c +++ /dev/null @@ -1,241 +0,0 @@ -/** - * @file HandleControlPacket.c - * This file contains the routines to deal with - * sending and receiving of control packets. - */ -#include "headers.h" - -/** - * When a control packet is received, analyze the - * "status" and call appropriate response function. - * Enqueue the control packet for Application. - * @return None - */ -static VOID handle_rx_control_packet(struct bcm_mini_adapter *Adapter, - struct sk_buff *skb) -{ - struct bcm_tarang_data *pTarang = NULL; - bool HighPriorityMessage = false; - struct sk_buff *newPacket = NULL; - CHAR cntrl_msg_mask_bit = 0; - bool drop_pkt_flag = TRUE; - USHORT usStatus = *(PUSHORT)(skb->data); - - if (netif_msg_pktdata(Adapter)) - print_hex_dump(KERN_DEBUG, PFX "rx control: ", DUMP_PREFIX_NONE, - 16, 1, skb->data, skb->len, 0); - - switch (usStatus) { - case CM_RESPONSES: /* 0xA0 */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, - DBG_LVL_ALL, - "MAC Version Seems to be Non Multi-Classifier, rejected by Driver"); - HighPriorityMessage = TRUE; - break; - case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP: - HighPriorityMessage = TRUE; - if (Adapter->LinkStatus == LINKUP_DONE) - CmControlResponseMessage(Adapter, - (skb->data + sizeof(USHORT))); - break; - case LINK_CONTROL_RESP: /* 0xA2 */ - case STATUS_RSP: /* 0xA1 */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, - DBG_LVL_ALL, "LINK_CONTROL_RESP"); - HighPriorityMessage = TRUE; - LinkControlResponseMessage(Adapter, - (skb->data + sizeof(USHORT))); - break; - case STATS_POINTER_RESP: /* 0xA6 */ - HighPriorityMessage = TRUE; - StatisticsResponse(Adapter, (skb->data + sizeof(USHORT))); - break; - case IDLE_MODE_STATUS: /* 0xA3 */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, - DBG_LVL_ALL, - "IDLE_MODE_STATUS Type Message Got from F/W"); - InterfaceIdleModeRespond(Adapter, (PUINT)(skb->data + - sizeof(USHORT))); - HighPriorityMessage = TRUE; - break; - - case AUTH_SS_HOST_MSG: - HighPriorityMessage = TRUE; - break; - - default: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, - DBG_LVL_ALL, "Got Default Response"); - /* Let the Application Deal with This Packet */ - break; - } - - /* Queue The Control Packet to The Application Queues */ - down(&Adapter->RxAppControlQueuelock); - - for (pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next) { - if (Adapter->device_removed) - break; - - drop_pkt_flag = TRUE; - /* - * There are cntrl msg from A0 to AC. It has been mapped to 0 to - * C bit in the cntrl mask. - * Also, by default AD to BF has been masked to the rest of the - * bits... which wil be ON by default. - * if mask bit is enable to particular pkt status, send it out - * to app else stop it. - */ - cntrl_msg_mask_bit = (usStatus & 0x1F); - /* - * printk("\ninew msg mask bit which is disable in mask:%X", - * cntrl_msg_mask_bit); - */ - if (pTarang->RxCntrlMsgBitMask & (1 << cntrl_msg_mask_bit)) - drop_pkt_flag = false; - - if ((drop_pkt_flag == TRUE) || - (pTarang->AppCtrlQueueLen > MAX_APP_QUEUE_LEN) - || ((pTarang->AppCtrlQueueLen > - MAX_APP_QUEUE_LEN / 2) && - (HighPriorityMessage == false))) { - /* - * Assumption:- - * 1. every tarang manages it own dropped pkt - * statitistics - * 2. Total packet dropped per tarang will be equal to - * the sum of all types of dropped pkt by that - * tarang only. - */ - struct bcm_mibs_dropped_cntrl_msg *msg = - &pTarang->stDroppedAppCntrlMsgs; - switch (*(PUSHORT)skb->data) { - case CM_RESPONSES: - msg->cm_responses++; - break; - case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP: - msg->cm_control_newdsx_multiclassifier_resp++; - break; - case LINK_CONTROL_RESP: - msg->link_control_resp++; - break; - case STATUS_RSP: - msg->status_rsp++; - break; - case STATS_POINTER_RESP: - msg->stats_pointer_resp++; - break; - case IDLE_MODE_STATUS: - msg->idle_mode_status++; - break; - case AUTH_SS_HOST_MSG: - msg->auth_ss_host_msg++; - break; - default: - msg->low_priority_message++; - break; - } - - continue; - } - - newPacket = skb_clone(skb, GFP_KERNEL); - if (!newPacket) - break; - ENQUEUEPACKET(pTarang->RxAppControlHead, - pTarang->RxAppControlTail, newPacket); - pTarang->AppCtrlQueueLen++; - } - up(&Adapter->RxAppControlQueuelock); - wake_up(&Adapter->process_read_wait_queue); - dev_kfree_skb(skb); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, - "After wake_up_interruptible"); -} - -/** - * @ingroup ctrl_pkt_functions - * Thread to handle control pkt reception - */ - -/* pointer to adapter object*/ -int control_packet_handler(struct bcm_mini_adapter *Adapter) -{ - struct sk_buff *ctrl_packet = NULL; - unsigned long flags = 0; - /* struct timeval tv; */ - /* int *puiBuffer = NULL; */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, - "Entering to make thread wait on control packet event!"); - while (1) { - wait_event_interruptible(Adapter->process_rx_cntrlpkt, - atomic_read(&Adapter->cntrlpktCnt) || - Adapter->bWakeUpDevice || - kthread_should_stop()); - - - if (kthread_should_stop()) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, - DBG_LVL_ALL, "Exiting\n"); - return 0; - } - if (TRUE == Adapter->bWakeUpDevice) { - Adapter->bWakeUpDevice = false; - if ((false == Adapter->bTriedToWakeUpFromlowPowerMode) - && ((TRUE == Adapter->IdleMode) || - (TRUE == Adapter->bShutStatus))) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - CP_CTRL_PKT, DBG_LVL_ALL, - "Calling InterfaceAbortIdlemode\n"); - /* - * Adapter->bTriedToWakeUpFromlowPowerMode - * = TRUE; - */ - InterfaceIdleModeWakeup(Adapter); - } - continue; - } - - while (atomic_read(&Adapter->cntrlpktCnt)) { - spin_lock_irqsave(&Adapter->control_queue_lock, flags); - ctrl_packet = Adapter->RxControlHead; - if (ctrl_packet) { - DEQUEUEPACKET(Adapter->RxControlHead, - Adapter->RxControlTail); - /* Adapter->RxControlHead=ctrl_packet->next; */ - } - - spin_unlock_irqrestore(&Adapter->control_queue_lock, - flags); - handle_rx_control_packet(Adapter, ctrl_packet); - atomic_dec(&Adapter->cntrlpktCnt); - } - - SetUpTargetDsxBuffers(Adapter); - } - return STATUS_SUCCESS; -} - -INT flushAllAppQ(void) -{ - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_tarang_data *pTarang = NULL; - struct sk_buff *PacketToDrop = NULL; - - for (pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next) { - while (pTarang->RxAppControlHead != NULL) { - PacketToDrop = pTarang->RxAppControlHead; - DEQUEUEPACKET(pTarang->RxAppControlHead, - pTarang->RxAppControlTail); - dev_kfree_skb(PacketToDrop); - } - pTarang->AppCtrlQueueLen = 0; - /* dropped contrl packet statistics also should be reset. */ - memset((PVOID)&pTarang->stDroppedAppCntrlMsgs, 0, - sizeof(struct bcm_mibs_dropped_cntrl_msg)); - - } - return STATUS_SUCCESS; -} - - diff --git a/drivers/staging/bcm/HostMIBSInterface.h b/drivers/staging/bcm/HostMIBSInterface.h deleted file mode 100644 index f922ac49b70e..000000000000 --- a/drivers/staging/bcm/HostMIBSInterface.h +++ /dev/null @@ -1,192 +0,0 @@ -#ifndef _HOST_MIBSINTERFACE_H -#define _HOST_MIBSINTERFACE_H - -/* - * Copyright (c) 2007 Beceem Communications Pvt. Ltd - * File Name: HostMIBSInterface.h - * Abstract: This file contains DS used by the Host to update the Host - * statistics used for the MIBS. - */ - -#define MIBS_MAX_CLASSIFIERS 100 -#define MIBS_MAX_PHSRULES 100 -#define MIBS_MAX_SERVICEFLOWS 17 -#define MIBS_MAX_IP_RANGE_LENGTH 4 -#define MIBS_MAX_PORT_RANGE 4 -#define MIBS_MAX_PROTOCOL_LENGTH 32 -#define MIBS_MAX_PHS_LENGTHS 255 -#define MIBS_IPV6_ADDRESS_SIZEINBYTES 0x10 -#define MIBS_IP_LENGTH_OF_ADDRESS 4 -#define MIBS_MAX_HIST_ENTRIES 12 -#define MIBS_PKTSIZEHIST_RANGE 128 - -union bcm_mibs_ip_addr { - struct { - /* Source Ip Address Range */ - unsigned long ulIpv4Addr[MIBS_MAX_IP_RANGE_LENGTH]; - /* Source Ip Mask Address Range */ - unsigned long ulIpv4Mask[MIBS_MAX_IP_RANGE_LENGTH]; - }; - struct { - /* Source Ip Address Range */ - unsigned long ulIpv6Addr[MIBS_MAX_IP_RANGE_LENGTH * 4]; - /* Source Ip Mask Address Range */ - unsigned long ulIpv6Mask[MIBS_MAX_IP_RANGE_LENGTH * 4]; - }; - struct { - unsigned char ucIpv4Address[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IP_LENGTH_OF_ADDRESS]; - unsigned char ucIpv4Mask[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IP_LENGTH_OF_ADDRESS]; - }; - struct { - unsigned char ucIpv6Address[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IPV6_ADDRESS_SIZEINBYTES]; - unsigned char ucIpv6Mask[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IPV6_ADDRESS_SIZEINBYTES]; - }; -}; - -struct bcm_mibs_host_info { - u64 GoodTransmits; - u64 GoodReceives; - /* this to keep track of the Tx and Rx MailBox Registers. */ - unsigned long NumDesUsed; - unsigned long CurrNumFreeDesc; - unsigned long PrevNumFreeDesc; - /* to keep track the no of byte received */ - unsigned long PrevNumRcevBytes; - unsigned long CurrNumRcevBytes; - /* QOS Related */ - unsigned long BEBucketSize; - unsigned long rtPSBucketSize; - unsigned long LastTxQueueIndex; - bool TxOutofDescriptors; - bool TimerActive; - u32 u32TotalDSD; - u32 aTxPktSizeHist[MIBS_MAX_HIST_ENTRIES]; - u32 aRxPktSizeHist[MIBS_MAX_HIST_ENTRIES]; -}; - -struct bcm_mibs_classifier_rule { - unsigned long ulSFID; - unsigned char ucReserved[2]; - u16 uiClassifierRuleIndex; - bool bUsed; - unsigned short usVCID_Value; - u8 u8ClassifierRulePriority; - union bcm_mibs_ip_addr stSrcIpAddress; - /* IP Source Address Length */ - unsigned char ucIPSourceAddressLength; - union bcm_mibs_ip_addr stDestIpAddress; - /* IP Destination Address Length */ - unsigned char ucIPDestinationAddressLength; - unsigned char ucIPTypeOfServiceLength; - unsigned char ucTosLow; - unsigned char ucTosHigh; - unsigned char ucTosMask; - unsigned char ucProtocolLength; - unsigned char ucProtocol[MIBS_MAX_PROTOCOL_LENGTH]; - unsigned short usSrcPortRangeLo[MIBS_MAX_PORT_RANGE]; - unsigned short usSrcPortRangeHi[MIBS_MAX_PORT_RANGE]; - unsigned char ucSrcPortRangeLength; - unsigned short usDestPortRangeLo[MIBS_MAX_PORT_RANGE]; - unsigned short usDestPortRangeHi[MIBS_MAX_PORT_RANGE]; - unsigned char ucDestPortRangeLength; - bool bProtocolValid; - bool bTOSValid; - bool bDestIpValid; - bool bSrcIpValid; - unsigned char ucDirection; - bool bIpv6Protocol; - u32 u32PHSRuleID; -}; - -struct bcm_mibs_phs_rule { - unsigned long ulSFID; - u8 u8PHSI; - u8 u8PHSFLength; - u8 u8PHSF[MIBS_MAX_PHS_LENGTHS]; - u8 u8PHSMLength; - u8 u8PHSM[MIBS_MAX_PHS_LENGTHS]; - u8 u8PHSS; - u8 u8PHSV; - u8 reserved[5]; - long PHSModifiedBytes; - unsigned long PHSModifiedNumPackets; - unsigned long PHSErrorNumPackets; -}; - -struct bcm_mibs_parameters { - u32 wmanIfSfid; - u32 wmanIfCmnCpsSfState; - u32 wmanIfCmnCpsMaxSustainedRate; - u32 wmanIfCmnCpsMaxTrafficBurst; - u32 wmanIfCmnCpsMinReservedRate; - u32 wmanIfCmnCpsToleratedJitter; - u32 wmanIfCmnCpsMaxLatency; - u32 wmanIfCmnCpsFixedVsVariableSduInd; - u32 wmanIfCmnCpsSduSize; - u32 wmanIfCmnCpsSfSchedulingType; - u32 wmanIfCmnCpsArqEnable; - u32 wmanIfCmnCpsArqWindowSize; - u32 wmanIfCmnCpsArqBlockLifetime; - u32 wmanIfCmnCpsArqSyncLossTimeout; - u32 wmanIfCmnCpsArqDeliverInOrder; - u32 wmanIfCmnCpsArqRxPurgeTimeout; - u32 wmanIfCmnCpsArqBlockSize; - u32 wmanIfCmnCpsMinRsvdTolerableRate; - u32 wmanIfCmnCpsReqTxPolicy; - u32 wmanIfCmnSfCsSpecification; - u32 wmanIfCmnCpsTargetSaid; -}; - -struct bcm_mibs_table { - unsigned long ulSFID; - unsigned short usVCID_Value; - unsigned int uiThreshold; - u8 u8TrafficPriority; - bool bValid; - bool bActive; - bool bActivateRequestSent; - u8 u8QueueType; - unsigned int uiMaxBucketSize; - unsigned int uiCurrentQueueDepthOnTarget; - unsigned int uiCurrentBytesOnHost; - unsigned int uiCurrentPacketsOnHost; - unsigned int uiDroppedCountBytes; - unsigned int uiDroppedCountPackets; - unsigned int uiSentBytes; - unsigned int uiSentPackets; - unsigned int uiCurrentDrainRate; - unsigned int uiThisPeriodSentBytes; - u64 liDrainCalculated; - unsigned int uiCurrentTokenCount; - u64 liLastUpdateTokenAt; - unsigned int uiMaxAllowedRate; - unsigned int NumOfPacketsSent; - unsigned char ucDirection; - unsigned short usCID; - struct bcm_mibs_parameters stMibsExtServiceFlowTable; - unsigned int uiCurrentRxRate; - unsigned int uiThisPeriodRxBytes; - unsigned int uiTotalRxBytes; - unsigned int uiTotalTxBytes; -}; - -struct bcm_mibs_dropped_cntrl_msg { - unsigned long cm_responses; - unsigned long cm_control_newdsx_multiclassifier_resp; - unsigned long link_control_resp; - unsigned long status_rsp; - unsigned long stats_pointer_resp; - unsigned long idle_mode_status; - unsigned long auth_ss_host_msg; - unsigned long low_priority_message; -}; - -struct bcm_host_stats_mibs { - struct bcm_mibs_host_info stHostInfo; - struct bcm_mibs_classifier_rule astClassifierTable[MIBS_MAX_CLASSIFIERS]; - struct bcm_mibs_table astSFtable[MIBS_MAX_SERVICEFLOWS]; - struct bcm_mibs_phs_rule astPhsRulesTable[MIBS_MAX_PHSRULES]; - struct bcm_mibs_dropped_cntrl_msg stDroppedAppCntrlMsgs; -}; - -#endif diff --git a/drivers/staging/bcm/IPv6Protocol.c b/drivers/staging/bcm/IPv6Protocol.c deleted file mode 100644 index 27f3f416f184..000000000000 --- a/drivers/staging/bcm/IPv6Protocol.c +++ /dev/null @@ -1,476 +0,0 @@ -#include "headers.h" - -static bool MatchSrcIpv6Address(struct bcm_classifier_rule *pstClassifierRule, - struct bcm_ipv6_hdr *pstIpv6Header); -static bool MatchDestIpv6Address(struct bcm_classifier_rule *pstClassifierRule, - struct bcm_ipv6_hdr *pstIpv6Header); -static VOID DumpIpv6Header(struct bcm_ipv6_hdr *pstIpv6Header); - -static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload, - UCHAR *pucNextHeader, bool *bParseDone, USHORT *pusPayloadLength) -{ - UCHAR *pucRetHeaderPtr = NULL; - UCHAR *pucPayloadPtr = NULL; - USHORT usNextHeaderOffset = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if ((ppucPayload == NULL) || (*pusPayloadLength == 0) || - (*bParseDone)) { - *bParseDone = TRUE; - return NULL; - } - - pucRetHeaderPtr = *ppucPayload; - pucPayloadPtr = *ppucPayload; - - if (!pucRetHeaderPtr || !pucPayloadPtr) { - *bParseDone = TRUE; - return NULL; - } - - /* Get the Nextt Header Type */ - *bParseDone = false; - - - switch (*pucNextHeader) { - case IPV6HDR_TYPE_HOPBYHOP: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, "\nIPv6 HopByHop Header"); - usNextHeaderOffset += sizeof(struct bcm_ipv6_options_hdr); - break; - - case IPV6HDR_TYPE_ROUTING: - { - struct bcm_ipv6_routing_hdr *pstIpv6RoutingHeader; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, "\nIPv6 Routing Header"); - pstIpv6RoutingHeader = - (struct bcm_ipv6_routing_hdr *)pucPayloadPtr; - usNextHeaderOffset += sizeof(struct bcm_ipv6_routing_hdr); - usNextHeaderOffset += pstIpv6RoutingHeader->ucNumAddresses * - IPV6_ADDRESS_SIZEINBYTES; - } - break; - - case IPV6HDR_TYPE_FRAGMENTATION: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, - "\nIPv6 Fragmentation Header"); - usNextHeaderOffset += sizeof(struct bcm_ipv6_fragment_hdr); - break; - - case IPV6HDR_TYPE_DESTOPTS: - { - struct bcm_ipv6_dest_options_hdr *pstIpv6DestOptsHdr = - (struct bcm_ipv6_dest_options_hdr *)pucPayloadPtr; - int nTotalOptions = pstIpv6DestOptsHdr->ucHdrExtLen; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, - "\nIPv6 DestOpts Header Header"); - usNextHeaderOffset += sizeof(struct bcm_ipv6_dest_options_hdr); - usNextHeaderOffset += nTotalOptions * - IPV6_DESTOPTS_HDR_OPTIONSIZE; - } - break; - - - case IPV6HDR_TYPE_AUTHENTICATION: - { - struct bcm_ipv6_authentication_hdr *pstIpv6AuthHdr = - (struct bcm_ipv6_authentication_hdr *)pucPayloadPtr; - int nHdrLen = pstIpv6AuthHdr->ucLength; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, - "\nIPv6 Authentication Header"); - usNextHeaderOffset += nHdrLen * 4; - } - break; - - case IPV6HDR_TYPE_ENCRYPTEDSECURITYPAYLOAD: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, - "\nIPv6 Encrypted Security Payload Header"); - *bParseDone = TRUE; - break; - - case IPV6_ICMP_HDR_TYPE: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, "\nICMP Header"); - *bParseDone = TRUE; - break; - - case TCP_HEADER_TYPE: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, "\nTCP Header"); - *bParseDone = TRUE; - break; - - case UDP_HEADER_TYPE: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, "\nUDP Header"); - *bParseDone = TRUE; - break; - - default: - *bParseDone = TRUE; - break; - } - - if (*bParseDone == false) { - if (*pusPayloadLength <= usNextHeaderOffset) { - *bParseDone = TRUE; - } else { - *pucNextHeader = *pucPayloadPtr; - pucPayloadPtr += usNextHeaderOffset; - (*pusPayloadLength) -= usNextHeaderOffset; - } - - } - - *ppucPayload = pucPayloadPtr; - return pucRetHeaderPtr; -} - - -static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort, - USHORT *pusDestPort, USHORT usPayloadLength, UCHAR ucNextHeader) -{ - UCHAR *pIpv6HdrScanContext = pucPayload; - bool bDone = false; - UCHAR ucHeaderType = 0; - UCHAR *pucNextHeader = NULL; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if (!pucPayload || (usPayloadLength == 0)) - return 0; - - *pusSrcPort = *pusDestPort = 0; - ucHeaderType = ucNextHeader; - while (!bDone) { - pucNextHeader = GetNextIPV6ChainedHeader(&pIpv6HdrScanContext, - &ucHeaderType, - &bDone, - &usPayloadLength); - if (bDone) { - if ((ucHeaderType == TCP_HEADER_TYPE) || - (ucHeaderType == UDP_HEADER_TYPE)) { - *pusSrcPort = *((PUSHORT)(pucNextHeader)); - *pusDestPort = *((PUSHORT)(pucNextHeader+2)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, - "\nProtocol Ports - Src Port :0x%x Dest Port : 0x%x", - ntohs(*pusSrcPort), - ntohs(*pusDestPort)); - } - break; - - } - } - return ucHeaderType; -} - - -/* - * Arg 1 struct bcm_mini_adapter *Adapter is a pointer ot the driver control - * structure - * Arg 2 PVOID pcIpHeader is a pointer to the IP header of the packet - */ -USHORT IpVersion6(struct bcm_mini_adapter *Adapter, PVOID pcIpHeader, - struct bcm_classifier_rule *pstClassifierRule) -{ - USHORT ushDestPort = 0; - USHORT ushSrcPort = 0; - UCHAR ucNextProtocolAboveIP = 0; - struct bcm_ipv6_hdr *pstIpv6Header = NULL; - bool bClassificationSucceed = false; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, "IpVersion6 ==========>\n"); - - pstIpv6Header = pcIpHeader; - - DumpIpv6Header(pstIpv6Header); - - /* - * Try to get the next higher layer protocol - * and the Ports Nos if TCP or UDP - */ - ucNextProtocolAboveIP = GetIpv6ProtocolPorts((UCHAR *)(pcIpHeader + - sizeof(struct bcm_ipv6_hdr)), - &ushSrcPort, - &ushDestPort, - pstIpv6Header->usPayloadLength, - pstIpv6Header->ucNextHeader); - - do { - if (pstClassifierRule->ucDirection == 0) { - /* - * cannot be processed for classification. - * it is a down link connection - */ - break; - } - - if (!pstClassifierRule->bIpv6Protocol) { - /* - * We are looking for Ipv6 Classifiers - * Lets ignore this classifier and try the next one - */ - break; - } - - bClassificationSucceed = MatchSrcIpv6Address(pstClassifierRule, - pstIpv6Header); - if (!bClassificationSucceed) - break; - - bClassificationSucceed = MatchDestIpv6Address(pstClassifierRule, - pstIpv6Header); - if (!bClassificationSucceed) - break; - - /* - * Match the protocol type. - * For IPv6 the next protocol at end of - * Chain of IPv6 prot headers - */ - bClassificationSucceed = MatchProtocol(pstClassifierRule, - ucNextProtocolAboveIP); - if (!bClassificationSucceed) - break; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, "\nIPv6 Protocol Matched"); - - if ((ucNextProtocolAboveIP == TCP_HEADER_TYPE) || - (ucNextProtocolAboveIP == UDP_HEADER_TYPE)) { - /* Match Src Port */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, "\nIPv6 Source Port:%x\n", - ntohs(ushSrcPort)); - bClassificationSucceed = MatchSrcPort(pstClassifierRule, - ntohs(ushSrcPort)); - if (!bClassificationSucceed) - break; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, "\nIPv6 Src Port Matched"); - - /* Match Dest Port */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, - "\nIPv6 Destination Port:%x\n", - ntohs(ushDestPort)); - bClassificationSucceed = MatchDestPort(pstClassifierRule, - ntohs(ushDestPort)); - if (!bClassificationSucceed) - break; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, - "\nIPv6 Dest Port Matched"); - } - } while (0); - - if (bClassificationSucceed == TRUE) { - INT iMatchedSFQueueIndex = 0; - - iMatchedSFQueueIndex = SearchSfid(Adapter, - pstClassifierRule->ulSFID); - if ((iMatchedSFQueueIndex >= NO_OF_QUEUES) || - (Adapter->PackInfo[iMatchedSFQueueIndex].bActive == false)) - bClassificationSucceed = false; - } - - return bClassificationSucceed; -} - - -static bool MatchSrcIpv6Address(struct bcm_classifier_rule *pstClassifierRule, - struct bcm_ipv6_hdr *pstIpv6Header) -{ - UINT uiLoopIndex = 0; - UINT uiIpv6AddIndex = 0; - UINT uiIpv6AddrNoLongWords = 4; - ULONG aulSrcIP[4]; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - union u_ip_address *src_addr = &pstClassifierRule->stSrcIpAddress; - - /* - * This is the no. of Src Addresses ie Range of IP Addresses contained - * in the classifier rule for which we need to match - */ - UINT uiCountIPSrcAddresses = - (UINT)pstClassifierRule->ucIPSourceAddressLength; - - - if (uiCountIPSrcAddresses == 0) - return TRUE; - - - /* First Convert the Ip Address in the packet to Host Endian order */ - for (uiIpv6AddIndex = 0; - uiIpv6AddIndex < uiIpv6AddrNoLongWords; - uiIpv6AddIndex++) - aulSrcIP[uiIpv6AddIndex] = - ntohl(pstIpv6Header->ulSrcIpAddress[uiIpv6AddIndex]); - - for (uiLoopIndex = 0; - uiLoopIndex < uiCountIPSrcAddresses; - uiLoopIndex += uiIpv6AddrNoLongWords) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "\n Src Ipv6 Address In Received Packet :\n "); - DumpIpv6Address(aulSrcIP); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "\n Src Ipv6 Mask In Classifier Rule:\n"); - DumpIpv6Address(&src_addr->ulIpv6Mask[uiLoopIndex]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "\n Src Ipv6 Address In Classifier Rule :\n"); - DumpIpv6Address(&src_addr->ulIpv6Addr[uiLoopIndex]); - - for (uiIpv6AddIndex = 0; - uiIpv6AddIndex < uiIpv6AddrNoLongWords; - uiIpv6AddIndex++) { - if ((src_addr->ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & - aulSrcIP[uiIpv6AddIndex]) != - src_addr->ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) { - /* - * Match failed for current Ipv6 Address - * Try next Ipv6 Address - */ - break; - } - - if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) { - /* Match Found */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, - "Ipv6 Src Ip Address Matched\n"); - return TRUE; - } - } - } - return false; -} - -static bool MatchDestIpv6Address(struct bcm_classifier_rule *pstClassifierRule, - struct bcm_ipv6_hdr *pstIpv6Header) -{ - UINT uiLoopIndex = 0; - UINT uiIpv6AddIndex = 0; - UINT uiIpv6AddrNoLongWords = 4; - ULONG aulDestIP[4]; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - union u_ip_address *dest_addr = &pstClassifierRule->stDestIpAddress; - - /* - * This is the no. of Destination Addresses - * ie Range of IP Addresses contained in the classifier rule - * for which we need to match - */ - UINT uiCountIPDestinationAddresses = - (UINT)pstClassifierRule->ucIPDestinationAddressLength; - - if (uiCountIPDestinationAddresses == 0) - return TRUE; - - - /* First Convert the Ip Address in the packet to Host Endian order */ - for (uiIpv6AddIndex = 0; - uiIpv6AddIndex < uiIpv6AddrNoLongWords; - uiIpv6AddIndex++) - aulDestIP[uiIpv6AddIndex] = - ntohl(pstIpv6Header->ulDestIpAddress[uiIpv6AddIndex]); - - for (uiLoopIndex = 0; - uiLoopIndex < uiCountIPDestinationAddresses; - uiLoopIndex += uiIpv6AddrNoLongWords) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "\n Destination Ipv6 Address In Received Packet :\n "); - DumpIpv6Address(aulDestIP); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "\n Destination Ipv6 Mask In Classifier Rule :\n"); - DumpIpv6Address(&dest_addr->ulIpv6Mask[uiLoopIndex]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "\n Destination Ipv6 Address In Classifier Rule :\n"); - DumpIpv6Address(&dest_addr->ulIpv6Addr[uiLoopIndex]); - - for (uiIpv6AddIndex = 0; - uiIpv6AddIndex < uiIpv6AddrNoLongWords; - uiIpv6AddIndex++) { - if ((dest_addr->ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & - aulDestIP[uiIpv6AddIndex]) != - dest_addr->ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) { - /* - * Match failed for current Ipv6 Address. - * Try next Ipv6 Address - */ - break; - } - - if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) { - /* Match Found */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, - "Ipv6 Destination Ip Address Matched\n"); - return TRUE; - } - } - } - return false; - -} - -VOID DumpIpv6Address(ULONG *puIpv6Address) -{ - UINT uiIpv6AddrNoLongWords = 4; - UINT uiIpv6AddIndex = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - for (uiIpv6AddIndex = 0; - uiIpv6AddIndex < uiIpv6AddrNoLongWords; - uiIpv6AddIndex++) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - ":%lx", puIpv6Address[uiIpv6AddIndex]); - } - -} - -static VOID DumpIpv6Header(struct bcm_ipv6_hdr *pstIpv6Header) -{ - UCHAR ucVersion; - UCHAR ucPrio; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "----Ipv6 Header---"); - ucVersion = pstIpv6Header->ucVersionPrio & 0xf0; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "Version : %x\n", ucVersion); - ucPrio = pstIpv6Header->ucVersionPrio & 0x0f; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "Priority : %x\n", ucPrio); - /* - * BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - * "Flow Label : %x\n",(pstIpv6Header->ucVersionPrio &0xf0); - */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "Payload Length : %x\n", - ntohs(pstIpv6Header->usPayloadLength)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "Next Header : %x\n", pstIpv6Header->ucNextHeader); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "Hop Limit : %x\n", pstIpv6Header->ucHopLimit); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "Src Address :\n"); - DumpIpv6Address(pstIpv6Header->ulSrcIpAddress); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "Dest Address :\n"); - DumpIpv6Address(pstIpv6Header->ulDestIpAddress); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "----Ipv6 Header End---"); - - -} diff --git a/drivers/staging/bcm/IPv6ProtocolHdr.h b/drivers/staging/bcm/IPv6ProtocolHdr.h deleted file mode 100644 index 96b36a579af2..000000000000 --- a/drivers/staging/bcm/IPv6ProtocolHdr.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef _IPV6_PROTOCOL_DEFINES_ -#define _IPV6_PROTOCOL_DEFINES_ - -#define IPV6HDR_TYPE_HOPBYHOP 0x0 -#define IPV6HDR_TYPE_ROUTING 0x2B -#define IPV6HDR_TYPE_FRAGMENTATION 0x2C -#define IPV6HDR_TYPE_DESTOPTS 0x3c -#define IPV6HDR_TYPE_AUTHENTICATION 0x33 -#define IPV6HDR_TYPE_ENCRYPTEDSECURITYPAYLOAD 0x34 -#define MASK_IPV6_CS_SPEC 0x2 - -#define TCP_HEADER_TYPE 0x6 -#define UDP_HEADER_TYPE 0x11 -#define IPV6_ICMP_HDR_TYPE 0x2 -#define IPV6_FLOWLABEL_BITOFFSET 9 - -#define IPV6_MAX_CHAINEDHDR_BUFFBYTES 0x64 -/* - * Size of Dest Options field of Destinations Options Header - * in bytes. - */ -#define IPV6_DESTOPTS_HDR_OPTIONSIZE 0x8 - -struct bcm_ipv6_hdr { - unsigned char ucVersionPrio; - unsigned char aucFlowLabel[3]; - unsigned short usPayloadLength; - unsigned char ucNextHeader; - unsigned char ucHopLimit; - unsigned long ulSrcIpAddress[4]; - unsigned long ulDestIpAddress[4]; -}; - -struct bcm_ipv6_routing_hdr { - unsigned char ucNextHeader; - unsigned char ucRoutingType; - unsigned char ucNumAddresses; - unsigned char ucNextAddress; - unsigned long ulReserved; -}; - -struct bcm_ipv6_fragment_hdr { - unsigned char ucNextHeader; - unsigned char ucReserved; - unsigned short usFragmentOffset; - unsigned long ulIdentification; -}; - -struct bcm_ipv6_dest_options_hdr { - unsigned char ucNextHeader; - unsigned char ucHdrExtLen; - unsigned char ucDestOptions[6]; -}; - -struct bcm_ipv6_options_hdr { - unsigned char ucNextHeader; - unsigned char ucMisc[3]; - unsigned long ulJumboPayloadLen; -}; - -struct bcm_ipv6_authentication_hdr { - unsigned char ucNextHeader; - unsigned char ucLength; - unsigned short usReserved; - unsigned long ulSecurityParametersIndex; -}; - -enum bcm_ipaddr_context { - eSrcIpAddress, - eDestIpAddress -}; - -/* Function Prototypes */ - -unsigned short IpVersion6(struct bcm_mini_adapter *Adapter, /* < Pointer to the driver control structure */ - void *pcIpHeader, /* <Pointer to the IP Hdr of the packet */ - struct bcm_classifier_rule *pstClassifierRule); - -void DumpIpv6Address(unsigned long *puIpv6Address); - -extern bool MatchSrcPort(struct bcm_classifier_rule *pstClassifierRule, unsigned short ushSrcPort); -extern bool MatchDestPort(struct bcm_classifier_rule *pstClassifierRule, unsigned short ushSrcPort); -extern bool MatchProtocol(struct bcm_classifier_rule *pstClassifierRule, unsigned char ucProtocol); - -#endif diff --git a/drivers/staging/bcm/InterfaceAdapter.h b/drivers/staging/bcm/InterfaceAdapter.h deleted file mode 100644 index 06a6b18bca48..000000000000 --- a/drivers/staging/bcm/InterfaceAdapter.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef _INTERFACE_ADAPTER_H -#define _INTERFACE_ADAPTER_H - -struct bcm_bulk_endpoint_in { - char *bulk_in_buffer; - size_t bulk_in_size; - unsigned char bulk_in_endpointAddr; - unsigned int bulk_in_pipe; -}; - -struct bcm_bulk_endpoint_out { - unsigned char bulk_out_buffer; - size_t bulk_out_size; - unsigned char bulk_out_endpointAddr; - unsigned int bulk_out_pipe; - /* this is used when int out endpoint is used as bulk out end point */ - unsigned char int_out_interval; -}; - -struct bcm_intr_endpoint_in { - char *int_in_buffer; - size_t int_in_size; - unsigned char int_in_endpointAddr; - unsigned char int_in_interval; - unsigned int int_in_pipe; -}; - -struct bcm_intr_endpoint_out { - char *int_out_buffer; - size_t int_out_size; - unsigned char int_out_endpointAddr; - unsigned char int_out_interval; - unsigned int int_out_pipe; -}; - -struct bcm_usb_tcb { - struct urb *urb; - void *psIntfAdapter; - bool bUsed; -}; - -struct bcm_usb_rcb { - struct urb *urb; - void *psIntfAdapter; - bool bUsed; -}; - -/* - * This is the interface specific Sub-Adapter - * Structure. - */ -struct bcm_interface_adapter { - struct usb_device *udev; - struct usb_interface *interface; - /* Bulk endpoint in info */ - struct bcm_bulk_endpoint_in sBulkIn; - /* Bulk endpoint out info */ - struct bcm_bulk_endpoint_out sBulkOut; - /* Interrupt endpoint in info */ - struct bcm_intr_endpoint_in sIntrIn; - /* Interrupt endpoint out info */ - struct bcm_intr_endpoint_out sIntrOut; - unsigned long ulInterruptData[2]; - struct urb *psInterruptUrb; - struct bcm_usb_tcb asUsbTcb[MAXIMUM_USB_TCB]; - struct bcm_usb_rcb asUsbRcb[MAXIMUM_USB_RCB]; - atomic_t uNumTcbUsed; - atomic_t uCurrTcb; - atomic_t uNumRcbUsed; - atomic_t uCurrRcb; - struct bcm_mini_adapter *psAdapter; - bool bFlashBoot; - bool bHighSpeedDevice; - bool bSuspended; - bool bPreparingForBusSuspend; - struct work_struct usbSuspendWork; -}; - -#endif diff --git a/drivers/staging/bcm/InterfaceDld.c b/drivers/staging/bcm/InterfaceDld.c deleted file mode 100644 index abc7a7ab782a..000000000000 --- a/drivers/staging/bcm/InterfaceDld.c +++ /dev/null @@ -1,317 +0,0 @@ -#include "headers.h" - -int InterfaceFileDownload(PVOID arg, struct file *flp, unsigned int on_chip_loc) -{ - /* unsigned int reg = 0; */ - mm_segment_t oldfs = {0}; - int errno = 0, len = 0; /* ,is_config_file = 0 */ - loff_t pos = 0; - struct bcm_interface_adapter *psIntfAdapter = arg; - /* struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter; */ - char *buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); - - if (!buff) - return -ENOMEM; - - while (1) { - oldfs = get_fs(); - set_fs(get_ds()); - len = vfs_read(flp, (void __force __user *)buff, - MAX_TRANSFER_CTRL_BYTE_USB, &pos); - set_fs(oldfs); - if (len <= 0) { - if (len < 0) - errno = len; - else - errno = 0; - break; - } - /* BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_INITEXIT, MP_INIT, - * DBG_LVL_ALL, buff, - * MAX_TRANSFER_CTRL_BYTE_USB); - */ - errno = InterfaceWRM(psIntfAdapter, on_chip_loc, buff, len); - if (errno) - break; - on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB; - } - - kfree(buff); - return errno; -} - -int InterfaceFileReadbackFromChip(PVOID arg, struct file *flp, - unsigned int on_chip_loc) -{ - char *buff, *buff_readback; - unsigned int reg = 0; - mm_segment_t oldfs = {0}; - int errno = 0, len = 0, is_config_file = 0; - loff_t pos = 0; - static int fw_down; - INT Status = STATUS_SUCCESS; - struct bcm_interface_adapter *psIntfAdapter = arg; - int bytes; - - buff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA); - buff_readback = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA); - if (!buff || !buff_readback) { - kfree(buff); - kfree(buff_readback); - - return -ENOMEM; - } - - is_config_file = (on_chip_loc == CONFIG_BEGIN_ADDR) ? 1 : 0; - - while (1) { - oldfs = get_fs(); - set_fs(get_ds()); - len = vfs_read(flp, (void __force __user *)buff, - MAX_TRANSFER_CTRL_BYTE_USB, &pos); - set_fs(oldfs); - fw_down++; - - if (len <= 0) { - if (len < 0) - errno = len; - else - errno = 0; - break; - } - - bytes = InterfaceRDM(psIntfAdapter, on_chip_loc, - buff_readback, len); - if (bytes < 0) { - Status = bytes; - goto exit; - } - reg++; - if ((len-sizeof(unsigned int)) < 4) { - if (memcmp(buff_readback, buff, len)) { - Status = -EIO; - goto exit; - } - } else { - len -= 4; - - while (len) { - if (*(unsigned int *)&buff_readback[len] != - *(unsigned int *)&buff[len]) { - Status = -EIO; - goto exit; - } - len -= 4; - } - } - on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB; - } /* End of while(1) */ - -exit: - kfree(buff); - kfree(buff_readback); - return Status; -} - -static int bcm_download_config_file(struct bcm_mini_adapter *Adapter, - struct bcm_firmware_info *psFwInfo) -{ - int retval = STATUS_SUCCESS; - B_UINT32 value = 0; - - if (Adapter->pstargetparams == NULL) { - Adapter->pstargetparams = - kmalloc(sizeof(struct bcm_target_params), GFP_KERNEL); - if (Adapter->pstargetparams == NULL) - return -ENOMEM; - } - - if (psFwInfo->u32FirmwareLength != sizeof(struct bcm_target_params)) - return -EIO; - - retval = copy_from_user(Adapter->pstargetparams, - psFwInfo->pvMappedFirmwareAddress, - psFwInfo->u32FirmwareLength); - if (retval) { - kfree(Adapter->pstargetparams); - Adapter->pstargetparams = NULL; - return -EFAULT; - } - - /* Parse the structure and then Download the Firmware */ - beceem_parse_target_struct(Adapter); - - /* Initializing the NVM. */ - BcmInitNVM(Adapter); - retval = InitLedSettings(Adapter); - - if (retval) - return retval; - - if (Adapter->LEDInfo.led_thread_running & - BCM_LED_THREAD_RUNNING_ACTIVELY) { - Adapter->LEDInfo.bLedInitDone = false; - Adapter->DriverState = DRIVER_INIT; - wake_up(&Adapter->LEDInfo.notify_led_event); - } - - if (Adapter->LEDInfo.led_thread_running & - BCM_LED_THREAD_RUNNING_ACTIVELY) { - Adapter->DriverState = FW_DOWNLOAD; - wake_up(&Adapter->LEDInfo.notify_led_event); - } - - /* Initialize the DDR Controller */ - retval = ddr_init(Adapter); - if (retval) - return retval; - - value = 0; - wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, - &value, sizeof(value)); - wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, - &value, sizeof(value)); - - if (Adapter->eNVMType == NVM_FLASH) { - retval = PropagateCalParamsFromFlashToMemory(Adapter); - if (retval) - return retval; - } - - retval = buffDnldVerify(Adapter, (PUCHAR)Adapter->pstargetparams, - sizeof(struct bcm_target_params), CONFIG_BEGIN_ADDR); - - if (retval) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, - MP_INIT, DBG_LVL_ALL, - "configuration file not downloaded properly"); - else - Adapter->bCfgDownloaded = TRUE; - - return retval; -} - -int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter, - struct bcm_firmware_info *psFwInfo) -{ - int retval = STATUS_SUCCESS; - PUCHAR buff = NULL; - - /* Config File is needed for the Driver to download the Config file and - * Firmware. Check for the Config file to be first to be sent from the - * Application - */ - atomic_set(&Adapter->uiMBupdate, false); - if (!Adapter->bCfgDownloaded && - psFwInfo->u32StartingAddress != CONFIG_BEGIN_ADDR) { - /* Can't Download Firmware. */ - return -EINVAL; - } - - /* If Config File, Finish the DDR Settings and then Download CFG File */ - if (psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR) { - retval = bcm_download_config_file(Adapter, psFwInfo); - } else { - buff = kzalloc(psFwInfo->u32FirmwareLength, GFP_KERNEL); - if (buff == NULL) - return -ENOMEM; - - retval = copy_from_user(buff, - psFwInfo->pvMappedFirmwareAddress, - psFwInfo->u32FirmwareLength); - if (retval != STATUS_SUCCESS) { - retval = -EFAULT; - goto error; - } - - retval = buffDnldVerify(Adapter, - buff, - psFwInfo->u32FirmwareLength, - psFwInfo->u32StartingAddress); - - if (retval != STATUS_SUCCESS) - goto error; - } - -error: - kfree(buff); - return retval; -} - -static INT buffDnld(struct bcm_mini_adapter *Adapter, - PUCHAR mappedbuffer, UINT u32FirmwareLength, - ULONG u32StartingAddress) -{ - unsigned int len = 0; - int retval = STATUS_SUCCESS; - - len = u32FirmwareLength; - - while (u32FirmwareLength) { - len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB); - retval = wrm(Adapter, u32StartingAddress, mappedbuffer, len); - - if (retval) - break; - u32StartingAddress += len; - u32FirmwareLength -= len; - mappedbuffer += len; - } - return retval; -} - -static INT buffRdbkVerify(struct bcm_mini_adapter *Adapter, - PUCHAR mappedbuffer, UINT u32FirmwareLength, - ULONG u32StartingAddress) -{ - UINT len = u32FirmwareLength; - INT retval = STATUS_SUCCESS; - PUCHAR readbackbuff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); - int bytes; - - if (NULL == readbackbuff) - return -ENOMEM; - - while (u32FirmwareLength && !retval) { - len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB); - bytes = rdm(Adapter, u32StartingAddress, readbackbuff, len); - - if (bytes < 0) { - retval = bytes; - break; - } - - if (memcmp(readbackbuff, mappedbuffer, len) != 0) { - pr_err("%s() failed. The firmware doesn't match what was written", - __func__); - retval = -EIO; - } - - u32StartingAddress += len; - u32FirmwareLength -= len; - mappedbuffer += len; - - } /* end of while (u32FirmwareLength && !retval) */ - kfree(readbackbuff); - return retval; -} - -INT buffDnldVerify(struct bcm_mini_adapter *Adapter, - unsigned char *mappedbuffer, - unsigned int u32FirmwareLength, - unsigned long u32StartingAddress) -{ - INT status = STATUS_SUCCESS; - - status = buffDnld(Adapter, mappedbuffer, - u32FirmwareLength, u32StartingAddress); - if (status != STATUS_SUCCESS) - goto error; - - status = buffRdbkVerify(Adapter, mappedbuffer, - u32FirmwareLength, u32StartingAddress); - if (status != STATUS_SUCCESS) - goto error; -error: - return status; -} diff --git a/drivers/staging/bcm/InterfaceIdleMode.c b/drivers/staging/bcm/InterfaceIdleMode.c deleted file mode 100644 index 612c89fba341..000000000000 --- a/drivers/staging/bcm/InterfaceIdleMode.c +++ /dev/null @@ -1,274 +0,0 @@ -#include "headers.h" - -/* -Function: InterfaceIdleModeWakeup - -Description: This is the hardware specific Function for - waking up HW device from Idle mode. - A software abort pattern is written to the - device to wake it and necessary power state - transitions from host are performed here. - -Input parameters: IN struct bcm_mini_adapter *Adapter - - Miniport Adapter Context - -Return: BCM_STATUS_SUCCESS - If Wakeup of the HW Interface - was successful. - Other - If an error occurred. -*/ - -/* -Function: InterfaceIdleModeRespond - -Description: This is the hardware specific Function for - responding to Idle mode request from target. - Necessary power state transitions from host for - idle mode or other device specific initializations - are performed here. - -Input parameters: IN struct bcm_mini_adapter * Adapter - - Miniport Adapter Context - -Return: BCM_STATUS_SUCCESS - If Idle mode response related - HW configuration was successful. - Other - If an error occurred. -*/ - -/* -"dmem bfc02f00 100" tells how many time device went in Idle mode. -this value will be at address bfc02fa4.just before value d0ea1dle. - -Set time value by writing at bfc02f98 7d0 - -checking the Ack timer expire on kannon by running command -d qcslog .. if it shows e means host has not send response -to f/w with in 200 ms. Response should be -send to f/w with in 200 ms after the Idle/Shutdown req issued - -*/ - - -int InterfaceIdleModeRespond(struct bcm_mini_adapter *Adapter, - unsigned int *puiBuffer) -{ - int status = STATUS_SUCCESS; - unsigned int uiRegRead = 0; - int bytes; - - if (ntohl(*puiBuffer) == GO_TO_IDLE_MODE_PAYLOAD) { - if (ntohl(*(puiBuffer+1)) == 0) { - - status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, - &uiRegRead, sizeof(uiRegRead)); - if (status) - return status; - - if (Adapter->ulPowerSaveMode == - DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) { - uiRegRead = 0x00000000; - status = wrmalt(Adapter, - DEBUG_INTERRUPT_GENERATOR_REGISTOR, - &uiRegRead, sizeof(uiRegRead)); - if (status) - return status; - } - /* Below Register should not br read in case of - * Manual and Protocol Idle mode */ - else if (Adapter->ulPowerSaveMode != - DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) { - /* clear on read Register */ - bytes = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG0, - &uiRegRead, sizeof(uiRegRead)); - if (bytes < 0) { - status = bytes; - return status; - } - /* clear on read Register */ - bytes = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG1, - &uiRegRead, sizeof(uiRegRead)); - if (bytes < 0) { - status = bytes; - return status; - } - } - - /* Set Idle Mode Flag to False and - * Clear IdleMode reg. */ - Adapter->IdleMode = false; - Adapter->bTriedToWakeUpFromlowPowerMode = false; - - wake_up(&Adapter->lowpower_mode_wait_queue); - - } else { - if (TRUE == Adapter->IdleMode) - return status; - - uiRegRead = 0; - - if (Adapter->chip_id == BCS220_2 || - Adapter->chip_id == BCS220_2BC || - Adapter->chip_id == BCS250_BC || - Adapter->chip_id == BCS220_3) { - - bytes = rdmalt(Adapter, HPM_CONFIG_MSW, - &uiRegRead, sizeof(uiRegRead)); - if (bytes < 0) { - status = bytes; - return status; - } - - - uiRegRead |= (1<<17); - - status = wrmalt(Adapter, HPM_CONFIG_MSW, - &uiRegRead, sizeof(uiRegRead)); - if (status) - return status; - } - SendIdleModeResponse(Adapter); - } - } else if (ntohl(*puiBuffer) == IDLE_MODE_SF_UPDATE_MSG) { - OverrideServiceFlowParams(Adapter, puiBuffer); - } - return status; -} - -static int InterfaceAbortIdlemode(struct bcm_mini_adapter *Adapter, - unsigned int Pattern) -{ - int status = STATUS_SUCCESS; - unsigned int value; - unsigned int chip_id; - unsigned long timeout = 0, itr = 0; - - int lenwritten = 0; - unsigned char aucAbortPattern[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF}; - struct bcm_interface_adapter *psInterfaceAdapter = - Adapter->pvInterfaceAdapter; - - /* Abort Bus suspend if its already suspended */ - if ((TRUE == psInterfaceAdapter->bSuspended) && - (TRUE == Adapter->bDoSuspend)) - status = usb_autopm_get_interface( - psInterfaceAdapter->interface); - - if ((Adapter->ulPowerSaveMode == - DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) || - (Adapter->ulPowerSaveMode == - DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)) { - /* write the SW abort pattern. */ - status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, - &Pattern, sizeof(Pattern)); - if (status) - return status; - } - - if (Adapter->ulPowerSaveMode == - DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) { - value = 0x80000000; - status = wrmalt(Adapter, - DEBUG_INTERRUPT_GENERATOR_REGISTOR, - &value, sizeof(value)); - if (status) - return status; - } else if (Adapter->ulPowerSaveMode != - DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) { - /* - * Get a Interrupt Out URB and send 8 Bytes Down - * To be Done in Thread Context. - * Not using Asynchronous Mechanism. - */ - status = usb_interrupt_msg(psInterfaceAdapter->udev, - usb_sndintpipe(psInterfaceAdapter->udev, - psInterfaceAdapter->sIntrOut.int_out_endpointAddr), - aucAbortPattern, - 8, - &lenwritten, - 5000); - if (status) - return status; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - IDLE_MODE, DBG_LVL_ALL, - "NOB Sent down :%d", lenwritten); - - /* mdelay(25); */ - - timeout = jiffies + msecs_to_jiffies(50); - while (time_after(timeout, jiffies)) { - itr++; - rdmalt(Adapter, CHIP_ID_REG, &chip_id, sizeof(UINT)); - if (0xbece3200 == (chip_id&~(0xF0))) - chip_id = chip_id&~(0xF0); - if (chip_id == Adapter->chip_id) - break; - } - if (time_before(timeout, jiffies)) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - IDLE_MODE, DBG_LVL_ALL, - "Not able to read chip-id even after 25 msec"); - else - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - IDLE_MODE, DBG_LVL_ALL, - "Number of completed iteration to read chip-id :%lu", itr); - - status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, - &Pattern, sizeof(status)); - if (status) - return status; - } - return status; -} -int InterfaceIdleModeWakeup(struct bcm_mini_adapter *Adapter) -{ - if (Adapter->bTriedToWakeUpFromlowPowerMode) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - IDLE_MODE, DBG_LVL_ALL, - "Wake up already attempted.. ignoring\n"); - } else { - Adapter->bTriedToWakeUpFromlowPowerMode = TRUE; - InterfaceAbortIdlemode(Adapter, Adapter->usIdleModePattern); - - } - return 0; -} - -void InterfaceHandleShutdownModeWakeup(struct bcm_mini_adapter *Adapter) -{ - unsigned int uiRegVal = 0; - INT Status = 0; - int bytes; - - if (Adapter->ulPowerSaveMode == - DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) { - /* clear idlemode interrupt. */ - uiRegVal = 0; - Status = wrmalt(Adapter, - DEBUG_INTERRUPT_GENERATOR_REGISTOR, - &uiRegVal, sizeof(uiRegVal)); - if (Status) - return; - } - - else { - -/* clear Interrupt EP registers. */ - bytes = rdmalt(Adapter, - DEVICE_INT_OUT_EP_REG0, - &uiRegVal, sizeof(uiRegVal)); - if (bytes < 0) { - Status = bytes; - return; - } - - bytes = rdmalt(Adapter, - DEVICE_INT_OUT_EP_REG1, - &uiRegVal, sizeof(uiRegVal)); - if (bytes < 0) { - Status = bytes; - return; - } - } -} - diff --git a/drivers/staging/bcm/InterfaceIdleMode.h b/drivers/staging/bcm/InterfaceIdleMode.h deleted file mode 100644 index 2ef64003aa89..000000000000 --- a/drivers/staging/bcm/InterfaceIdleMode.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _INTERFACE_IDLEMODE_H -#define _INTERFACE_IDLEMODE_H - -INT InterfaceIdleModeWakeup(struct bcm_mini_adapter *Adapter); - -INT InterfaceIdleModeRespond(struct bcm_mini_adapter *Adapter, - unsigned int *puiBuffer); - -VOID InterfaceWriteIdleModeWakePattern(struct bcm_mini_adapter *Adapter); - -INT InterfaceWakeUp(struct bcm_mini_adapter *Adapter); - -VOID InterfaceHandleShutdownModeWakeup(struct bcm_mini_adapter *Adapter); -#endif - diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c deleted file mode 100644 index bb61d34886b3..000000000000 --- a/drivers/staging/bcm/InterfaceInit.c +++ /dev/null @@ -1,729 +0,0 @@ -#include "headers.h" -#include <linux/usb/ch9.h> -static struct usb_device_id InterfaceUsbtable[] = { - { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3B) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3L) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_SYM) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_226) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_FOXCONN, BCM_USB_PRODUCT_ID_1901) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_TU25) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_226) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_326) }, - { } -}; -MODULE_DEVICE_TABLE(usb, InterfaceUsbtable); - -static int debug = -1; -module_param(debug, uint, 0600); -MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); - -static const u32 default_msg = - NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK - | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR - | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN; - -static int InterfaceAdapterInit(struct bcm_interface_adapter *Adapter); - -static void InterfaceAdapterFree(struct bcm_interface_adapter *psIntfAdapter) -{ - int i = 0; - struct bcm_mini_adapter *ps_ad = psIntfAdapter->psAdapter; - - /* Wake up the wait_queue... */ - if (ps_ad->LEDInfo.led_thread_running & - BCM_LED_THREAD_RUNNING_ACTIVELY) { - ps_ad->DriverState = DRIVER_HALT; - wake_up(&ps_ad->LEDInfo.notify_led_event); - } - reset_card_proc(ps_ad); - - /* - * worst case time taken by the RDM/WRM will be 5 sec. will check after - * every 100 ms to accertain the device is not being accessed. After - * this No RDM/WRM should be made. - */ - while (ps_ad->DeviceAccess) { - BCM_DEBUG_PRINT(ps_ad, DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, "Device is being accessed.\n"); - msleep(100); - } - /* Free interrupt URB */ - /* ps_ad->device_removed = TRUE; */ - usb_free_urb(psIntfAdapter->psInterruptUrb); - - /* Free transmit URBs */ - for (i = 0; i < MAXIMUM_USB_TCB; i++) { - if (psIntfAdapter->asUsbTcb[i].urb != NULL) { - usb_free_urb(psIntfAdapter->asUsbTcb[i].urb); - psIntfAdapter->asUsbTcb[i].urb = NULL; - } - } - /* Free receive URB and buffers */ - for (i = 0; i < MAXIMUM_USB_RCB; i++) { - if (psIntfAdapter->asUsbRcb[i].urb != NULL) { - kfree(psIntfAdapter->asUsbRcb[i].urb->transfer_buffer); - usb_free_urb(psIntfAdapter->asUsbRcb[i].urb); - psIntfAdapter->asUsbRcb[i].urb = NULL; - } - } - AdapterFree(ps_ad); -} - -static void ConfigureEndPointTypesThroughEEPROM( - struct bcm_mini_adapter *Adapter) -{ - u32 ulReg; - int bytes; - struct bcm_interface_adapter *interfaceAdapter; - - /* Program EP2 MAX_PKT_SIZE */ - ulReg = ntohl(EP2_MPS_REG); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x128, 4, TRUE); - ulReg = ntohl(EP2_MPS); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x12C, 4, TRUE); - - ulReg = ntohl(EP2_CFG_REG); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x132, 4, TRUE); - interfaceAdapter = - (struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter); - if (interfaceAdapter->bHighSpeedDevice) { - ulReg = ntohl(EP2_CFG_INT); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x136, 4, TRUE); - } else { - /* USE BULK EP as TX in FS mode. */ - ulReg = ntohl(EP2_CFG_BULK); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x136, 4, TRUE); - } - - /* Program EP4 MAX_PKT_SIZE. */ - ulReg = ntohl(EP4_MPS_REG); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x13C, 4, TRUE); - ulReg = ntohl(EP4_MPS); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x140, 4, TRUE); - - /* Program TX EP as interrupt(Alternate Setting) */ - bytes = rdmalt(Adapter, 0x0F0110F8, &ulReg, sizeof(u32)); - if (bytes < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, "reading of Tx EP failed\n"); - return; - } - ulReg |= 0x6; - - ulReg = ntohl(ulReg); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1CC, 4, TRUE); - - ulReg = ntohl(EP4_CFG_REG); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1C8, 4, TRUE); - /* Program ISOCHRONOUS EP size to zero. */ - ulReg = ntohl(ISO_MPS_REG); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1D2, 4, TRUE); - ulReg = ntohl(ISO_MPS); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1D6, 4, TRUE); - - /* - * Update EEPROM Version. - * Read 4 bytes from 508 and modify 511 and 510. - */ - ReadBeceemEEPROM(Adapter, 0x1FC, &ulReg); - ulReg &= 0x0101FFFF; - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1FC, 4, TRUE); - - /* - * Update length field if required. - * Also make the string NULL terminated. - */ - - ReadBeceemEEPROM(Adapter, 0xA8, &ulReg); - if ((ulReg&0x00FF0000)>>16 > 0x30) { - ulReg = (ulReg&0xFF00FFFF)|(0x30<<16); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0xA8, 4, TRUE); - } - ReadBeceemEEPROM(Adapter, 0x148, &ulReg); - if ((ulReg&0x00FF0000)>>16 > 0x30) { - ulReg = (ulReg&0xFF00FFFF)|(0x30<<16); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x148, 4, TRUE); - } - ulReg = 0; - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x122, 4, TRUE); - ulReg = 0; - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1C2, 4, TRUE); -} - -static int usbbcm_device_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct usb_device *udev = interface_to_usbdev(intf); - int retval; - struct bcm_mini_adapter *psAdapter; - struct bcm_interface_adapter *psIntfAdapter; - struct net_device *ndev; - - /* Reserve one extra queue for the bit-bucket */ - ndev = alloc_etherdev_mq(sizeof(struct bcm_mini_adapter), - NO_OF_QUEUES + 1); - if (ndev == NULL) { - dev_err(&udev->dev, DRV_NAME ": no memory for device\n"); - return -ENOMEM; - } - - SET_NETDEV_DEV(ndev, &intf->dev); - - psAdapter = netdev_priv(ndev); - psAdapter->dev = ndev; - psAdapter->msg_enable = netif_msg_init(debug, default_msg); - - /* Init default driver debug state */ - - psAdapter->stDebugState.debug_level = DBG_LVL_CURR; - psAdapter->stDebugState.type = DBG_TYPE_INITEXIT; - - /* - * Technically, one can start using BCM_DEBUG_PRINT after this point. - * However, realize that by default the Type/Subtype bitmaps are all - * zero now; so no prints will actually appear until the TestApp turns - * on debug paths via the ioctl(); so practically speaking, in early - * init, no logging happens. - * - * A solution (used below): we explicitly set the bitmaps to 1 for - * Type=DBG_TYPE_INITEXIT and ALL subtype's of the same. Now all bcm - * debug statements get logged, enabling debug during early init. - * Further, we turn this OFF once init_module() completes. - */ - - psAdapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0xff; - BCM_SHOW_DEBUG_BITMAP(psAdapter); - - retval = InitAdapter(psAdapter); - if (retval) { - dev_err(&udev->dev, DRV_NAME ": InitAdapter Failed\n"); - AdapterFree(psAdapter); - return retval; - } - - /* Allocate interface adapter structure */ - psIntfAdapter = kzalloc(sizeof(struct bcm_interface_adapter), - GFP_KERNEL); - if (psIntfAdapter == NULL) { - AdapterFree(psAdapter); - return -ENOMEM; - } - - psAdapter->pvInterfaceAdapter = psIntfAdapter; - psIntfAdapter->psAdapter = psAdapter; - - /* Store usb interface in Interface Adapter */ - psIntfAdapter->interface = intf; - usb_set_intfdata(intf, psIntfAdapter); - - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, - "psIntfAdapter 0x%p\n", psIntfAdapter); - retval = InterfaceAdapterInit(psIntfAdapter); - if (retval) { - /* If the Firmware/Cfg File is not present - * then return success, let the application - * download the files. - */ - if (-ENOENT == retval) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, - "File Not Found. Use app to download.\n"); - return STATUS_SUCCESS; - } - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, "InterfaceAdapterInit failed.\n"); - usb_set_intfdata(intf, NULL); - udev = interface_to_usbdev(intf); - usb_put_dev(udev); - InterfaceAdapterFree(psIntfAdapter); - return retval; - } - if (psAdapter->chip_id > T3) { - uint32_t uiNackZeroLengthInt = 4; - - retval = - wrmalt(psAdapter, DISABLE_USB_ZERO_LEN_INT, - &uiNackZeroLengthInt, - sizeof(uiNackZeroLengthInt)); - if (retval) - return retval; - } - - /* Check whether the USB-Device Supports remote Wake-Up */ - if (USB_CONFIG_ATT_WAKEUP & udev->actconfig->desc.bmAttributes) { - /* If Suspend then only support dynamic suspend */ - if (psAdapter->bDoSuspend) { -#ifdef CONFIG_PM - pm_runtime_set_autosuspend_delay(&udev->dev, 0); - intf->needs_remote_wakeup = 1; - usb_enable_autosuspend(udev); - device_init_wakeup(&intf->dev, 1); - INIT_WORK(&psIntfAdapter->usbSuspendWork, - putUsbSuspend); - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, - "Enabling USB Auto-Suspend\n"); -#endif - } else { - intf->needs_remote_wakeup = 0; - usb_disable_autosuspend(udev); - } - } - - psAdapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0x0; - return retval; -} - -static void usbbcm_disconnect(struct usb_interface *intf) -{ - struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf); - struct bcm_mini_adapter *psAdapter; - struct usb_device *udev = interface_to_usbdev(intf); - - if (psIntfAdapter == NULL) - return; - - psAdapter = psIntfAdapter->psAdapter; - netif_device_detach(psAdapter->dev); - - if (psAdapter->bDoSuspend) - intf->needs_remote_wakeup = 0; - - psAdapter->device_removed = TRUE; - usb_set_intfdata(intf, NULL); - InterfaceAdapterFree(psIntfAdapter); - usb_put_dev(udev); -} - -static int AllocUsbCb(struct bcm_interface_adapter *psIntfAdapter) -{ - int i = 0; - - for (i = 0; i < MAXIMUM_USB_TCB; i++) { - psIntfAdapter->asUsbTcb[i].urb = usb_alloc_urb(0, GFP_KERNEL); - - if (psIntfAdapter->asUsbTcb[i].urb == NULL) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, - DBG_TYPE_PRINTK, 0, 0, - "Can't allocate Tx urb for index %d\n", - i); - return -ENOMEM; - } - } - - for (i = 0; i < MAXIMUM_USB_RCB; i++) { - psIntfAdapter->asUsbRcb[i].urb = usb_alloc_urb(0, GFP_KERNEL); - - if (psIntfAdapter->asUsbRcb[i].urb == NULL) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, - DBG_TYPE_PRINTK, 0, 0, - "Can't allocate Rx urb for index %d\n", - i); - return -ENOMEM; - } - - psIntfAdapter->asUsbRcb[i].urb->transfer_buffer = - kmalloc(MAX_DATA_BUFFER_SIZE, GFP_KERNEL); - - if (psIntfAdapter->asUsbRcb[i].urb->transfer_buffer == NULL) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, - DBG_TYPE_PRINTK, 0, 0, - "Can't allocate Rx buffer for index %d\n", - i); - return -ENOMEM; - } - psIntfAdapter->asUsbRcb[i].urb->transfer_buffer_length = - MAX_DATA_BUFFER_SIZE; - } - return 0; -} - -static int device_run(struct bcm_interface_adapter *psIntfAdapter) -{ - int value = 0; - UINT status = STATUS_SUCCESS; - struct bcm_mini_adapter *psAd = psIntfAdapter->psAdapter; - - status = InitCardAndDownloadFirmware(psAd); - if (status != STATUS_SUCCESS) { - pr_err(DRV_NAME "InitCardAndDownloadFirmware failed.\n"); - return status; - } - if (psAd->fw_download_done) { - if (StartInterruptUrb(psIntfAdapter)) { - BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, - "Cannot send interrupt in URB\n"); - } - - /* - * now register the cntrl interface. after downloading the f/w - * waiting for 5 sec to get the mailbox interrupt. - */ - psAd->waiting_to_fw_download_done = false; - value = wait_event_timeout(psAd->ioctl_fw_dnld_wait_queue, - psAd->waiting_to_fw_download_done, - 5 * HZ); - - if (value == 0) - pr_err(DRV_NAME ": Timeout waiting for mailbox interrupt.\n"); - - if (register_control_device_interface(psAd) < 0) { - pr_err(DRV_NAME ": Register Control Device failed.\n"); - return -EIO; - } - } - return 0; -} - -static int select_alternate_setting_for_highspeed_modem( - struct bcm_interface_adapter *psIntfAdapter, - struct usb_endpoint_descriptor **endpoint, - const struct usb_host_interface *iface_desc, - int *usedIntOutForBulkTransfer) -{ - int retval = 0; - struct bcm_mini_adapter *psAd = psIntfAdapter->psAdapter; - - /* selecting alternate setting one as a default setting - * for High Speed modem. */ - if (psIntfAdapter->bHighSpeedDevice) - retval = usb_set_interface(psIntfAdapter->udev, - DEFAULT_SETTING_0, - ALTERNATE_SETTING_1); - BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, - "BCM16 is applicable on this dongle\n"); - if (retval || !psIntfAdapter->bHighSpeedDevice) { - *usedIntOutForBulkTransfer = EP2; - *endpoint = &iface_desc->endpoint[EP2].desc; - BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, - "Interface altsetting failed or modem is configured to Full Speed, hence will work on default setting 0\n"); - /* - * If Modem is high speed device EP2 should be - * INT OUT End point - * - * If Mode is FS then EP2 should be bulk end - * point - */ - if ((psIntfAdapter->bHighSpeedDevice && - !usb_endpoint_is_int_out(*endpoint)) || - (!psIntfAdapter->bHighSpeedDevice && - !usb_endpoint_is_bulk_out(*endpoint))) { - BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, - "Configuring the EEPROM\n"); - /* change the EP2, EP4 to INT OUT end point */ - ConfigureEndPointTypesThroughEEPROM( - psAd); - - /* - * It resets the device and if any thing - * gets changed in USB descriptor it - * will show fail and re-enumerate the - * device - */ - retval = usb_reset_device(psIntfAdapter->udev); - if (retval) { - BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, - DRV_ENTRY, DBG_LVL_ALL, - "reset failed. Re-enumerating the device.\n"); - return retval; - } - - } - if (!psIntfAdapter->bHighSpeedDevice && - usb_endpoint_is_bulk_out(*endpoint)) { - /* - * Once BULK is selected in FS mode. - * Revert it back to INT. - * Else USB_IF will fail. - */ - UINT _uiData = ntohl(EP2_CFG_INT); - - BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, - "Reverting Bulk to INT as it is in Full Speed mode.\n"); - BeceemEEPROMBulkWrite(psAd, (PUCHAR) & _uiData, 0x136, - 4, TRUE); - } - } else { - *usedIntOutForBulkTransfer = EP4; - *endpoint = &iface_desc->endpoint[EP4].desc; - BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, - "Choosing AltSetting as a default setting.\n"); - if (!usb_endpoint_is_int_out(*endpoint)) { - BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, - "Dongle does not have BCM16 Fix.\n"); - /* - * change the EP2, EP4 to INT OUT end point and use EP4 - * in altsetting - */ - ConfigureEndPointTypesThroughEEPROM(psAd); - - /* - * It resets the device and if any thing - * gets changed in USB descriptor it - * will show fail and re-enumerate the - * device - */ - retval = usb_reset_device(psIntfAdapter->udev); - if (retval) { - BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, - DRV_ENTRY, DBG_LVL_ALL, - "reset failed. Re-enumerating the device.\n"); - return retval; - } - } - } - - return 0; -} - -static int InterfaceAdapterInit(struct bcm_interface_adapter *psIntfAdapter) -{ - struct usb_host_interface *iface_desc; - struct usb_endpoint_descriptor *endpoint; - size_t buffer_size; - unsigned long value; - int retval = 0; - int usedIntOutForBulkTransfer = 0; - bool bBcm16 = false; - UINT uiData = 0; - int bytes; - struct bcm_mini_adapter *psAd = psIntfAdapter->psAdapter; - - /* Store the usb dev into interface adapter */ - psIntfAdapter->udev = - usb_get_dev(interface_to_usbdev(psIntfAdapter->interface)); - - psIntfAdapter->bHighSpeedDevice = - (psIntfAdapter->udev->speed == USB_SPEED_HIGH); - psAd->interface_rdm = BcmRDM; - psAd->interface_wrm = BcmWRM; - - bytes = rdmalt(psAd, CHIP_ID_REG, (u32 *) &(psAd->chip_id), - sizeof(u32)); - if (bytes < 0) { - retval = bytes; - BCM_DEBUG_PRINT(psAd, DBG_TYPE_PRINTK, 0, 0, - "CHIP ID Read Failed\n"); - return retval; - } - - if (0xbece3200 == (psAd->chip_id & ~(0xF0))) - psAd->chip_id &= ~0xF0; - - dev_info(&psIntfAdapter->udev->dev, "RDM Chip ID 0x%lx\n", - psAd->chip_id); - - iface_desc = psIntfAdapter->interface->cur_altsetting; - - if (psAd->chip_id == T3B) { - /* T3B device will have EEPROM, check if EEPROM is proper and - * BCM16 can be done or not. */ - BeceemEEPROMBulkRead(psAd, &uiData, 0x0, 4); - if (uiData == BECM) - bBcm16 = TRUE; - - dev_info(&psIntfAdapter->udev->dev, - "number of alternate setting %d\n", - psIntfAdapter->interface->num_altsetting); - - if (bBcm16 == TRUE) { - retval = select_alternate_setting_for_highspeed_modem( - psIntfAdapter, &endpoint, iface_desc, - &usedIntOutForBulkTransfer); - if (retval) - return retval; - } - } - - iface_desc = psIntfAdapter->interface->cur_altsetting; - - for (value = 0; value < iface_desc->desc.bNumEndpoints; ++value) { - endpoint = &iface_desc->endpoint[value].desc; - - if (!psIntfAdapter->sBulkIn.bulk_in_endpointAddr && - usb_endpoint_is_bulk_in(endpoint)) { - buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); - psIntfAdapter->sBulkIn.bulk_in_size = buffer_size; - psIntfAdapter->sBulkIn.bulk_in_endpointAddr = - endpoint->bEndpointAddress; - psIntfAdapter->sBulkIn.bulk_in_pipe = usb_rcvbulkpipe( - psIntfAdapter->udev, - psIntfAdapter->sBulkIn.bulk_in_endpointAddr); - } - - if (!psIntfAdapter->sBulkOut.bulk_out_endpointAddr && - usb_endpoint_is_bulk_out(endpoint)) { - psIntfAdapter->sBulkOut.bulk_out_endpointAddr = - endpoint->bEndpointAddress; - psIntfAdapter->sBulkOut.bulk_out_pipe = usb_sndbulkpipe( - psIntfAdapter->udev, - psIntfAdapter->sBulkOut.bulk_out_endpointAddr); - } - - if (!psIntfAdapter->sIntrIn.int_in_endpointAddr && - usb_endpoint_is_int_in(endpoint)) { - buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); - psIntfAdapter->sIntrIn.int_in_size = buffer_size; - psIntfAdapter->sIntrIn.int_in_endpointAddr = - endpoint->bEndpointAddress; - psIntfAdapter->sIntrIn.int_in_interval = - endpoint->bInterval; - psIntfAdapter->sIntrIn.int_in_buffer = - kmalloc(buffer_size, GFP_KERNEL); - if (!psIntfAdapter->sIntrIn.int_in_buffer) - return -EINVAL; - } - - if (!psIntfAdapter->sIntrOut.int_out_endpointAddr && - usb_endpoint_is_int_out(endpoint)) { - if (!psIntfAdapter->sBulkOut.bulk_out_endpointAddr && - (psAd->chip_id == T3B) && - (value == usedIntOutForBulkTransfer)) { - /* - * use first intout end point as a bulk out end - * point - */ - buffer_size = - le16_to_cpu(endpoint->wMaxPacketSize); - psIntfAdapter->sBulkOut.bulk_out_size = - buffer_size; - psIntfAdapter->sBulkOut.bulk_out_endpointAddr = - endpoint->bEndpointAddress; - psIntfAdapter->sBulkOut.bulk_out_pipe = - usb_sndintpipe(psIntfAdapter->udev, - psIntfAdapter->sBulkOut - .bulk_out_endpointAddr); - psIntfAdapter->sBulkOut.int_out_interval = - endpoint->bInterval; - } else if (value == EP6) { - buffer_size = - le16_to_cpu(endpoint->wMaxPacketSize); - psIntfAdapter->sIntrOut.int_out_size = - buffer_size; - psIntfAdapter->sIntrOut.int_out_endpointAddr = - endpoint->bEndpointAddress; - psIntfAdapter->sIntrOut.int_out_interval = - endpoint->bInterval; - psIntfAdapter->sIntrOut.int_out_buffer = - kmalloc(buffer_size, GFP_KERNEL); - if (!psIntfAdapter->sIntrOut.int_out_buffer) - return -EINVAL; - } - } - } - - usb_set_intfdata(psIntfAdapter->interface, psIntfAdapter); - - psAd->bcm_file_download = InterfaceFileDownload; - psAd->bcm_file_readback_from_chip = InterfaceFileReadbackFromChip; - psAd->interface_transmit = InterfaceTransmitPacket; - - retval = CreateInterruptUrb(psIntfAdapter); - - if (retval) { - BCM_DEBUG_PRINT(psAd, DBG_TYPE_PRINTK, 0, 0, - "Cannot create interrupt urb\n"); - return retval; - } - - retval = AllocUsbCb(psIntfAdapter); - if (retval) - return retval; - - return device_run(psIntfAdapter); -} - -static int InterfaceSuspend(struct usb_interface *intf, pm_message_t message) -{ - struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf); - - psIntfAdapter->bSuspended = TRUE; - - if (psIntfAdapter->bPreparingForBusSuspend) { - psIntfAdapter->bPreparingForBusSuspend = false; - - if (psIntfAdapter->psAdapter->LinkStatus == LINKUP_DONE) { - psIntfAdapter->psAdapter->IdleMode = TRUE; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, - DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, - "Host Entered in PMU Idle Mode.\n"); - } else { - psIntfAdapter->psAdapter->bShutStatus = TRUE; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, - DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, - "Host Entered in PMU Shutdown Mode.\n"); - } - } - psIntfAdapter->psAdapter->bPreparingForLowPowerMode = false; - - /* Signaling the control pkt path */ - wake_up(&psIntfAdapter->psAdapter->lowpower_mode_wait_queue); - - return 0; -} - -static int InterfaceResume(struct usb_interface *intf) -{ - struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf); - - mdelay(100); - psIntfAdapter->bSuspended = false; - - StartInterruptUrb(psIntfAdapter); - InterfaceRx(psIntfAdapter); - return 0; -} - -static struct usb_driver usbbcm_driver = { - .name = "usbbcm", - .probe = usbbcm_device_probe, - .disconnect = usbbcm_disconnect, - .suspend = InterfaceSuspend, - .resume = InterfaceResume, - .id_table = InterfaceUsbtable, - .supports_autosuspend = 1, -}; - -struct class *bcm_class; - -static __init int bcm_init(void) -{ - int retval; - - pr_info("%s: %s, %s\n", DRV_NAME, DRV_DESCRIPTION, DRV_VERSION); - pr_info("%s\n", DRV_COPYRIGHT); - - bcm_class = class_create(THIS_MODULE, DRV_NAME); - if (IS_ERR(bcm_class)) { - pr_err(DRV_NAME ": could not create class\n"); - return PTR_ERR(bcm_class); - } - - retval = usb_register(&usbbcm_driver); - if (retval < 0) { - pr_err(DRV_NAME ": could not register usb driver\n"); - class_destroy(bcm_class); - return retval; - } - return 0; -} - -static __exit void bcm_exit(void) -{ - usb_deregister(&usbbcm_driver); - class_destroy(bcm_class); -} - -module_init(bcm_init); -module_exit(bcm_exit); - -MODULE_DESCRIPTION(DRV_DESCRIPTION); -MODULE_VERSION(DRV_VERSION); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/bcm/InterfaceInit.h b/drivers/staging/bcm/InterfaceInit.h deleted file mode 100644 index ffa6e9667ec4..000000000000 --- a/drivers/staging/bcm/InterfaceInit.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _INTERFACE_INIT_H -#define _INTERFACE_INIT_H - -#define BCM_USB_VENDOR_ID_T3 0x198f -#define BCM_USB_VENDOR_ID_FOXCONN 0x0489 -#define BCM_USB_VENDOR_ID_ZTE 0x19d2 - -#define BCM_USB_PRODUCT_ID_T3 0x0300 -#define BCM_USB_PRODUCT_ID_T3B 0x0210 -#define BCM_USB_PRODUCT_ID_T3L 0x0220 -#define BCM_USB_PRODUCT_ID_SYM 0x15E -#define BCM_USB_PRODUCT_ID_1901 0xe017 -#define BCM_USB_PRODUCT_ID_226 0x0132 /* not sure if this is valid */ -#define BCM_USB_PRODUCT_ID_ZTE_226 0x172 -#define BCM_USB_PRODUCT_ID_ZTE_326 0x173 /* ZTE AX326 */ -#define BCM_USB_PRODUCT_ID_ZTE_TU25 0x0007 - -#define BCM_USB_MINOR_BASE 192 - -int InterfaceInitialize(void); - -int InterfaceExit(void); - -int usbbcm_worker_thread(struct bcm_interface_adapter *psIntfAdapter); - -#endif diff --git a/drivers/staging/bcm/InterfaceIsr.c b/drivers/staging/bcm/InterfaceIsr.c deleted file mode 100644 index b9f8a7aa24fe..000000000000 --- a/drivers/staging/bcm/InterfaceIsr.c +++ /dev/null @@ -1,190 +0,0 @@ -#include "headers.h" - - -static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/) -{ - int status = urb->status; - struct bcm_interface_adapter *psIntfAdapter = - (struct bcm_interface_adapter *)urb->context; - struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter; - - if (netif_msg_intr(Adapter)) - pr_info(PFX "%s: interrupt status %d\n", - Adapter->dev->name, status); - - if (Adapter->device_removed) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, "Device has Got Removed."); - return; - } - - if ((Adapter->bPreparingForLowPowerMode && Adapter->bDoSuspend) || - psIntfAdapter->bSuspended || - psIntfAdapter->bPreparingForBusSuspend) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, - "Interrupt call back is called while suspending the device"); - return; - } - - switch (status) { - /* success */ - case STATUS_SUCCESS: - if (urb->actual_length) { - - if (psIntfAdapter->ulInterruptData[1] & 0xFF) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - INTF_INIT, DBG_LVL_ALL, - "Got USIM interrupt"); - } - - if (psIntfAdapter->ulInterruptData[1] & 0xFF00) { - atomic_set(&Adapter->CurrNumFreeTxDesc, - (psIntfAdapter->ulInterruptData[1] & - 0xFF00) >> 8); - atomic_set(&Adapter->uiMBupdate, TRUE); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - INTF_INIT, DBG_LVL_ALL, - "TX mailbox contains %d", - atomic_read(&Adapter->CurrNumFreeTxDesc)); - } - if (psIntfAdapter->ulInterruptData[1] >> 16) { - Adapter->CurrNumRecvDescs = - (psIntfAdapter->ulInterruptData[1] >> 16); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - INTF_INIT, DBG_LVL_ALL, - "RX mailbox contains %d", - Adapter->CurrNumRecvDescs); - InterfaceRx(psIntfAdapter); - } - if (Adapter->fw_download_done && - !Adapter->downloadDDR && - atomic_read(&Adapter->CurrNumFreeTxDesc)) { - - psIntfAdapter->psAdapter->downloadDDR += 1; - wake_up(&Adapter->tx_packet_wait_queue); - } - if (!Adapter->waiting_to_fw_download_done) { - Adapter->waiting_to_fw_download_done = TRUE; - wake_up(&Adapter->ioctl_fw_dnld_wait_queue); - } - if (!atomic_read(&Adapter->TxPktAvail)) { - atomic_set(&Adapter->TxPktAvail, 1); - wake_up(&Adapter->tx_packet_wait_queue); - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, "Firing interrupt in URB"); - } - break; - case -ENOENT: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, "URB has got disconnected...."); - return; - case -EINPROGRESS: - /* - * This situation may happened when URBunlink is used. for - * detail check usb_unlink_urb documentation. - */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, - "Impossibe condition has occurred... something very bad is going on"); - break; - /* return; */ - case -EPIPE: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, - "Interrupt IN endPoint has got halted/stalled...need to clear this"); - Adapter->bEndPointHalted = TRUE; - wake_up(&Adapter->tx_packet_wait_queue); - urb->status = STATUS_SUCCESS; - return; - /* software-driven interface shutdown */ - case -ECONNRESET: /* URB got unlinked */ - case -ESHUTDOWN: /* hardware gone. this is the serious problem */ - /* - * Occurs only when something happens with the - * host controller device - */ - case -ENODEV: /* Device got removed */ - case -EINVAL: - /* - * Some thing very bad happened with the URB. No - * description is available. - */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, "interrupt urb error %d", status); - urb->status = STATUS_SUCCESS; - break; - /* return; */ - default: - /* - * This is required to check what is the defaults conditions - * when it occurs.. - */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, - "GOT DEFAULT INTERRUPT URB STATUS :%d..Please Analyze it...", - status); - break; - } - - StartInterruptUrb(psIntfAdapter); - - -} - -int CreateInterruptUrb(struct bcm_interface_adapter *psIntfAdapter) -{ - psIntfAdapter->psInterruptUrb = usb_alloc_urb(0, GFP_KERNEL); - if (!psIntfAdapter->psInterruptUrb) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, - INTF_INIT, DBG_LVL_ALL, - "Cannot allocate interrupt urb"); - return -ENOMEM; - } - psIntfAdapter->psInterruptUrb->transfer_buffer = - psIntfAdapter->ulInterruptData; - psIntfAdapter->psInterruptUrb->transfer_buffer_length = - sizeof(psIntfAdapter->ulInterruptData); - - psIntfAdapter->sIntrIn.int_in_pipe = usb_rcvintpipe(psIntfAdapter->udev, - psIntfAdapter->sIntrIn.int_in_endpointAddr); - - usb_fill_int_urb(psIntfAdapter->psInterruptUrb, psIntfAdapter->udev, - psIntfAdapter->sIntrIn.int_in_pipe, - psIntfAdapter->psInterruptUrb->transfer_buffer, - psIntfAdapter->psInterruptUrb->transfer_buffer_length, - read_int_callback, psIntfAdapter, - psIntfAdapter->sIntrIn.int_in_interval); - - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, "Interrupt Interval: %d\n", - psIntfAdapter->sIntrIn.int_in_interval); - return 0; -} - - -INT StartInterruptUrb(struct bcm_interface_adapter *psIntfAdapter) -{ - INT status = 0; - - if (!(psIntfAdapter->psAdapter->device_removed || - psIntfAdapter->psAdapter->bEndPointHalted || - psIntfAdapter->bSuspended || - psIntfAdapter->bPreparingForBusSuspend || - psIntfAdapter->psAdapter->StopAllXaction)) { - status = - usb_submit_urb(psIntfAdapter->psInterruptUrb, GFP_ATOMIC); - if (status) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, - DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, - "Cannot send inturb %d\n", status); - if (status == -EPIPE) { - psIntfAdapter->psAdapter->bEndPointHalted = - TRUE; - wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); - } - } - } - return status; -} - diff --git a/drivers/staging/bcm/InterfaceIsr.h b/drivers/staging/bcm/InterfaceIsr.h deleted file mode 100644 index 3073bd71cfeb..000000000000 --- a/drivers/staging/bcm/InterfaceIsr.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _INTERFACE_ISR_H -#define _INTERFACE_ISR_H - -int CreateInterruptUrb(struct bcm_interface_adapter *psIntfAdapter); - - -INT StartInterruptUrb(struct bcm_interface_adapter *psIntfAdapter); - - -VOID InterfaceEnableInterrupt(struct bcm_mini_adapter *Adapter); - -VOID InterfaceDisableInterrupt(struct bcm_mini_adapter *Adapter); - -#endif - diff --git a/drivers/staging/bcm/InterfaceMacros.h b/drivers/staging/bcm/InterfaceMacros.h deleted file mode 100644 index fedb79437f33..000000000000 --- a/drivers/staging/bcm/InterfaceMacros.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _INTERFACE_MACROS_H -#define _INTERFACE_MACROS_H - -#define BCM_USB_MAX_READ_LENGTH 2048 - -#define MAXIMUM_USB_TCB 128 -#define MAXIMUM_USB_RCB 128 - -#define MAX_BUFFERS_PER_QUEUE 256 - -#define MAX_DATA_BUFFER_SIZE 2048 - -/* Num of Asynchronous reads pending */ -#define NUM_RX_DESC 64 - -#define SYS_CFG 0x0F000C00 - -#endif diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c deleted file mode 100644 index e5bcfec2a6cf..000000000000 --- a/drivers/staging/bcm/InterfaceMisc.c +++ /dev/null @@ -1,247 +0,0 @@ -#include "headers.h" - -static int adapter_err_occurred(const struct bcm_interface_adapter *ad) -{ - if (ad->psAdapter->device_removed == TRUE) { - BCM_DEBUG_PRINT(ad->psAdapter, DBG_TYPE_PRINTK, 0, 0, - "Device got removed"); - return -ENODEV; - } - - if ((ad->psAdapter->StopAllXaction == TRUE) && - (ad->psAdapter->chip_id >= T3LPB)) { - BCM_DEBUG_PRINT(ad->psAdapter, DBG_TYPE_OTHERS, RDM, - DBG_LVL_ALL, - "Currently Xaction is not allowed on the bus"); - return -EACCES; - } - - if (ad->bSuspended == TRUE || ad->bPreparingForBusSuspend == TRUE) { - BCM_DEBUG_PRINT(ad->psAdapter, DBG_TYPE_OTHERS, RDM, - DBG_LVL_ALL, - "Bus is in suspended states hence RDM not allowed.."); - return -EACCES; - } - - return 0; -} - -int InterfaceRDM(struct bcm_interface_adapter *psIntfAdapter, - unsigned int addr, - void *buff, - int len) -{ - int bytes; - int err = 0; - - if (!psIntfAdapter) - return -EINVAL; - - err = adapter_err_occurred(psIntfAdapter); - if (err) - return err; - - psIntfAdapter->psAdapter->DeviceAccess = TRUE; - - bytes = usb_control_msg(psIntfAdapter->udev, - usb_rcvctrlpipe(psIntfAdapter->udev, 0), - 0x02, - 0xC2, - (addr & 0xFFFF), - ((addr >> 16) & 0xFFFF), - buff, - len, - 5000); - - if (-ENODEV == bytes) - psIntfAdapter->psAdapter->device_removed = TRUE; - - if (bytes < 0) - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, - DBG_LVL_ALL, "RDM failed status :%d", bytes); - else - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, - DBG_LVL_ALL, "RDM sent %d", bytes); - - psIntfAdapter->psAdapter->DeviceAccess = false; - return bytes; -} - -int InterfaceWRM(struct bcm_interface_adapter *psIntfAdapter, - unsigned int addr, - void *buff, - int len) -{ - int retval = 0; - int err = 0; - - if (!psIntfAdapter) - return -EINVAL; - - err = adapter_err_occurred(psIntfAdapter); - if (err) - return err; - - psIntfAdapter->psAdapter->DeviceAccess = TRUE; - - retval = usb_control_msg(psIntfAdapter->udev, - usb_sndctrlpipe(psIntfAdapter->udev, 0), - 0x01, - 0x42, - (addr & 0xFFFF), - ((addr >> 16) & 0xFFFF), - buff, - len, - 5000); - - if (-ENODEV == retval) - psIntfAdapter->psAdapter->device_removed = TRUE; - - if (retval < 0) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, - DBG_LVL_ALL, "WRM failed status :%d", retval); - psIntfAdapter->psAdapter->DeviceAccess = false; - return retval; - } else { - psIntfAdapter->psAdapter->DeviceAccess = false; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, - DBG_LVL_ALL, "WRM sent %d", retval); - return STATUS_SUCCESS; - } -} - -int BcmRDM(void *arg, - unsigned int addr, - void *buff, - int len) -{ - return InterfaceRDM((struct bcm_interface_adapter *)arg, addr, buff, - len); -} - -int BcmWRM(void *arg, - unsigned int addr, - void *buff, - int len) -{ - return InterfaceWRM((struct bcm_interface_adapter *)arg, addr, buff, - len); -} - -int Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter) -{ - struct bcm_interface_adapter *psIntfAdapter = - (struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter); - int status = STATUS_SUCCESS; - - /* - * usb_clear_halt - tells device to clear endpoint halt/stall condition - * @dev: device whose endpoint is halted - * @pipe: endpoint "pipe" being cleared - * @ Context: !in_interrupt () - * - * usb_clear_halt is the synchrnous call and returns 0 on success else - * returns with error code. - * This is used to clear halt conditions for bulk and interrupt - * endpoints only. - * Control and isochronous endpoints never halts. - * - * Any URBs queued for such an endpoint should normally be unlinked by - * the driver before clearing the halt condition. - * - */ - - /* Killing all the submitted urbs to different end points. */ - Bcm_kill_all_URBs(psIntfAdapter); - - /* clear the halted/stalled state for every end point */ - status = usb_clear_halt(psIntfAdapter->udev, - psIntfAdapter->sIntrIn.int_in_pipe); - if (status != STATUS_SUCCESS) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, - "Unable to Clear Halt of Interrupt IN end point. :%d ", - status); - - status = usb_clear_halt(psIntfAdapter->udev, - psIntfAdapter->sBulkIn.bulk_in_pipe); - if (status != STATUS_SUCCESS) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, - "Unable to Clear Halt of Bulk IN end point. :%d ", - status); - - status = usb_clear_halt(psIntfAdapter->udev, - psIntfAdapter->sBulkOut.bulk_out_pipe); - if (status != STATUS_SUCCESS) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, - "Unable to Clear Halt of Bulk OUT end point. :%d ", - status); - - return status; -} - -void Bcm_kill_all_URBs(struct bcm_interface_adapter *psIntfAdapter) -{ - struct urb *tempUrb = NULL; - unsigned int i; - - /* - * usb_kill_urb - cancel a transfer request and wait for it to finish - * @urb: pointer to URB describing a previously submitted request, - * returns nothing as it is void returned API. - * - * This routine cancels an in-progress request. It is guaranteed that - * upon return all completion handlers will have finished and the URB - * will be totally idle and available for reuse - * - * This routine may not be used in an interrupt context (such as a - * bottom half or a completion handler), or when holding a spinlock, or - * in other situations where the caller can't schedule(). - * - */ - - /* Cancel submitted Interrupt-URB's */ - if (psIntfAdapter->psInterruptUrb) { - if (psIntfAdapter->psInterruptUrb->status == -EINPROGRESS) - usb_kill_urb(psIntfAdapter->psInterruptUrb); - } - - /* Cancel All submitted TX URB's */ - for (i = 0; i < MAXIMUM_USB_TCB; i++) { - tempUrb = psIntfAdapter->asUsbTcb[i].urb; - if (tempUrb) { - if (tempUrb->status == -EINPROGRESS) - usb_kill_urb(tempUrb); - } - } - - for (i = 0; i < MAXIMUM_USB_RCB; i++) { - tempUrb = psIntfAdapter->asUsbRcb[i].urb; - if (tempUrb) { - if (tempUrb->status == -EINPROGRESS) - usb_kill_urb(tempUrb); - } - } - - atomic_set(&psIntfAdapter->uNumTcbUsed, 0); - atomic_set(&psIntfAdapter->uCurrTcb, 0); - - atomic_set(&psIntfAdapter->uNumRcbUsed, 0); - atomic_set(&psIntfAdapter->uCurrRcb, 0); -} - -void putUsbSuspend(struct work_struct *work) -{ - struct bcm_interface_adapter *psIntfAdapter = NULL; - struct usb_interface *intf = NULL; - - psIntfAdapter = container_of(work, struct bcm_interface_adapter, - usbSuspendWork); - intf = psIntfAdapter->interface; - - if (psIntfAdapter->bSuspended == false) - usb_autopm_put_interface(intf); -} - diff --git a/drivers/staging/bcm/InterfaceMisc.h b/drivers/staging/bcm/InterfaceMisc.h deleted file mode 100644 index 0e5e38b26329..000000000000 --- a/drivers/staging/bcm/InterfaceMisc.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef __INTERFACE_MISC_H -#define __INTERFACE_MISC_H - -INT -InterfaceRDM(struct bcm_interface_adapter *psIntfAdapter, - UINT addr, - PVOID buff, - INT len); - -INT -InterfaceWRM(struct bcm_interface_adapter *psIntfAdapter, - UINT addr, - PVOID buff, - INT len); - - -int InterfaceFileDownload(PVOID psIntfAdapter, - struct file *flp, - unsigned int on_chip_loc); - -int InterfaceFileReadbackFromChip(PVOID psIntfAdapter, - struct file *flp, - unsigned int on_chip_loc); - - -int BcmRDM(PVOID arg, - UINT addr, - PVOID buff, - INT len); - -int BcmWRM(PVOID arg, - UINT addr, - PVOID buff, - INT len); - -INT Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter); - -VOID Bcm_kill_all_URBs(struct bcm_interface_adapter *psIntfAdapter); - -#define DISABLE_USB_ZERO_LEN_INT 0x0F011878 - -#endif /* __INTERFACE_MISC_H */ diff --git a/drivers/staging/bcm/InterfaceRx.c b/drivers/staging/bcm/InterfaceRx.c deleted file mode 100644 index 0f179b9382d3..000000000000 --- a/drivers/staging/bcm/InterfaceRx.c +++ /dev/null @@ -1,289 +0,0 @@ -#include "headers.h" - -static void handle_control_packet(struct bcm_interface_adapter *interface, - struct bcm_mini_adapter *ad, - struct bcm_leader *leader, - struct sk_buff *skb, - struct urb *urb) -{ - BCM_DEBUG_PRINT(interface->psAdapter, DBG_TYPE_RX, RX_CTRL, DBG_LVL_ALL, - "Received control pkt..."); - *(PUSHORT)skb->data = leader->Status; - memcpy(skb->data+sizeof(USHORT), urb->transfer_buffer + - (sizeof(struct bcm_leader)), leader->PLength); - skb->len = leader->PLength + sizeof(USHORT); - - spin_lock(&ad->control_queue_lock); - ENQUEUEPACKET(ad->RxControlHead, ad->RxControlTail, skb); - spin_unlock(&ad->control_queue_lock); - - atomic_inc(&ad->cntrlpktCnt); - wake_up(&ad->process_rx_cntrlpkt); -} - -static void format_eth_hdr_to_stack(struct bcm_interface_adapter *interface, - struct bcm_mini_adapter *ad, - struct bcm_leader *p_leader, - struct sk_buff *skb, - struct urb *urb, - UINT ui_index, - int queue_index, - bool b_header_supression_endabled) -{ - /* - * Data Packet, Format a proper Ethernet Header - * and give it to the stack - */ - BCM_DEBUG_PRINT(interface->psAdapter, DBG_TYPE_RX, RX_DATA, - DBG_LVL_ALL, "Received Data pkt..."); - skb_reserve(skb, 2 + SKB_RESERVE_PHS_BYTES); - memcpy(skb->data+ETH_HLEN, (PUCHAR)urb->transfer_buffer + - sizeof(struct bcm_leader), p_leader->PLength); - skb->dev = ad->dev; - - /* currently skb->len has extra ETH_HLEN bytes in the beginning */ - skb_put(skb, p_leader->PLength + ETH_HLEN); - ad->PackInfo[queue_index].uiTotalRxBytes += p_leader->PLength; - ad->PackInfo[queue_index].uiThisPeriodRxBytes += p_leader->PLength; - BCM_DEBUG_PRINT(interface->psAdapter, DBG_TYPE_RX, RX_DATA, - DBG_LVL_ALL, "Received Data pkt of len :0x%X", - p_leader->PLength); - - if (netif_running(ad->dev)) { - /* Moving ahead by ETH_HLEN to the data ptr as received from FW */ - skb_pull(skb, ETH_HLEN); - PHSReceive(ad, p_leader->Vcid, skb, &skb->len, - NULL, b_header_supression_endabled); - - if (!ad->PackInfo[queue_index].bEthCSSupport) { - skb_push(skb, ETH_HLEN); - - memcpy(skb->data, skb->dev->dev_addr, 6); - memcpy(skb->data+6, skb->dev->dev_addr, 6); - (*(skb->data+11))++; - *(skb->data+12) = 0x08; - *(skb->data+13) = 0x00; - p_leader->PLength += ETH_HLEN; - } - - skb->protocol = eth_type_trans(skb, ad->dev); - netif_rx(skb); - } else { - BCM_DEBUG_PRINT(interface->psAdapter, DBG_TYPE_RX, - RX_DATA, DBG_LVL_ALL, - "i/f not up hance freeing SKB..."); - dev_kfree_skb(skb); - } - - ++ad->dev->stats.rx_packets; - ad->dev->stats.rx_bytes += p_leader->PLength; - - for (ui_index = 0; ui_index < MIBS_MAX_HIST_ENTRIES; ui_index++) { - if ((p_leader->PLength <= - MIBS_PKTSIZEHIST_RANGE*(ui_index+1)) && - (p_leader->PLength > MIBS_PKTSIZEHIST_RANGE*(ui_index))) - - ad->aRxPktSizeHist[ui_index]++; - } -} - -static int SearchVcid(struct bcm_mini_adapter *Adapter, unsigned short usVcid) -{ - int iIndex = 0; - - for (iIndex = (NO_OF_QUEUES-1); iIndex >= 0; iIndex--) - if (Adapter->PackInfo[iIndex].usVCID_Value == usVcid) - return iIndex; - return NO_OF_QUEUES+1; - -} - - -static struct bcm_usb_rcb * -GetBulkInRcb(struct bcm_interface_adapter *psIntfAdapter) -{ - struct bcm_usb_rcb *pRcb = NULL; - UINT index = 0; - - if ((atomic_read(&psIntfAdapter->uNumRcbUsed) < MAXIMUM_USB_RCB) && - (psIntfAdapter->psAdapter->StopAllXaction == false)) { - index = atomic_read(&psIntfAdapter->uCurrRcb); - pRcb = &psIntfAdapter->asUsbRcb[index]; - pRcb->bUsed = TRUE; - pRcb->psIntfAdapter = psIntfAdapter; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX, RX_DPC, - DBG_LVL_ALL, "Got Rx desc %d used %d", index, - atomic_read(&psIntfAdapter->uNumRcbUsed)); - index = (index + 1) % MAXIMUM_USB_RCB; - atomic_set(&psIntfAdapter->uCurrRcb, index); - atomic_inc(&psIntfAdapter->uNumRcbUsed); - } - return pRcb; -} - -/*this is receive call back - when pkt available for receive (BULK IN- end point)*/ -static void read_bulk_callback(struct urb *urb) -{ - struct sk_buff *skb = NULL; - bool bHeaderSupressionEnabled = false; - int QueueIndex = NO_OF_QUEUES + 1; - UINT uiIndex = 0; - struct bcm_usb_rcb *pRcb = (struct bcm_usb_rcb *)urb->context; - struct bcm_interface_adapter *psIntfAdapter = pRcb->psIntfAdapter; - struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter; - struct bcm_leader *pLeader = urb->transfer_buffer; - - if (unlikely(netif_msg_rx_status(Adapter))) - pr_info(PFX "%s: rx urb status %d length %d\n", - Adapter->dev->name, urb->status, urb->actual_length); - - if ((Adapter->device_removed == TRUE) || - (TRUE == Adapter->bEndPointHalted) || - (0 == urb->actual_length)) { - pRcb->bUsed = false; - atomic_dec(&psIntfAdapter->uNumRcbUsed); - return; - } - - if (urb->status != STATUS_SUCCESS) { - if (urb->status == -EPIPE) { - Adapter->bEndPointHalted = TRUE; - wake_up(&Adapter->tx_packet_wait_queue); - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, - DBG_LVL_ALL, - "Rx URB has got cancelled. status :%d", - urb->status); - } - pRcb->bUsed = false; - atomic_dec(&psIntfAdapter->uNumRcbUsed); - urb->status = STATUS_SUCCESS; - return; - } - - if (Adapter->bDoSuspend && (Adapter->bPreparingForLowPowerMode)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, - "device is going in low power mode while PMU option selected..hence rx packet should not be process"); - return; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, - "Read back done len %d\n", pLeader->PLength); - if (!pLeader->PLength) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, - "Leader Length 0"); - atomic_dec(&psIntfAdapter->uNumRcbUsed); - return; - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, - "Leader Status:0x%hX, Length:0x%hX, VCID:0x%hX", - pLeader->Status, pLeader->PLength, pLeader->Vcid); - if (MAX_CNTL_PKT_SIZE < pLeader->PLength) { - if (netif_msg_rx_err(Adapter)) - pr_info(PFX "%s: corrupted leader length...%d\n", - Adapter->dev->name, pLeader->PLength); - ++Adapter->dev->stats.rx_dropped; - atomic_dec(&psIntfAdapter->uNumRcbUsed); - return; - } - - QueueIndex = SearchVcid(Adapter, pLeader->Vcid); - if (QueueIndex < NO_OF_QUEUES) { - bHeaderSupressionEnabled = - Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled; - bHeaderSupressionEnabled = - bHeaderSupressionEnabled & Adapter->bPHSEnabled; - } - - skb = dev_alloc_skb(pLeader->PLength + SKB_RESERVE_PHS_BYTES + - SKB_RESERVE_ETHERNET_HEADER); - if (!skb) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, - "NO SKBUFF!!! Dropping the Packet"); - atomic_dec(&psIntfAdapter->uNumRcbUsed); - return; - } - /* If it is a control Packet, then call handle_bcm_packet ()*/ - if ((ntohs(pLeader->Vcid) == VCID_CONTROL_PACKET) || - (!(pLeader->Status >= 0x20 && pLeader->Status <= 0x3F))) { - handle_control_packet(psIntfAdapter, Adapter, pLeader, skb, - urb); - } else { - format_eth_hdr_to_stack(psIntfAdapter, Adapter, pLeader, skb, - urb, uiIndex, QueueIndex, - bHeaderSupressionEnabled); - } - Adapter->PrevNumRecvDescs++; - pRcb->bUsed = false; - atomic_dec(&psIntfAdapter->uNumRcbUsed); -} - -static int ReceiveRcb(struct bcm_interface_adapter *psIntfAdapter, - struct bcm_usb_rcb *pRcb) -{ - struct urb *urb = pRcb->urb; - int retval = 0; - - usb_fill_bulk_urb(urb, psIntfAdapter->udev, - usb_rcvbulkpipe(psIntfAdapter->udev, - psIntfAdapter->sBulkIn.bulk_in_endpointAddr), - urb->transfer_buffer, - BCM_USB_MAX_READ_LENGTH, - read_bulk_callback, pRcb); - - if (false == psIntfAdapter->psAdapter->device_removed && - false == psIntfAdapter->psAdapter->bEndPointHalted && - false == psIntfAdapter->bSuspended && - false == psIntfAdapter->bPreparingForBusSuspend) { - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX, - RX_DPC, DBG_LVL_ALL, - "failed submitting read urb, error %d", - retval); - /* if this return value is because of pipe halt. need to clear this. */ - if (retval == -EPIPE) { - psIntfAdapter->psAdapter->bEndPointHalted = TRUE; - wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); - } - - } - } - return retval; -} - -/* -Function: InterfaceRx - -Description: This is the hardware specific Function for Receiving - data packet/control packets from the device. - -Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapter Context - - - -Return: TRUE - If Rx was successful. - Other - If an error occurred. -*/ - -bool InterfaceRx(struct bcm_interface_adapter *psIntfAdapter) -{ - USHORT RxDescCount = NUM_RX_DESC - - atomic_read(&psIntfAdapter->uNumRcbUsed); - - struct bcm_usb_rcb *pRcb = NULL; - - while (RxDescCount) { - pRcb = GetBulkInRcb(psIntfAdapter); - if (pRcb == NULL) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, - DBG_TYPE_PRINTK, 0, 0, - "Unable to get Rcb pointer"); - return false; - } - ReceiveRcb(psIntfAdapter, pRcb); - RxDescCount--; - } - return TRUE; -} - diff --git a/drivers/staging/bcm/InterfaceRx.h b/drivers/staging/bcm/InterfaceRx.h deleted file mode 100644 index b4e858bcda34..000000000000 --- a/drivers/staging/bcm/InterfaceRx.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _INTERFACE_RX_H -#define _INTERFACE_RX_H - -bool InterfaceRx(struct bcm_interface_adapter *Adapter); - -#endif - diff --git a/drivers/staging/bcm/InterfaceTx.c b/drivers/staging/bcm/InterfaceTx.c deleted file mode 100644 index 9b3f64b821ed..000000000000 --- a/drivers/staging/bcm/InterfaceTx.c +++ /dev/null @@ -1,213 +0,0 @@ -#include "headers.h" - -static void prepare_low_power_mode(struct urb *urb, - struct bcm_interface_adapter *interface, - struct bcm_mini_adapter *ps_adapter, - struct bcm_mini_adapter *ad, - struct bcm_link_request *p_control_msg, - bool *b_power_down_msg) -{ - if (((p_control_msg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) && - (p_control_msg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE))) { - - *b_power_down_msg = TRUE; - /* - * This covers the bus err while Idle Request msg - * sent down. - */ - if (urb->status != STATUS_SUCCESS) { - ps_adapter->bPreparingForLowPowerMode = false; - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND, - DBG_LVL_ALL, - "Idle Mode Request msg failed to reach to Modem"); - /* Signalling the cntrl pkt path in Ioctl */ - wake_up(&ps_adapter->lowpower_mode_wait_queue); - StartInterruptUrb(interface); - return; - } - - if (ps_adapter->bDoSuspend == false) { - ps_adapter->IdleMode = TRUE; - /* since going in Idle mode completed hence making this var false */ - ps_adapter->bPreparingForLowPowerMode = false; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND, - DBG_LVL_ALL, - "Host Entered in Idle Mode State..."); - /* Signalling the cntrl pkt path in Ioctl*/ - wake_up(&ps_adapter->lowpower_mode_wait_queue); - } - - } else if ((p_control_msg->Leader.Status == LINK_UP_CONTROL_REQ) && - (p_control_msg->szData[0] == LINK_UP_ACK) && - (p_control_msg->szData[1] == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) && - (p_control_msg->szData[2] == SHUTDOWN_ACK_FROM_DRIVER)) { - /* - * This covers the bus err while shutdown Request - * msg sent down. - */ - if (urb->status != STATUS_SUCCESS) { - ps_adapter->bPreparingForLowPowerMode = false; - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND, - DBG_LVL_ALL, - "Shutdown Request Msg failed to reach to Modem"); - /* Signalling the cntrl pkt path in Ioctl */ - wake_up(&ps_adapter->lowpower_mode_wait_queue); - StartInterruptUrb(interface); - return; - } - - *b_power_down_msg = TRUE; - if (ps_adapter->bDoSuspend == false) { - ps_adapter->bShutStatus = TRUE; - /* - * since going in shutdown mode completed hence - * making this var false - */ - ps_adapter->bPreparingForLowPowerMode = false; - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND, - DBG_LVL_ALL, - "Host Entered in shutdown Mode State..."); - /* Signalling the cntrl pkt path in Ioctl */ - wake_up(&ps_adapter->lowpower_mode_wait_queue); - } - } - - if (ps_adapter->bDoSuspend && *b_power_down_msg) { - /* issuing bus suspend request */ - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, - "Issuing the Bus suspend request to USB stack"); - interface->bPreparingForBusSuspend = TRUE; - schedule_work(&interface->usbSuspendWork); - } -} - -/*this is transmit call-back(BULK OUT)*/ -static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) -{ - struct bcm_usb_tcb *pTcb = (struct bcm_usb_tcb *)urb->context; - struct bcm_interface_adapter *psIntfAdapter = pTcb->psIntfAdapter; - struct bcm_link_request *pControlMsg = - (struct bcm_link_request *)urb->transfer_buffer; - struct bcm_mini_adapter *psAdapter = psIntfAdapter->psAdapter; - bool bpowerDownMsg = false; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if (unlikely(netif_msg_tx_done(Adapter))) - pr_info(PFX "%s: transmit status %d\n", Adapter->dev->name, - urb->status); - - if (urb->status != STATUS_SUCCESS) { - if (urb->status == -EPIPE) { - psIntfAdapter->psAdapter->bEndPointHalted = TRUE; - wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, - DBG_LVL_ALL, - "Tx URB has got cancelled. status :%d", - urb->status); - } - } - - pTcb->bUsed = false; - atomic_dec(&psIntfAdapter->uNumTcbUsed); - - if (TRUE == psAdapter->bPreparingForLowPowerMode) { - prepare_low_power_mode(urb, psIntfAdapter, psAdapter, Adapter, - pControlMsg, &bpowerDownMsg); - } - - usb_free_coherent(urb->dev, urb->transfer_buffer_length, - urb->transfer_buffer, urb->transfer_dma); -} - - -static struct bcm_usb_tcb *GetBulkOutTcb(struct bcm_interface_adapter *psIntfAdapter) -{ - struct bcm_usb_tcb *pTcb = NULL; - UINT index = 0; - - if ((atomic_read(&psIntfAdapter->uNumTcbUsed) < MAXIMUM_USB_TCB) && - (psIntfAdapter->psAdapter->StopAllXaction == false)) { - index = atomic_read(&psIntfAdapter->uCurrTcb); - pTcb = &psIntfAdapter->asUsbTcb[index]; - pTcb->bUsed = TRUE; - pTcb->psIntfAdapter = psIntfAdapter; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_TX, - NEXT_SEND, DBG_LVL_ALL, - "Got Tx desc %d used %d", - index, - atomic_read(&psIntfAdapter->uNumTcbUsed)); - index = (index + 1) % MAXIMUM_USB_TCB; - atomic_set(&psIntfAdapter->uCurrTcb, index); - atomic_inc(&psIntfAdapter->uNumTcbUsed); - } - return pTcb; -} - -static int TransmitTcb(struct bcm_interface_adapter *psIntfAdapter, - struct bcm_usb_tcb *pTcb, PVOID data, int len) -{ - - struct urb *urb = pTcb->urb; - int retval = 0; - - urb->transfer_buffer = usb_alloc_coherent(psIntfAdapter->udev, len, - GFP_ATOMIC, &urb->transfer_dma); - if (!urb->transfer_buffer) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, - "Error allocating memory\n"); - return -ENOMEM; - } - memcpy(urb->transfer_buffer, data, len); - urb->transfer_buffer_length = len; - - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_TX, NEXT_SEND, - DBG_LVL_ALL, "Sending Bulk out packet\n"); - /* For T3B,INT OUT end point will be used as bulk out end point */ - if ((psIntfAdapter->psAdapter->chip_id == T3B) && - (psIntfAdapter->bHighSpeedDevice == TRUE)) { - usb_fill_int_urb(urb, psIntfAdapter->udev, - psIntfAdapter->sBulkOut.bulk_out_pipe, - urb->transfer_buffer, len, write_bulk_callback, pTcb, - psIntfAdapter->sBulkOut.int_out_interval); - } else { - usb_fill_bulk_urb(urb, psIntfAdapter->udev, - psIntfAdapter->sBulkOut.bulk_out_pipe, - urb->transfer_buffer, len, write_bulk_callback, pTcb); - } - urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* For DMA transfer */ - - if (false == psIntfAdapter->psAdapter->device_removed && - false == psIntfAdapter->psAdapter->bEndPointHalted && - false == psIntfAdapter->bSuspended && - false == psIntfAdapter->bPreparingForBusSuspend) { - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_TX, - NEXT_SEND, DBG_LVL_ALL, - "failed submitting write urb, error %d", - retval); - if (retval == -EPIPE) { - psIntfAdapter->psAdapter->bEndPointHalted = TRUE; - wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); - } - } - } - return retval; -} - -int InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len) -{ - struct bcm_usb_tcb *pTcb = NULL; - struct bcm_interface_adapter *psIntfAdapter = arg; - - pTcb = GetBulkOutTcb(psIntfAdapter); - if (pTcb == NULL) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, - "No URB to transmit packet, dropping packet"); - return -EFAULT; - } - return TransmitTcb(psIntfAdapter, pTcb, data, len); -} - diff --git a/drivers/staging/bcm/InterfaceTx.h b/drivers/staging/bcm/InterfaceTx.h deleted file mode 100644 index 273147577c17..000000000000 --- a/drivers/staging/bcm/InterfaceTx.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _INTERFACE_TX_H -#define _INTERFACE_TX_H - -INT InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len); - -#endif - diff --git a/drivers/staging/bcm/Ioctl.h b/drivers/staging/bcm/Ioctl.h deleted file mode 100644 index fa5f8671612e..000000000000 --- a/drivers/staging/bcm/Ioctl.h +++ /dev/null @@ -1,226 +0,0 @@ -#ifndef _IOCTL_H_ -#define _IOCTL_H_ - -struct bcm_rdm_buffer { - unsigned long Register; - unsigned long Length; -} __packed; - -struct bcm_wrm_buffer { - unsigned long Register; - unsigned long Length; - unsigned char Data[4]; -} __packed; - -struct bcm_ioctl_buffer { - void __user *InputBuffer; - unsigned long InputLength; - void __user *OutputBuffer; - unsigned long OutputLength; -} __packed; - -struct bcm_gpio_info { - unsigned int uiGpioNumber; /* valid numbers 0-15 */ - unsigned int uiGpioValue; /* 1 set ; 0 not set */ -} __packed; - -struct bcm_user_thread_req { - /* 0->Inactivate LED thread. */ - /* 1->Activate the LED thread */ - unsigned int ThreadState; -} __packed; - -#define LED_THREAD_ACTIVATION_REQ 1 -#define BCM_IOCTL 'k' -#define IOCTL_SEND_CONTROL_MESSAGE _IOW(BCM_IOCTL, 0x801, int) -#define IOCTL_BCM_REGISTER_WRITE _IOW(BCM_IOCTL, 0x802, int) -#define IOCTL_BCM_REGISTER_READ _IOR(BCM_IOCTL, 0x803, int) -#define IOCTL_BCM_COMMON_MEMORY_WRITE _IOW(BCM_IOCTL, 0x804, int) -#define IOCTL_BCM_COMMON_MEMORY_READ _IOR(BCM_IOCTL, 0x805, int) -#define IOCTL_GET_CONTROL_MESSAGE _IOR(BCM_IOCTL, 0x806, int) -#define IOCTL_BCM_FIRMWARE_DOWNLOAD _IOW(BCM_IOCTL, 0x807, int) -#define IOCTL_BCM_SET_SEND_VCID _IOW(BCM_IOCTL, 0x808, int) -#define IOCTL_BCM_SWITCH_TRANSFER_MODE _IOW(BCM_IOCTL, 0x809, int) -#define IOCTL_LINK_REQ _IOW(BCM_IOCTL, 0x80A, int) -#define IOCTL_RSSI_LEVEL_REQ _IOW(BCM_IOCTL, 0x80B, int) -#define IOCTL_IDLE_REQ _IOW(BCM_IOCTL, 0x80C, int) -#define IOCTL_SS_INFO_REQ _IOW(BCM_IOCTL, 0x80D, int) -#define IOCTL_GET_STATISTICS_POINTER _IOW(BCM_IOCTL, 0x80E, int) -#define IOCTL_CM_REQUEST _IOW(BCM_IOCTL, 0x80F, int) -#define IOCTL_INIT_PARAM_REQ _IOW(BCM_IOCTL, 0x810, int) -#define IOCTL_MAC_ADDR_REQ _IOW(BCM_IOCTL, 0x811, int) -#define IOCTL_MAC_ADDR_RESP _IOWR(BCM_IOCTL, 0x812, int) -#define IOCTL_CLASSIFICATION_RULE _IOW(BCM_IOCTL, 0x813, char) -#define IOCTL_CLOSE_NOTIFICATION _IO(BCM_IOCTL, 0x814) -#define IOCTL_LINK_UP _IO(BCM_IOCTL, 0x815) -#define IOCTL_LINK_DOWN _IO(BCM_IOCTL, 0x816, struct bcm_ioctl_buffer) -#define IOCTL_CHIP_RESET _IO(BCM_IOCTL, 0x816) -#define IOCTL_CINR_LEVEL_REQ _IOW(BCM_IOCTL, 0x817, char) -#define IOCTL_WTM_CONTROL_REQ _IOW(BCM_IOCTL, 0x817, char) -#define IOCTL_BE_BUCKET_SIZE _IOW(BCM_IOCTL, 0x818, unsigned long) -#define IOCTL_RTPS_BUCKET_SIZE _IOW(BCM_IOCTL, 0x819, unsigned long) -#define IOCTL_QOS_THRESHOLD _IOW(BCM_IOCTL, 0x820, unsigned long) -#define IOCTL_DUMP_PACKET_INFO _IO(BCM_IOCTL, 0x821) -#define IOCTL_GET_PACK_INFO _IOR(BCM_IOCTL, 0x823, int) -#define IOCTL_BCM_GET_DRIVER_VERSION _IOR(BCM_IOCTL, 0x829, int) -#define IOCTL_BCM_GET_CURRENT_STATUS _IOW(BCM_IOCTL, 0x828, int) -#define IOCTL_BCM_GPIO_SET_REQUEST _IOW(BCM_IOCTL, 0x82A, int) -#define IOCTL_BCM_GPIO_STATUS_REQUEST _IOW(BCM_IOCTL, 0x82b, int) -#define IOCTL_BCM_GET_DSX_INDICATION _IOR(BCM_IOCTL, 0x854, int) -#define IOCTL_BCM_BUFFER_DOWNLOAD_START _IOW(BCM_IOCTL, 0x855, int) -#define IOCTL_BCM_BUFFER_DOWNLOAD _IOW(BCM_IOCTL, 0x856, int) -#define IOCTL_BCM_BUFFER_DOWNLOAD_STOP _IOW(BCM_IOCTL, 0x857, int) -#define IOCTL_BCM_REGISTER_WRITE_PRIVATE _IOW(BCM_IOCTL, 0x826, char) -#define IOCTL_BCM_REGISTER_READ_PRIVATE _IOW(BCM_IOCTL, 0x827, char) -#define IOCTL_BCM_SET_DEBUG _IOW(BCM_IOCTL, 0x824, struct bcm_ioctl_buffer) -#define IOCTL_BCM_EEPROM_REGISTER_WRITE _IOW(BCM_IOCTL, 0x858, int) -#define IOCTL_BCM_EEPROM_REGISTER_READ _IOR(BCM_IOCTL, 0x859, int) -#define IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE _IOR(BCM_IOCTL, 0x860, int) -#define IOCTL_BCM_SET_MAC_TRACING _IOW(BCM_IOCTL, 0x82c, int) -#define IOCTL_BCM_GET_HOST_MIBS _IOW(BCM_IOCTL, 0x853, int) -#define IOCTL_BCM_NVM_READ _IOR(BCM_IOCTL, 0x861, int) -#define IOCTL_BCM_NVM_WRITE _IOW(BCM_IOCTL, 0x862, int) -#define IOCTL_BCM_GET_NVM_SIZE _IOR(BCM_IOCTL, 0x863, int) -#define IOCTL_BCM_CAL_INIT _IOR(BCM_IOCTL, 0x864, int) -#define IOCTL_BCM_BULK_WRM _IOW(BCM_IOCTL, 0x90B, int) -#define IOCTL_BCM_FLASH2X_SECTION_READ _IOR(BCM_IOCTL, 0x865, int) -#define IOCTL_BCM_FLASH2X_SECTION_WRITE _IOW(BCM_IOCTL, 0x866, int) -#define IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP _IOR(BCM_IOCTL, 0x867, int) -#define IOCTL_BCM_SET_ACTIVE_SECTION _IOW(BCM_IOCTL, 0x868, int) -#define IOCTL_BCM_IDENTIFY_ACTIVE_SECTION _IO(BCM_IOCTL, 0x869) -#define IOCTL_BCM_COPY_SECTION _IOW(BCM_IOCTL, 0x870, int) -#define IOCTL_BCM_GET_FLASH_CS_INFO _IOR(BCM_IOCTL, 0x871, int) -#define IOCTL_BCM_SELECT_DSD _IOW(BCM_IOCTL, 0x872, int) -#define IOCTL_BCM_NVM_RAW_READ _IOR(BCM_IOCTL, 0x875, int) -#define IOCTL_BCM_CNTRLMSG_MASK _IOW(BCM_IOCTL, 0x874, int) -#define IOCTL_BCM_GET_DEVICE_DRIVER_INFO _IOR(BCM_IOCTL, 0x877, int) -#define IOCTL_BCM_TIME_SINCE_NET_ENTRY _IOR(BCM_IOCTL, 0x876, int) -#define BCM_LED_THREAD_STATE_CHANGE_REQ _IOW(BCM_IOCTL, 0x878, int) -#define IOCTL_BCM_GPIO_MULTI_REQUEST _IOW(BCM_IOCTL, 0x82D, struct bcm_ioctl_buffer) -#define IOCTL_BCM_GPIO_MODE_REQUEST _IOW(BCM_IOCTL, 0x82E, struct bcm_ioctl_buffer) - -enum bcm_interface_type { - BCM_MII, - BCM_CARDBUS, - BCM_USB, - BCM_SDIO, - BCM_PCMCIA -}; - -struct bcm_driver_info { - enum bcm_nvm_type u32NVMType; - unsigned int MaxRDMBufferSize; - enum bcm_interface_type u32InterfaceType; - unsigned int u32DSDStartOffset; - unsigned int u32RxAlignmentCorrection; - unsigned int u32Reserved[10]; -}; - -struct bcm_nvm_readwrite { - void __user *pBuffer; - uint32_t uiOffset; - uint32_t uiNumBytes; - bool bVerify; -}; - -struct bcm_bulk_wrm_buffer { - unsigned long Register; - unsigned long SwapEndian; - unsigned long Values[1]; -}; - -enum bcm_flash2x_section_val { - NO_SECTION_VAL = 0, /* no section chosen when absolute offset is given for RD/WR */ - ISO_IMAGE1, - ISO_IMAGE2, - DSD0, - DSD1, - DSD2, - VSA0, - VSA1, - VSA2, - SCSI, - CONTROL_SECTION, - ISO_IMAGE1_PART2, - ISO_IMAGE1_PART3, - ISO_IMAGE2_PART2, - ISO_IMAGE2_PART3, - TOTAL_SECTIONS -}; - -/* - * Structure used for READ/WRITE Flash Map2.x - */ -struct bcm_flash2x_readwrite { - enum bcm_flash2x_section_val Section; /* section to be read/written */ - u32 offset; /* offset within section. */ - u32 numOfBytes; /* number of bytes from the offset */ - u32 bVerify; - void __user *pDataBuff; /* buffer for reading/writing */ -}; - -/* - * This structure is used for coping one section to other. - * there are two ways to copy one section to other. - * it NOB =0, complete section will be copied on to other. - * if NOB !=0, only NOB will be copied from the given offset. - */ - -struct bcm_flash2x_copy_section { - enum bcm_flash2x_section_val SrcSection; - enum bcm_flash2x_section_val DstSection; - u32 offset; - u32 numOfBytes; -}; - -/* - * This section provide the complete bitmap of the Flash. - * using this map lib/APP will issue read/write command. - * Fields are defined as : - * Bit [0] = section is present //1:present, 0: Not present - * Bit [1] = section is valid //1: valid, 0: not valid - * Bit [2] = Section is R/W //0: RW, 1: RO - * Bit [3] = Section is Active or not 1 means Active, 0->inactive - * Bit [7...3] = Reserved - */ - -struct bcm_flash2x_bitmap { - unsigned char ISO_IMAGE1; - unsigned char ISO_IMAGE2; - unsigned char DSD0; - unsigned char DSD1; - unsigned char DSD2; - unsigned char VSA0; - unsigned char VSA1; - unsigned char VSA2; - unsigned char SCSI; - unsigned char CONTROL_SECTION; - /* Reserved for future use */ - unsigned char Reserved0; - unsigned char Reserved1; - unsigned char Reserved2; -}; - -struct bcm_time_elapsed { - u64 ul64TimeElapsedSinceNetEntry; - u32 uiReserved[4]; -}; - -enum { - WIMAX_IDX = 0, /* To access WiMAX chip GPIO's for GPIO_MULTI_INFO or GPIO_MULTI_MODE */ - HOST_IDX, /* To access Host chip GPIO's for GPIO_MULTI_INFO or GPIO_MULTI_MODE */ - MAX_IDX -}; - -struct bcm_gpio_multi_info { - unsigned int uiGPIOCommand; /* 1 for set and 0 for get */ - unsigned int uiGPIOMask; /* set the corresponding bit to 1 to access GPIO */ - unsigned int uiGPIOValue; /* 0 or 1; value to be set when command is 1. */ -} __packed; - -struct bcm_gpio_multi_mode { - unsigned int uiGPIOMode; /* 1 for OUT mode, 0 for IN mode */ - unsigned int uiGPIOMask; /* GPIO mask to set mode */ -} __packed; - -#endif diff --git a/drivers/staging/bcm/Kconfig b/drivers/staging/bcm/Kconfig deleted file mode 100644 index 8acf4b24a7c9..000000000000 --- a/drivers/staging/bcm/Kconfig +++ /dev/null @@ -1,6 +0,0 @@ -config BCM_WIMAX - tristate "Beceem BCS200/BCS220-3 and BCSM250 wimax support" - depends on USB && NET - help - This is an experimental driver for the Beceem WIMAX chipset used - by Sprint 4G. diff --git a/drivers/staging/bcm/LeakyBucket.c b/drivers/staging/bcm/LeakyBucket.c deleted file mode 100644 index d6b55f993b57..000000000000 --- a/drivers/staging/bcm/LeakyBucket.c +++ /dev/null @@ -1,364 +0,0 @@ -/********************************************************************** -* LEAKYBUCKET.C -* This file contains the routines related to Leaky Bucket Algorithm. -***********************************************************************/ -#include "headers.h" - -/** - * UpdateTokenCount() - Calculates the token count for each channel - * and updates the same in Adapter structure - * @Adapter: Pointer to the Adapter structure. - * - * Return: None - */ -static VOID UpdateTokenCount(register struct bcm_mini_adapter *Adapter) -{ - ULONG liCurrentTime; - INT i = 0; - struct timeval tv; - struct bcm_packet_info *curr_pi; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, - "=====>\n"); - if (NULL == Adapter) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, - DBG_LVL_ALL, "Adapter found NULL!\n"); - return; - } - - do_gettimeofday(&tv); - for (i = 0; i < NO_OF_QUEUES; i++) { - curr_pi = &Adapter->PackInfo[i]; - - if (TRUE == curr_pi->bValid && (1 == curr_pi->ucDirection)) { - liCurrentTime = ((tv.tv_sec - - curr_pi->stLastUpdateTokenAt.tv_sec)*1000 + - (tv.tv_usec - curr_pi->stLastUpdateTokenAt.tv_usec) / - 1000); - if (0 != liCurrentTime) { - curr_pi->uiCurrentTokenCount += (ULONG) - ((curr_pi->uiMaxAllowedRate) * - ((ULONG)((liCurrentTime)))/1000); - memcpy(&curr_pi->stLastUpdateTokenAt, &tv, - sizeof(struct timeval)); - curr_pi->liLastUpdateTokenAt = liCurrentTime; - if (curr_pi->uiCurrentTokenCount >= - curr_pi->uiMaxBucketSize) { - curr_pi->uiCurrentTokenCount = - curr_pi->uiMaxBucketSize; - } - } - } - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, - "<=====\n"); -} - - -/** - * IsPacketAllowedForFlow() - This function checks whether the given - * packet from the specified queue can be allowed for transmission by - * checking the token count. - * @Adapter: Pointer to the Adpater structure. - * @iQIndex: The queue Identifier. - * @ulPacketLength: Number of bytes to be transmitted. - * - * Returns: The number of bytes allowed for transmission. - */ -static ULONG GetSFTokenCount(struct bcm_mini_adapter *Adapter, struct bcm_packet_info *psSF) -{ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, - "IsPacketAllowedForFlow ===>"); - - /* Validate the parameters */ - if (NULL == Adapter || (psSF < Adapter->PackInfo && - (uintptr_t)psSF > (uintptr_t) &Adapter->PackInfo[HiPriority])) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, - "IPAFF: Got wrong Parameters:Adapter: %p, QIndex: %zd\n", - Adapter, (psSF-Adapter->PackInfo)); - return 0; - } - - if (false != psSF->bValid && psSF->ucDirection) { - if (0 != psSF->uiCurrentTokenCount) { - return psSF->uiCurrentTokenCount; - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, - DBG_LVL_ALL, - "Not enough tokens in queue %zd Available %u\n", - psSF-Adapter->PackInfo, psSF->uiCurrentTokenCount); - psSF->uiPendedLast = 1; - } - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, - "IPAFF: Queue %zd not valid\n", - psSF-Adapter->PackInfo); - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, - "IsPacketAllowedForFlow <==="); - return 0; -} - -/** -@ingroup tx_functions -This function despatches packet from the specified queue. -@return Zero(success) or Negative value(failure) -*/ -static INT SendPacketFromQueue(struct bcm_mini_adapter *Adapter,/**<Logical Adapter*/ - struct bcm_packet_info *psSF, /**<Queue identifier*/ - struct sk_buff *Packet) /**<Pointer to the packet to be sent*/ -{ - INT Status = STATUS_FAILURE; - UINT uiIndex = 0, PktLen = 0; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, - "=====>"); - if (!Adapter || !Packet || !psSF) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, - "Got NULL Adapter or Packet"); - return -EINVAL; - } - - if (psSF->liDrainCalculated == 0) - psSF->liDrainCalculated = jiffies; - /* send the packet to the fifo.. */ - PktLen = Packet->len; - Status = SetupNextSend(Adapter, Packet, psSF->usVCID_Value); - if (Status == 0) { - for (uiIndex = 0; uiIndex < MIBS_MAX_HIST_ENTRIES; uiIndex++) { - if ((PktLen <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1)) && - (PktLen > MIBS_PKTSIZEHIST_RANGE*(uiIndex))) - Adapter->aTxPktSizeHist[uiIndex]++; - } - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, - "<====="); - return Status; -} - -static void get_data_packet(struct bcm_mini_adapter *ad, - struct bcm_packet_info *ps_sf) -{ - int packet_len; - struct sk_buff *qpacket; - - if (!ps_sf->ucDirection) - return; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - "UpdateTokenCount "); - if (ad->IdleMode || ad->bPreparingForLowPowerMode) - return; /* in idle mode */ - - /* Check for Free Descriptors */ - if (atomic_read(&ad->CurrNumFreeTxDesc) <= - MINIMUM_PENDING_DESCRIPTORS) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - " No Free Tx Descriptor(%d) is available for Data pkt..", - atomic_read(&ad->CurrNumFreeTxDesc)); - return; - } - - spin_lock_bh(&ps_sf->SFQueueLock); - qpacket = ps_sf->FirstTxQueue; - - if (qpacket) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - "Dequeuing Data Packet"); - - if (ps_sf->bEthCSSupport) - packet_len = qpacket->len; - else - packet_len = qpacket->len - ETH_HLEN; - - packet_len <<= 3; - if (packet_len <= GetSFTokenCount(ad, ps_sf)) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, - DBG_LVL_ALL, "Allowed bytes %d", - (packet_len >> 3)); - - DEQUEUEPACKET(ps_sf->FirstTxQueue, ps_sf->LastTxQueue); - ps_sf->uiCurrentBytesOnHost -= (qpacket->len); - ps_sf->uiCurrentPacketsOnHost--; - atomic_dec(&ad->TotalPacketCount); - spin_unlock_bh(&ps_sf->SFQueueLock); - - SendPacketFromQueue(ad, ps_sf, qpacket); - ps_sf->uiPendedLast = false; - } else { - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, - DBG_LVL_ALL, "For Queue: %zd\n", - ps_sf - ad->PackInfo); - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, - DBG_LVL_ALL, - "\nAvailable Tokens = %d required = %d\n", - ps_sf->uiCurrentTokenCount, - packet_len); - /* - this part indicates that because of - non-availability of the tokens - pkt has not been send out hence setting the - pending flag indicating the host to send it out - first next iteration. - */ - ps_sf->uiPendedLast = TRUE; - spin_unlock_bh(&ps_sf->SFQueueLock); - } - } else { - spin_unlock_bh(&ps_sf->SFQueueLock); - } -} - -static void send_control_packet(struct bcm_mini_adapter *ad, - struct bcm_packet_info *ps_sf) -{ - char *ctrl_packet = NULL; - INT status = 0; - - if ((atomic_read(&ad->CurrNumFreeTxDesc) > 0) && - (atomic_read(&ad->index_rd_txcntrlpkt) != - atomic_read(&ad->index_wr_txcntrlpkt))) { - ctrl_packet = ad->txctlpacket - [(atomic_read(&ad->index_rd_txcntrlpkt)%MAX_CNTRL_PKTS)]; - if (ctrl_packet) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, - DBG_LVL_ALL, - "Sending Control packet"); - status = SendControlPacket(ad, ctrl_packet); - if (STATUS_SUCCESS == status) { - spin_lock_bh(&ps_sf->SFQueueLock); - ps_sf->NumOfPacketsSent++; - ps_sf->uiSentBytes += ((struct bcm_leader *)ctrl_packet)->PLength; - ps_sf->uiSentPackets++; - atomic_dec(&ad->TotalPacketCount); - ps_sf->uiCurrentBytesOnHost -= ((struct bcm_leader *)ctrl_packet)->PLength; - ps_sf->uiCurrentPacketsOnHost--; - atomic_inc(&ad->index_rd_txcntrlpkt); - spin_unlock_bh(&ps_sf->SFQueueLock); - } else { - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, - DBG_LVL_ALL, - "SendControlPacket Failed\n"); - } - } else { - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, - DBG_LVL_ALL, - " Control Pkt is not available, Indexing is wrong...."); - } - } -} - -/** - * CheckAndSendPacketFromIndex() - This function dequeues the - * data/control packet from the specified queue for transmission. - * @Adapter: Pointer to the driver control structure. - * @iQIndex: The queue Identifier. - * - * Returns: None. - */ -static VOID CheckAndSendPacketFromIndex(struct bcm_mini_adapter *Adapter, - struct bcm_packet_info *psSF) -{ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - "%zd ====>", (psSF-Adapter->PackInfo)); - if ((psSF != &Adapter->PackInfo[HiPriority]) && - Adapter->LinkUpStatus && - atomic_read(&psSF->uiPerSFTxResourceCount)) { /* Get data packet */ - - get_data_packet(Adapter, psSF); - } else { - send_control_packet(Adapter, psSF); - } -} - - -/** - * transmit_packets() - This function transmits the packets from - * different queues, if free descriptors are available on target. - * @Adapter: Pointer to the Adapter structure. - * - * Returns: None. - */ -VOID transmit_packets(struct bcm_mini_adapter *Adapter) -{ - UINT uiPrevTotalCount = 0; - int iIndex = 0; - - bool exit_flag = TRUE; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - "=====>"); - - if (NULL == Adapter) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - "Got NULL Adapter"); - return; - } - if (Adapter->device_removed == TRUE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - "Device removed"); - return; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - "\nUpdateTokenCount ====>\n"); - - UpdateTokenCount(Adapter); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - "\nPruneQueueAllSF ====>\n"); - - PruneQueueAllSF(Adapter); - - uiPrevTotalCount = atomic_read(&Adapter->TotalPacketCount); - - for (iIndex = HiPriority; iIndex >= 0; iIndex--) { - if (!uiPrevTotalCount || (TRUE == Adapter->device_removed)) - break; - - if (Adapter->PackInfo[iIndex].bValid && - Adapter->PackInfo[iIndex].uiPendedLast && - Adapter->PackInfo[iIndex].uiCurrentBytesOnHost) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, - DBG_LVL_ALL, - "Calling CheckAndSendPacketFromIndex.."); - CheckAndSendPacketFromIndex(Adapter, - &Adapter->PackInfo[iIndex]); - uiPrevTotalCount--; - } - } - - while (uiPrevTotalCount > 0 && !Adapter->device_removed) { - exit_flag = TRUE; - /* second iteration to parse non-pending queues */ - for (iIndex = HiPriority; iIndex >= 0; iIndex--) { - if (!uiPrevTotalCount || - (TRUE == Adapter->device_removed)) - break; - - if (Adapter->PackInfo[iIndex].bValid && - Adapter->PackInfo[iIndex].uiCurrentBytesOnHost && - !Adapter->PackInfo[iIndex].uiPendedLast) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, - TX_PACKETS, DBG_LVL_ALL, - "Calling CheckAndSendPacketFromIndex.."); - CheckAndSendPacketFromIndex(Adapter, &Adapter->PackInfo[iIndex]); - uiPrevTotalCount--; - exit_flag = false; - } - } - - if (Adapter->IdleMode || Adapter->bPreparingForLowPowerMode) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, - DBG_LVL_ALL, "In Idle Mode\n"); - break; - } - if (exit_flag == TRUE) - break; - } /* end of inner while loop */ - - update_per_cid_rx(Adapter); - Adapter->txtransmit_running = 0; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - "<======"); -} diff --git a/drivers/staging/bcm/Macros.h b/drivers/staging/bcm/Macros.h deleted file mode 100644 index dc01e3016d4f..000000000000 --- a/drivers/staging/bcm/Macros.h +++ /dev/null @@ -1,352 +0,0 @@ -/************************************* -* Macros.h -**************************************/ -#ifndef __MACROS_H__ -#define __MACROS_H__ - -#define TX_TIMER_PERIOD 10 /*10 msec*/ -#define MAX_CLASSIFIERS 100 -#define MAX_TARGET_DSX_BUFFERS 24 - -#define MAX_CNTRL_PKTS 100 -#define MAX_DATA_PKTS 200 -#define MAX_ETH_SIZE 1536 -#define MAX_CNTL_PKT_SIZE 2048 - -#define MTU_SIZE 1400 -#define TX_QLEN 5 - -#define MAC_ADDR_REGISTER 0xbf60d000 - - -/* Quality of Service */ -#define NO_OF_QUEUES 17 -#define HiPriority (NO_OF_QUEUES-1) -#define LowPriority 0 -#define BE 2 -#define rtPS 4 -#define ERTPS 5 -#define UGS 6 - -#define BE_BUCKET_SIZE (1024*1024*100) /* 32kb */ -#define rtPS_BUCKET_SIZE (1024*1024*100) /* 8kb */ -#define MAX_ALLOWED_RATE (1024*1024*100) -#define TX_PACKET_THRESHOLD 10 -#define XSECONDS (1*HZ) -#define DSC_ACTIVATE_REQUEST 248 -#define QUEUE_DEPTH_OFFSET 0x1fc01000 -#define MAX_DEVICE_DESC_SIZE 2040 -#define MAX_CTRL_QUEUE_LEN 100 -#define MAX_APP_QUEUE_LEN 200 -#define MAX_LATENCY_ALLOWED 0xFFFFFFFF -#define DEFAULT_UG_INTERVAL 250 -#define DEFAULT_UGI_FACTOR 4 - -#define DEFAULT_PERSFCOUNT 60 -#define MAX_CONNECTIONS 10 -#define MAX_CLASS_NAME_LENGTH 32 - -#define ETH_LENGTH_OF_ADDRESS 6 -#define MAX_MULTICAST_ADDRESSES 32 -#define IP_LENGTH_OF_ADDRESS 4 - -#define IP_PACKET_ONLY_MODE 0 -#define ETH_PACKET_TUNNELING_MODE 1 - -/* Link Request */ -#define SET_MAC_ADDRESS_REQUEST 0 -#define SYNC_UP_REQUEST 1 -#define SYNCED_UP 2 -#define LINK_UP_REQUEST 3 -#define LINK_CONNECTED 4 -#define SYNC_UP_NOTIFICATION 2 -#define LINK_UP_NOTIFICATION 4 - - -#define LINK_NET_ENTRY 0x0002 -#define HMC_STATUS 0x0004 -#define LINK_UP_CONTROL_REQ 0x83 - -#define STATS_POINTER_REQ_STATUS 0x86 -#define NETWORK_ENTRY_REQ_PAYLOAD 198 -#define LINK_DOWN_REQ_PAYLOAD 226 -#define SYNC_UP_REQ_PAYLOAD 228 -#define STATISTICS_POINTER_REQ 237 -#define LINK_UP_REQ_PAYLOAD 245 -#define LINK_UP_ACK 246 - -#define STATS_MSG_SIZE 4 -#define INDEX_TO_DATA 4 - -#define GO_TO_IDLE_MODE_PAYLOAD 210 -#define COME_UP_FROM_IDLE_MODE_PAYLOAD 211 -#define IDLE_MODE_SF_UPDATE_MSG 187 - -#define SKB_RESERVE_ETHERNET_HEADER 16 -#define SKB_RESERVE_PHS_BYTES 32 - -#define IP_PACKET_ONLY_MODE 0 -#define ETH_PACKET_TUNNELING_MODE 1 - -#define ETH_CS_802_3 1 -#define ETH_CS_802_1Q_VLAN 3 -#define IPV4_CS 1 -#define IPV6_CS 2 -#define ETH_CS_MASK 0x3f - -/** \brief Validity bit maps for TLVs in packet classification rule */ - -#define PKT_CLASSIFICATION_USER_PRIORITY_VALID 0 -#define PKT_CLASSIFICATION_VLANID_VALID 1 - -#ifndef MIN -#define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b)) -#endif - - -/*Leader related terms */ -#define LEADER_STATUS 0x00 -#define LEADER_STATUS_TCP_ACK 0x1 -#define LEADER_SIZE sizeof(struct bcm_leader) -#define MAC_ADDR_REQ_SIZE sizeof(struct bcm_packettosend) -#define SS_INFO_REQ_SIZE sizeof(struct bcm_packettosend) -#define CM_REQUEST_SIZE (LEADER_SIZE + sizeof(stLocalSFChangeRequest)) -#define IDLE_REQ_SIZE sizeof(struct bcm_packettosend) - - -#define MAX_TRANSFER_CTRL_BYTE_USB (2*1024) - -#define GET_MAILBOX1_REG_REQUEST 0x87 -#define GET_MAILBOX1_REG_RESPONSE 0x67 -#define VCID_CONTROL_PACKET 0x00 - -#define TRANSMIT_NETWORK_DATA 0x00 -#define RECEIVED_NETWORK_DATA 0x20 - -#define CM_RESPONSES 0xA0 -#define STATUS_RSP 0xA1 -#define LINK_CONTROL_RESP 0xA2 -#define IDLE_MODE_STATUS 0xA3 -#define STATS_POINTER_RESP 0xA6 -#define MGMT_MSG_INFO_SW_STATUS 0xA7 -#define AUTH_SS_HOST_MSG 0xA8 - -#define CM_DSA_ACK_PAYLOAD 247 -#define CM_DSC_ACK_PAYLOAD 248 -#define CM_DSD_ACK_PAYLOAD 249 -#define CM_DSDEACTVATE 250 -#define TOTAL_MASKED_ADDRESS_IN_BYTES 32 - -#define MAC_REQ 0 -#define LINK_RESP 1 -#define RSSI_INDICATION 2 - -#define SS_INFO 4 -#define STATISTICS_INFO 5 -#define CM_INDICATION 6 -#define PARAM_RESP 7 -#define BUFFER_1K 1024 -#define BUFFER_2K (BUFFER_1K*2) -#define BUFFER_4K (BUFFER_2K*2) -#define BUFFER_8K (BUFFER_4K*2) -#define BUFFER_16K (BUFFER_8K*2) -#define DOWNLINK_DIR 0 -#define UPLINK_DIR 1 - -#define BCM_SIGNATURE "BECEEM" - - -#define GPIO_OUTPUT_REGISTER 0x0F00003C -#define BCM_GPIO_OUTPUT_SET_REG 0x0F000040 -#define BCM_GPIO_OUTPUT_CLR_REG 0x0F000044 -#define GPIO_MODE_REGISTER 0x0F000034 -#define GPIO_PIN_STATE_REGISTER 0x0F000038 - -struct bcm_link_state { - unsigned char ucLinkStatus; - unsigned char bIdleMode; - unsigned char bShutdownMode; -}; - -enum enLinkStatus { - WAIT_FOR_SYNC = 1, - PHY_SYNC_ACHIVED = 2, - LINKUP_IN_PROGRESS = 3, - LINKUP_DONE = 4, - DREG_RECEIVED = 5, - LINK_STATUS_RESET_RECEIVED = 6, - PERIODIC_WAKE_UP_NOTIFICATION_FRM_FW = 7, - LINK_SHUTDOWN_REQ_FROM_FIRMWARE = 8, - COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW = 9 -}; - -enum bcm_phs_dsc_action { - eAddPHSRule = 0, - eSetPHSRule, - eDeletePHSRule, - eDeleteAllPHSRules -}; - -#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ 0x89 /* Host to Mac */ -#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP 0xA9 /* Mac to Host */ -#define MASK_DISABLE_HEADER_SUPPRESSION 0x10 /* 0b000010000 */ -#define MINIMUM_PENDING_DESCRIPTORS 5 - -#define SHUTDOWN_HOSTINITIATED_REQUESTPAYLOAD 0xCC -#define SHUTDOWN_ACK_FROM_DRIVER 0x1 -#define SHUTDOWN_NACK_FROM_DRIVER 0x2 - -#define LINK_SYNC_UP_SUBTYPE 0x0001 -#define LINK_SYNC_DOWN_SUBTYPE 0x0001 - - - -#define CONT_MODE 1 -#define SINGLE_DESCRIPTOR 1 - - -#define DESCRIPTOR_LENGTH 0x30 -#define FIRMWARE_DESCS_ADDRESS 0x1F100000 - - -#define CLOCK_RESET_CNTRL_REG_1 0x0F00000C -#define CLOCK_RESET_CNTRL_REG_2 0x0F000840 - - - -#define TX_DESCRIPTOR_HEAD_REGISTER 0x0F010034 -#define RX_DESCRIPTOR_HEAD_REGISTER 0x0F010094 - -#define STATISTICS_BEGIN_ADDR 0xbf60f02c - -#define MAX_PENDING_CTRL_PACKET (MAX_CTRL_QUEUE_LEN-10) - -#define WIMAX_MAX_MTU (MTU_SIZE + ETH_HLEN) -#define AUTO_LINKUP_ENABLE 0x2 -#define AUTO_SYNC_DISABLE 0x1 -#define AUTO_FIRM_DOWNLOAD 0x1 -#define SETTLE_DOWN_TIME 50 - -#define HOST_BUS_SUSPEND_BIT 16 - -#define IDLE_MESSAGE 0x81 - -#define MIPS_CLOCK_133MHz 1 - -#define TARGET_CAN_GO_TO_IDLE_MODE 2 -#define TARGET_CAN_NOT_GO_TO_IDLE_MODE 3 -#define IDLE_MODE_PAYLOAD_LENGTH 8 - -#define IP_HEADER(Buffer) ((IPHeaderFormat *)(Buffer)) -#define IPV4 4 -#define IP_VERSION(byte) (((byte&0xF0)>>4)) - -#define SET_MAC_ADDRESS 193 -#define SET_MAC_ADDRESS_RESPONSE 236 - -#define IDLE_MODE_WAKEUP_PATTERN 0xd0ea1d1e -#define IDLE_MODE_WAKEUP_NOTIFIER_ADDRESS 0x1FC02FA8 -#define IDLE_MODE_MAX_RETRY_COUNT 1000 - -#define CONFIG_BEGIN_ADDR 0xBF60B000 - -#define FIRMWARE_BEGIN_ADDR 0xBFC00000 - -#define INVALID_QUEUE_INDEX NO_OF_QUEUES - -#define INVALID_PID ((pid_t)-1) -#define DDR_80_MHZ 0 -#define DDR_100_MHZ 1 -#define DDR_120_MHZ 2 /* Additional Frequency for T3LP */ -#define DDR_133_MHZ 3 -#define DDR_140_MHZ 4 /* Not Used (Reserved for future) */ -#define DDR_160_MHZ 5 /* Additional Frequency for T3LP */ -#define DDR_180_MHZ 6 /* Not Used (Reserved for future) */ -#define DDR_200_MHZ 7 /* Not Used (Reserved for future) */ - -#define MIPS_200_MHZ 0 -#define MIPS_160_MHZ 1 - -#define PLL_800_MHZ 0 -#define PLL_266_MHZ 1 - -#define DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING 0 -#define DEVICE_POWERSAVE_MODE_AS_PMU_CLOCK_GATING 1 -#define DEVICE_POWERSAVE_MODE_AS_PMU_SHUTDOWN 2 -#define DEVICE_POWERSAVE_MODE_AS_RESERVED 3 -#define DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE 4 - - -#define EEPROM_REJECT_REG_1 0x0f003018 -#define EEPROM_REJECT_REG_2 0x0f00301c -#define EEPROM_REJECT_REG_3 0x0f003008 -#define EEPROM_REJECT_REG_4 0x0f003020 -#define EEPROM_REJECT_MASK 0x0fffffff -#define VSG_MODE 0x3 - -/* Idle Mode Related Registers */ -#define DEBUG_INTERRUPT_GENERATOR_REGISTOR 0x0F00007C -#define SW_ABORT_IDLEMODE_LOC 0x0FF01FFC - -#define SW_ABORT_IDLEMODE_PATTERN 0xd0ea1d1e -#define DEVICE_INT_OUT_EP_REG0 0x0F011870 -#define DEVICE_INT_OUT_EP_REG1 0x0F011874 - -#define BIN_FILE "/lib/firmware/macxvi200.bin" -#define CFG_FILE "/lib/firmware/macxvi.cfg" -#define SF_MAX_ALLOWED_PACKETS_TO_BACKUP 128 -#define MIN_VAL(x, y) ((x) < (y) ? (x) : (y)) -#define MAC_ADDRESS_SIZE 6 -#define EEPROM_COMMAND_Q_REG 0x0F003018 -#define EEPROM_READ_DATA_Q_REG 0x0F003020 -#define CHIP_ID_REG 0x0F000000 -#define GPIO_MODE_REG 0x0F000034 -#define GPIO_OUTPUT_REG 0x0F00003C -#define WIMAX_MAX_ALLOWED_RATE (1024*1024*50) - -#define T3 0xbece0300 -#define TARGET_SFID_TXDESC_MAP_LOC 0xBFFFF400 - -#define RWM_READ 0 -#define RWM_WRITE 1 - -#define T3LPB 0xbece3300 -#define BCS220_2 0xbece3311 -#define BCS220_2BC 0xBECE3310 -#define BCS250_BC 0xbece3301 -#define BCS220_3 0xbece3321 - - -#define HPM_CONFIG_LDO145 0x0F000D54 -#define HPM_CONFIG_MSW 0x0F000D58 - -#define T3B 0xbece0310 -enum bcm_nvm_type { - NVM_AUTODETECT = 0, - NVM_EEPROM, - NVM_FLASH, - NVM_UNKNOWN -}; - -enum bcm_pmu_modes { - HYBRID_MODE_7C = 0, - INTERNAL_MODE_6 = 1, - HYBRID_MODE_6 = 2 -}; - -#define MAX_RDM_WRM_RETIRES 1 - -enum eAbortPattern { - ABORT_SHUTDOWN_MODE = 1, - ABORT_IDLE_REG = 1, - ABORT_IDLE_MODE = 2, - ABORT_IDLE_SYNCDOWN = 3 -}; - - -/* Offsets used by driver in skb cb variable */ -#define SKB_CB_CLASSIFICATION_OFFSET 0 -#define SKB_CB_LATENCY_OFFSET 1 -#define SKB_CB_TCPACK_OFFSET 2 - -#endif /* __MACROS_H__ */ diff --git a/drivers/staging/bcm/Makefile b/drivers/staging/bcm/Makefile deleted file mode 100644 index 652b7f87737c..000000000000 --- a/drivers/staging/bcm/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# -# Makefile for Beceem USB Wimax card -# - -obj-$(CONFIG_BCM_WIMAX) += bcm_wimax.o - -bcm_wimax-y := InterfaceDld.o InterfaceIdleMode.o InterfaceInit.o InterfaceRx.o \ - InterfaceIsr.o InterfaceMisc.o InterfaceTx.o \ - CmHost.o IPv6Protocol.o Qos.o Transmit.o\ - Bcmnet.o DDRInit.o HandleControlPacket.o\ - LeakyBucket.o Misc.o sort.o Bcmchar.o hostmibs.o PHSModule.o\ - led_control.o nvm.o vendorspecificextn.o diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c deleted file mode 100644 index 883f7394dee6..000000000000 --- a/drivers/staging/bcm/Misc.c +++ /dev/null @@ -1,1587 +0,0 @@ -#include "headers.h" - -static int BcmFileDownload(struct bcm_mini_adapter *Adapter, const char *path, unsigned int loc); -static void doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter); -static void HandleShutDownModeRequest(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer); -static int bcm_parse_target_params(struct bcm_mini_adapter *Adapter); -static void beceem_protocol_reset(struct bcm_mini_adapter *Adapter); - -static void default_wimax_protocol_initialize(struct bcm_mini_adapter *Adapter) -{ - unsigned int uiLoopIndex; - - for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES-1; uiLoopIndex++) { - Adapter->PackInfo[uiLoopIndex].uiThreshold = TX_PACKET_THRESHOLD; - Adapter->PackInfo[uiLoopIndex].uiMaxAllowedRate = MAX_ALLOWED_RATE; - Adapter->PackInfo[uiLoopIndex].uiMaxBucketSize = 20*1024*1024; - } - - Adapter->BEBucketSize = BE_BUCKET_SIZE; - Adapter->rtPSBucketSize = rtPS_BUCKET_SIZE; - Adapter->LinkStatus = SYNC_UP_REQUEST; - Adapter->TransferMode = IP_PACKET_ONLY_MODE; - Adapter->usBestEffortQueueIndex = -1; -} - -int InitAdapter(struct bcm_mini_adapter *psAdapter) -{ - int i = 0; - int Status = STATUS_SUCCESS; - - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Initialising Adapter = %p", psAdapter); - - if (psAdapter == NULL) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Adapter is NULL"); - return -EINVAL; - } - - sema_init(&psAdapter->NVMRdmWrmLock, 1); - sema_init(&psAdapter->rdmwrmsync, 1); - spin_lock_init(&psAdapter->control_queue_lock); - spin_lock_init(&psAdapter->txtransmitlock); - sema_init(&psAdapter->RxAppControlQueuelock, 1); - sema_init(&psAdapter->fw_download_sema, 1); - sema_init(&psAdapter->LowPowerModeSync, 1); - - for (i = 0; i < NO_OF_QUEUES; i++) - spin_lock_init(&psAdapter->PackInfo[i].SFQueueLock); - i = 0; - - init_waitqueue_head(&psAdapter->process_rx_cntrlpkt); - init_waitqueue_head(&psAdapter->tx_packet_wait_queue); - init_waitqueue_head(&psAdapter->process_read_wait_queue); - init_waitqueue_head(&psAdapter->ioctl_fw_dnld_wait_queue); - init_waitqueue_head(&psAdapter->lowpower_mode_wait_queue); - psAdapter->waiting_to_fw_download_done = TRUE; - psAdapter->fw_download_done = false; - - default_wimax_protocol_initialize(psAdapter); - for (i = 0; i < MAX_CNTRL_PKTS; i++) { - psAdapter->txctlpacket[i] = kmalloc(MAX_CNTL_PKT_SIZE, GFP_KERNEL); - if (!psAdapter->txctlpacket[i]) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No More Cntl pkts got, max got is %d", i); - return -ENOMEM; - } - } - - if (AllocAdapterDsxBuffer(psAdapter)) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to allocate DSX buffers"); - return -EINVAL; - } - - /* Initialize PHS interface */ - if (phs_init(&psAdapter->stBCMPhsContext, psAdapter) != 0) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "%s:%s:%d:Error PHS Init Failed=====>\n", __FILE__, __func__, __LINE__); - return -ENOMEM; - } - - Status = BcmAllocFlashCSStructure(psAdapter); - if (Status) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Memory Allocation for Flash structure failed"); - return Status; - } - - Status = vendorextnInit(psAdapter); - - if (STATUS_SUCCESS != Status) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Vendor Init Failed"); - return Status; - } - - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Adapter initialised"); - - return STATUS_SUCCESS; -} - -void AdapterFree(struct bcm_mini_adapter *Adapter) -{ - int count; - - beceem_protocol_reset(Adapter); - vendorextnExit(Adapter); - - if (Adapter->control_packet_handler && !IS_ERR(Adapter->control_packet_handler)) - kthread_stop(Adapter->control_packet_handler); - - if (Adapter->transmit_packet_thread && !IS_ERR(Adapter->transmit_packet_thread)) - kthread_stop(Adapter->transmit_packet_thread); - - wake_up(&Adapter->process_read_wait_queue); - - if (Adapter->LEDInfo.led_thread_running & (BCM_LED_THREAD_RUNNING_ACTIVELY | BCM_LED_THREAD_RUNNING_INACTIVELY)) - kthread_stop(Adapter->LEDInfo.led_cntrl_threadid); - - unregister_networkdev(Adapter); - - /* FIXME: use proper wait_event and refcounting */ - while (atomic_read(&Adapter->ApplicationRunning)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Waiting for Application to close.. %d\n", atomic_read(&Adapter->ApplicationRunning)); - msleep(100); - } - unregister_control_device_interface(Adapter); - kfree(Adapter->pstargetparams); - - for (count = 0; count < MAX_CNTRL_PKTS; count++) - kfree(Adapter->txctlpacket[count]); - - FreeAdapterDsxBuffer(Adapter); - kfree(Adapter->pvInterfaceAdapter); - - /* Free the PHS Interface */ - PhsCleanup(&Adapter->stBCMPhsContext); - - BcmDeAllocFlashCSStructure(Adapter); - - free_netdev(Adapter->dev); -} - -static int create_worker_threads(struct bcm_mini_adapter *psAdapter) -{ - /* Rx Control Packets Processing */ - psAdapter->control_packet_handler = kthread_run((int (*)(void *)) - control_packet_handler, psAdapter, "%s-rx", DRV_NAME); - if (IS_ERR(psAdapter->control_packet_handler)) { - pr_notice(DRV_NAME ": could not create control thread\n"); - return PTR_ERR(psAdapter->control_packet_handler); - } - - /* Tx Thread */ - psAdapter->transmit_packet_thread = kthread_run((int (*)(void *)) - tx_pkt_handler, psAdapter, "%s-tx", DRV_NAME); - if (IS_ERR(psAdapter->transmit_packet_thread)) { - pr_notice(DRV_NAME ": could not creat transmit thread\n"); - kthread_stop(psAdapter->control_packet_handler); - return PTR_ERR(psAdapter->transmit_packet_thread); - } - return 0; -} - -static struct file *open_firmware_file(struct bcm_mini_adapter *Adapter, const char *path) -{ - struct file *flp = filp_open(path, O_RDONLY, S_IRWXU); - - if (IS_ERR(flp)) { - pr_err(DRV_NAME "Unable To Open File %s, err %ld", path, PTR_ERR(flp)); - flp = NULL; - } - - if (Adapter->device_removed) - flp = NULL; - - return flp; -} - -/* Arguments: - * Logical Adapter - * Path to image file - * Download Address on the chip - */ -static int BcmFileDownload(struct bcm_mini_adapter *Adapter, const char *path, unsigned int loc) -{ - int errorno = 0; - struct file *flp = NULL; - struct timeval tv = {0}; - - flp = open_firmware_file(Adapter, path); - if (!flp) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Unable to Open %s\n", path); - return -ENOENT; - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Opened file is = %s and length =0x%lx to be downloaded at =0x%x", path, (unsigned long)file_inode(flp)->i_size, loc); - do_gettimeofday(&tv); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "download start %lx", ((tv.tv_sec * 1000) + (tv.tv_usec / 1000))); - if (Adapter->bcm_file_download(Adapter->pvInterfaceAdapter, flp, loc)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to download the firmware with error %x!!!", -EIO); - errorno = -EIO; - goto exit_download; - } - vfs_llseek(flp, 0, 0); - if (Adapter->bcm_file_readback_from_chip(Adapter->pvInterfaceAdapter, flp, loc)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to read back firmware!"); - errorno = -EIO; - goto exit_download; - } - -exit_download: - filp_close(flp, NULL); - return errorno; -} - -/** - * @ingroup ctrl_pkt_functions - * This function copies the contents of given buffer - * to the control packet and queues it for transmission. - * @note Do not acquire the spinlock, as it it already acquired. - * @return SUCCESS/FAILURE. - * Arguments: - * Logical Adapter - * Control Packet Buffer - */ -int CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, void *ioBuffer) -{ - struct bcm_leader *pLeader = NULL; - int Status = 0; - unsigned char *ctrl_buff; - unsigned int pktlen = 0; - struct bcm_link_request *pLinkReq = NULL; - PUCHAR pucAddIndication = NULL; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "======>"); - if (!ioBuffer) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Got Null Buffer\n"); - return -EINVAL; - } - - pLinkReq = (struct bcm_link_request *)ioBuffer; - pLeader = (struct bcm_leader *)ioBuffer; /* ioBuffer Contains sw_Status and Payload */ - - if (Adapter->bShutStatus == TRUE && - pLinkReq->szData[0] == LINK_DOWN_REQ_PAYLOAD && - pLinkReq->szData[1] == LINK_SYNC_UP_SUBTYPE) { - - /* Got sync down in SHUTDOWN..we could not process this. */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "SYNC DOWN Request in Shut Down Mode..\n"); - return STATUS_FAILURE; - } - - if ((pLeader->Status == LINK_UP_CONTROL_REQ) && - ((pLinkReq->szData[0] == LINK_UP_REQ_PAYLOAD && - (pLinkReq->szData[1] == LINK_SYNC_UP_SUBTYPE)) || /* Sync Up Command */ - pLinkReq->szData[0] == NETWORK_ENTRY_REQ_PAYLOAD)) /* Net Entry Command */ { - - if (Adapter->LinkStatus > PHY_SYNC_ACHIVED) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "LinkStatus is Greater than PHY_SYN_ACHIEVED"); - return STATUS_FAILURE; - } - - if (Adapter->bShutStatus == TRUE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "SYNC UP IN SHUTDOWN..Device WakeUp\n"); - if (Adapter->bTriedToWakeUpFromlowPowerMode == false) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Waking up for the First Time..\n"); - Adapter->usIdleModePattern = ABORT_SHUTDOWN_MODE; /* change it to 1 for current support. */ - Adapter->bWakeUpDevice = TRUE; - wake_up(&Adapter->process_rx_cntrlpkt); - Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue, !Adapter->bShutStatus, (5 * HZ)); - - if (Status == -ERESTARTSYS) - return Status; - - if (Adapter->bShutStatus) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Shutdown Mode Wake up Failed - No Wake Up Received\n"); - return STATUS_FAILURE; - } - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Wakeup has been tried already...\n"); - } - } - } - - if (Adapter->IdleMode == TRUE) { - /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle mode ... hence\n"); */ - if (pLeader->Status == LINK_UP_CONTROL_REQ || pLeader->Status == 0x80 || - pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ) { - - if ((pLeader->Status == LINK_UP_CONTROL_REQ) && (pLinkReq->szData[0] == LINK_DOWN_REQ_PAYLOAD)) { - if (pLinkReq->szData[1] == LINK_SYNC_DOWN_SUBTYPE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Link Down Sent in Idle Mode\n"); - Adapter->usIdleModePattern = ABORT_IDLE_SYNCDOWN; /* LINK DOWN sent in Idle Mode */ - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "ABORT_IDLE_MODE pattern is being written\n"); - Adapter->usIdleModePattern = ABORT_IDLE_REG; - } - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "ABORT_IDLE_MODE pattern is being written\n"); - Adapter->usIdleModePattern = ABORT_IDLE_MODE; - } - - /*Setting bIdleMode_tx_from_host to TRUE to indicate LED control thread to represent - * the wake up from idlemode is from host - */ - /* Adapter->LEDInfo.bIdleMode_tx_from_host = TRUE; */ - Adapter->bWakeUpDevice = TRUE; - wake_up(&Adapter->process_rx_cntrlpkt); - - /* We should not send DREG message down while in idlemode. */ - if (LINK_DOWN_REQ_PAYLOAD == pLinkReq->szData[0]) - return STATUS_SUCCESS; - - Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue, !Adapter->IdleMode, (5 * HZ)); - - if (Status == -ERESTARTSYS) - return Status; - - if (Adapter->IdleMode) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Idle Mode Wake up Failed - No Wake Up Received\n"); - return STATUS_FAILURE; - } - } else { - return STATUS_SUCCESS; - } - } - - /* The Driver has to send control messages with a particular VCID */ - pLeader->Vcid = VCID_CONTROL_PACKET; /* VCID for control packet. */ - - /* Allocate skb for Control Packet */ - pktlen = pLeader->PLength; - ctrl_buff = (char *)Adapter->txctlpacket[atomic_read(&Adapter->index_wr_txcntrlpkt)%MAX_CNTRL_PKTS]; - - if (!ctrl_buff) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "mem allocation Failed"); - return -ENOMEM; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Control packet to be taken =%d and address is =%pincoming address is =%p and packet len=%x", - atomic_read(&Adapter->index_wr_txcntrlpkt), ctrl_buff, ioBuffer, pktlen); - - if (pLeader) { - if ((pLeader->Status == 0x80) || - (pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ)) { - /* - * Restructure the DSX message to handle Multiple classifier Support - * Write the Service Flow param Structures directly to the target - * and embed the pointers in the DSX messages sent to target. - */ - /* Lets store the current length of the control packet we are transmitting */ - pucAddIndication = (PUCHAR)ioBuffer + LEADER_SIZE; - pktlen = pLeader->PLength; - Status = StoreCmControlResponseMessage(Adapter, pucAddIndication, &pktlen); - if (Status != 1) { - ClearTargetDSXBuffer(Adapter, ((struct bcm_add_indication_alt *)pucAddIndication)->u16TID, false); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, " Error Restoring The DSX Control Packet. Dsx Buffers on Target may not be Setup Properly "); - return STATUS_FAILURE; - } - /* - * update the leader to use the new length - * The length of the control packet is length of message being sent + Leader length - */ - pLeader->PLength = pktlen; - } - } - - if (pktlen + LEADER_SIZE > MAX_CNTL_PKT_SIZE) - return -EINVAL; - - memset(ctrl_buff, 0, pktlen+LEADER_SIZE); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Copying the Control Packet Buffer with length=%d\n", pLeader->PLength); - *(struct bcm_leader *)ctrl_buff = *pLeader; - memcpy(ctrl_buff + LEADER_SIZE, ((PUCHAR)ioBuffer + LEADER_SIZE), pLeader->PLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Enqueuing the Control Packet"); - - /* Update the statistics counters */ - spin_lock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock); - Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost += pLeader->PLength; - Adapter->PackInfo[HiPriority].uiCurrentPacketsOnHost++; - atomic_inc(&Adapter->TotalPacketCount); - spin_unlock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock); - Adapter->PackInfo[HiPriority].bValid = TRUE; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "CurrBytesOnHost: %x bValid: %x", - Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost, - Adapter->PackInfo[HiPriority].bValid); - Status = STATUS_SUCCESS; - /*Queue the packet for transmission */ - atomic_inc(&Adapter->index_wr_txcntrlpkt); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Calling transmit_packets"); - atomic_set(&Adapter->TxPktAvail, 1); - wake_up(&Adapter->tx_packet_wait_queue); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<===="); - return Status; -} - -/****************************************************************** -* Function - LinkMessage() -* -* Description - This function builds the Sync-up and Link-up request -* packet messages depending on the device Link status. -* -* Parameters - Adapter: Pointer to the Adapter structure. -* -* Returns - None. -*******************************************************************/ -void LinkMessage(struct bcm_mini_adapter *Adapter) -{ - struct bcm_link_request *pstLinkRequest = NULL; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "=====>"); - if (Adapter->LinkStatus == SYNC_UP_REQUEST && Adapter->AutoSyncup) { - pstLinkRequest = kzalloc(sizeof(struct bcm_link_request), GFP_ATOMIC); - if (!pstLinkRequest) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Can not allocate memory for Link request!"); - return; - } - /* sync up request... */ - Adapter->LinkStatus = WAIT_FOR_SYNC; /* current link status */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Requesting For SyncUp..."); - pstLinkRequest->szData[0] = LINK_UP_REQ_PAYLOAD; - pstLinkRequest->szData[1] = LINK_SYNC_UP_SUBTYPE; - pstLinkRequest->Leader.Status = LINK_UP_CONTROL_REQ; - pstLinkRequest->Leader.PLength = sizeof(ULONG); - Adapter->bSyncUpRequestSent = TRUE; - - } else if (Adapter->LinkStatus == PHY_SYNC_ACHIVED && Adapter->AutoLinkUp) { - pstLinkRequest = kzalloc(sizeof(struct bcm_link_request), GFP_ATOMIC); - if (!pstLinkRequest) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Can not allocate memory for Link request!"); - return; - } - /* LINK_UP_REQUEST */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Requesting For LinkUp..."); - pstLinkRequest->szData[0] = LINK_UP_REQ_PAYLOAD; - pstLinkRequest->szData[1] = LINK_NET_ENTRY; - pstLinkRequest->Leader.Status = LINK_UP_CONTROL_REQ; - pstLinkRequest->Leader.PLength = sizeof(ULONG); - } - if (pstLinkRequest) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Calling CopyBufferToControlPacket"); - CopyBufferToControlPacket(Adapter, pstLinkRequest); - kfree(pstLinkRequest); - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "LinkMessage <====="); - return; -} - -/********************************************************************** -* Function - StatisticsResponse() -* -* Description - This function handles the Statistics response packet. -* -* Parameters - Adapter : Pointer to the Adapter structure. -* - pvBuffer: Starting address of Statistic response data. -* -* Returns - None. -************************************************************************/ -void StatisticsResponse(struct bcm_mini_adapter *Adapter, void *pvBuffer) -{ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s====>", __func__); - Adapter->StatisticsPointer = ntohl(*(__be32 *)pvBuffer); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %x", (unsigned int)Adapter->StatisticsPointer); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s <====", __func__); -} - -/********************************************************************** -* Function - LinkControlResponseMessage() -* -* Description - This function handles the Link response packets. -* -* Parameters - Adapter : Pointer to the Adapter structure. -* - pucBuffer: Starting address of Link response data. -* -* Returns - None. -***********************************************************************/ -void LinkControlResponseMessage(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer) -{ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "=====>"); - - if (*pucBuffer == LINK_UP_ACK) { - switch (*(pucBuffer+1)) { - case PHY_SYNC_ACHIVED: /* SYNCed UP */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "PHY_SYNC_ACHIVED"); - - if (Adapter->LinkStatus == LINKUP_DONE) - beceem_protocol_reset(Adapter); - - Adapter->usBestEffortQueueIndex = INVALID_QUEUE_INDEX; - Adapter->LinkStatus = PHY_SYNC_ACHIVED; - - if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { - Adapter->DriverState = NO_NETWORK_ENTRY; - wake_up(&Adapter->LEDInfo.notify_led_event); - } - - LinkMessage(Adapter); - break; - - case LINKUP_DONE: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "LINKUP_DONE"); - Adapter->LinkStatus = LINKUP_DONE; - Adapter->bPHSEnabled = *(pucBuffer+3); - Adapter->bETHCSEnabled = *(pucBuffer+4) & ETH_CS_MASK; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "PHS Support Status Received In LinkUp Ack : %x\n", Adapter->bPHSEnabled); - - if ((false == Adapter->bShutStatus) && (false == Adapter->IdleMode)) { - if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { - Adapter->DriverState = NORMAL_OPERATION; - wake_up(&Adapter->LEDInfo.notify_led_event); - } - } - LinkMessage(Adapter); - break; - - case WAIT_FOR_SYNC: - /* - * Driver to ignore the DREG_RECEIVED - * WiMAX Application should handle this Message - */ - /* Adapter->liTimeSinceLastNetEntry = 0; */ - Adapter->LinkUpStatus = 0; - Adapter->LinkStatus = 0; - Adapter->usBestEffortQueueIndex = INVALID_QUEUE_INDEX; - Adapter->bTriedToWakeUpFromlowPowerMode = false; - Adapter->IdleMode = false; - beceem_protocol_reset(Adapter); - - break; - case LINK_SHUTDOWN_REQ_FROM_FIRMWARE: - case COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW: - { - HandleShutDownModeRequest(Adapter, pucBuffer); - } - break; - default: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "default case:LinkResponse %x", *(pucBuffer + 1)); - break; - } - } else if (SET_MAC_ADDRESS_RESPONSE == *pucBuffer) { - PUCHAR puMacAddr = (pucBuffer + 1); - - Adapter->LinkStatus = SYNC_UP_REQUEST; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "MAC address response, sending SYNC_UP"); - LinkMessage(Adapter); - memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE); - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "%s <=====", __func__); -} - -void SendIdleModeResponse(struct bcm_mini_adapter *Adapter) -{ - int status = 0, NVMAccess = 0, lowPwrAbortMsg = 0; - struct timeval tv; - struct bcm_link_request stIdleResponse = {{0} }; - - memset(&tv, 0, sizeof(tv)); - stIdleResponse.Leader.Status = IDLE_MESSAGE; - stIdleResponse.Leader.PLength = IDLE_MODE_PAYLOAD_LENGTH; - stIdleResponse.szData[0] = GO_TO_IDLE_MODE_PAYLOAD; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, " ============>"); - - /********************************* - *down_trylock - - * if [ semaphore is available ] - * acquire semaphone and return value 0 ; - * else - * return non-zero value ; - * - ***********************************/ - - NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); - lowPwrAbortMsg = down_trylock(&Adapter->LowPowerModeSync); - - - if ((NVMAccess || lowPwrAbortMsg || atomic_read(&Adapter->TotalPacketCount)) && - (Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)) { - - if (!NVMAccess) - up(&Adapter->NVMRdmWrmLock); - - if (!lowPwrAbortMsg) - up(&Adapter->LowPowerModeSync); - - stIdleResponse.szData[1] = TARGET_CAN_NOT_GO_TO_IDLE_MODE; /* NACK- device access is going on. */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "HOST IS NACKING Idle mode To F/W!!!!!!!!"); - Adapter->bPreparingForLowPowerMode = false; - } else { - stIdleResponse.szData[1] = TARGET_CAN_GO_TO_IDLE_MODE; /* 2; Idle ACK */ - Adapter->StatisticsPointer = 0; - - /* Wait for the LED to TURN OFF before sending ACK response */ - if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { - int iRetVal = 0; - - /* Wake the LED Thread with IDLEMODE_ENTER State */ - Adapter->DriverState = LOWPOWER_MODE_ENTER; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "LED Thread is Running..Hence Setting LED Event as IDLEMODE_ENTER jiffies:%ld", jiffies); - wake_up(&Adapter->LEDInfo.notify_led_event); - - /* Wait for 1 SEC for LED to OFF */ - iRetVal = wait_event_timeout(Adapter->LEDInfo.idleModeSyncEvent, Adapter->LEDInfo.bIdle_led_off, msecs_to_jiffies(1000)); - - /* If Timed Out to Sync IDLE MODE Enter, do IDLE mode Exit and Send NACK to device */ - if (iRetVal <= 0) { - stIdleResponse.szData[1] = TARGET_CAN_NOT_GO_TO_IDLE_MODE; /* NACK- device access is going on. */ - Adapter->DriverState = NORMAL_OPERATION; - wake_up(&Adapter->LEDInfo.notify_led_event); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "NACKING Idle mode as time out happen from LED side!!!!!!!!"); - } - } - - if (stIdleResponse.szData[1] == TARGET_CAN_GO_TO_IDLE_MODE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "ACKING IDLE MODE !!!!!!!!!"); - down(&Adapter->rdmwrmsync); - Adapter->bPreparingForLowPowerMode = TRUE; - up(&Adapter->rdmwrmsync); - /* Killing all URBS. */ - if (Adapter->bDoSuspend == TRUE) - Bcm_kill_all_URBs((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter)); - } else { - Adapter->bPreparingForLowPowerMode = false; - } - - if (!NVMAccess) - up(&Adapter->NVMRdmWrmLock); - - if (!lowPwrAbortMsg) - up(&Adapter->LowPowerModeSync); - } - - status = CopyBufferToControlPacket(Adapter, &stIdleResponse); - if (status != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "fail to send the Idle mode Request\n"); - Adapter->bPreparingForLowPowerMode = false; - StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter)); - } - do_gettimeofday(&tv); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "IdleMode Msg submitter to Q :%ld ms", tv.tv_sec * 1000 + tv.tv_usec / 1000); -} - -/****************************************************************** -* Function - DumpPackInfo() -* -* Description - This function dumps the all Queue(PackInfo[]) details. -* -* Parameters - Adapter: Pointer to the Adapter structure. -* -* Returns - None. -*******************************************************************/ -void DumpPackInfo(struct bcm_mini_adapter *Adapter) -{ - unsigned int uiLoopIndex = 0; - unsigned int uiIndex = 0; - unsigned int uiClsfrIndex = 0; - struct bcm_classifier_rule *pstClassifierEntry = NULL; - - for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "*********** Showing Details Of Queue %d***** ******", uiLoopIndex); - if (false == Adapter->PackInfo[uiLoopIndex].bValid) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bValid is false for %X index\n", uiLoopIndex); - continue; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, " Dumping SF Rule Entry For SFID %lX\n", Adapter->PackInfo[uiLoopIndex].ulSFID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, " ucDirection %X\n", Adapter->PackInfo[uiLoopIndex].ucDirection); - - if (Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Ipv6 Service Flow\n"); - else - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Ipv4 Service Flow\n"); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "SF Traffic Priority %X\n", Adapter->PackInfo[uiLoopIndex].u8TrafficPriority); - - for (uiClsfrIndex = 0; uiClsfrIndex < MAX_CLASSIFIERS; uiClsfrIndex++) { - pstClassifierEntry = &Adapter->astClassifierTable[uiClsfrIndex]; - if (!pstClassifierEntry->bUsed) - continue; - - if (pstClassifierEntry->ulSFID != Adapter->PackInfo[uiLoopIndex].ulSFID) - continue; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tDumping Classifier Rule Entry For Index: %X Classifier Rule ID : %X\n", uiClsfrIndex, pstClassifierEntry->uiClassifierRuleIndex); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tDumping Classifier Rule Entry For Index: %X usVCID_Value : %X\n", uiClsfrIndex, pstClassifierEntry->usVCID_Value); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tDumping Classifier Rule Entry For Index: %X bProtocolValid : %X\n", uiClsfrIndex, pstClassifierEntry->bProtocolValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tDumping Classifier Rule Entry For Index: %X bTOSValid : %X\n", uiClsfrIndex, pstClassifierEntry->bTOSValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tDumping Classifier Rule Entry For Index: %X bDestIpValid : %X\n", uiClsfrIndex, pstClassifierEntry->bDestIpValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tDumping Classifier Rule Entry For Index: %X bSrcIpValid : %X\n", uiClsfrIndex, pstClassifierEntry->bSrcIpValid); - - for (uiIndex = 0; uiIndex < MAX_PORT_RANGE; uiIndex++) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tusSrcPortRangeLo:%X\n", pstClassifierEntry->usSrcPortRangeLo[uiIndex]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tusSrcPortRangeHi:%X\n", pstClassifierEntry->usSrcPortRangeHi[uiIndex]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tusDestPortRangeLo:%X\n", pstClassifierEntry->usDestPortRangeLo[uiIndex]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tusDestPortRangeHi:%X\n", pstClassifierEntry->usDestPortRangeHi[uiIndex]); - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tucIPSourceAddressLength : 0x%x\n", pstClassifierEntry->ucIPSourceAddressLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tucIPDestinationAddressLength : 0x%x\n", pstClassifierEntry->ucIPDestinationAddressLength); - for (uiIndex = 0; uiIndex < pstClassifierEntry->ucIPSourceAddressLength; uiIndex++) { - if (Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tIpv6 ulSrcIpAddr :\n"); - DumpIpv6Address(pstClassifierEntry->stSrcIpAddress.ulIpv6Addr); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tIpv6 ulSrcIpMask :\n"); - DumpIpv6Address(pstClassifierEntry->stSrcIpAddress.ulIpv6Mask); - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tulSrcIpAddr:%lX\n", pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[uiIndex]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tulSrcIpMask:%lX\n", pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[uiIndex]); - } - } - - for (uiIndex = 0; uiIndex < pstClassifierEntry->ucIPDestinationAddressLength; uiIndex++) { - if (Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tIpv6 ulDestIpAddr :\n"); - DumpIpv6Address(pstClassifierEntry->stDestIpAddress.ulIpv6Addr); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tIpv6 ulDestIpMask :\n"); - DumpIpv6Address(pstClassifierEntry->stDestIpAddress.ulIpv6Mask); - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tulDestIpAddr:%lX\n", pstClassifierEntry->stDestIpAddress.ulIpv4Addr[uiIndex]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tulDestIpMask:%lX\n", pstClassifierEntry->stDestIpAddress.ulIpv4Mask[uiIndex]); - } - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tucProtocol:0x%X\n", pstClassifierEntry->ucProtocol[0]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tu8ClassifierRulePriority:%X\n", pstClassifierEntry->u8ClassifierRulePriority); - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ulSFID:%lX\n", Adapter->PackInfo[uiLoopIndex].ulSFID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "usVCID_Value:%X\n", Adapter->PackInfo[uiLoopIndex].usVCID_Value); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "PhsEnabled: 0x%X\n", Adapter->PackInfo[uiLoopIndex].bHeaderSuppressionEnabled); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiThreshold:%X\n", Adapter->PackInfo[uiLoopIndex].uiThreshold); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bValid:%X\n", Adapter->PackInfo[uiLoopIndex].bValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bActive:%X\n", Adapter->PackInfo[uiLoopIndex].bActive); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ActivateReqSent: %x", Adapter->PackInfo[uiLoopIndex].bActivateRequestSent); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "u8QueueType:%X\n", Adapter->PackInfo[uiLoopIndex].u8QueueType); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiMaxBucketSize:%X\n", Adapter->PackInfo[uiLoopIndex].uiMaxBucketSize); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiPerSFTxResourceCount:%X\n", atomic_read(&Adapter->PackInfo[uiLoopIndex].uiPerSFTxResourceCount)); - /* DumpDebug(DUMP_INFO,("bCSSupport:%X\n",Adapter->PackInfo[uiLoopIndex].bCSSupport)); */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "CurrQueueDepthOnTarget: %x\n", Adapter->PackInfo[uiLoopIndex].uiCurrentQueueDepthOnTarget); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiCurrentBytesOnHost:%X\n", Adapter->PackInfo[uiLoopIndex].uiCurrentBytesOnHost); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiCurrentPacketsOnHost:%X\n", Adapter->PackInfo[uiLoopIndex].uiCurrentPacketsOnHost); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiDroppedCountBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiDroppedCountBytes); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiDroppedCountPackets:%X\n", Adapter->PackInfo[uiLoopIndex].uiDroppedCountPackets); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiSentBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiSentBytes); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiSentPackets:%X\n", Adapter->PackInfo[uiLoopIndex].uiSentPackets); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiCurrentDrainRate:%X\n", Adapter->PackInfo[uiLoopIndex].uiCurrentDrainRate); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiThisPeriodSentBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiThisPeriodSentBytes); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "liDrainCalculated:%llX\n", Adapter->PackInfo[uiLoopIndex].liDrainCalculated); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiCurrentTokenCount:%X\n", Adapter->PackInfo[uiLoopIndex].uiCurrentTokenCount); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "liLastUpdateTokenAt:%llX\n", Adapter->PackInfo[uiLoopIndex].liLastUpdateTokenAt); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiMaxAllowedRate:%X\n", Adapter->PackInfo[uiLoopIndex].uiMaxAllowedRate); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiPendedLast:%X\n", Adapter->PackInfo[uiLoopIndex].uiPendedLast); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "NumOfPacketsSent:%X\n", Adapter->PackInfo[uiLoopIndex].NumOfPacketsSent); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Direction: %x\n", Adapter->PackInfo[uiLoopIndex].ucDirection); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "CID: %x\n", Adapter->PackInfo[uiLoopIndex].usCID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ProtocolValid: %x\n", Adapter->PackInfo[uiLoopIndex].bProtocolValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "TOSValid: %x\n", Adapter->PackInfo[uiLoopIndex].bTOSValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "DestIpValid: %x\n", Adapter->PackInfo[uiLoopIndex].bDestIpValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "SrcIpValid: %x\n", Adapter->PackInfo[uiLoopIndex].bSrcIpValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ActiveSet: %x\n", Adapter->PackInfo[uiLoopIndex].bActiveSet); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "AdmittedSet: %x\n", Adapter->PackInfo[uiLoopIndex].bAdmittedSet); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "AuthzSet: %x\n", Adapter->PackInfo[uiLoopIndex].bAuthorizedSet); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ClassifyPrority: %x\n", Adapter->PackInfo[uiLoopIndex].bClassifierPriority); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiMaxLatency: %x\n", Adapter->PackInfo[uiLoopIndex].uiMaxLatency); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, - DBG_LVL_ALL, "ServiceClassName: %*ph\n", - 4, Adapter->PackInfo[uiLoopIndex]. - ucServiceClassName); -/* BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bHeaderSuppressionEnabled :%X\n", Adapter->PackInfo[uiLoopIndex].bHeaderSuppressionEnabled); - * BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalTxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalTxBytes); - * BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalRxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalRxBytes); - * DumpDebug(DUMP_INFO,(" uiRanOutOfResCount:%X\n",Adapter->PackInfo[uiLoopIndex].uiRanOutOfResCount)); - */ - } - - for (uiLoopIndex = 0; uiLoopIndex < MIBS_MAX_HIST_ENTRIES; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Adapter->aRxPktSizeHist[%x] = %x\n", uiLoopIndex, Adapter->aRxPktSizeHist[uiLoopIndex]); - - for (uiLoopIndex = 0; uiLoopIndex < MIBS_MAX_HIST_ENTRIES; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Adapter->aTxPktSizeHist[%x] = %x\n", uiLoopIndex, Adapter->aTxPktSizeHist[uiLoopIndex]); -} - -int reset_card_proc(struct bcm_mini_adapter *ps_adapter) -{ - int retval = STATUS_SUCCESS; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_interface_adapter *psIntfAdapter = NULL; - unsigned int value = 0, uiResetValue = 0; - int bytes; - - psIntfAdapter = ((struct bcm_interface_adapter *)(ps_adapter->pvInterfaceAdapter)); - ps_adapter->bDDRInitDone = false; - - if (ps_adapter->chip_id >= T3LPB) { - /* SYS_CFG register is write protected hence for modifying this reg value, it should be read twice before */ - rdmalt(ps_adapter, SYS_CFG, &value, sizeof(value)); - rdmalt(ps_adapter, SYS_CFG, &value, sizeof(value)); - - /* making bit[6...5] same as was before f/w download. this setting force the h/w to */ - /* re-populated the SP RAM area with the string descriptor. */ - value = value | (ps_adapter->syscfgBefFwDld & 0x00000060); - wrmalt(ps_adapter, SYS_CFG, &value, sizeof(value)); - } - - /* killing all submitted URBs. */ - psIntfAdapter->psAdapter->StopAllXaction = TRUE; - Bcm_kill_all_URBs(psIntfAdapter); - /* Reset the UMA-B Device */ - if (ps_adapter->chip_id >= T3LPB) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Resetting UMA-B\n"); - retval = usb_reset_device(psIntfAdapter->udev); - psIntfAdapter->psAdapter->StopAllXaction = false; - - if (retval != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reset failed with ret value :%d", retval); - goto err_exit; - } - - if (ps_adapter->chip_id == BCS220_2 || - ps_adapter->chip_id == BCS220_2BC || - ps_adapter->chip_id == BCS250_BC || - ps_adapter->chip_id == BCS220_3) { - - bytes = rdmalt(ps_adapter, HPM_CONFIG_LDO145, &value, sizeof(value)); - if (bytes < 0) { - retval = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "read failed with status :%d", retval); - goto err_exit; - } - /* setting 0th bit */ - value |= (1<<0); - retval = wrmalt(ps_adapter, HPM_CONFIG_LDO145, &value, sizeof(value)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "write failed with status :%d", retval); - goto err_exit; - } - } - } else { - bytes = rdmalt(ps_adapter, 0x0f007018, &value, sizeof(value)); - if (bytes < 0) { - retval = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "read failed with status :%d", retval); - goto err_exit; - } - value &= (~(1<<16)); - retval = wrmalt(ps_adapter, 0x0f007018, &value, sizeof(value)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "write failed with status :%d", retval); - goto err_exit; - } - - /* Toggling the GPIO 8, 9 */ - value = 0; - retval = wrmalt(ps_adapter, GPIO_OUTPUT_REGISTER, &value, sizeof(value)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "write failed with status :%d", retval); - goto err_exit; - } - value = 0x300; - retval = wrmalt(ps_adapter, GPIO_MODE_REGISTER, &value, sizeof(value)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "write failed with status :%d", retval); - goto err_exit; - } - mdelay(50); - } - - /* ps_adapter->downloadDDR = false; */ - if (ps_adapter->bFlashBoot) { - /* In flash boot mode MIPS state register has reverse polarity. - * So just or with setting bit 30. - * Make the MIPS in Reset state. - */ - rdmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &uiResetValue, sizeof(uiResetValue)); - uiResetValue |= (1<<30); - wrmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &uiResetValue, sizeof(uiResetValue)); - } - - if (ps_adapter->chip_id >= T3LPB) { - uiResetValue = 0; - /* - * WA for SYSConfig Issue. - * Read SYSCFG Twice to make it writable. - */ - rdmalt(ps_adapter, SYS_CFG, &uiResetValue, sizeof(uiResetValue)); - if (uiResetValue & (1<<4)) { - uiResetValue = 0; - rdmalt(ps_adapter, SYS_CFG, &uiResetValue, sizeof(uiResetValue)); /* 2nd read to make it writable. */ - uiResetValue &= (~(1<<4)); - wrmalt(ps_adapter, SYS_CFG, &uiResetValue, sizeof(uiResetValue)); - } - } - uiResetValue = 0; - wrmalt(ps_adapter, 0x0f01186c, &uiResetValue, sizeof(uiResetValue)); - -err_exit: - psIntfAdapter->psAdapter->StopAllXaction = false; - return retval; -} - -int run_card_proc(struct bcm_mini_adapter *ps_adapter) -{ - int status = STATUS_SUCCESS; - int bytes; - - unsigned int value = 0; - { - bytes = rdmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &value, sizeof(value)); - if (bytes < 0) { - status = bytes; - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "%s:%d\n", __func__, __LINE__); - return status; - } - - if (ps_adapter->bFlashBoot) - value &= (~(1<<30)); - else - value |= (1<<30); - - if (wrmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "%s:%d\n", __func__, __LINE__); - return STATUS_FAILURE; - } - } - return status; -} - -int InitCardAndDownloadFirmware(struct bcm_mini_adapter *ps_adapter) -{ - int status; - unsigned int value = 0; - /* - * Create the threads first and then download the - * Firm/DDR Settings.. - */ - status = create_worker_threads(ps_adapter); - if (status < 0) - return status; - - status = bcm_parse_target_params(ps_adapter); - if (status) - return status; - - if (ps_adapter->chip_id >= T3LPB) { - rdmalt(ps_adapter, SYS_CFG, &value, sizeof(value)); - ps_adapter->syscfgBefFwDld = value; - - if ((value & 0x60) == 0) - ps_adapter->bFlashBoot = TRUE; - } - - reset_card_proc(ps_adapter); - - /* Initializing the NVM. */ - BcmInitNVM(ps_adapter); - status = ddr_init(ps_adapter); - if (status) { - pr_err(DRV_NAME "ddr_init Failed\n"); - return status; - } - - /* Download cfg file */ - status = buffDnldVerify(ps_adapter, - (PUCHAR)ps_adapter->pstargetparams, - sizeof(struct bcm_target_params), - CONFIG_BEGIN_ADDR); - if (status) { - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Error downloading CFG file"); - goto OUT; - } - - if (register_networkdev(ps_adapter)) { - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Netdevice failed. Cleanup needs to be performed."); - return -EIO; - } - - if (false == ps_adapter->AutoFirmDld) { - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "AutoFirmDld Disabled in CFG File..\n"); - /* If Auto f/w download is disable, register the control interface, */ - /* register the control interface after the mailbox. */ - if (register_control_device_interface(ps_adapter) < 0) { - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Control Device failed. Cleanup needs to be performed."); - return -EIO; - } - return STATUS_SUCCESS; - } - - /* - * Do the LED Settings here. It will be used by the Firmware Download - * Thread. - */ - - /* - * 1. If the LED Settings fails, do not stop and do the Firmware download. - * 2. This init would happened only if the cfg file is present, else - * call from the ioctl context. - */ - - status = InitLedSettings(ps_adapter); - if (status) { - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_PRINTK, 0, 0, "INIT LED FAILED\n"); - return status; - } - - if (ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { - ps_adapter->DriverState = DRIVER_INIT; - wake_up(&ps_adapter->LEDInfo.notify_led_event); - } - - if (ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { - ps_adapter->DriverState = FW_DOWNLOAD; - wake_up(&ps_adapter->LEDInfo.notify_led_event); - } - - value = 0; - wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value)); - wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value)); - - if (ps_adapter->eNVMType == NVM_FLASH) { - status = PropagateCalParamsFromFlashToMemory(ps_adapter); - if (status) { - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Propagation of Cal param failed .."); - goto OUT; - } - } - - /* Download Firmare */ - status = BcmFileDownload(ps_adapter, BIN_FILE, FIRMWARE_BEGIN_ADDR); - if (status != 0) { - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No Firmware File is present...\n"); - goto OUT; - } - - status = run_card_proc(ps_adapter); - if (status) { - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "run_card_proc Failed\n"); - goto OUT; - } - - ps_adapter->fw_download_done = TRUE; - mdelay(10); - -OUT: - if (ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { - ps_adapter->DriverState = FW_DOWNLOAD_DONE; - wake_up(&ps_adapter->LEDInfo.notify_led_event); - } - - return status; -} - -static int bcm_parse_target_params(struct bcm_mini_adapter *Adapter) -{ - struct file *flp = NULL; - char *buff; - int len = 0; - - buff = kmalloc(BUFFER_1K, GFP_KERNEL); - if (!buff) - return -ENOMEM; - - Adapter->pstargetparams = kmalloc(sizeof(struct bcm_target_params), GFP_KERNEL); - if (Adapter->pstargetparams == NULL) { - kfree(buff); - return -ENOMEM; - } - - flp = open_firmware_file(Adapter, CFG_FILE); - if (!flp) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "NOT ABLE TO OPEN THE %s FILE\n", CFG_FILE); - kfree(buff); - kfree(Adapter->pstargetparams); - Adapter->pstargetparams = NULL; - return -ENOENT; - } - len = kernel_read(flp, 0, buff, BUFFER_1K); - filp_close(flp, NULL); - - if (len != sizeof(struct bcm_target_params)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Mismatch in Target Param Structure!\n"); - kfree(buff); - kfree(Adapter->pstargetparams); - Adapter->pstargetparams = NULL; - return -ENOENT; - } - - /* Check for autolink in config params */ - /* - * Values in Adapter->pstargetparams are in network byte order - */ - memcpy(Adapter->pstargetparams, buff, sizeof(struct bcm_target_params)); - kfree(buff); - beceem_parse_target_struct(Adapter); - return STATUS_SUCCESS; -} - -void beceem_parse_target_struct(struct bcm_mini_adapter *Adapter) -{ - unsigned int uiHostDrvrCfg6 = 0, uiEEPROMFlag = 0; - - if (ntohl(Adapter->pstargetparams->m_u32PhyParameter2) & AUTO_SYNC_DISABLE) { - pr_info(DRV_NAME ": AutoSyncup is Disabled\n"); - Adapter->AutoSyncup = false; - } else { - pr_info(DRV_NAME ": AutoSyncup is Enabled\n"); - Adapter->AutoSyncup = TRUE; - } - - if (ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_LINKUP_ENABLE) { - pr_info(DRV_NAME ": Enabling autolink up"); - Adapter->AutoLinkUp = TRUE; - } else { - pr_info(DRV_NAME ": Disabling autolink up"); - Adapter->AutoLinkUp = false; - } - /* Setting the DDR Setting.. */ - Adapter->DDRSetting = (ntohl(Adapter->pstargetparams->HostDrvrConfig6) >> 8)&0x0F; - Adapter->ulPowerSaveMode = (ntohl(Adapter->pstargetparams->HostDrvrConfig6)>>12)&0x0F; - pr_info(DRV_NAME ": DDR Setting: %x\n", Adapter->DDRSetting); - pr_info(DRV_NAME ": Power Save Mode: %lx\n", Adapter->ulPowerSaveMode); - if (ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_FIRM_DOWNLOAD) { - pr_info(DRV_NAME ": Enabling Auto Firmware Download\n"); - Adapter->AutoFirmDld = TRUE; - } else { - pr_info(DRV_NAME ": Disabling Auto Firmware Download\n"); - Adapter->AutoFirmDld = false; - } - uiHostDrvrCfg6 = ntohl(Adapter->pstargetparams->HostDrvrConfig6); - Adapter->bMipsConfig = (uiHostDrvrCfg6>>20)&0x01; - pr_info(DRV_NAME ": MIPSConfig : 0x%X\n", Adapter->bMipsConfig); - /* used for backward compatibility. */ - Adapter->bDPLLConfig = (uiHostDrvrCfg6>>19)&0x01; - Adapter->PmuMode = (uiHostDrvrCfg6 >> 24) & 0x03; - pr_info(DRV_NAME ": PMU MODE: %x", Adapter->PmuMode); - - if ((uiHostDrvrCfg6 >> HOST_BUS_SUSPEND_BIT) & (0x01)) { - Adapter->bDoSuspend = TRUE; - pr_info(DRV_NAME ": Making DoSuspend TRUE as per configFile"); - } - - uiEEPROMFlag = ntohl(Adapter->pstargetparams->m_u32EEPROMFlag); - pr_info(DRV_NAME ": uiEEPROMFlag : 0x%X\n", uiEEPROMFlag); - Adapter->eNVMType = (enum bcm_nvm_type)((uiEEPROMFlag>>4)&0x3); - Adapter->bStatusWrite = (uiEEPROMFlag>>6)&0x1; - Adapter->uiSectorSizeInCFG = 1024*(0xFFFF & ntohl(Adapter->pstargetparams->HostDrvrConfig4)); - Adapter->bSectorSizeOverride = (bool) ((ntohl(Adapter->pstargetparams->HostDrvrConfig4))>>16)&0x1; - - if (ntohl(Adapter->pstargetparams->m_u32PowerSavingModeOptions) & 0x01) - Adapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE; - - if (Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) - doPowerAutoCorrection(Adapter); -} - -static void doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter) -{ - unsigned int reporting_mode; - - reporting_mode = ntohl(psAdapter->pstargetparams->m_u32PowerSavingModeOptions) & 0x02; - psAdapter->bIsAutoCorrectEnabled = !((char)(psAdapter->ulPowerSaveMode >> 3) & 0x1); - - if (reporting_mode) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "can't do suspen/resume as reporting mode is enable"); - psAdapter->bDoSuspend = false; - } - - if (psAdapter->bIsAutoCorrectEnabled && (psAdapter->chip_id >= T3LPB)) { - /* If reporting mode is enable, switch PMU to PMC */ - { - psAdapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PMU_CLOCK_GATING; - psAdapter->bDoSuspend = false; - } - - /* clearing space bit[15..12] */ - psAdapter->pstargetparams->HostDrvrConfig6 &= ~(htonl((0xF << 12))); - /* placing the power save mode option */ - psAdapter->pstargetparams->HostDrvrConfig6 |= htonl((psAdapter->ulPowerSaveMode << 12)); - } else if (psAdapter->bIsAutoCorrectEnabled == false) { - /* remove the autocorrect disable bit set before dumping. */ - psAdapter->ulPowerSaveMode &= ~(1 << 3); - psAdapter->pstargetparams->HostDrvrConfig6 &= ~(htonl(1 << 15)); - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Using Forced User Choice: %lx\n", psAdapter->ulPowerSaveMode); - } -} - -static void convertEndian(unsigned char rwFlag, unsigned int *puiBuffer, unsigned int uiByteCount) -{ - unsigned int uiIndex = 0; - - if (RWM_WRITE == rwFlag) { - for (uiIndex = 0; uiIndex < (uiByteCount/sizeof(unsigned int)); uiIndex++) - puiBuffer[uiIndex] = htonl(puiBuffer[uiIndex]); - } else { - for (uiIndex = 0; uiIndex < (uiByteCount/sizeof(unsigned int)); uiIndex++) - puiBuffer[uiIndex] = ntohl(puiBuffer[uiIndex]); - } -} - -int rdm(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, PCHAR pucBuff, size_t sSize) -{ - return Adapter->interface_rdm(Adapter->pvInterfaceAdapter, - uiAddress, pucBuff, sSize); -} - -int wrm(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, PCHAR pucBuff, size_t sSize) -{ - int iRetVal; - - iRetVal = Adapter->interface_wrm(Adapter->pvInterfaceAdapter, - uiAddress, pucBuff, sSize); - return iRetVal; -} - -int wrmalt(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size) -{ - convertEndian(RWM_WRITE, pucBuff, size); - return wrm(Adapter, uiAddress, (PUCHAR)pucBuff, size); -} - -int rdmalt(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size) -{ - int uiRetVal = 0; - - uiRetVal = rdm(Adapter, uiAddress, (PUCHAR)pucBuff, size); - convertEndian(RWM_READ, (unsigned int *)pucBuff, size); - - return uiRetVal; -} - -int wrmWithLock(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, PCHAR pucBuff, size_t sSize) -{ - int status = STATUS_SUCCESS; - - down(&Adapter->rdmwrmsync); - - if ((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus == TRUE) || - (Adapter->bPreparingForLowPowerMode == TRUE)) { - - status = -EACCES; - goto exit; - } - - status = wrm(Adapter, uiAddress, pucBuff, sSize); -exit: - up(&Adapter->rdmwrmsync); - return status; -} - -int wrmaltWithLock(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size) -{ - int iRetVal = STATUS_SUCCESS; - - down(&Adapter->rdmwrmsync); - - if ((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus == TRUE) || - (Adapter->bPreparingForLowPowerMode == TRUE)) { - - iRetVal = -EACCES; - goto exit; - } - - iRetVal = wrmalt(Adapter, uiAddress, pucBuff, size); -exit: - up(&Adapter->rdmwrmsync); - return iRetVal; -} - -int rdmaltWithLock(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size) -{ - int uiRetVal = STATUS_SUCCESS; - - down(&Adapter->rdmwrmsync); - if ((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus == TRUE) || - (Adapter->bPreparingForLowPowerMode == TRUE)) { - - uiRetVal = -EACCES; - goto exit; - } - - uiRetVal = rdmalt(Adapter, uiAddress, pucBuff, size); -exit: - up(&Adapter->rdmwrmsync); - return uiRetVal; -} - -static void HandleShutDownModeWakeup(struct bcm_mini_adapter *Adapter) -{ - int clear_abort_pattern = 0, Status = 0; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n"); - /* target has woken up From Shut Down */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Clearing Shut Down Software abort pattern\n"); - Status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, (unsigned int *)&clear_abort_pattern, sizeof(clear_abort_pattern)); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "WRM to SW_ABORT_IDLEMODE_LOC failed with err:%d", Status); - return; - } - - if (Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) { - msleep(100); - InterfaceHandleShutdownModeWakeup(Adapter); - msleep(100); - } - - if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { - Adapter->DriverState = NO_NETWORK_ENTRY; - wake_up(&Adapter->LEDInfo.notify_led_event); - } - - Adapter->bTriedToWakeUpFromlowPowerMode = false; - Adapter->bShutStatus = false; - wake_up(&Adapter->lowpower_mode_wait_queue); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n"); -} - -static void SendShutModeResponse(struct bcm_mini_adapter *Adapter) -{ - struct bcm_link_request stShutdownResponse; - unsigned int NVMAccess = 0, lowPwrAbortMsg = 0; - unsigned int Status = 0; - - memset(&stShutdownResponse, 0, sizeof(struct bcm_link_request)); - stShutdownResponse.Leader.Status = LINK_UP_CONTROL_REQ; - stShutdownResponse.Leader.PLength = 8; /* 8 bytes; */ - stShutdownResponse.szData[0] = LINK_UP_ACK; - stShutdownResponse.szData[1] = LINK_SHUTDOWN_REQ_FROM_FIRMWARE; - - /********************************* - * down_trylock - - * if [ semaphore is available ] - * acquire semaphone and return value 0 ; - * else - * return non-zero value ; - * - ***********************************/ - - NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); - lowPwrAbortMsg = down_trylock(&Adapter->LowPowerModeSync); - - if (NVMAccess || lowPwrAbortMsg || atomic_read(&Adapter->TotalPacketCount)) { - if (!NVMAccess) - up(&Adapter->NVMRdmWrmLock); - - if (!lowPwrAbortMsg) - up(&Adapter->LowPowerModeSync); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Device Access is going on NACK the Shut Down MODE\n"); - stShutdownResponse.szData[2] = SHUTDOWN_NACK_FROM_DRIVER; /* NACK- device access is going on. */ - Adapter->bPreparingForLowPowerMode = false; - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Sending SHUTDOWN MODE ACK\n"); - stShutdownResponse.szData[2] = SHUTDOWN_ACK_FROM_DRIVER; /* ShutDown ACK */ - - /* Wait for the LED to TURN OFF before sending ACK response */ - if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { - int iRetVal = 0; - - /* Wake the LED Thread with LOWPOWER_MODE_ENTER State */ - Adapter->DriverState = LOWPOWER_MODE_ENTER; - wake_up(&Adapter->LEDInfo.notify_led_event); - - /* Wait for 1 SEC for LED to OFF */ - iRetVal = wait_event_timeout(Adapter->LEDInfo.idleModeSyncEvent, Adapter->LEDInfo.bIdle_led_off, msecs_to_jiffies(1000)); - - /* If Timed Out to Sync IDLE MODE Enter, do IDLE mode Exit and Send NACK to device */ - if (iRetVal <= 0) { - stShutdownResponse.szData[1] = SHUTDOWN_NACK_FROM_DRIVER; /* NACK- device access is going on. */ - Adapter->DriverState = NO_NETWORK_ENTRY; - wake_up(&Adapter->LEDInfo.notify_led_event); - } - } - - if (stShutdownResponse.szData[2] == SHUTDOWN_ACK_FROM_DRIVER) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "ACKING SHUTDOWN MODE !!!!!!!!!"); - down(&Adapter->rdmwrmsync); - Adapter->bPreparingForLowPowerMode = TRUE; - up(&Adapter->rdmwrmsync); - /* Killing all URBS. */ - if (Adapter->bDoSuspend == TRUE) - Bcm_kill_all_URBs((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter)); - } else { - Adapter->bPreparingForLowPowerMode = false; - } - - if (!NVMAccess) - up(&Adapter->NVMRdmWrmLock); - - if (!lowPwrAbortMsg) - up(&Adapter->LowPowerModeSync); - } - - Status = CopyBufferToControlPacket(Adapter, &stShutdownResponse); - if (Status != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "fail to send the Idle mode Request\n"); - Adapter->bPreparingForLowPowerMode = false; - StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter)); - } -} - -static void HandleShutDownModeRequest(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer) -{ - unsigned int uiResetValue = 0; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n"); - - if (*(pucBuffer+1) == COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW) { - HandleShutDownModeWakeup(Adapter); - } else if (*(pucBuffer+1) == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) { - /* Target wants to go to Shut Down Mode */ - /* InterfacePrepareForShutdown(Adapter); */ - if (Adapter->chip_id == BCS220_2 || - Adapter->chip_id == BCS220_2BC || - Adapter->chip_id == BCS250_BC || - Adapter->chip_id == BCS220_3) { - - rdmalt(Adapter, HPM_CONFIG_MSW, &uiResetValue, 4); - uiResetValue |= (1<<17); - wrmalt(Adapter, HPM_CONFIG_MSW, &uiResetValue, 4); - } - - SendShutModeResponse(Adapter); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "ShutDownModeResponse:Notification received: Sending the response(Ack/Nack)\n"); - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n"); -} - -void ResetCounters(struct bcm_mini_adapter *Adapter) -{ - beceem_protocol_reset(Adapter); - Adapter->CurrNumRecvDescs = 0; - Adapter->PrevNumRecvDescs = 0; - Adapter->LinkUpStatus = 0; - Adapter->LinkStatus = 0; - atomic_set(&Adapter->cntrlpktCnt, 0); - atomic_set(&Adapter->TotalPacketCount, 0); - Adapter->fw_download_done = false; - Adapter->LinkStatus = 0; - Adapter->AutoLinkUp = false; - Adapter->IdleMode = false; - Adapter->bShutStatus = false; -} - -struct bcm_classifier_rule *GetFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentification, ULONG SrcIP) -{ - unsigned int uiIndex = 0; - - for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) { - if ((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) && - (Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification) && - (Adapter->astFragmentedPktClassifierTable[uiIndex].ulSrcIpAddress == SrcIP) && - !Adapter->astFragmentedPktClassifierTable[uiIndex].bOutOfOrderFragment) - - return Adapter->astFragmentedPktClassifierTable[uiIndex].pstMatchedClassifierEntry; - } - return NULL; -} - -void AddFragIPClsEntry(struct bcm_mini_adapter *Adapter, struct bcm_fragmented_packet_info *psFragPktInfo) -{ - unsigned int uiIndex = 0; - - for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) { - if (!Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) { - memcpy(&Adapter->astFragmentedPktClassifierTable[uiIndex], psFragPktInfo, sizeof(struct bcm_fragmented_packet_info)); - break; - } - } -} - -void DelFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentification, ULONG SrcIp) -{ - unsigned int uiIndex = 0; - - for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) { - if ((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) && - (Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification) && - (Adapter->astFragmentedPktClassifierTable[uiIndex].ulSrcIpAddress == SrcIp)) - - memset(&Adapter->astFragmentedPktClassifierTable[uiIndex], 0, sizeof(struct bcm_fragmented_packet_info)); - } -} - -void update_per_cid_rx(struct bcm_mini_adapter *Adapter) -{ - unsigned int qindex = 0; - - if ((jiffies - Adapter->liDrainCalculated) < XSECONDS) - return; - - for (qindex = 0; qindex < HiPriority; qindex++) { - if (Adapter->PackInfo[qindex].ucDirection == 0) { - Adapter->PackInfo[qindex].uiCurrentRxRate = - (Adapter->PackInfo[qindex].uiCurrentRxRate + - Adapter->PackInfo[qindex].uiThisPeriodRxBytes) / 2; - - Adapter->PackInfo[qindex].uiThisPeriodRxBytes = 0; - } else { - Adapter->PackInfo[qindex].uiCurrentDrainRate = - (Adapter->PackInfo[qindex].uiCurrentDrainRate + - Adapter->PackInfo[qindex].uiThisPeriodSentBytes) / 2; - Adapter->PackInfo[qindex].uiThisPeriodSentBytes = 0; - } - } - Adapter->liDrainCalculated = jiffies; -} - -void update_per_sf_desc_cnts(struct bcm_mini_adapter *Adapter) -{ - int iIndex = 0; - u32 uibuff[MAX_TARGET_DSX_BUFFERS]; - int bytes; - - if (!atomic_read(&Adapter->uiMBupdate)) - return; - - bytes = rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (unsigned int *)uibuff, sizeof(unsigned int) * MAX_TARGET_DSX_BUFFERS); - if (bytes < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "rdm failed\n"); - return; - } - - for (iIndex = 0; iIndex < HiPriority; iIndex++) { - if (Adapter->PackInfo[iIndex].bValid && Adapter->PackInfo[iIndex].ucDirection) { - if (Adapter->PackInfo[iIndex].usVCID_Value < MAX_TARGET_DSX_BUFFERS) - atomic_set(&Adapter->PackInfo[iIndex].uiPerSFTxResourceCount, uibuff[Adapter->PackInfo[iIndex].usVCID_Value]); - else - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid VCID : %x\n", Adapter->PackInfo[iIndex].usVCID_Value); - } - } - atomic_set(&Adapter->uiMBupdate, false); -} - -void flush_queue(struct bcm_mini_adapter *Adapter, unsigned int iQIndex) -{ - struct sk_buff *PacketToDrop = NULL; - struct net_device_stats *netstats = &Adapter->dev->stats; - - spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock); - - while (Adapter->PackInfo[iQIndex].FirstTxQueue && atomic_read(&Adapter->TotalPacketCount)) { - PacketToDrop = Adapter->PackInfo[iQIndex].FirstTxQueue; - if (PacketToDrop && PacketToDrop->len) { - netstats->tx_dropped++; - DEQUEUEPACKET(Adapter->PackInfo[iQIndex].FirstTxQueue, Adapter->PackInfo[iQIndex].LastTxQueue); - Adapter->PackInfo[iQIndex].uiCurrentPacketsOnHost--; - Adapter->PackInfo[iQIndex].uiCurrentBytesOnHost -= PacketToDrop->len; - - /* Adding dropped statistics */ - Adapter->PackInfo[iQIndex].uiDroppedCountBytes += PacketToDrop->len; - Adapter->PackInfo[iQIndex].uiDroppedCountPackets++; - dev_kfree_skb(PacketToDrop); - atomic_dec(&Adapter->TotalPacketCount); - } - } - spin_unlock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock); -} - -static void beceem_protocol_reset(struct bcm_mini_adapter *Adapter) -{ - int i; - - if (netif_msg_link(Adapter)) - pr_notice(PFX "%s: protocol reset\n", Adapter->dev->name); - - netif_carrier_off(Adapter->dev); - netif_stop_queue(Adapter->dev); - - Adapter->IdleMode = false; - Adapter->LinkUpStatus = false; - ClearTargetDSXBuffer(Adapter, 0, TRUE); - /* Delete All Classifier Rules */ - - for (i = 0; i < HiPriority; i++) - DeleteAllClassifiersForSF(Adapter, i); - - flush_all_queues(Adapter); - - if (Adapter->TimerActive == TRUE) - Adapter->TimerActive = false; - - memset(Adapter->astFragmentedPktClassifierTable, 0, sizeof(struct bcm_fragmented_packet_info) * MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES); - - for (i = 0; i < HiPriority; i++) { - /* resetting only the first size (S_MIBS_SERVICEFLOW_TABLE) for the SF. */ - /* It is same between MIBs and SF. */ - memset(&Adapter->PackInfo[i].stMibsExtServiceFlowTable, 0, sizeof(struct bcm_mibs_parameters)); - } -} diff --git a/drivers/staging/bcm/PHSDefines.h b/drivers/staging/bcm/PHSDefines.h deleted file mode 100644 index cd78ee4ffa22..000000000000 --- a/drivers/staging/bcm/PHSDefines.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef BCM_PHS_DEFINES_H -#define BCM_PHS_DEFINES_H - -#define PHS_INVALID_TABLE_INDEX 0xffffffff -#define PHS_MEM_TAG "_SHP" - -/* PHS Defines */ -#define STATUS_PHS_COMPRESSED 0xa1 -#define STATUS_PHS_NOCOMPRESSION 0xa2 -#define APPLY_PHS 1 -#define MAX_NO_BIT 7 -#define ZERO_PHSI 0 -#define VERIFY 0 -#define SIZE_MULTIPLE_32 4 -#define UNCOMPRESSED_PACKET 0 -#define DYNAMIC 0 -#define SUPPRESS 0x80 -#define NO_CLASSIFIER_MATCH 0 -#define SEND_PACKET_UNCOMPRESSED 0 -#define PHSI_IS_ZERO 0 -#define PHSI_LEN 1 -#define ERROR_LEN 0 -#define PHS_BUFFER_SIZE 1532 -#define MAX_PHSRULE_PER_SF 20 -#define MAX_SERVICEFLOWS 17 - -/* PHS Error Defines */ -#define PHS_SUCCESS 0 -#define ERR_PHS_INVALID_DEVICE_EXETENSION 0x800 -#define ERR_PHS_INVALID_PHS_RULE 0x801 -#define ERR_PHS_RULE_ALREADY_EXISTS 0x802 -#define ERR_SF_MATCH_FAIL 0x803 -#define ERR_INVALID_CLASSIFIERTABLE_FOR_SF 0x804 -#define ERR_SFTABLE_FULL 0x805 -#define ERR_CLSASSIFIER_TABLE_FULL 0x806 -#define ERR_PHSRULE_MEMALLOC_FAIL 0x807 -#define ERR_CLSID_MATCH_FAIL 0x808 -#define ERR_PHSRULE_MATCH_FAIL 0x809 - -struct bcm_phs_rule { - u8 u8PHSI; - u8 u8PHSFLength; - u8 u8PHSF[MAX_PHS_LENGTHS]; - u8 u8PHSMLength; - u8 u8PHSM[MAX_PHS_LENGTHS]; - u8 u8PHSS; - u8 u8PHSV; - u8 u8RefCnt; - u8 bUnclassifiedPHSRule; - u8 u8Reserved[3]; - long PHSModifiedBytes; - unsigned long PHSModifiedNumPackets; - unsigned long PHSErrorNumPackets; -}; - -enum bcm_phs_classifier_context { - eActiveClassifierRuleContext, - eOldClassifierRuleContext -}; - -struct bcm_phs_classifier_entry { - u8 bUsed; - u16 uiClassifierRuleId; - u8 u8PHSI; - struct bcm_phs_rule *pstPhsRule; - u8 bUnclassifiedPHSRule; -}; - -struct bcm_phs_classifier_table { - u16 uiTotalClassifiers; - struct bcm_phs_classifier_entry stActivePhsRulesList[MAX_PHSRULE_PER_SF]; - struct bcm_phs_classifier_entry stOldPhsRulesList[MAX_PHSRULE_PER_SF]; - u16 uiOldestPhsRuleIndex; -}; - -struct bcm_phs_entry { - u8 bUsed; - u16 uiVcid; - struct bcm_phs_classifier_table *pstClassifierTable; -}; - -struct bcm_phs_table { - u16 uiTotalServiceFlows; - struct bcm_phs_entry stSFList[MAX_SERVICEFLOWS]; -}; - -struct bcm_phs_extension { - /* PHS Specific data */ - struct bcm_phs_table *pstServiceFlowPhsRulesTable; - void *CompressedTxBuffer; - void *UnCompressedRxBuffer; -}; - -#endif diff --git a/drivers/staging/bcm/PHSModule.c b/drivers/staging/bcm/PHSModule.c deleted file mode 100644 index 5f4e503d54ec..000000000000 --- a/drivers/staging/bcm/PHSModule.c +++ /dev/null @@ -1,1703 +0,0 @@ -#include "headers.h" - -static UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid, - B_UINT16 uiClsId, - struct bcm_phs_table *psServiceFlowTable, - struct bcm_phs_rule *psPhsRule, - B_UINT8 u8AssociatedPHSI); - -static UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid, - B_UINT16 uiClsId, - struct bcm_phs_entry *pstServiceFlowEntry, - struct bcm_phs_rule *psPhsRule, - B_UINT8 u8AssociatedPHSI); - -static UINT CreateClassifierPHSRule(B_UINT16 uiClsId, - struct bcm_phs_classifier_table *psaClassifiertable, - struct bcm_phs_rule *psPhsRule, - enum bcm_phs_classifier_context eClsContext, - B_UINT8 u8AssociatedPHSI); - -static UINT UpdateClassifierPHSRule(B_UINT16 uiClsId, - struct bcm_phs_classifier_entry *pstClassifierEntry, - struct bcm_phs_classifier_table *psaClassifiertable, - struct bcm_phs_rule *psPhsRule, - B_UINT8 u8AssociatedPHSI); - -static bool ValidatePHSRuleComplete(const struct bcm_phs_rule *psPhsRule); - -static bool DerefPhsRule(B_UINT16 uiClsId, - struct bcm_phs_classifier_table *psaClassifiertable, - struct bcm_phs_rule *pstPhsRule); - -static UINT GetClassifierEntry(struct bcm_phs_classifier_table *pstClassifierTable, - B_UINT32 uiClsid, - enum bcm_phs_classifier_context eClsContext, - struct bcm_phs_classifier_entry **ppstClassifierEntry); - -static UINT GetPhsRuleEntry(struct bcm_phs_classifier_table *pstClassifierTable, - B_UINT32 uiPHSI, - enum bcm_phs_classifier_context eClsContext, - struct bcm_phs_rule **ppstPhsRule); - -static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesTable); - -static int phs_compress(struct bcm_phs_rule *phs_members, - unsigned char *in_buf, - unsigned char *out_buf, - unsigned int *header_size, - UINT *new_header_size); - -static int verify_suppress_phsf(unsigned char *in_buffer, - unsigned char *out_buffer, - unsigned char *phsf, - unsigned char *phsm, - unsigned int phss, - unsigned int phsv, - UINT *new_header_size); - -static int phs_decompress(unsigned char *in_buf, - unsigned char *out_buf, - struct bcm_phs_rule *phs_rules, - UINT *header_size); - -static ULONG PhsCompress(void *pvContext, - B_UINT16 uiVcid, - B_UINT16 uiClsId, - void *pvInputBuffer, - void *pvOutputBuffer, - UINT *pOldHeaderSize, - UINT *pNewHeaderSize); - -static ULONG PhsDeCompress(void *pvContext, - B_UINT16 uiVcid, - void *pvInputBuffer, - void *pvOutputBuffer, - UINT *pInHeaderSize, - UINT *pOutHeaderSize); - -#define IN -#define OUT - -/* - * Function: PHSTransmit - * Description: This routine handle PHS(Payload Header Suppression for Tx path. - * It extracts a fragment of the NDIS_PACKET containing the header - * to be suppressed. It then suppresses the header by invoking PHS exported compress routine. - * The header data after suppression is copied back to the NDIS_PACKET. - * - * Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapter Context - * IN Packet - NDIS packet containing data to be transmitted - * IN USHORT Vcid - vcid pertaining to connection on which the packet is being sent.Used to - * identify PHS rule to be applied. - * B_UINT16 uiClassifierRuleID - Classifier Rule ID - * BOOLEAN bHeaderSuppressionEnabled - indicates if header suprression is enabled for SF. - * - * Return: STATUS_SUCCESS - If the send was successful. - * Other - If an error occurred. - */ - -int PHSTransmit(struct bcm_mini_adapter *Adapter, - struct sk_buff **pPacket, - USHORT Vcid, - B_UINT16 uiClassifierRuleID, - bool bHeaderSuppressionEnabled, - UINT *PacketLen, - UCHAR bEthCSSupport) -{ - /* PHS Sepcific */ - UINT unPHSPktHdrBytesCopied = 0; - UINT unPhsOldHdrSize = 0; - UINT unPHSNewPktHeaderLen = 0; - /* Pointer to PHS IN Hdr Buffer */ - PUCHAR pucPHSPktHdrInBuf = - Adapter->stPhsTxContextInfo.ucaHdrSuppressionInBuf; - /* Pointer to PHS OUT Hdr Buffer */ - PUCHAR pucPHSPktHdrOutBuf = - Adapter->stPhsTxContextInfo.ucaHdrSuppressionOutBuf; - UINT usPacketType; - UINT BytesToRemove = 0; - bool bPHSI = 0; - LONG ulPhsStatus = 0; - UINT numBytesCompressed = 0; - struct sk_buff *newPacket = NULL; - struct sk_buff *Packet = *pPacket; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "In PHSTransmit"); - - if (!bEthCSSupport) - BytesToRemove = ETH_HLEN; - /* - * Accumulate the header upto the size we support suppression - * from NDIS packet - */ - - usPacketType = ((struct ethhdr *)(Packet->data))->h_proto; - - pucPHSPktHdrInBuf = Packet->data + BytesToRemove; - /* considering data after ethernet header */ - if ((*PacketLen - BytesToRemove) < MAX_PHS_LENGTHS) - unPHSPktHdrBytesCopied = (*PacketLen - BytesToRemove); - else - unPHSPktHdrBytesCopied = MAX_PHS_LENGTHS; - - if ((unPHSPktHdrBytesCopied > 0) && - (unPHSPktHdrBytesCopied <= MAX_PHS_LENGTHS)) { - - /* - * Step 2 Suppress Header using PHS and fill into intermediate - * ucaPHSPktHdrOutBuf. - * Suppress only if IP Header and PHS Enabled For the - * Service Flow - */ - if (((usPacketType == ETHERNET_FRAMETYPE_IPV4) || - (usPacketType == ETHERNET_FRAMETYPE_IPV6)) && - (bHeaderSuppressionEnabled)) { - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, - DBG_LVL_ALL, - "\nTrying to PHS Compress Using Classifier rule 0x%X", - uiClassifierRuleID); - unPHSNewPktHeaderLen = unPHSPktHdrBytesCopied; - ulPhsStatus = PhsCompress(&Adapter->stBCMPhsContext, - Vcid, - uiClassifierRuleID, - pucPHSPktHdrInBuf, - pucPHSPktHdrOutBuf, - &unPhsOldHdrSize, - &unPHSNewPktHeaderLen); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, - DBG_LVL_ALL, - "\nPHS Old header Size : %d New Header Size %d\n", - unPhsOldHdrSize, unPHSNewPktHeaderLen); - - if (unPHSNewPktHeaderLen == unPhsOldHdrSize) { - - if (ulPhsStatus == STATUS_PHS_COMPRESSED) - bPHSI = *pucPHSPktHdrOutBuf; - - ulPhsStatus = STATUS_PHS_NOCOMPRESSION; - } - - if (ulPhsStatus == STATUS_PHS_COMPRESSED) { - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - PHS_SEND, DBG_LVL_ALL, - "PHS Sending packet Compressed"); - - if (skb_cloned(Packet)) { - newPacket = - skb_copy(Packet, GFP_ATOMIC); - - if (newPacket == NULL) - return STATUS_FAILURE; - - dev_kfree_skb(Packet); - *pPacket = Packet = newPacket; - pucPHSPktHdrInBuf = - Packet->data + BytesToRemove; - } - - numBytesCompressed = unPhsOldHdrSize - - (unPHSNewPktHeaderLen + PHSI_LEN); - - memcpy(pucPHSPktHdrInBuf + numBytesCompressed, - pucPHSPktHdrOutBuf, - unPHSNewPktHeaderLen + PHSI_LEN); - memcpy(Packet->data + numBytesCompressed, - Packet->data, BytesToRemove); - skb_pull(Packet, numBytesCompressed); - - return STATUS_SUCCESS; - } else { - /* if one byte headroom is not available, - * increase it through skb_cow - */ - if (!(skb_headroom(Packet) > 0)) { - - if (skb_cow(Packet, 1)) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_PRINTK, - 0, 0, - "SKB Cow Failed\n"); - return STATUS_FAILURE; - } - } - skb_push(Packet, 1); - - /* - * CAUTION: The MAC Header is getting corrupted - * here for IP CS - can be saved by copying 14 - * Bytes. not needed .... hence corrupting it. - */ - *(Packet->data + BytesToRemove) = bPHSI; - return STATUS_SUCCESS; - } - } else { - - if (!bHeaderSuppressionEnabled) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - PHS_SEND, DBG_LVL_ALL, - "\nHeader Suppression Disabled For SF: No PHS\n"); - - return STATUS_SUCCESS; - } - } - - /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - * "PHSTransmit : Dumping data packet After PHS"); */ - return STATUS_SUCCESS; -} - -int PHSReceive(struct bcm_mini_adapter *Adapter, - USHORT usVcid, - struct sk_buff *packet, - UINT *punPacketLen, - UCHAR *pucEthernetHdr, - UINT bHeaderSuppressionEnabled) -{ - u32 nStandardPktHdrLen = 0; - u32 nTotalsuppressedPktHdrBytes = 0; - int ulPhsStatus = 0; - PUCHAR pucInBuff = NULL; - UINT TotalBytesAdded = 0; - - if (!bHeaderSuppressionEnabled) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, - DBG_LVL_ALL, - "\nPhs Disabled for incoming packet"); - return ulPhsStatus; - } - - pucInBuff = packet->data; - - /* Restore PHS suppressed header */ - nStandardPktHdrLen = packet->len; - ulPhsStatus = PhsDeCompress(&Adapter->stBCMPhsContext, - usVcid, - pucInBuff, - Adapter->ucaPHSPktRestoreBuf, - &nTotalsuppressedPktHdrBytes, - &nStandardPktHdrLen); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, - "\nSuppressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x", - nTotalsuppressedPktHdrBytes, nStandardPktHdrLen); - - if (ulPhsStatus != STATUS_PHS_COMPRESSED) { - skb_pull(packet, 1); - return STATUS_SUCCESS; - } else { - TotalBytesAdded = nStandardPktHdrLen - - nTotalsuppressedPktHdrBytes - PHSI_LEN; - - if (TotalBytesAdded) { - if (skb_headroom(packet) >= (SKB_RESERVE_ETHERNET_HEADER + TotalBytesAdded)) - skb_push(packet, TotalBytesAdded); - else { - if (skb_cow(packet, skb_headroom(packet) + TotalBytesAdded)) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_PRINTK, 0, 0, - "cow failed in receive\n"); - return STATUS_FAILURE; - } - - skb_push(packet, TotalBytesAdded); - } - } - - memcpy(packet->data, Adapter->ucaPHSPktRestoreBuf, - nStandardPktHdrLen); - } - - return STATUS_SUCCESS; -} - -void DumpFullPacket(UCHAR *pBuf, UINT nPktLen) -{ - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, - "Dumping Data Packet"); - BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, - pBuf, nPktLen); -} - -/* - * Procedure: phs_init - * - * Description: This routine is responsible for allocating memory for classifier - * and PHS rules. - * - * Arguments: - * pPhsdeviceExtension - ptr to Device extension containing PHS Classifier rules - * and PHS Rules , RX, TX buffer etc - * - * Returns: - * TRUE(1) -If allocation of memory was successful. - * FALSE -If allocation of memory fails. - */ -int phs_init(struct bcm_phs_extension *pPhsdeviceExtension, - struct bcm_mini_adapter *Adapter) -{ - int i; - struct bcm_phs_table *pstServiceFlowTable; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "\nPHS:phs_init function"); - - if (pPhsdeviceExtension->pstServiceFlowPhsRulesTable) - return -EINVAL; - - pPhsdeviceExtension->pstServiceFlowPhsRulesTable = - kzalloc(sizeof(struct bcm_phs_table), GFP_KERNEL); - - if (!pPhsdeviceExtension->pstServiceFlowPhsRulesTable) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, - "\nAllocation ServiceFlowPhsRulesTable failed"); - return -ENOMEM; - } - - pstServiceFlowTable = pPhsdeviceExtension->pstServiceFlowPhsRulesTable; - for (i = 0; i < MAX_SERVICEFLOWS; i++) { - struct bcm_phs_entry sServiceFlow = - pstServiceFlowTable->stSFList[i]; - sServiceFlow.pstClassifierTable = - kzalloc(sizeof(struct bcm_phs_classifier_table), - GFP_KERNEL); - if (!sServiceFlow.pstClassifierTable) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "\nAllocation failed"); - free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable); - pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL; - return -ENOMEM; - } - } - - pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL); - if (pPhsdeviceExtension->CompressedTxBuffer == NULL) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "\nAllocation failed"); - free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable); - pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL; - return -ENOMEM; - } - - pPhsdeviceExtension->UnCompressedRxBuffer = - kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL); - if (pPhsdeviceExtension->UnCompressedRxBuffer == NULL) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "\nAllocation failed"); - kfree(pPhsdeviceExtension->CompressedTxBuffer); - free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable); - pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL; - return -ENOMEM; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "\n phs_init Successful"); - return STATUS_SUCCESS; -} - -int PhsCleanup(IN struct bcm_phs_extension *pPHSDeviceExt) -{ - if (pPHSDeviceExt->pstServiceFlowPhsRulesTable) { - free_phs_serviceflow_rules(pPHSDeviceExt->pstServiceFlowPhsRulesTable); - pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL; - } - - kfree(pPHSDeviceExt->CompressedTxBuffer); - pPHSDeviceExt->CompressedTxBuffer = NULL; - - kfree(pPHSDeviceExt->UnCompressedRxBuffer); - pPHSDeviceExt->UnCompressedRxBuffer = NULL; - - return 0; -} - -/* - * PHS functions - * PhsUpdateClassifierRule - * - * Routine Description: - * Exported function to add or modify a PHS Rule. - * - * Arguments: - * IN void* pvContext - PHS Driver Specific Context - * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies - * IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies. - * IN struct bcm_phs_rule *psPhsRule - The PHS Rule strcuture to be added to the PHS Rule table. - * - * Return Value: - * - * 0 if successful, - * >0 Error. - */ -ULONG PhsUpdateClassifierRule(IN void *pvContext, - IN B_UINT16 uiVcid , - IN B_UINT16 uiClsId , - IN struct bcm_phs_rule *psPhsRule, - IN B_UINT8 u8AssociatedPHSI) -{ - ULONG lStatus = 0; - UINT nSFIndex = 0; - struct bcm_phs_entry *pstServiceFlowEntry = NULL; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_extension *pDeviceExtension = - (struct bcm_phs_extension *)pvContext; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "PHS With Corr2 Changes\n"); - - if (pDeviceExtension == NULL) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "Invalid Device Extension\n"); - return ERR_PHS_INVALID_DEVICE_EXETENSION; - } - - if (u8AssociatedPHSI == 0) - return ERR_PHS_INVALID_PHS_RULE; - - /* Retrieve the SFID Entry Index for requested Service Flow */ - nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid, &pstServiceFlowEntry); - - if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - /* This is a new SF. Create a mapping entry for this */ - lStatus = CreateSFToClassifierRuleMapping(uiVcid, uiClsId, - pDeviceExtension->pstServiceFlowPhsRulesTable, - psPhsRule, - u8AssociatedPHSI); - return lStatus; - } - - /* SF already Exists Add PHS Rule to existing SF */ - lStatus = CreateClassiferToPHSRuleMapping(uiVcid, uiClsId, - pstServiceFlowEntry, - psPhsRule, - u8AssociatedPHSI); - - return lStatus; -} - -/* - * PhsDeletePHSRule - * - * Routine Description: - * Deletes the specified phs Rule within Vcid - * - * Arguments: - * IN void* pvContext - PHS Driver Specific Context - * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies - * IN B_UINT8 u8PHSI - the PHS Index identifying PHS rule to be deleted. - * - * Return Value: - * - * 0 if successful, - * >0 Error. - */ -ULONG PhsDeletePHSRule(IN void *pvContext, - IN B_UINT16 uiVcid, - IN B_UINT8 u8PHSI) -{ - UINT nSFIndex = 0, nClsidIndex = 0; - struct bcm_phs_entry *pstServiceFlowEntry = NULL; - struct bcm_phs_classifier_table *pstClassifierRulesTable = NULL; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext; - struct bcm_phs_classifier_entry *curr_entry; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "======>\n"); - - if (pDeviceExtension) { - /* Retrieve the SFID Entry Index for requested Service Flow */ - nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid, &pstServiceFlowEntry); - - if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "SFID Match Failed\n"); - return ERR_SF_MATCH_FAIL; - } - - pstClassifierRulesTable = pstServiceFlowEntry->pstClassifierTable; - if (pstClassifierRulesTable) { - for (nClsidIndex = 0; nClsidIndex < MAX_PHSRULE_PER_SF; nClsidIndex++) { - curr_entry = &pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]; - if (curr_entry->bUsed && - curr_entry->pstPhsRule && - (curr_entry->pstPhsRule->u8PHSI == u8PHSI)) { - - if (curr_entry->pstPhsRule->u8RefCnt) - curr_entry->pstPhsRule->u8RefCnt--; - - if (0 == curr_entry->pstPhsRule->u8RefCnt) - kfree(curr_entry->pstPhsRule); - - memset(curr_entry, - 0, - sizeof(struct bcm_phs_classifier_entry)); - } - } - } - } - return 0; -} - -/* - * PhsDeleteClassifierRule - * - * Routine Description: - * Exported function to Delete a PHS Rule for the SFID,CLSID Pair. - * - * Arguments: - * IN void* pvContext - PHS Driver Specific Context - * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies - * IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies. - * - * Return Value: - * - * 0 if successful, - * >0 Error. - */ -ULONG PhsDeleteClassifierRule(IN void *pvContext, - IN B_UINT16 uiVcid, - IN B_UINT16 uiClsId) -{ - UINT nSFIndex = 0, nClsidIndex = 0; - struct bcm_phs_entry *pstServiceFlowEntry = NULL; - struct bcm_phs_classifier_entry *pstClassifierEntry = NULL; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_extension *pDeviceExtension = - (struct bcm_phs_extension *)pvContext; - - if (!pDeviceExtension) - goto out; - - /* Retrieve the SFID Entry Index for requested Service Flow */ - nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid, &pstServiceFlowEntry); - if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "SFID Match Failed\n"); - return ERR_SF_MATCH_FAIL; - } - - nClsidIndex = - GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, - uiClsId, - eActiveClassifierRuleContext, - &pstClassifierEntry); - - if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) && - (!pstClassifierEntry->bUnclassifiedPHSRule)) { - if (pstClassifierEntry->pstPhsRule) { - if (pstClassifierEntry->pstPhsRule->u8RefCnt) - pstClassifierEntry->pstPhsRule->u8RefCnt--; - - if (0 == pstClassifierEntry->pstPhsRule->u8RefCnt) - kfree(pstClassifierEntry->pstPhsRule); - } - memset(pstClassifierEntry, 0, - sizeof(struct bcm_phs_classifier_entry)); - } - - nClsidIndex = - GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, - uiClsId, - eOldClassifierRuleContext, - &pstClassifierEntry); - - if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) && - (!pstClassifierEntry->bUnclassifiedPHSRule)) { - kfree(pstClassifierEntry->pstPhsRule); - memset(pstClassifierEntry, 0, - sizeof(struct bcm_phs_classifier_entry)); - } - -out: - return 0; -} - -/* - * PhsDeleteSFRules - * - * Routine Description: - * Exported function to Delete a all PHS Rules for the SFID. - * - * Arguments: - * IN void* pvContext - PHS Driver Specific Context - * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rules need to be deleted - * - * Return Value: - * - * 0 if successful, - * >0 Error. - */ -ULONG PhsDeleteSFRules(IN void *pvContext, IN B_UINT16 uiVcid) -{ - UINT nSFIndex = 0, nClsidIndex = 0; - struct bcm_phs_entry *pstServiceFlowEntry = NULL; - struct bcm_phs_classifier_table *pstClassifierRulesTable = NULL; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_extension *pDeviceExtension = - (struct bcm_phs_extension *)pvContext; - struct bcm_phs_classifier_entry *curr_clsf_entry; - struct bcm_phs_classifier_entry *curr_rules_list; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "====>\n"); - - if (!pDeviceExtension) - goto out; - - /* Retrieve the SFID Entry Index for requested Service Flow */ - nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid, &pstServiceFlowEntry); - if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "SFID Match Failed\n"); - return ERR_SF_MATCH_FAIL; - } - - pstClassifierRulesTable = pstServiceFlowEntry->pstClassifierTable; - if (pstClassifierRulesTable) { - for (nClsidIndex = 0; nClsidIndex < MAX_PHSRULE_PER_SF; nClsidIndex++) { - curr_clsf_entry = - &pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]; - - curr_rules_list = - &pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]; - - if (curr_clsf_entry->pstPhsRule) { - - if (curr_clsf_entry->pstPhsRule->u8RefCnt) - curr_clsf_entry->pstPhsRule->u8RefCnt--; - - if (0 == curr_clsf_entry->pstPhsRule->u8RefCnt) - kfree(curr_clsf_entry->pstPhsRule); - - curr_clsf_entry->pstPhsRule = NULL; - } - memset(curr_clsf_entry, 0, - sizeof(struct bcm_phs_classifier_entry)); - if (curr_rules_list->pstPhsRule) { - - if (curr_rules_list->pstPhsRule->u8RefCnt) - curr_rules_list->pstPhsRule->u8RefCnt--; - - if (0 == curr_rules_list->pstPhsRule->u8RefCnt) - kfree(curr_rules_list->pstPhsRule); - - curr_rules_list->pstPhsRule = NULL; - } - memset(curr_rules_list, 0, - sizeof(struct bcm_phs_classifier_entry)); - } - } - pstServiceFlowEntry->bUsed = false; - pstServiceFlowEntry->uiVcid = 0; - -out: - return 0; -} - -/* - * PhsCompress - * - * Routine Description: - * Exported function to compress the data using PHS. - * - * Arguments: - * IN void* pvContext - PHS Driver Specific Context. - * IN B_UINT16 uiVcid - The Service Flow ID to which current - * packet header compression applies. - * IN UINT uiClsId - The Classifier ID to which current packet - * header compression applies. - * IN void *pvInputBuffer - The Input buffer containg packet header - * data - * IN void *pvOutputBuffer - The output buffer returned by this - * function after PHS - * IN UINT *pOldHeaderSize - The actual size of the header before PHS - * IN UINT *pNewHeaderSize - The new size of the header after applying - * PHS - * - * Return Value: - * - * 0 if successful, - * >0 Error. - */ -static ULONG PhsCompress(IN void *pvContext, - IN B_UINT16 uiVcid, - IN B_UINT16 uiClsId, - IN void *pvInputBuffer, - OUT void *pvOutputBuffer, - OUT UINT *pOldHeaderSize, - OUT UINT *pNewHeaderSize) -{ - UINT nSFIndex = 0, nClsidIndex = 0; - struct bcm_phs_entry *pstServiceFlowEntry = NULL; - struct bcm_phs_classifier_entry *pstClassifierEntry = NULL; - struct bcm_phs_rule *pstPhsRule = NULL; - ULONG lStatus = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_extension *pDeviceExtension = - (struct bcm_phs_extension *)pvContext; - - if (pDeviceExtension == NULL) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "Invalid Device Extension\n"); - lStatus = STATUS_PHS_NOCOMPRESSION; - return lStatus; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "Suppressing header\n"); - - /* Retrieve the SFID Entry Index for requested Service Flow */ - nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid, &pstServiceFlowEntry); - if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "SFID Match Failed\n"); - lStatus = STATUS_PHS_NOCOMPRESSION; - return lStatus; - } - - nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, - uiClsId, eActiveClassifierRuleContext, - &pstClassifierEntry); - - if (nClsidIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "No PHS Rule Defined For Classifier\n"); - lStatus = STATUS_PHS_NOCOMPRESSION; - return lStatus; - } - - /* get rule from SF id,Cls ID pair and proceed */ - pstPhsRule = pstClassifierEntry->pstPhsRule; - if (!ValidatePHSRuleComplete(pstPhsRule)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "PHS Rule Defined For Classifier But Not Complete\n"); - lStatus = STATUS_PHS_NOCOMPRESSION; - return lStatus; - } - - /* Compress Packet */ - lStatus = phs_compress(pstPhsRule, - (PUCHAR)pvInputBuffer, - (PUCHAR)pvOutputBuffer, - pOldHeaderSize, - pNewHeaderSize); - - if (lStatus == STATUS_PHS_COMPRESSED) { - pstPhsRule->PHSModifiedBytes += - *pOldHeaderSize - *pNewHeaderSize - 1; - pstPhsRule->PHSModifiedNumPackets++; - } else { - pstPhsRule->PHSErrorNumPackets++; - } - - return lStatus; -} - -/* - * PhsDeCompress - * - * Routine Description: - * Exported function to restore the packet header in Rx path. - * - * Arguments: - * IN void* pvContext - PHS Driver Specific Context. - * IN B_UINT16 uiVcid - The Service Flow ID to which current - * packet header restoration applies. - * IN void *pvInputBuffer - The Input buffer containg suppressed - * packet header data - * OUT void *pvOutputBuffer - The output buffer returned by this - * function after restoration - * OUT UINT *pHeaderSize - The packet header size after restoration - * is returned in this parameter. - * - * Return Value: - * - * 0 if successful, - * >0 Error. - */ -static ULONG PhsDeCompress(IN void *pvContext, - IN B_UINT16 uiVcid, - IN void *pvInputBuffer, - OUT void *pvOutputBuffer, - OUT UINT *pInHeaderSize, - OUT UINT *pOutHeaderSize) -{ - UINT nSFIndex = 0, nPhsRuleIndex = 0; - struct bcm_phs_entry *pstServiceFlowEntry = NULL; - struct bcm_phs_rule *pstPhsRule = NULL; - UINT phsi; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_extension *pDeviceExtension = - (struct bcm_phs_extension *)pvContext; - - *pInHeaderSize = 0; - if (pDeviceExtension == NULL) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, - DBG_LVL_ALL, "Invalid Device Extension\n"); - return ERR_PHS_INVALID_DEVICE_EXETENSION; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, - "Restoring header\n"); - - phsi = *((unsigned char *)(pvInputBuffer)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, - "PHSI To Be Used For restore : %x\n", phsi); - if (phsi == UNCOMPRESSED_PACKET) - return STATUS_PHS_NOCOMPRESSION; - - /* Retrieve the SFID Entry Index for requested Service Flow */ - nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid, &pstServiceFlowEntry); - if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, - DBG_LVL_ALL, - "SFID Match Failed During Lookup\n"); - return ERR_SF_MATCH_FAIL; - } - - nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable, - phsi, - eActiveClassifierRuleContext, - &pstPhsRule); - if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) { - /* Phs Rule does not exist in active rules table. Lets try - * in the old rules table. */ - nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable, - phsi, - eOldClassifierRuleContext, - &pstPhsRule); - if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) - return ERR_PHSRULE_MATCH_FAIL; - } - - *pInHeaderSize = phs_decompress((PUCHAR)pvInputBuffer, - (PUCHAR)pvOutputBuffer, - pstPhsRule, - pOutHeaderSize); - - pstPhsRule->PHSModifiedBytes += *pOutHeaderSize - *pInHeaderSize - 1; - - pstPhsRule->PHSModifiedNumPackets++; - return STATUS_PHS_COMPRESSED; -} - -/* - * Procedure: free_phs_serviceflow_rules - * - * Description: This routine is responsible for freeing memory allocated for - * PHS rules. - * - * Arguments: - * rules - ptr to S_SERVICEFLOW_TABLE structure. - * - * Returns: - * Does not return any value. - */ -static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesTable) -{ - int i, j; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_classifier_entry *curr_act_rules_list; - struct bcm_phs_classifier_entry *curr_old_rules_list; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "=======>\n"); - - if (!psServiceFlowRulesTable) - goto out; - - for (i = 0; i < MAX_SERVICEFLOWS; i++) { - struct bcm_phs_entry stServiceFlowEntry = - psServiceFlowRulesTable->stSFList[i]; - struct bcm_phs_classifier_table *pstClassifierRulesTable = - stServiceFlowEntry.pstClassifierTable; - - if (pstClassifierRulesTable) { - for (j = 0; j < MAX_PHSRULE_PER_SF; j++) { - curr_act_rules_list = - &pstClassifierRulesTable->stActivePhsRulesList[j]; - - curr_old_rules_list = - &pstClassifierRulesTable->stOldPhsRulesList[j]; - - if (curr_act_rules_list->pstPhsRule) { - - if (curr_act_rules_list->pstPhsRule->u8RefCnt) - curr_act_rules_list->pstPhsRule->u8RefCnt--; - - if (0 == curr_act_rules_list->pstPhsRule->u8RefCnt) - kfree(curr_act_rules_list->pstPhsRule); - - curr_act_rules_list->pstPhsRule = NULL; - } - - if (curr_old_rules_list->pstPhsRule) { - - if (curr_old_rules_list->pstPhsRule->u8RefCnt) - curr_old_rules_list->pstPhsRule->u8RefCnt--; - - if (0 == curr_old_rules_list->pstPhsRule->u8RefCnt) - kfree(curr_old_rules_list->pstPhsRule); - - curr_old_rules_list->pstPhsRule = NULL; - } - } - kfree(pstClassifierRulesTable); - stServiceFlowEntry.pstClassifierTable = - pstClassifierRulesTable = NULL; - } - } - -out: - - kfree(psServiceFlowRulesTable); - psServiceFlowRulesTable = NULL; -} - -static bool ValidatePHSRuleComplete(IN const struct bcm_phs_rule *psPhsRule) -{ - return (psPhsRule && - psPhsRule->u8PHSI && - psPhsRule->u8PHSS && - psPhsRule->u8PHSFLength); -} - -UINT GetServiceFlowEntry(IN struct bcm_phs_table *psServiceFlowTable, - IN B_UINT16 uiVcid, - struct bcm_phs_entry **ppstServiceFlowEntry) -{ - int i; - struct bcm_phs_entry *curr_sf_list; - - for (i = 0; i < MAX_SERVICEFLOWS; i++) { - curr_sf_list = &psServiceFlowTable->stSFList[i]; - if (curr_sf_list->bUsed && (curr_sf_list->uiVcid == uiVcid)) { - *ppstServiceFlowEntry = curr_sf_list; - return i; - } - } - - *ppstServiceFlowEntry = NULL; - return PHS_INVALID_TABLE_INDEX; -} - -static UINT GetClassifierEntry(IN struct bcm_phs_classifier_table *pstClassifierTable, - IN B_UINT32 uiClsid, - enum bcm_phs_classifier_context eClsContext, - OUT struct bcm_phs_classifier_entry **ppstClassifierEntry) -{ - int i; - struct bcm_phs_classifier_entry *psClassifierRules = NULL; - - for (i = 0; i < MAX_PHSRULE_PER_SF; i++) { - - if (eClsContext == eActiveClassifierRuleContext) - psClassifierRules = - &pstClassifierTable->stActivePhsRulesList[i]; - else - psClassifierRules = - &pstClassifierTable->stOldPhsRulesList[i]; - - if (psClassifierRules->bUsed && - (psClassifierRules->uiClassifierRuleId == uiClsid)) { - *ppstClassifierEntry = psClassifierRules; - return i; - } - } - - *ppstClassifierEntry = NULL; - return PHS_INVALID_TABLE_INDEX; -} - -static UINT GetPhsRuleEntry(IN struct bcm_phs_classifier_table *pstClassifierTable, - IN B_UINT32 uiPHSI, - enum bcm_phs_classifier_context eClsContext, - OUT struct bcm_phs_rule **ppstPhsRule) -{ - int i; - struct bcm_phs_classifier_entry *pstClassifierRule = NULL; - - for (i = 0; i < MAX_PHSRULE_PER_SF; i++) { - if (eClsContext == eActiveClassifierRuleContext) - pstClassifierRule = - &pstClassifierTable->stActivePhsRulesList[i]; - else - pstClassifierRule = - &pstClassifierTable->stOldPhsRulesList[i]; - - if (pstClassifierRule->bUsed && - (pstClassifierRule->u8PHSI == uiPHSI)) { - *ppstPhsRule = pstClassifierRule->pstPhsRule; - return i; - } - } - - *ppstPhsRule = NULL; - return PHS_INVALID_TABLE_INDEX; -} - -static UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid, - IN B_UINT16 uiClsId, - IN struct bcm_phs_table *psServiceFlowTable, - struct bcm_phs_rule *psPhsRule, - B_UINT8 u8AssociatedPHSI) -{ - struct bcm_phs_classifier_table *psaClassifiertable = NULL; - UINT uiStatus = 0; - int iSfIndex; - bool bFreeEntryFound = false; - struct bcm_phs_entry *curr_list; - - /* Check for a free entry in SFID table */ - for (iSfIndex = 0; iSfIndex < MAX_SERVICEFLOWS; iSfIndex++) { - curr_list = &psServiceFlowTable->stSFList[iSfIndex]; - if (!curr_list->bUsed) { - bFreeEntryFound = TRUE; - break; - } - } - - if (!bFreeEntryFound) - return ERR_SFTABLE_FULL; - - psaClassifiertable = curr_list->pstClassifierTable; - uiStatus = CreateClassifierPHSRule(uiClsId, - psaClassifiertable, - psPhsRule, - eActiveClassifierRuleContext, - u8AssociatedPHSI); - if (uiStatus == PHS_SUCCESS) { - /* Add entry at free index to the SF */ - curr_list->bUsed = TRUE; - curr_list->uiVcid = uiVcid; - } - - return uiStatus; -} - -static UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid, - IN B_UINT16 uiClsId, - IN struct bcm_phs_entry *pstServiceFlowEntry, - struct bcm_phs_rule *psPhsRule, - B_UINT8 u8AssociatedPHSI) -{ - struct bcm_phs_classifier_entry *pstClassifierEntry = NULL; - UINT uiStatus = PHS_SUCCESS; - UINT nClassifierIndex = 0; - struct bcm_phs_classifier_table *psaClassifiertable = NULL; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - psaClassifiertable = pstServiceFlowEntry->pstClassifierTable; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "==>"); - - /* Check if the supplied Classifier already exists */ - nClassifierIndex = GetClassifierEntry( - pstServiceFlowEntry->pstClassifierTable, - uiClsId, - eActiveClassifierRuleContext, - &pstClassifierEntry); - - if (nClassifierIndex == PHS_INVALID_TABLE_INDEX) { - /* - * The Classifier doesn't exist. So its a new classifier being - * added. - * Add new entry to associate PHS Rule to the Classifier - */ - - uiStatus = CreateClassifierPHSRule(uiClsId, psaClassifiertable, - psPhsRule, - eActiveClassifierRuleContext, - u8AssociatedPHSI); - return uiStatus; - } - - /* - * The Classifier exists.The PHS Rule for this classifier - * is being modified - */ - - if (pstClassifierEntry->u8PHSI == psPhsRule->u8PHSI) { - if (pstClassifierEntry->pstPhsRule == NULL) - return ERR_PHS_INVALID_PHS_RULE; - - /* - * This rule already exists if any fields are changed for this - * PHS rule update them. - */ - /* If any part of PHSF is valid then we update PHSF */ - if (psPhsRule->u8PHSFLength) { - /* update PHSF */ - memcpy(pstClassifierEntry->pstPhsRule->u8PHSF, - psPhsRule->u8PHSF, - MAX_PHS_LENGTHS); - } - - if (psPhsRule->u8PHSFLength) { - /* update PHSFLen */ - pstClassifierEntry->pstPhsRule->u8PHSFLength = - psPhsRule->u8PHSFLength; - } - - if (psPhsRule->u8PHSMLength) { - /* update PHSM */ - memcpy(pstClassifierEntry->pstPhsRule->u8PHSM, - psPhsRule->u8PHSM, - MAX_PHS_LENGTHS); - } - - if (psPhsRule->u8PHSMLength) { - /* update PHSM Len */ - pstClassifierEntry->pstPhsRule->u8PHSMLength = - psPhsRule->u8PHSMLength; - } - - if (psPhsRule->u8PHSS) { - /* update PHSS */ - pstClassifierEntry->pstPhsRule->u8PHSS = - psPhsRule->u8PHSS; - } - - /* update PHSV */ - pstClassifierEntry->pstPhsRule->u8PHSV = psPhsRule->u8PHSV; - } else { - /* A new rule is being set for this classifier. */ - uiStatus = UpdateClassifierPHSRule(uiClsId, - pstClassifierEntry, - psaClassifiertable, - psPhsRule, - u8AssociatedPHSI); - } - - return uiStatus; -} - -static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, - struct bcm_phs_classifier_table *psaClassifiertable, - struct bcm_phs_rule *psPhsRule, - enum bcm_phs_classifier_context eClsContext, - B_UINT8 u8AssociatedPHSI) -{ - UINT iClassifierIndex = 0; - bool bFreeEntryFound = false; - struct bcm_phs_classifier_entry *psClassifierRules = NULL; - UINT nStatus = PHS_SUCCESS; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "Inside CreateClassifierPHSRule"); - - if (psaClassifiertable == NULL) - return ERR_INVALID_CLASSIFIERTABLE_FOR_SF; - - if (eClsContext == eOldClassifierRuleContext) { - /* - * If An Old Entry for this classifier ID already exists in the - * old rules table replace it. - */ - - iClassifierIndex = GetClassifierEntry(psaClassifiertable, - uiClsId, - eClsContext, - &psClassifierRules); - - if (iClassifierIndex != PHS_INVALID_TABLE_INDEX) { - /* - * The Classifier already exists in the old rules table - * Lets replace the old classifier with the new one. - */ - bFreeEntryFound = TRUE; - } - } - - if (!bFreeEntryFound) { - /* Continue to search for a free location to add the rule */ - for (iClassifierIndex = 0; iClassifierIndex < - MAX_PHSRULE_PER_SF; iClassifierIndex++) { - if (eClsContext == eActiveClassifierRuleContext) - psClassifierRules = &psaClassifiertable->stActivePhsRulesList[iClassifierIndex]; - else - psClassifierRules = &psaClassifiertable->stOldPhsRulesList[iClassifierIndex]; - - if (!psClassifierRules->bUsed) { - bFreeEntryFound = TRUE; - break; - } - } - } - - if (!bFreeEntryFound) { - - if (eClsContext == eActiveClassifierRuleContext) - return ERR_CLSASSIFIER_TABLE_FULL; - else { - /* Lets replace the oldest rule if we are looking in - * old Rule table */ - if (psaClassifiertable->uiOldestPhsRuleIndex >= MAX_PHSRULE_PER_SF) - psaClassifiertable->uiOldestPhsRuleIndex = 0; - - iClassifierIndex = - psaClassifiertable->uiOldestPhsRuleIndex; - psClassifierRules = - &psaClassifiertable->stOldPhsRulesList[iClassifierIndex]; - - (psaClassifiertable->uiOldestPhsRuleIndex)++; - } - } - - if (eClsContext == eOldClassifierRuleContext) { - - if (psClassifierRules->pstPhsRule == NULL) { - - psClassifierRules->pstPhsRule = - kmalloc(sizeof(struct bcm_phs_rule), - GFP_KERNEL); - - if (NULL == psClassifierRules->pstPhsRule) - return ERR_PHSRULE_MEMALLOC_FAIL; - } - - psClassifierRules->bUsed = TRUE; - psClassifierRules->uiClassifierRuleId = uiClsId; - psClassifierRules->u8PHSI = psPhsRule->u8PHSI; - psClassifierRules->bUnclassifiedPHSRule = - psPhsRule->bUnclassifiedPHSRule; - - /* Update The PHS rule */ - memcpy(psClassifierRules->pstPhsRule, psPhsRule, - sizeof(struct bcm_phs_rule)); - } else - nStatus = UpdateClassifierPHSRule(uiClsId, - psClassifierRules, - psaClassifiertable, - psPhsRule, - u8AssociatedPHSI); - - return nStatus; -} - -static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId, - IN struct bcm_phs_classifier_entry *pstClassifierEntry, - struct bcm_phs_classifier_table *psaClassifiertable, - struct bcm_phs_rule *psPhsRule, - B_UINT8 u8AssociatedPHSI) -{ - struct bcm_phs_rule *pstAddPhsRule = NULL; - UINT nPhsRuleIndex = 0; - bool bPHSRuleOrphaned = false; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - psPhsRule->u8RefCnt = 0; - - /* Step 1 Deref Any Exisiting PHS Rule in this classifier Entry */ - bPHSRuleOrphaned = DerefPhsRule(uiClsId, psaClassifiertable, - pstClassifierEntry->pstPhsRule); - - /* Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in - * Classifier table for this SF */ - nPhsRuleIndex = GetPhsRuleEntry(psaClassifiertable, u8AssociatedPHSI, - eActiveClassifierRuleContext, - &pstAddPhsRule); - if (PHS_INVALID_TABLE_INDEX == nPhsRuleIndex) { - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, - "\nAdding New PHSRuleEntry For Classifier"); - - if (psPhsRule->u8PHSI == 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "\nError PHSI is Zero\n"); - return ERR_PHS_INVALID_PHS_RULE; - } - - /* Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for - * uiClsId */ - if (false == bPHSRuleOrphaned) { - - pstClassifierEntry->pstPhsRule = - kmalloc(sizeof(struct bcm_phs_rule), - GFP_KERNEL); - if (NULL == pstClassifierEntry->pstPhsRule) - return ERR_PHSRULE_MEMALLOC_FAIL; - } - memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, - sizeof(struct bcm_phs_rule)); - } else { - /* Step 2.b PHS Rule Exists Tie uiClsId with the existing - * PHS Rule */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, - "\nTying Classifier to Existing PHS Rule"); - if (bPHSRuleOrphaned) { - kfree(pstClassifierEntry->pstPhsRule); - pstClassifierEntry->pstPhsRule = NULL; - } - pstClassifierEntry->pstPhsRule = pstAddPhsRule; - } - - pstClassifierEntry->bUsed = TRUE; - pstClassifierEntry->u8PHSI = pstClassifierEntry->pstPhsRule->u8PHSI; - pstClassifierEntry->uiClassifierRuleId = uiClsId; - pstClassifierEntry->pstPhsRule->u8RefCnt++; - pstClassifierEntry->bUnclassifiedPHSRule = - pstClassifierEntry->pstPhsRule->bUnclassifiedPHSRule; - - return PHS_SUCCESS; -} - -static bool DerefPhsRule(IN B_UINT16 uiClsId, - struct bcm_phs_classifier_table *psaClassifiertable, - struct bcm_phs_rule *pstPhsRule) -{ - if (pstPhsRule == NULL) - return false; - - if (pstPhsRule->u8RefCnt) - pstPhsRule->u8RefCnt--; - - return (0 == pstPhsRule->u8RefCnt); -} - -static void dbg_print_st_cls_entry(struct bcm_mini_adapter *ad, - struct bcm_phs_entry *st_serv_flow_entry, - struct bcm_phs_classifier_entry *st_cls_entry) -{ - int k; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n VCID : %#X", st_serv_flow_entry->uiVcid); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n ClassifierID : %#X", st_cls_entry->uiClassifierRuleId); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSRuleID : %#X", st_cls_entry->u8PHSI); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n****************PHS Rule********************\n"); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSI : %#X", st_cls_entry->pstPhsRule->u8PHSI); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSFLength : %#X ", st_cls_entry->pstPhsRule->u8PHSFLength); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSF : "); - - for (k = 0 ; k < st_cls_entry->pstPhsRule->u8PHSFLength; k++) - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ", st_cls_entry->pstPhsRule->u8PHSF[k]); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSMLength : %#X", st_cls_entry->pstPhsRule->u8PHSMLength); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSM :"); - - for (k = 0; k < st_cls_entry->pstPhsRule->u8PHSMLength; k++) - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ", st_cls_entry->pstPhsRule->u8PHSM[k]); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSS : %#X ", st_cls_entry->pstPhsRule->u8PHSS); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSV : %#X", st_cls_entry->pstPhsRule->u8PHSV); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n********************************************\n"); -} - -static void phsrules_per_sf_dbg_print(struct bcm_mini_adapter *ad, - struct bcm_phs_entry *st_serv_flow_entry) -{ - int j, l; - struct bcm_phs_classifier_entry st_cls_entry; - - for (j = 0; j < MAX_PHSRULE_PER_SF; j++) { - - for (l = 0; l < 2; l++) { - - if (l == 0) { - st_cls_entry = st_serv_flow_entry->pstClassifierTable->stActivePhsRulesList[j]; - if (st_cls_entry.bUsed) - BCM_DEBUG_PRINT(ad, - DBG_TYPE_OTHERS, - DUMP_INFO, - (DBG_LVL_ALL | DBG_NO_FUNC_PRINT), - "\n Active PHS Rule :\n"); - } else { - st_cls_entry = st_serv_flow_entry->pstClassifierTable->stOldPhsRulesList[j]; - if (st_cls_entry.bUsed) - BCM_DEBUG_PRINT(ad, - DBG_TYPE_OTHERS, - DUMP_INFO, - (DBG_LVL_ALL | DBG_NO_FUNC_PRINT), - "\n Old PHS Rule :\n"); - } - - if (st_cls_entry.bUsed) { - dbg_print_st_cls_entry(ad, - st_serv_flow_entry, - &st_cls_entry); - } - } - } -} - -void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension) -{ - int i; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, - "\n Dumping PHS Rules :\n"); - - for (i = 0; i < MAX_SERVICEFLOWS; i++) { - - struct bcm_phs_entry stServFlowEntry = - pDeviceExtension->pstServiceFlowPhsRulesTable->stSFList[i]; - - if (!stServFlowEntry.bUsed) - continue; - - phsrules_per_sf_dbg_print(Adapter, &stServFlowEntry); - } -} - -/* - * Procedure: phs_decompress - * - * Description: This routine restores the static fields within the packet. - * - * Arguments: - * in_buf - ptr to incoming packet buffer. - * out_buf - ptr to output buffer where the suppressed - * header is copied. - * decomp_phs_rules - ptr to PHS rule. - * header_size - ptr to field which holds the phss or - * phsf_length. - * - * Returns: - * size - The number of bytes of dynamic fields present with in the - * incoming packet header. - * 0 - If PHS rule is NULL.If PHSI is 0 indicateing packet as - * uncompressed. - */ -static int phs_decompress(unsigned char *in_buf, - unsigned char *out_buf, - struct bcm_phs_rule *decomp_phs_rules, - UINT *header_size) -{ - int phss, size = 0; - struct bcm_phs_rule *tmp_memb; - int bit, i = 0; - unsigned char *phsf, *phsm; - int in_buf_len = *header_size - 1; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - in_buf++; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, - "====>\n"); - *header_size = 0; - - if (decomp_phs_rules == NULL) - return 0; - - tmp_memb = decomp_phs_rules; - /* - * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL, - * "\nDECOMP:In phs_decompress PHSI 1 %d",phsi)); - * header_size = tmp_memb->u8PHSFLength; - */ - phss = tmp_memb->u8PHSS; - phsf = tmp_memb->u8PHSF; - phsm = tmp_memb->u8PHSM; - - if (phss > MAX_PHS_LENGTHS) - phss = MAX_PHS_LENGTHS; - - /* - * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL, - * "\nDECOMP: - * In phs_decompress PHSI %d phss %d index %d",phsi,phss,index)); - */ - while ((phss > 0) && (size < in_buf_len)) { - bit = ((*phsm << i) & SUPPRESS); - - if (bit == SUPPRESS) { - *out_buf = *phsf; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, - DBG_LVL_ALL, - "\nDECOMP:In phss %d phsf %d output %d", - phss, *phsf, *out_buf); - } else { - *out_buf = *in_buf; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, - DBG_LVL_ALL, - "\nDECOMP:In phss %d input %d output %d", - phss, *in_buf, *out_buf); - in_buf++; - size++; - } - out_buf++; - phsf++; - phss--; - i++; - *header_size = *header_size + 1; - - if (i > MAX_NO_BIT) { - i = 0; - phsm++; - } - } - - return size; -} - -/* - * Procedure: phs_compress - * - * Description: This routine suppresses the static fields within the packet. - * Before that it will verify the fields to be suppressed with the corresponding - * fields in the phsf. For verification it checks the phsv field of PHS rule. - * If set and verification succeeds it suppresses the field.If any one static - * field is found different none of the static fields are suppressed then the - * packet is sent as uncompressed packet with phsi=0. - * - * Arguments: - * phs_rule - ptr to PHS rule. - * in_buf - ptr to incoming packet buffer. - * out_buf - ptr to output buffer where the suppressed header is - * copied. - * header_size - ptr to field which holds the phss. - * - * Returns: - * size - The number of bytes copied into the output buffer i.e - * dynamic fields - * 0 - If PHS rule is NULL.If PHSV field is not set. If the - * verification fails. - */ -static int phs_compress(struct bcm_phs_rule *phs_rule, - unsigned char *in_buf, - unsigned char *out_buf, - UINT *header_size, - UINT *new_header_size) -{ - unsigned char *old_addr = out_buf; - int suppress = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if (phs_rule == NULL) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "\nphs_compress(): phs_rule null!"); - *out_buf = ZERO_PHSI; - return STATUS_PHS_NOCOMPRESSION; - } - - if (phs_rule->u8PHSS <= *new_header_size) - *header_size = phs_rule->u8PHSS; - else - *header_size = *new_header_size; - - /* To copy PHSI */ - out_buf++; - suppress = verify_suppress_phsf(in_buf, out_buf, phs_rule->u8PHSF, - phs_rule->u8PHSM, phs_rule->u8PHSS, - phs_rule->u8PHSV, new_header_size); - - if (suppress == STATUS_PHS_COMPRESSED) { - *old_addr = (unsigned char)phs_rule->u8PHSI; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "\nCOMP:In phs_compress phsi %d", - phs_rule->u8PHSI); - } else { - *old_addr = ZERO_PHSI; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "\nCOMP:In phs_compress PHSV Verification failed"); - } - - return suppress; -} - -/* - * Procedure: verify_suppress_phsf - * - * Description: This routine verifies the fields of the packet and if all the - * static fields are equal it adds the phsi of that PHS rule.If any static - * field differs it woun't suppress any field. - * - * Arguments: - * rules_set - ptr to classifier_rules. - * in_buffer - ptr to incoming packet buffer. - * out_buffer - ptr to output buffer where the suppressed header is copied. - * phsf - ptr to phsf. - * phsm - ptr to phsm. - * phss - variable holding phss. - * - * Returns: - * size - The number of bytes copied into the output buffer i.e dynamic - * fields. - * 0 - Packet has failed the verification. - */ -static int verify_suppress_phsf(unsigned char *in_buffer, - unsigned char *out_buffer, - unsigned char *phsf, - unsigned char *phsm, - unsigned int phss, - unsigned int phsv, - UINT *new_header_size) -{ - unsigned int size = 0; - int bit, i = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "\nCOMP:In verify_phsf PHSM - 0x%X", *phsm); - - if (phss > (*new_header_size)) - phss = *new_header_size; - - while (phss > 0) { - bit = ((*phsm << i) & SUPPRESS); - if (bit == SUPPRESS) { - if (*in_buffer != *phsf) { - if (phsv == VERIFY) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - PHS_SEND, - DBG_LVL_ALL, - "\nCOMP:In verify_phsf failed for field %d buf %d phsf %d", - phss, - *in_buffer, - *phsf); - return STATUS_PHS_NOCOMPRESSION; - } - } else - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - PHS_SEND, - DBG_LVL_ALL, - "\nCOMP:In verify_phsf success for field %d buf %d phsf %d", - phss, - *in_buffer, - *phsf); - } else { - *out_buffer = *in_buffer; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - PHS_SEND, - DBG_LVL_ALL, - "\nCOMP:In copying_header input %d out %d", - *in_buffer, - *out_buffer); - out_buffer++; - size++; - } - - in_buffer++; - phsf++; - phss--; - i++; - - if (i > MAX_NO_BIT) { - i = 0; - phsm++; - } - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "\nCOMP:In verify_phsf success"); - *new_header_size = size; - return STATUS_PHS_COMPRESSED; -} diff --git a/drivers/staging/bcm/PHSModule.h b/drivers/staging/bcm/PHSModule.h deleted file mode 100644 index d84d60ba48f9..000000000000 --- a/drivers/staging/bcm/PHSModule.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef BCM_MINIPORT_PHSMODULE_H -#define BCM_MINIPORT_PHSMODULE_H - -int PHSTransmit(struct bcm_mini_adapter *Adapter, - struct sk_buff **pPacket, - USHORT Vcid, - B_UINT16 uiClassifierRuleID, - bool bHeaderSuppressionEnabled, - PUINT PacketLen, - UCHAR bEthCSSupport); - -int PHSReceive(struct bcm_mini_adapter *Adapter, - USHORT usVcid, - struct sk_buff *packet, - UINT *punPacketLen, - UCHAR *pucEthernetHdr, - UINT - ); - - -void DumpDataPacketHeader(PUCHAR pPkt); - -void DumpFullPacket(UCHAR *pBuf, UINT nPktLen); - -void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension); - - -int phs_init(struct bcm_phs_extension *pPhsdeviceExtension, - struct bcm_mini_adapter *Adapter); - -int PhsCleanup(struct bcm_phs_extension *pPHSDeviceExt); - -/* Utility Functions */ -ULONG PhsUpdateClassifierRule(void *pvContext, - B_UINT16 uiVcid, - B_UINT16 uiClsId, - struct bcm_phs_rule *psPhsRule, - B_UINT8 u8AssociatedPHSI); - -ULONG PhsDeletePHSRule(void *pvContext, B_UINT16 uiVcid, B_UINT8 u8PHSI); - -ULONG PhsDeleteClassifierRule(void *pvContext, - B_UINT16 uiVcid, - B_UINT16 uiClsId); - -ULONG PhsDeleteSFRules(void *pvContext, B_UINT16 uiVcid); - - -bool ValidatePHSRule(struct bcm_phs_rule *psPhsRule); - -UINT GetServiceFlowEntry(struct bcm_phs_table *psServiceFlowTable, - B_UINT16 uiVcid, - struct bcm_phs_entry **ppstServiceFlowEntry); - - -void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension); - - -#endif diff --git a/drivers/staging/bcm/Protocol.h b/drivers/staging/bcm/Protocol.h deleted file mode 100644 index 9818128d9320..000000000000 --- a/drivers/staging/bcm/Protocol.h +++ /dev/null @@ -1,128 +0,0 @@ -/************************************ -* Protocol.h -*************************************/ -#ifndef __PROTOCOL_H__ -#define __PROTOCOL_H__ - -#define IPV4 4 -#define IPV6 6 - -struct ArpHeader { - struct arphdr arp; - unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */ - unsigned char ar_sip[4]; /* sender IP address */ - unsigned char ar_tha[ETH_ALEN]; /* target hardware address */ - unsigned char ar_tip[4]; /* target IP address */ -}; - -struct bcm_transport_header { - union { - struct udphdr uhdr; - struct tcphdr thdr; - }; -} __packed; - -enum bcm_ip_frame_type { - eNonIPPacket, - eIPv4Packet, - eIPv6Packet -}; - -enum bcm_eth_frame_type { - eEthUnsupportedFrame, - eEth802LLCFrame, - eEth802LLCSNAPFrame, - eEth802QVLANFrame, - eEthOtherFrame -}; - -struct bcm_eth_packet_info { - enum bcm_ip_frame_type eNwpktIPFrameType; - enum bcm_eth_frame_type eNwpktEthFrameType; - unsigned short usEtherType; - unsigned char ucDSAP; -}; - -struct bcm_eth_q_frame { - struct bcm_eth_header EThHdr; - unsigned short UserPriority:3; - unsigned short CFI:1; - unsigned short VLANID:12; - unsigned short EthType; -} __packed; - -struct bcm_eth_llc_frame { - struct bcm_eth_header EThHdr; - unsigned char DSAP; - unsigned char SSAP; - unsigned char Control; -} __packed; - -struct bcm_eth_llc_snap_frame { - struct bcm_eth_header EThHdr; - unsigned char DSAP; - unsigned char SSAP; - unsigned char Control; - unsigned char OUI[3]; - unsigned short usEtherType; -} __packed; - -struct bcm_ethernet2_frame { - struct bcm_eth_header EThHdr; -} __packed; - -#define ETHERNET_FRAMETYPE_IPV4 ntohs(0x0800) -#define ETHERNET_FRAMETYPE_IPV6 ntohs(0x86dd) -#define ETHERNET_FRAMETYPE_802QVLAN ntohs(0x8100) - -/* Per SF CS Specification Encodings */ -enum bcm_spec_encoding { - eCSSpecUnspecified = 0, - eCSPacketIPV4, - eCSPacketIPV6, - eCS802_3PacketEthernet, - eCS802_1QPacketVLAN, - eCSPacketIPV4Over802_3Ethernet, - eCSPacketIPV6Over802_3Ethernet, - eCSPacketIPV4Over802_1QVLAN, - eCSPacketIPV6Over802_1QVLAN, - eCSPacketUnsupported -}; - -#define IP6_HEADER_LEN 40 -#define IP_VERSION(byte) (((byte&0xF0)>>4)) - -#define MAC_ADDRESS_SIZE 6 -#define ETH_AND_IP_HEADER_LEN (14 + 20) -#define L4_SRC_PORT_LEN 2 -#define L4_DEST_PORT_LEN 2 -#define CTRL_PKT_LEN (8 + ETH_AND_IP_HEADER_LEN) - -#define ETH_ARP_FRAME 0x806 -#define ETH_IPV4_FRAME 0x800 -#define ETH_IPV6_FRAME 0x86DD -#define UDP 0x11 -#define TCP 0x06 - -#define ARP_OP_REQUEST 0x01 -#define ARP_OP_REPLY 0x02 -#define ARP_PKT_SIZE 60 - -/* This is the format for the TCP packet header */ -struct bcm_tcp_header { - unsigned short usSrcPort; - unsigned short usDestPort; - unsigned long ulSeqNumber; - unsigned long ulAckNumber; - unsigned char HeaderLength; - unsigned char ucFlags; - unsigned short usWindowsSize; - unsigned short usChkSum; - unsigned short usUrgetPtr; -}; - -#define TCP_HEADER_LEN sizeof(struct bcm_tcp_header) -#define TCP_ACK 0x10 /* Bit 4 in tcpflags field. */ -#define GET_TCP_HEADER_LEN(byte) ((byte&0xF0)>>4) - -#endif /* __PROTOCOL_H__ */ diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h deleted file mode 100644 index 1ddc8b2539f6..000000000000 --- a/drivers/staging/bcm/Prototypes.h +++ /dev/null @@ -1,217 +0,0 @@ -#ifndef _PROTOTYPES_H_ -#define _PROTOTYPES_H_ - -VOID LinkControlResponseMessage(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer); - -VOID StatisticsResponse(struct bcm_mini_adapter *Adapter, PVOID pvBuffer); - -VOID IdleModeResponse(struct bcm_mini_adapter *Adapter, PUINT puiBuffer); - -int control_packet_handler(struct bcm_mini_adapter *Adapter); - -VOID DeleteAllClassifiersForSF(struct bcm_mini_adapter *Adapter, UINT uiSearchRuleIndex); - -VOID flush_all_queues(struct bcm_mini_adapter *Adapter); - -int register_control_device_interface(struct bcm_mini_adapter *ps_adapter); - -void unregister_control_device_interface(struct bcm_mini_adapter *Adapter); - -INT CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter,/**<Logical Adapter*/ - PVOID ioBuffer/**<Control Packet Buffer*/ - ); - -VOID SortPackInfo(struct bcm_mini_adapter *Adapter); - -VOID SortClassifiers(struct bcm_mini_adapter *Adapter); - -VOID flush_all_queues(struct bcm_mini_adapter *Adapter); - -VOID PruneQueueAllSF(struct bcm_mini_adapter *Adapter); - -INT SearchSfid(struct bcm_mini_adapter *Adapter, UINT uiSfid); - -USHORT ClassifyPacket(struct bcm_mini_adapter *Adapter, struct sk_buff *skb); - -bool MatchSrcPort(struct bcm_classifier_rule *pstClassifierRule, USHORT ushSrcPort); - -bool MatchDestPort(struct bcm_classifier_rule *pstClassifierRule, USHORT ushSrcPort); - -bool MatchProtocol(struct bcm_classifier_rule *pstClassifierRule, UCHAR ucProtocol); - -INT SetupNextSend(struct bcm_mini_adapter *Adapter, /**<Logical Adapter*/ - struct sk_buff *Packet, /**<data buffer*/ - USHORT Vcid); - -VOID LinkMessage(struct bcm_mini_adapter *Adapter); - -VOID transmit_packets(struct bcm_mini_adapter *Adapter); - -INT SendControlPacket(struct bcm_mini_adapter *Adapter, /**<Logical Adapter*/ - char *pControlPacket/**<Control Packet*/ - ); - -int register_networkdev(struct bcm_mini_adapter *Adapter); - -void unregister_networkdev(struct bcm_mini_adapter *Adapter); - -INT AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter); - -VOID AdapterFree(struct bcm_mini_adapter *Adapter); - -INT FreeAdapterDsxBuffer(struct bcm_mini_adapter *Adapter); - -int tx_pkt_handler(struct bcm_mini_adapter *Adapter); - -int reset_card_proc(struct bcm_mini_adapter *Adapter); - -int run_card_proc(struct bcm_mini_adapter *Adapter); - -int InitCardAndDownloadFirmware(struct bcm_mini_adapter *ps_adapter); - -INT ReadMacAddressFromNVM(struct bcm_mini_adapter *Adapter); - -int register_control_device_interface(struct bcm_mini_adapter *ps_adapter); - -void DumpPackInfo(struct bcm_mini_adapter *Adapter); - -int rdm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t size); - -int wrm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t size); - -int wrmalt(struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize); - -int rdmalt(struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize); - -int get_dsx_sf_data_to_application(struct bcm_mini_adapter *Adapter, UINT uiSFId, void __user *user_buffer); - -void SendIdleModeResponse(struct bcm_mini_adapter *Adapter); - -int ProcessGetHostMibs(struct bcm_mini_adapter *Adapter, struct bcm_host_stats_mibs *buf); - -void GetDroppedAppCntrlPktMibs(struct bcm_host_stats_mibs *ioBuffer, struct bcm_tarang_data *pTarang); - -void beceem_parse_target_struct(struct bcm_mini_adapter *Adapter); - -int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter, struct bcm_firmware_info *psFwInfo); - -void CopyMIBSExtendedSFParameters(struct bcm_mini_adapter *Adapter, - struct bcm_connect_mgr_params *psfLocalSet, UINT uiSearchRuleIndex); - -VOID ResetCounters(struct bcm_mini_adapter *Adapter); - -int InitLedSettings(struct bcm_mini_adapter *Adapter); - -struct bcm_classifier_rule *GetFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentification, ULONG SrcIP); - -void AddFragIPClsEntry(struct bcm_mini_adapter *Adapter, struct bcm_fragmented_packet_info *psFragPktInfo); - -void DelFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentification, ULONG SrcIp); - -void update_per_cid_rx(struct bcm_mini_adapter *Adapter); - -void update_per_sf_desc_cnts(struct bcm_mini_adapter *Adapter); - -void ClearTargetDSXBuffer(struct bcm_mini_adapter *Adapter, B_UINT16 TID, bool bFreeAll); - -void flush_queue(struct bcm_mini_adapter *Adapter, UINT iQIndex); - -INT flushAllAppQ(VOID); - -INT BeceemEEPROMBulkRead( - struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes); - -INT WriteBeceemEEPROM(struct bcm_mini_adapter *Adapter, UINT uiEEPROMOffset, UINT uiData); - -INT PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter); - -INT BeceemEEPROMBulkWrite( - struct bcm_mini_adapter *Adapter, - PUCHAR pBuffer, - UINT uiOffset, - UINT uiNumBytes, - bool bVerify); - -INT ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter, UINT dwAddress, UINT *pdwData); - -INT BeceemNVMRead( - struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes); - -INT BeceemNVMWrite( - struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes, - bool bVerify); - -INT BcmInitNVM(struct bcm_mini_adapter *Adapter); - -INT BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter, UINT uiSectorSize); - -bool IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section); - -INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_bitmap *psFlash2xBitMap); - -INT BcmFlash2xBulkWrite( - struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - enum bcm_flash2x_section_val eFlashSectionVal, - UINT uiOffset, - UINT uiNumBytes, - UINT bVerify); - -INT BcmFlash2xBulkRead( - struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - enum bcm_flash2x_section_val eFlashSectionVal, - UINT uiOffsetWithinSectionVal, - UINT uiNumBytes); - -INT BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal); - -INT BcmSetActiveSection(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectVal); - -INT BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter); - -INT BcmDeAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter); - -INT BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section sCopySectStrut); - -INT BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal); - -INT BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal); - -INT validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_readwrite *psFlash2xReadWrite); - -INT IsFlash2x(struct bcm_mini_adapter *Adapter); - -INT BcmCopySection(struct bcm_mini_adapter *Adapter, - enum bcm_flash2x_section_val SrcSection, - enum bcm_flash2x_section_val DstSection, - UINT offset, - UINT numOfBytes); - -bool IsNonCDLessDevice(struct bcm_mini_adapter *Adapter); - -VOID OverrideServiceFlowParams(struct bcm_mini_adapter *Adapter, PUINT puiBuffer); - -int wrmaltWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize); - -int rdmaltWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize); - -int wrmWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t size); - -INT buffDnldVerify(struct bcm_mini_adapter *Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength, - unsigned long u32StartingAddress); - -VOID putUsbSuspend(struct work_struct *work); - -bool IsReqGpioIsLedInNVM(struct bcm_mini_adapter *Adapter, UINT gpios); - -#endif diff --git a/drivers/staging/bcm/Qos.c b/drivers/staging/bcm/Qos.c deleted file mode 100644 index b3ac614cd35f..000000000000 --- a/drivers/staging/bcm/Qos.c +++ /dev/null @@ -1,1200 +0,0 @@ -/** - * @file Qos.C - * This file contains the routines related to Quality of Service. -*/ -#include "headers.h" - -static void EThCSGetPktInfo(struct bcm_mini_adapter *Adapter, - PVOID pvEthPayload, - struct bcm_eth_packet_info *pstEthCsPktInfo); - -static bool EThCSClassifyPkt(struct bcm_mini_adapter *Adapter, - struct sk_buff *skb, - struct bcm_eth_packet_info *pstEthCsPktInfo, - struct bcm_classifier_rule *pstClassifierRule, - B_UINT8 EthCSCupport); - -static USHORT IpVersion4(struct bcm_mini_adapter *Adapter, struct iphdr *iphd, - struct bcm_classifier_rule *pstClassifierRule); - -static VOID PruneQueue(struct bcm_mini_adapter *Adapter, INT iIndex); - - -/******************************************************************* -* Function - MatchSrcIpAddress() -* -* Description - Checks whether the Source IP address from the packet -* matches with that of Queue. -* -* Parameters - pstClassifierRule: Pointer to the packet info structure. -* - ulSrcIP : Source IP address from the packet. -* -* Returns - TRUE(If address matches) else FAIL . -*********************************************************************/ -static bool MatchSrcIpAddress(struct bcm_classifier_rule *pstClassifierRule, - ULONG ulSrcIP) -{ - UCHAR ucLoopIndex = 0; - - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - union u_ip_address *src_addr; - - ulSrcIP = ntohl(ulSrcIP); - if (0 == pstClassifierRule->ucIPSourceAddressLength) - return TRUE; - for (ucLoopIndex = 0; - ucLoopIndex < (pstClassifierRule->ucIPSourceAddressLength); - ucLoopIndex++) { - src_addr = &pstClassifierRule->stSrcIpAddress; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Src Ip Address Mask:0x%x PacketIp:0x%x and Classification:0x%x", - (UINT)src_addr->ulIpv4Mask[ucLoopIndex], - (UINT)ulSrcIP, - (UINT)src_addr->ulIpv6Addr[ucLoopIndex]); - - if ((src_addr->ulIpv4Mask[ucLoopIndex] & ulSrcIP) == - (src_addr->ulIpv4Addr[ucLoopIndex] & - src_addr->ulIpv4Mask[ucLoopIndex])) - return TRUE; - } - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Src Ip Address Not Matched"); - return false; -} - - -/******************************************************************* -* Function - MatchDestIpAddress() -* -* Description - Checks whether the Destination IP address from the packet -* matches with that of Queue. -* -* Parameters - pstClassifierRule: Pointer to the packet info structure. -* - ulDestIP : Destination IP address from the packet. -* -* Returns - TRUE(If address matches) else FAIL . -*********************************************************************/ -static bool MatchDestIpAddress(struct bcm_classifier_rule *pstClassifierRule, ULONG ulDestIP) -{ - UCHAR ucLoopIndex = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - union u_ip_address *dest_addr = &pstClassifierRule->stDestIpAddress; - - ulDestIP = ntohl(ulDestIP); - if (0 == pstClassifierRule->ucIPDestinationAddressLength) - return TRUE; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Destination Ip Address 0x%x 0x%x 0x%x ", - (UINT)ulDestIP, - (UINT)dest_addr->ulIpv4Mask[ucLoopIndex], - (UINT)dest_addr->ulIpv4Addr[ucLoopIndex]); - - for (ucLoopIndex = 0; - ucLoopIndex < (pstClassifierRule->ucIPDestinationAddressLength); - ucLoopIndex++) { - if ((dest_addr->ulIpv4Mask[ucLoopIndex] & ulDestIP) == - (dest_addr->ulIpv4Addr[ucLoopIndex] & - dest_addr->ulIpv4Mask[ucLoopIndex])) - return TRUE; - } - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Destination Ip Address Not Matched"); - return false; -} - - -/************************************************************************ -* Function - MatchTos() -* -* Description - Checks the TOS from the packet matches with that of queue. -* -* Parameters - pstClassifierRule : Pointer to the packet info structure. -* - ucTypeOfService: TOS from the packet. -* -* Returns - TRUE(If address matches) else FAIL. -**************************************************************************/ -static bool MatchTos(struct bcm_classifier_rule *pstClassifierRule, - UCHAR ucTypeOfService) -{ - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if (3 != pstClassifierRule->ucIPTypeOfServiceLength) - return TRUE; - - if (((pstClassifierRule->ucTosMask & ucTypeOfService) <= - pstClassifierRule->ucTosHigh) && - ((pstClassifierRule->ucTosMask & ucTypeOfService) >= - pstClassifierRule->ucTosLow)) - return TRUE; - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Type Of Service Not Matched"); - return false; -} - - -/*************************************************************************** -* Function - MatchProtocol() -* -* Description - Checks the protocol from the packet matches with that of queue. -* -* Parameters - pstClassifierRule: Pointer to the packet info structure. -* - ucProtocol : Protocol from the packet. -* -* Returns - TRUE(If address matches) else FAIL. -****************************************************************************/ -bool MatchProtocol(struct bcm_classifier_rule *pstClassifierRule, - UCHAR ucProtocol) -{ - UCHAR ucLoopIndex = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if (0 == pstClassifierRule->ucProtocolLength) - return TRUE; - for (ucLoopIndex = 0; - ucLoopIndex < pstClassifierRule->ucProtocolLength; - ucLoopIndex++) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Protocol:0x%X Classification Protocol:0x%X", - ucProtocol, - pstClassifierRule->ucProtocol[ucLoopIndex]); - if (pstClassifierRule->ucProtocol[ucLoopIndex] == ucProtocol) - return TRUE; - } - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Protocol Not Matched"); - return false; -} - - -/*********************************************************************** -* Function - MatchSrcPort() -* -* Description - Checks, Source port from the packet matches with that of queue. -* -* Parameters - pstClassifierRule: Pointer to the packet info structure. -* - ushSrcPort : Source port from the packet. -* -* Returns - TRUE(If address matches) else FAIL. -***************************************************************************/ -bool MatchSrcPort(struct bcm_classifier_rule *pstClassifierRule, - USHORT ushSrcPort) -{ - UCHAR ucLoopIndex = 0; - - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - - if (0 == pstClassifierRule->ucSrcPortRangeLength) - return TRUE; - for (ucLoopIndex = 0; - ucLoopIndex < pstClassifierRule->ucSrcPortRangeLength; - ucLoopIndex++) { - if (ushSrcPort <= pstClassifierRule->usSrcPortRangeHi[ucLoopIndex] && - ushSrcPort >= pstClassifierRule->usSrcPortRangeLo[ucLoopIndex]) - return TRUE; - } - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Src Port: %x Not Matched ", - ushSrcPort); - return false; -} - - -/*********************************************************************** -* Function - MatchDestPort() -* -* Description - Checks, Destination port from packet matches with that of queue. -* -* Parameters - pstClassifierRule: Pointer to the packet info structure. -* - ushDestPort : Destination port from the packet. -* -* Returns - TRUE(If address matches) else FAIL. -***************************************************************************/ -bool MatchDestPort(struct bcm_classifier_rule *pstClassifierRule, - USHORT ushDestPort) -{ - UCHAR ucLoopIndex = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if (0 == pstClassifierRule->ucDestPortRangeLength) - return TRUE; - - for (ucLoopIndex = 0; - ucLoopIndex < pstClassifierRule->ucDestPortRangeLength; - ucLoopIndex++) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Matching Port:0x%X 0x%X 0x%X", - ushDestPort, - pstClassifierRule->usDestPortRangeLo[ucLoopIndex], - pstClassifierRule->usDestPortRangeHi[ucLoopIndex]); - - if (ushDestPort <= pstClassifierRule->usDestPortRangeHi[ucLoopIndex] && - ushDestPort >= pstClassifierRule->usDestPortRangeLo[ucLoopIndex]) - return TRUE; - } - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Dest Port: %x Not Matched", - ushDestPort); - return false; -} -/** - * @ingroup tx_functions - * Compares IPV4 Ip address and port number - * @return Queue Index. -*/ -static USHORT IpVersion4(struct bcm_mini_adapter *Adapter, - struct iphdr *iphd, - struct bcm_classifier_rule *pstClassifierRule) -{ - struct bcm_transport_header *xprt_hdr = NULL; - bool bClassificationSucceed = false; - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "========>"); - - xprt_hdr = (struct bcm_transport_header *)((PUCHAR)iphd + sizeof(struct iphdr)); - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Trying to see Direction = %d %d", - pstClassifierRule->ucDirection, - pstClassifierRule->usVCID_Value); - - /* Checking classifier validity */ - if (!pstClassifierRule->bUsed || - pstClassifierRule->ucDirection == DOWNLINK_DIR) - goto out; - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "is IPv6 check!"); - if (pstClassifierRule->bIpv6Protocol) - goto out; - - /* Checking IP header parameter */ - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Trying to match Source IP Address"); - if (!MatchSrcIpAddress(pstClassifierRule, iphd->saddr)) - goto out; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Source IP Address Matched"); - - if (!MatchDestIpAddress(pstClassifierRule, iphd->daddr)) - goto out; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Destination IP Address Matched"); - - if (!MatchTos(pstClassifierRule, iphd->tos)) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "TOS Match failed\n"); - goto out; - } - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "TOS Matched"); - - if (!MatchProtocol(pstClassifierRule, iphd->protocol)) - goto out; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Protocol Matched"); - - /* - * if protocol is not TCP or UDP then no - * need of comparing source port and destination port - */ - if (iphd->protocol != TCP && iphd->protocol != UDP) { - bClassificationSucceed = TRUE; - goto out; - } - /* Checking Transport Layer Header field if present */ - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Source Port %04x", - (iphd->protocol == UDP) ? xprt_hdr->uhdr.source : xprt_hdr->thdr.source); - - if (!MatchSrcPort(pstClassifierRule, - ntohs((iphd->protocol == UDP) ? - xprt_hdr->uhdr.source : xprt_hdr->thdr.source))) - goto out; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Src Port Matched"); - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Destination Port %04x", - (iphd->protocol == UDP) ? xprt_hdr->uhdr.dest : - xprt_hdr->thdr.dest); - - if (!MatchDestPort(pstClassifierRule, - ntohs((iphd->protocol == UDP) ? - xprt_hdr->uhdr.dest : xprt_hdr->thdr.dest))) - goto out; - bClassificationSucceed = TRUE; - -out: - if (TRUE == bClassificationSucceed) { - INT iMatchedSFQueueIndex = 0; - - iMatchedSFQueueIndex = - SearchSfid(Adapter, pstClassifierRule->ulSFID); - if (iMatchedSFQueueIndex >= NO_OF_QUEUES) - bClassificationSucceed = false; - else if (false == Adapter->PackInfo[iMatchedSFQueueIndex].bActive) - bClassificationSucceed = false; - } - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "IpVersion4 <=========="); - - return bClassificationSucceed; -} - -VOID PruneQueueAllSF(struct bcm_mini_adapter *Adapter) -{ - UINT iIndex = 0; - - for (iIndex = 0; iIndex < HiPriority; iIndex++) { - if (!Adapter->PackInfo[iIndex].bValid) - continue; - - PruneQueue(Adapter, iIndex); - } -} - - -/** - * @ingroup tx_functions - * This function checks if the max queue size for a queue - * is less than number of bytes in the queue. If so - - * drops packets from the Head till the number of bytes is - * less than or equal to max queue size for the queue. - */ -static VOID PruneQueue(struct bcm_mini_adapter *Adapter, INT iIndex) -{ - struct sk_buff *PacketToDrop = NULL; - struct net_device_stats *netstats; - struct bcm_packet_info *curr_pack_info = &Adapter->PackInfo[iIndex]; - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - PRUNE_QUEUE, - DBG_LVL_ALL, - "=====> Index %d", - iIndex); - - if (iIndex == HiPriority) - return; - - if (!Adapter || (iIndex < 0) || (iIndex > HiPriority)) - return; - - /* To Store the netdevice statistic */ - netstats = &Adapter->dev->stats; - - spin_lock_bh(&curr_pack_info->SFQueueLock); - - while (1) { -/* while((UINT)curr_pack_info->uiCurrentPacketsOnHost > - SF_MAX_ALLOWED_PACKETS_TO_BACKUP) { */ - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - PRUNE_QUEUE, - DBG_LVL_ALL, - "uiCurrentBytesOnHost:%x uiMaxBucketSize :%x", - curr_pack_info->uiCurrentBytesOnHost, - curr_pack_info->uiMaxBucketSize); - - PacketToDrop = curr_pack_info->FirstTxQueue; - - if (PacketToDrop == NULL) - break; - if ((curr_pack_info->uiCurrentPacketsOnHost < - SF_MAX_ALLOWED_PACKETS_TO_BACKUP) && - ((1000*(jiffies - *((B_UINT32 *)(PacketToDrop->cb) + - SKB_CB_LATENCY_OFFSET))/HZ) <= - curr_pack_info->uiMaxLatency)) - break; - - if (PacketToDrop) { - if (netif_msg_tx_err(Adapter)) - pr_info(PFX "%s: tx queue %d overlimit\n", - Adapter->dev->name, iIndex); - - netstats->tx_dropped++; - - DEQUEUEPACKET(curr_pack_info->FirstTxQueue, - curr_pack_info->LastTxQueue); - /* update current bytes and packets count */ - curr_pack_info->uiCurrentBytesOnHost -= - PacketToDrop->len; - curr_pack_info->uiCurrentPacketsOnHost--; - /* update dropped bytes and packets counts */ - curr_pack_info->uiDroppedCountBytes += PacketToDrop->len; - curr_pack_info->uiDroppedCountPackets++; - dev_kfree_skb(PacketToDrop); - - } - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - PRUNE_QUEUE, - DBG_LVL_ALL, - "Dropped Bytes:%x Dropped Packets:%x", - curr_pack_info->uiDroppedCountBytes, - curr_pack_info->uiDroppedCountPackets); - - atomic_dec(&Adapter->TotalPacketCount); - } - - spin_unlock_bh(&curr_pack_info->SFQueueLock); - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - PRUNE_QUEUE, - DBG_LVL_ALL, - "TotalPacketCount:%x", - atomic_read(&Adapter->TotalPacketCount)); - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - PRUNE_QUEUE, - DBG_LVL_ALL, - "<====="); -} - -VOID flush_all_queues(struct bcm_mini_adapter *Adapter) -{ - INT iQIndex; - UINT uiTotalPacketLength; - struct sk_buff *PacketToDrop = NULL; - struct bcm_packet_info *curr_packet_info; - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - DUMP_INFO, - DBG_LVL_ALL, - "=====>"); - - /* down(&Adapter->data_packet_queue_lock); */ - for (iQIndex = LowPriority; iQIndex < HiPriority; iQIndex++) { - struct net_device_stats *netstats = &Adapter->dev->stats; - - curr_packet_info = &Adapter->PackInfo[iQIndex]; - - spin_lock_bh(&curr_packet_info->SFQueueLock); - while (curr_packet_info->FirstTxQueue) { - PacketToDrop = curr_packet_info->FirstTxQueue; - if (PacketToDrop) { - uiTotalPacketLength = PacketToDrop->len; - netstats->tx_dropped++; - } else - uiTotalPacketLength = 0; - - DEQUEUEPACKET(curr_packet_info->FirstTxQueue, - curr_packet_info->LastTxQueue); - - /* Free the skb */ - dev_kfree_skb(PacketToDrop); - - /* update current bytes and packets count */ - curr_packet_info->uiCurrentBytesOnHost -= uiTotalPacketLength; - curr_packet_info->uiCurrentPacketsOnHost--; - - /* update dropped bytes and packets counts */ - curr_packet_info->uiDroppedCountBytes += uiTotalPacketLength; - curr_packet_info->uiDroppedCountPackets++; - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - DUMP_INFO, - DBG_LVL_ALL, - "Dropped Bytes:%x Dropped Packets:%x", - curr_packet_info->uiDroppedCountBytes, - curr_packet_info->uiDroppedCountPackets); - atomic_dec(&Adapter->TotalPacketCount); - } - spin_unlock_bh(&curr_packet_info->SFQueueLock); - } - /* up(&Adapter->data_packet_queue_lock); */ - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - DUMP_INFO, - DBG_LVL_ALL, - "<====="); -} - -USHORT ClassifyPacket(struct bcm_mini_adapter *Adapter, struct sk_buff *skb) -{ - INT uiLoopIndex = 0; - struct bcm_classifier_rule *pstClassifierRule = NULL; - struct bcm_eth_packet_info stEthCsPktInfo; - PVOID pvEThPayload = NULL; - struct iphdr *pIpHeader = NULL; - INT uiSfIndex = 0; - USHORT usIndex = Adapter->usBestEffortQueueIndex; - bool bFragmentedPkt = false, bClassificationSucceed = false; - USHORT usCurrFragment = 0; - - struct bcm_tcp_header *pTcpHeader; - UCHAR IpHeaderLength; - UCHAR TcpHeaderLength; - - pvEThPayload = skb->data; - *((UINT32 *) (skb->cb) + SKB_CB_TCPACK_OFFSET) = 0; - EThCSGetPktInfo(Adapter, pvEThPayload, &stEthCsPktInfo); - - switch (stEthCsPktInfo.eNwpktEthFrameType) { - case eEth802LLCFrame: - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ClassifyPacket : 802LLCFrame\n"); - pIpHeader = pvEThPayload + sizeof(struct bcm_eth_llc_frame); - break; - case eEth802LLCSNAPFrame: - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ClassifyPacket : 802LLC SNAP Frame\n"); - pIpHeader = pvEThPayload + - sizeof(struct bcm_eth_llc_snap_frame); - break; - case eEth802QVLANFrame: - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ClassifyPacket : 802.1Q VLANFrame\n"); - pIpHeader = pvEThPayload + sizeof(struct bcm_eth_q_frame); - break; - case eEthOtherFrame: - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ClassifyPacket : ETH Other Frame\n"); - pIpHeader = pvEThPayload + sizeof(struct bcm_ethernet2_frame); - break; - default: - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ClassifyPacket : Unrecognized ETH Frame\n"); - pIpHeader = pvEThPayload + sizeof(struct bcm_ethernet2_frame); - break; - } - - if (stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet) { - usCurrFragment = (ntohs(pIpHeader->frag_off) & IP_OFFSET); - if ((ntohs(pIpHeader->frag_off) & IP_MF) || usCurrFragment) - bFragmentedPkt = TRUE; - - if (bFragmentedPkt) { - /* Fragmented Packet. Get Frag Classifier Entry. */ - pstClassifierRule = GetFragIPClsEntry(Adapter, - pIpHeader->id, - pIpHeader->saddr); - if (pstClassifierRule) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "It is next Fragmented pkt"); - bClassificationSucceed = TRUE; - } - if (!(ntohs(pIpHeader->frag_off) & IP_MF)) { - /* Fragmented Last packet . Remove Frag Classifier Entry */ - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "This is the last fragmented Pkt"); - DelFragIPClsEntry(Adapter, - pIpHeader->id, - pIpHeader->saddr); - } - } - } - - for (uiLoopIndex = MAX_CLASSIFIERS - 1; uiLoopIndex >= 0; uiLoopIndex--) { - if (bClassificationSucceed) - break; - /* - * Iterate through all classifiers which are already in order of priority - * to classify the packet until match found - */ - if (false == Adapter->astClassifierTable[uiLoopIndex].bUsed) { - bClassificationSucceed = false; - continue; - } - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Adapter->PackInfo[%d].bvalid=True\n", - uiLoopIndex); - - if (0 == Adapter->astClassifierTable[uiLoopIndex].ucDirection) { - bClassificationSucceed = false; /* cannot be processed for classification. */ - continue; /* it is a down link connection */ - } - - pstClassifierRule = &Adapter->astClassifierTable[uiLoopIndex]; - - uiSfIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID); - if (uiSfIndex >= NO_OF_QUEUES) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Queue Not Valid. SearchSfid for this classifier Failed\n"); - continue; - } - - if (Adapter->PackInfo[uiSfIndex].bEthCSSupport) { - - if (eEthUnsupportedFrame == stEthCsPktInfo.eNwpktEthFrameType) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - " ClassifyPacket : Packet Not a Valid Supported Ethernet Frame\n"); - bClassificationSucceed = false; - continue; - } - - - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Performing ETH CS Classification on Classifier Rule ID : %x Service Flow ID : %lx\n", - pstClassifierRule->uiClassifierRuleIndex, - Adapter->PackInfo[uiSfIndex].ulSFID); - bClassificationSucceed = EThCSClassifyPkt(Adapter, - skb, - &stEthCsPktInfo, - pstClassifierRule, - Adapter->PackInfo[uiSfIndex].bEthCSSupport); - - if (!bClassificationSucceed) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ClassifyPacket : Ethernet CS Classification Failed\n"); - continue; - } - } else { /* No ETH Supported on this SF */ - if (eEthOtherFrame != stEthCsPktInfo.eNwpktEthFrameType) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - " ClassifyPacket : Packet Not a 802.3 Ethernet Frame... hence not allowed over non-ETH CS SF\n"); - bClassificationSucceed = false; - continue; - } - } - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Proceeding to IP CS Clasification"); - - if (Adapter->PackInfo[uiSfIndex].bIPCSSupport) { - - if (stEthCsPktInfo.eNwpktIPFrameType == eNonIPPacket) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - " ClassifyPacket : Packet is Not an IP Packet\n"); - bClassificationSucceed = false; - continue; - } - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Dump IP Header :\n"); - DumpFullPacket((PUCHAR)pIpHeader, 20); - - if (stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet) - bClassificationSucceed = IpVersion4(Adapter, - pIpHeader, - pstClassifierRule); - else if (stEthCsPktInfo.eNwpktIPFrameType == eIPv6Packet) - bClassificationSucceed = IpVersion6(Adapter, - pIpHeader, - pstClassifierRule); - } - } - - if (bClassificationSucceed == TRUE) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "CF id : %d, SF ID is =%lu", - pstClassifierRule->uiClassifierRuleIndex, - pstClassifierRule->ulSFID); - - /* Store The matched Classifier in SKB */ - *((UINT32 *)(skb->cb)+SKB_CB_CLASSIFICATION_OFFSET) = - pstClassifierRule->uiClassifierRuleIndex; - if ((TCP == pIpHeader->protocol) && !bFragmentedPkt && - (ETH_AND_IP_HEADER_LEN + TCP_HEADER_LEN <= - skb->len)) { - IpHeaderLength = pIpHeader->ihl; - pTcpHeader = - (struct bcm_tcp_header *)(((PUCHAR)pIpHeader) + - (IpHeaderLength*4)); - TcpHeaderLength = GET_TCP_HEADER_LEN(pTcpHeader->HeaderLength); - - if ((pTcpHeader->ucFlags & TCP_ACK) && - (ntohs(pIpHeader->tot_len) == - (IpHeaderLength*4)+(TcpHeaderLength*4))) - *((UINT32 *) (skb->cb) + SKB_CB_TCPACK_OFFSET) = - TCP_ACK; - } - - usIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID); - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "index is =%d", - usIndex); - - /* - * If this is the first fragment of a Fragmented pkt, - * add this CF. Only This CF should be used for all other - * fragment of this Pkt. - */ - if (bFragmentedPkt && (usCurrFragment == 0)) { - /* - * First Fragment of Fragmented Packet. - * Create Frag CLS Entry - */ - struct bcm_fragmented_packet_info stFragPktInfo; - - stFragPktInfo.bUsed = TRUE; - stFragPktInfo.ulSrcIpAddress = pIpHeader->saddr; - stFragPktInfo.usIpIdentification = pIpHeader->id; - stFragPktInfo.pstMatchedClassifierEntry = - pstClassifierRule; - stFragPktInfo.bOutOfOrderFragment = false; - AddFragIPClsEntry(Adapter, &stFragPktInfo); - } - - - } - - return bClassificationSucceed ? usIndex : INVALID_QUEUE_INDEX; -} - -static bool EthCSMatchSrcMACAddress(struct bcm_classifier_rule *pstClassifierRule, - PUCHAR Mac) -{ - UINT i = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if (pstClassifierRule->ucEthCSSrcMACLen == 0) - return TRUE; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "%s\n", __func__); - for (i = 0; i < MAC_ADDRESS_SIZE; i++) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n", - i, - Mac[i], - pstClassifierRule->au8EThCSSrcMAC[i], - pstClassifierRule->au8EThCSSrcMACMask[i]); - if ((pstClassifierRule->au8EThCSSrcMAC[i] & - pstClassifierRule->au8EThCSSrcMACMask[i]) != - (Mac[i] & pstClassifierRule->au8EThCSSrcMACMask[i])) - return false; - } - return TRUE; -} - -static bool EthCSMatchDestMACAddress(struct bcm_classifier_rule *pstClassifierRule, - PUCHAR Mac) -{ - UINT i = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if (pstClassifierRule->ucEthCSDestMACLen == 0) - return TRUE; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "%s\n", - __func__); - for (i = 0; i < MAC_ADDRESS_SIZE; i++) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n", - i, - Mac[i], - pstClassifierRule->au8EThCSDestMAC[i], - pstClassifierRule->au8EThCSDestMACMask[i]); - if ((pstClassifierRule->au8EThCSDestMAC[i] & - pstClassifierRule->au8EThCSDestMACMask[i]) != - (Mac[i] & pstClassifierRule->au8EThCSDestMACMask[i])) - return false; - } - return TRUE; -} - -static bool EthCSMatchEThTypeSAP(struct bcm_classifier_rule *pstClassifierRule, - struct sk_buff *skb, - struct bcm_eth_packet_info *pstEthCsPktInfo) -{ - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if ((pstClassifierRule->ucEtherTypeLen == 0) || - (pstClassifierRule->au8EthCSEtherType[0] == 0)) - return TRUE; - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "%s SrcEtherType:%x CLS EtherType[0]:%x\n", - __func__, - pstEthCsPktInfo->usEtherType, - pstClassifierRule->au8EthCSEtherType[0]); - if (pstClassifierRule->au8EthCSEtherType[0] == 1) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "%s CLS EtherType[1]:%x EtherType[2]:%x\n", - __func__, - pstClassifierRule->au8EthCSEtherType[1], - pstClassifierRule->au8EthCSEtherType[2]); - - if (memcmp(&pstEthCsPktInfo->usEtherType, - &pstClassifierRule->au8EthCSEtherType[1], - 2) == 0) - return TRUE; - else - return false; - } - - if (pstClassifierRule->au8EthCSEtherType[0] == 2) { - if (eEth802LLCFrame != pstEthCsPktInfo->eNwpktEthFrameType) - return false; - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "%s EthCS DSAP:%x EtherType[2]:%x\n", - __func__, - pstEthCsPktInfo->ucDSAP, - pstClassifierRule->au8EthCSEtherType[2]); - if (pstEthCsPktInfo->ucDSAP == - pstClassifierRule->au8EthCSEtherType[2]) - return TRUE; - else - return false; - - } - - return false; - -} - -static bool EthCSMatchVLANRules(struct bcm_classifier_rule *pstClassifierRule, - struct sk_buff *skb, - struct bcm_eth_packet_info *pstEthCsPktInfo) -{ - bool bClassificationSucceed = false; - USHORT usVLANID; - B_UINT8 uPriority = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "%s CLS UserPrio:%x CLS VLANID:%x\n", - __func__, - ntohs(*((USHORT *)pstClassifierRule->usUserPriority)), - pstClassifierRule->usVLANID); - - /* - * In case FW didn't receive the TLV, - * the priority field should be ignored - */ - if (pstClassifierRule->usValidityBitMap & - (1<<PKT_CLASSIFICATION_USER_PRIORITY_VALID)) { - if (pstEthCsPktInfo->eNwpktEthFrameType != eEth802QVLANFrame) - return false; - - uPriority = (ntohs(*(USHORT *)(skb->data + - sizeof(struct bcm_eth_header))) & - 0xF000) >> 13; - - if ((uPriority >= pstClassifierRule->usUserPriority[0]) && - (uPriority <= - pstClassifierRule->usUserPriority[1])) - bClassificationSucceed = TRUE; - - if (!bClassificationSucceed) - return false; - } - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ETH CS 802.1 D User Priority Rule Matched\n"); - - bClassificationSucceed = false; - - if (pstClassifierRule->usValidityBitMap & - (1<<PKT_CLASSIFICATION_VLANID_VALID)) { - if (pstEthCsPktInfo->eNwpktEthFrameType != eEth802QVLANFrame) - return false; - - usVLANID = ntohs(*(USHORT *)(skb->data + - sizeof(struct bcm_eth_header))) & 0xFFF; - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "%s Pkt VLANID %x Priority: %d\n", - __func__, - usVLANID, - uPriority); - - if (usVLANID == ((pstClassifierRule->usVLANID & 0xFFF0) >> 4)) - bClassificationSucceed = TRUE; - - if (!bClassificationSucceed) - return false; - } - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ETH CS 802.1 Q VLAN ID Rule Matched\n"); - - return TRUE; -} - - -static bool EThCSClassifyPkt(struct bcm_mini_adapter *Adapter, - struct sk_buff *skb, - struct bcm_eth_packet_info *pstEthCsPktInfo, - struct bcm_classifier_rule *pstClassifierRule, - B_UINT8 EthCSCupport) -{ - bool bClassificationSucceed = false; - - bClassificationSucceed = EthCSMatchSrcMACAddress(pstClassifierRule, - ((struct bcm_eth_header *)(skb->data))->au8SourceAddress); - if (!bClassificationSucceed) - return false; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ETH CS SrcMAC Matched\n"); - - bClassificationSucceed = EthCSMatchDestMACAddress(pstClassifierRule, - ((struct bcm_eth_header *)(skb->data))->au8DestinationAddress); - if (!bClassificationSucceed) - return false; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ETH CS DestMAC Matched\n"); - - /* classify on ETHType/802.2SAP TLV */ - bClassificationSucceed = EthCSMatchEThTypeSAP(pstClassifierRule, - skb, - pstEthCsPktInfo); - if (!bClassificationSucceed) - return false; - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ETH CS EthType/802.2SAP Matched\n"); - - /* classify on 802.1VLAN Header Parameters */ - bClassificationSucceed = EthCSMatchVLANRules(pstClassifierRule, - skb, - pstEthCsPktInfo); - if (!bClassificationSucceed) - return false; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ETH CS 802.1 VLAN Rules Matched\n"); - - return bClassificationSucceed; -} - -static void EThCSGetPktInfo(struct bcm_mini_adapter *Adapter, - PVOID pvEthPayload, - struct bcm_eth_packet_info *pstEthCsPktInfo) -{ - USHORT u16Etype = ntohs( - ((struct bcm_eth_header *)pvEthPayload)->u16Etype); - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "EthCSGetPktInfo : Eth Hdr Type : %X\n", - u16Etype); - if (u16Etype > 0x5dc) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "EthCSGetPktInfo : ETH2 Frame\n"); - /* ETH2 Frame */ - if (u16Etype == ETHERNET_FRAMETYPE_802QVLAN) { - /* 802.1Q VLAN Header */ - pstEthCsPktInfo->eNwpktEthFrameType = eEth802QVLANFrame; - u16Etype = ((struct bcm_eth_q_frame *)pvEthPayload)->EthType; - /* ((ETH_CS_802_Q_FRAME*)pvEthPayload)->UserPriority */ - } else { - pstEthCsPktInfo->eNwpktEthFrameType = eEthOtherFrame; - u16Etype = ntohs(u16Etype); - } - } else { - /* 802.2 LLC */ - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "802.2 LLC Frame\n"); - pstEthCsPktInfo->eNwpktEthFrameType = eEth802LLCFrame; - pstEthCsPktInfo->ucDSAP = - ((struct bcm_eth_llc_frame *)pvEthPayload)->DSAP; - if (pstEthCsPktInfo->ucDSAP == 0xAA && ((struct bcm_eth_llc_frame *)pvEthPayload)->SSAP == 0xAA) { - /* SNAP Frame */ - pstEthCsPktInfo->eNwpktEthFrameType = eEth802LLCSNAPFrame; - u16Etype = ((struct bcm_eth_llc_snap_frame *)pvEthPayload)->usEtherType; - } - } - if (u16Etype == ETHERNET_FRAMETYPE_IPV4) - pstEthCsPktInfo->eNwpktIPFrameType = eIPv4Packet; - else if (u16Etype == ETHERNET_FRAMETYPE_IPV6) - pstEthCsPktInfo->eNwpktIPFrameType = eIPv6Packet; - else - pstEthCsPktInfo->eNwpktIPFrameType = eNonIPPacket; - - pstEthCsPktInfo->usEtherType = ((struct bcm_eth_header *)pvEthPayload)->u16Etype; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "EthCsPktInfo->eNwpktIPFrameType : %x\n", - pstEthCsPktInfo->eNwpktIPFrameType); - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "EthCsPktInfo->eNwpktEthFrameType : %x\n", - pstEthCsPktInfo->eNwpktEthFrameType); - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "EthCsPktInfo->usEtherType : %x\n", - pstEthCsPktInfo->usEtherType); -} - diff --git a/drivers/staging/bcm/Queue.h b/drivers/staging/bcm/Queue.h deleted file mode 100644 index 460c0aee67f6..000000000000 --- a/drivers/staging/bcm/Queue.h +++ /dev/null @@ -1,29 +0,0 @@ -/************************************* -* Queue.h -**************************************/ -#ifndef __QUEUE_H__ -#define __QUEUE_H__ - - - -#define ENQUEUEPACKET(_Head, _Tail, _Packet) \ -do { \ - if (!_Head) { \ - _Head = _Packet; \ - } \ - else { \ - (_Tail)->next = _Packet; \ - } \ - (_Packet)->next = NULL; \ - _Tail = _Packet; \ -} while (0) -#define DEQUEUEPACKET(Head, Tail) \ -do { \ - if (Head) { \ - if (!Head->next) { \ - Tail = NULL; \ - } \ - Head = Head->next; \ - } \ -} while (0) -#endif /* __QUEUE_H__ */ diff --git a/drivers/staging/bcm/TODO b/drivers/staging/bcm/TODO deleted file mode 100644 index 8467f45d08a6..000000000000 --- a/drivers/staging/bcm/TODO +++ /dev/null @@ -1,26 +0,0 @@ -This driver is barely functional in its current state. - -Kevin McKinney(klmckinney1@gmail.com) and Matthias Beyer(mail@beyermatthias.de) -are currently maintaining/cleaning up this driver. Please copy us on all -patches. More maintainers are aways welcomed. - -BIG: - - existing API is (/dev/tarang) should be replaced - Is it possible to use same API as Intel Wimax stack and - have same user level components. - - Qos and queue model is non-standard and inflexible. - Use existing TC Qos? - -TODO: - - support more than one board - eliminate global variables - - remove developer debug BCM_DEBUG() macros - add a limited number of messages through netif_msg() - - fix non-standard kernel style - - checkpatch warnings - - use request firmware - - fix use of file I/O to load config with better API - - merge some files together? - - cleanup/eliminate debug messages - - - diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c deleted file mode 100644 index 622a482e9826..000000000000 --- a/drivers/staging/bcm/Transmit.c +++ /dev/null @@ -1,271 +0,0 @@ -/** - * @file Transmit.c - * @defgroup tx_functions Transmission - * @section Queueing - * @dot - * digraph transmit1 { - * node[shape=box] - * edge[weight=5;color=red] - * - * bcm_transmit->GetPacketQueueIndex[label="IP Packet"] - * GetPacketQueueIndex->IpVersion4[label="IPV4"] - * GetPacketQueueIndex->IpVersion6[label="IPV6"] - * } - * - * @enddot - * - * @section De-Queueing - * @dot - * digraph transmit2 { - * node[shape=box] - * edge[weight=5;color=red] - * interrupt_service_thread->transmit_packets - * tx_pkt_hdler->transmit_packets - * transmit_packets->CheckAndSendPacketFromIndex - * transmit_packets->UpdateTokenCount - * CheckAndSendPacketFromIndex->PruneQueue - * CheckAndSendPacketFromIndex->IsPacketAllowedForFlow - * CheckAndSendPacketFromIndex->SendControlPacket[label="control pkt"] - * SendControlPacket->bcm_cmd53 - * CheckAndSendPacketFromIndex->SendPacketFromQueue[label="data pkt"] - * SendPacketFromQueue->SetupNextSend->bcm_cmd53 - * } - * @enddot - */ - -#include "headers.h" - -/** - * @ingroup ctrl_pkt_functions - * This function dispatches control packet to the h/w interface - * @return zero(success) or -ve value(failure) - */ -int SendControlPacket(struct bcm_mini_adapter *Adapter, char *pControlPacket) -{ - struct bcm_leader *PLeader = (struct bcm_leader *)pControlPacket; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx"); - if (!pControlPacket || !Adapter) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, - "Got NULL Control Packet or Adapter"); - return STATUS_FAILURE; - } - if ((atomic_read(&Adapter->CurrNumFreeTxDesc) < - ((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, - "NO FREE DESCRIPTORS TO SEND CONTROL PACKET"); - return STATUS_FAILURE; - } - - /* Update the netdevice statistics */ - /* Dump Packet */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, - "Leader Status: %x", PLeader->Status); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, - "Leader VCID: %x", PLeader->Vcid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, - "Leader Length: %x", PLeader->PLength); - if (Adapter->device_removed) - return 0; - - if (netif_msg_pktdata(Adapter)) - print_hex_dump(KERN_DEBUG, PFX "tx control: ", DUMP_PREFIX_NONE, - 16, 1, pControlPacket, - PLeader->PLength + LEADER_SIZE, 0); - - Adapter->interface_transmit(Adapter->pvInterfaceAdapter, - pControlPacket, - (PLeader->PLength + LEADER_SIZE)); - - atomic_dec(&Adapter->CurrNumFreeTxDesc); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, - "<========="); - return STATUS_SUCCESS; -} - -/** - * @ingroup tx_functions - * This function despatches the IP packets with the given vcid - * to the target via the host h/w interface. - * @return zero(success) or -ve value(failure) - */ -int SetupNextSend(struct bcm_mini_adapter *Adapter, - struct sk_buff *Packet, USHORT Vcid) -{ - int status = 0; - bool bHeaderSupressionEnabled = false; - B_UINT16 uiClassifierRuleID; - u16 QueueIndex = skb_get_queue_mapping(Packet); - struct bcm_packet_info *curr_packet_info = - &Adapter->PackInfo[QueueIndex]; - struct bcm_leader Leader = {0}; - - if (Packet->len > MAX_DEVICE_DESC_SIZE) { - status = STATUS_FAILURE; - goto errExit; - } - - /* Get the Classifier Rule ID */ - uiClassifierRuleID = *((UINT32 *) (Packet->cb) + - SKB_CB_CLASSIFICATION_OFFSET); - - bHeaderSupressionEnabled = curr_packet_info->bHeaderSuppressionEnabled & - Adapter->bPHSEnabled; - - if (Adapter->device_removed) { - status = STATUS_FAILURE; - goto errExit; - } - - status = PHSTransmit(Adapter, &Packet, Vcid, uiClassifierRuleID, - bHeaderSupressionEnabled, - (UINT *)&Packet->len, - curr_packet_info->bEthCSSupport); - - if (status != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, - "PHS Transmit failed..\n"); - goto errExit; - } - - Leader.Vcid = Vcid; - - if (TCP_ACK == *((UINT32 *) (Packet->cb) + SKB_CB_TCPACK_OFFSET)) - Leader.Status = LEADER_STATUS_TCP_ACK; - else - Leader.Status = LEADER_STATUS; - - if (curr_packet_info->bEthCSSupport) { - Leader.PLength = Packet->len; - if (skb_headroom(Packet) < LEADER_SIZE) { - status = skb_cow(Packet, LEADER_SIZE); - if (status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, - DBG_LVL_ALL, - "bcm_transmit : Failed To Increase headRoom\n"); - goto errExit; - } - } - skb_push(Packet, LEADER_SIZE); - memcpy(Packet->data, &Leader, LEADER_SIZE); - } else { - Leader.PLength = Packet->len - ETH_HLEN; - memcpy((struct bcm_leader *)skb_pull(Packet, - (ETH_HLEN - LEADER_SIZE)), - &Leader, - LEADER_SIZE); - } - - status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter, - Packet->data, - (Leader.PLength + LEADER_SIZE)); - if (status) { - ++Adapter->dev->stats.tx_errors; - if (netif_msg_tx_err(Adapter)) - pr_info(PFX "%s: transmit error %d\n", - Adapter->dev->name, - status); - } else { - struct net_device_stats *netstats = &Adapter->dev->stats; - - curr_packet_info->uiTotalTxBytes += Leader.PLength; - - netstats->tx_bytes += Leader.PLength; - ++netstats->tx_packets; - - curr_packet_info->uiCurrentTokenCount -= Leader.PLength << 3; - curr_packet_info->uiSentBytes += (Packet->len); - curr_packet_info->uiSentPackets++; - curr_packet_info->NumOfPacketsSent++; - - atomic_dec(&curr_packet_info->uiPerSFTxResourceCount); - curr_packet_info->uiThisPeriodSentBytes += Leader.PLength; - } - - atomic_dec(&Adapter->CurrNumFreeTxDesc); - -errExit: - dev_kfree_skb(Packet); - return status; -} - -static int tx_pending(struct bcm_mini_adapter *Adapter) -{ - return (atomic_read(&Adapter->TxPktAvail) - && MINIMUM_PENDING_DESCRIPTORS < - atomic_read(&Adapter->CurrNumFreeTxDesc)) - || Adapter->device_removed || (1 == Adapter->downloadDDR); -} - -/** - * @ingroup tx_functions - * Transmit thread - */ -int tx_pkt_handler(struct bcm_mini_adapter *Adapter) -{ - int status = 0; - - while (!kthread_should_stop()) { - /* FIXME - the timeout looks like workaround - * for racey usage of TxPktAvail - */ - if (Adapter->LinkUpStatus) - wait_event_timeout(Adapter->tx_packet_wait_queue, - tx_pending(Adapter), - msecs_to_jiffies(10)); - else - wait_event_interruptible(Adapter->tx_packet_wait_queue, - tx_pending(Adapter)); - - if (Adapter->device_removed) - break; - - if (Adapter->downloadDDR == 1) { - Adapter->downloadDDR += 1; - status = download_ddr_settings(Adapter); - if (status) - pr_err(PFX "DDR DOWNLOAD FAILED! %d\n", status); - continue; - } - - /* Check end point for halt/stall. */ - if (Adapter->bEndPointHalted == TRUE) { - Bcm_clear_halt_of_endpoints(Adapter); - Adapter->bEndPointHalted = false; - StartInterruptUrb((struct bcm_interface_adapter *) - (Adapter->pvInterfaceAdapter)); - } - - if (Adapter->LinkUpStatus && !Adapter->IdleMode) { - if (atomic_read(&Adapter->TotalPacketCount)) - update_per_sf_desc_cnts(Adapter); - } - - if (atomic_read(&Adapter->CurrNumFreeTxDesc) && - Adapter->LinkStatus == SYNC_UP_REQUEST && - !Adapter->bSyncUpRequestSent) { - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, - DBG_LVL_ALL, "Calling LinkMessage"); - LinkMessage(Adapter); - } - - if ((Adapter->IdleMode || Adapter->bShutStatus) && - atomic_read(&Adapter->TotalPacketCount)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, - TX_PACKETS, DBG_LVL_ALL, - "Device in Low Power mode...waking up"); - Adapter->usIdleModePattern = ABORT_IDLE_MODE; - Adapter->bWakeUpDevice = TRUE; - wake_up(&Adapter->process_rx_cntrlpkt); - } - - transmit_packets(Adapter); - atomic_set(&Adapter->TxPktAvail, 0); - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - "Exiting the tx thread..\n"); - Adapter->transmit_packet_thread = NULL; - return 0; -} diff --git a/drivers/staging/bcm/Typedefs.h b/drivers/staging/bcm/Typedefs.h deleted file mode 100644 index 90b3b25dd606..000000000000 --- a/drivers/staging/bcm/Typedefs.h +++ /dev/null @@ -1,47 +0,0 @@ -/**************************** -* Typedefs.h -****************************/ -#ifndef __TYPEDEFS_H__ -#define __TYPEDEFS_H__ -#define STATUS_SUCCESS 0 -#define STATUS_FAILURE -1 - - -#define TRUE 1 - - -typedef char CHAR; -typedef int INT; -typedef short SHORT; -typedef long LONG; -typedef void VOID; - -typedef unsigned char UCHAR; -typedef unsigned char B_UINT8; -typedef unsigned short USHORT; -typedef unsigned short B_UINT16; -typedef unsigned int UINT; -typedef unsigned int B_UINT32; -typedef unsigned long ULONG; -typedef unsigned long DWORD; - -typedef char *PCHAR; -typedef short *PSHORT; -typedef int *PINT; -typedef long *PLONG; -typedef void *PVOID; - -typedef unsigned char *PUCHAR; -typedef unsigned short *PUSHORT; -typedef unsigned int *PUINT; -typedef unsigned long *PULONG; -typedef unsigned long long ULONG64; -typedef unsigned long long LARGE_INTEGER; -typedef unsigned int UINT32; -#ifndef NULL -#define NULL 0 -#endif - - -#endif /* __TYPEDEFS_H__ */ - diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h deleted file mode 100644 index 8683c2d4276e..000000000000 --- a/drivers/staging/bcm/cntrl_SignalingInterface.h +++ /dev/null @@ -1,311 +0,0 @@ -#ifndef CNTRL_SIGNALING_INTERFACE_ -#define CNTRL_SIGNALING_INTERFACE_ - -#define DSA_REQ 11 -#define DSA_RSP 12 -#define DSA_ACK 13 -#define DSC_REQ 14 -#define DSC_RSP 15 -#define DSC_ACK 16 -#define DSD_REQ 17 -#define DSD_RSP 18 -#define DSD_ACK 19 -#define MAX_CLASSIFIERS_IN_SF 4 - -#define MAX_STRING_LEN 20 -#define MAX_PHS_LENGTHS 255 -#define VENDOR_PHS_PARAM_LENGTH 10 -#define MAX_NUM_ACTIVE_BS 10 -#define AUTH_TOKEN_LENGTH 10 -#define NUM_HARQ_CHANNELS 16 /* Changed from 10 to 16 to accommodate all HARQ channels */ -#define VENDOR_CLASSIFIER_PARAM_LENGTH 1 /* Changed the size to 1 byte since we dnt use it */ -#define VENDOR_SPECIF_QOS_PARAM 1 -#define VENDOR_PHS_PARAM_LENGTH 10 -#define MBS_CONTENTS_ID_LENGTH 10 -#define GLOBAL_SF_CLASSNAME_LENGTH 6 - -#define TYPE_OF_SERVICE_LENGTH 3 -#define IP_MASKED_SRC_ADDRESS_LENGTH 32 -#define IP_MASKED_DEST_ADDRESS_LENGTH 32 -#define PROTOCOL_SRC_PORT_RANGE_LENGTH 4 -#define PROTOCOL_DEST_PORT_RANGE_LENGTH 4 -#define ETHERNET_DEST_MAC_ADDR_LENGTH 12 -#define ETHERNET_SRC_MAC_ADDR_LENGTH 12 -#define NUM_ETHERTYPE_BYTES 3 -#define NUM_IPV6_FLOWLABLE_BYTES 3 - -struct bcm_packet_class_rules { - /* 16bit UserPriority Of The Service Flow */ - u16 u16UserPriority; - /* 16bit VLANID Of The Service Flow */ - u16 u16VLANID; - /* 16bit Packet Classification RuleIndex Of The Service Flow */ - u16 u16PacketClassificationRuleIndex; - /* 8bit Classifier Rule Priority Of The Service Flow */ - u8 u8ClassifierRulePriority; - /* Length of IP TypeOfService field */ - u8 u8IPTypeOfServiceLength; - /* 3bytes IP TypeOfService */ - u8 u8IPTypeOfService[TYPE_OF_SERVICE_LENGTH]; - /* Protocol used in classification of Service Flow */ - u8 u8Protocol; - /* Length of IP Masked Source Address */ - u8 u8IPMaskedSourceAddressLength; - /* IP Masked Source Address used in classification for the Service Flow */ - u8 u8IPMaskedSourceAddress[IP_MASKED_SRC_ADDRESS_LENGTH]; - /* Length of IP Destination Address */ - u8 u8IPDestinationAddressLength; - /* IP Destination Address used in classification for the Service Flow */ - u8 u8IPDestinationAddress[IP_MASKED_DEST_ADDRESS_LENGTH]; - /* Length of Protocol Source Port Range */ - u8 u8ProtocolSourcePortRangeLength; - /* Protocol Source Port Range used in the Service Flow */ - u8 u8ProtocolSourcePortRange[PROTOCOL_SRC_PORT_RANGE_LENGTH]; - /* Length of Protocol Dest Port Range */ - u8 u8ProtocolDestPortRangeLength; - /* Protocol Dest Port Range used in the Service Flow */ - u8 u8ProtocolDestPortRange[PROTOCOL_DEST_PORT_RANGE_LENGTH]; - /* Length of Ethernet Destination MAC Address */ - u8 u8EthernetDestMacAddressLength; - /* Ethernet Destination MAC Address used in classification of the Service Flow */ - u8 u8EthernetDestMacAddress[ETHERNET_DEST_MAC_ADDR_LENGTH]; - /* Length of Ethernet Source MAC Address */ - u8 u8EthernetSourceMACAddressLength; - /* Ethernet Source MAC Address used in classification of the Service Flow */ - u8 u8EthernetSourceMACAddress[ETHERNET_SRC_MAC_ADDR_LENGTH]; - /* Length of Ethertype */ - u8 u8EthertypeLength; - /* 3bytes Ethertype Of The Service Flow */ - u8 u8Ethertype[NUM_ETHERTYPE_BYTES]; - /* 8bit Associated PHSI Of The Service Flow */ - u8 u8AssociatedPHSI; - /* Length of Vendor Specific Classifier Param length Of The Service Flow */ - u8 u8VendorSpecificClassifierParamLength; - /* Vendor Specific Classifier Param Of The Service Flow */ - u8 u8VendorSpecificClassifierParam[VENDOR_CLASSIFIER_PARAM_LENGTH]; - /* Length Of IPv6 Flow Lable of the Service Flow */ - u8 u8IPv6FlowLableLength; - /* IPv6 Flow Lable Of The Service Flow */ - u8 u8IPv6FlowLable[NUM_IPV6_FLOWLABLE_BYTES]; - /* Action associated with the classifier rule */ - u8 u8ClassifierActionRule; - u16 u16ValidityBitMap; -}; - -struct bcm_phs_rules { - /* 8bit PHS Index Of The Service Flow */ - u8 u8PHSI; - /* PHSF Length Of The Service Flow */ - u8 u8PHSFLength; - /* String of bytes containing header information to be suppressed by the sending CS and reconstructed by the receiving CS */ - u8 u8PHSF[MAX_PHS_LENGTHS]; - /* PHSM Length Of The Service Flow */ - u8 u8PHSMLength; - /* PHS Mask for the SF */ - u8 u8PHSM[MAX_PHS_LENGTHS]; - /* 8bit Total number of bytes to be suppressed for the Service Flow */ - u8 u8PHSS; - /* 8bit Indicates whether or not Packet Header contents need to be verified prior to suppression */ - u8 u8PHSV; - /* Vendor Specific PHS param Length Of The Service Flow */ - u8 u8VendorSpecificPHSParamsLength; - /* Vendor Specific PHS param Of The Service Flow */ - u8 u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH]; - u8 u8Padding[2]; -}; - -struct bcm_convergence_types { - /* 8bit Phs Classfier Action Of The Service Flow */ - u8 u8ClassfierDSCAction; - /* 8bit Phs DSC Action Of The Service Flow */ - u8 u8PhsDSCAction; - /* 16bit Padding */ - u8 u8Padding[2]; - /* Packet classification rules structure */ - struct bcm_packet_class_rules cCPacketClassificationRule; - /* Payload header suppression rules structure */ - struct bcm_phs_rules cPhsRule; -}; - -struct bcm_connect_mgr_params { - /* 32bitSFID Of The Service Flow */ - u32 u32SFID; - /* 32bit Maximum Sustained Traffic Rate of the Service Flow */ - u32 u32MaxSustainedTrafficRate; - /* 32bit Maximum Traffic Burst allowed for the Service Flow */ - u32 u32MaxTrafficBurst; - /* 32bit Minimum Reserved Traffic Rate of the Service Flow */ - u32 u32MinReservedTrafficRate; - /* 32bit Tolerated Jitter of the Service Flow */ - u32 u32ToleratedJitter; - /* 32bit Maximum Latency of the Service Flow */ - u32 u32MaximumLatency; - /* 16bitCID Of The Service Flow */ - u16 u16CID; - /* 16bit SAID on which the service flow being set up shall be mapped */ - u16 u16TargetSAID; - /* 16bit ARQ window size negotiated */ - u16 u16ARQWindowSize; - /* 16bit Total Tx delay incl sending, receiving & processing delays */ - u16 u16ARQRetryTxTimeOut; - /* 16bit Total Rx delay incl sending, receiving & processing delays */ - u16 u16ARQRetryRxTimeOut; - /* 16bit ARQ block lifetime */ - u16 u16ARQBlockLifeTime; - /* 16bit ARQ Sync loss timeout */ - u16 u16ARQSyncLossTimeOut; - /* 16bit ARQ Purge timeout */ - u16 u16ARQRxPurgeTimeOut; - /* TODO::Remove this once we move to a new CORR2 driver - * brief Size of an ARQ block - */ - u16 u16ARQBlockSize; - /* #endif */ - /* 16bit Nominal interval b/w consecutive SDU arrivals at MAC SAP */ - u16 u16SDUInterArrivalTime; - /* 16bit Specifies the time base for rate measurement */ - u16 u16TimeBase; - /* 16bit Interval b/w Successive Grant oppurtunities */ - u16 u16UnsolicitedGrantInterval; - /* 16bit Interval b/w Successive Polling grant oppurtunities */ - u16 u16UnsolicitedPollingInterval; - /* internal var to get the overhead */ - u16 u16MacOverhead; - /* MBS contents Identifier */ - u16 u16MBSContentsID[MBS_CONTENTS_ID_LENGTH]; - /* MBS contents Identifier length */ - u8 u8MBSContentsIDLength; - /* ServiceClassName Length Of The Service Flow */ - u8 u8ServiceClassNameLength; - /* 32bytes ServiceClassName Of The Service Flow */ - u8 u8ServiceClassName[32]; - /* 8bit Indicates whether or not MBS service is requested for this Serivce Flow */ - u8 u8MBSService; - /* 8bit QOS Parameter Set specifies proper application of QoS parameters to Provisioned, Admitted and Active sets */ - u8 u8QosParamSet; - /* 8bit Traffic Priority Of the Service Flow */ - u8 u8TrafficPriority; - /* 8bit Uplink Grant Scheduling Type of The Service Flow */ - u8 u8ServiceFlowSchedulingType; - /* 8bit Request transmission Policy of the Service Flow */ - u8 u8RequesttransmissionPolicy; - /* 8bit Specifies whether SDUs for this Service flow are of FixedLength or Variable length */ - u8 u8FixedLengthVSVariableLengthSDUIndicator; - /* 8bit Length of the SDU for a fixed length SDU service flow */ - u8 u8SDUSize; - /* 8bit Indicates whether or not ARQ is requested for this connection */ - u8 u8ARQEnable; - /* < 8bit Indicates whether or not data has tobe delivered in order to higher layer */ - u8 u8ARQDeliverInOrder; - /* 8bit Receiver ARQ ACK processing time */ - u8 u8RxARQAckProcessingTime; - /* 8bit Convergence Sublayer Specification Of The Service Flow */ - u8 u8CSSpecification; - /* 8 bit Type of data delivery service */ - u8 u8TypeOfDataDeliveryService; - /* 8bit Specifies whether a service flow may generate Paging */ - u8 u8PagingPreference; - /* 8bit Indicates the MBS Zone through which the connection or virtual connection is valid */ - u8 u8MBSZoneIdentifierassignment; - /* 8bit Specifies whether traffic on SF should generate MOB_TRF_IND to MS in sleep mode */ - u8 u8TrafficIndicationPreference; - /* 8bit Speciifes the length of predefined Global QoS parameter set encoding for this SF */ - u8 u8GlobalServicesClassNameLength; - /* 6 byte Speciifes the predefined Global QoS parameter set encoding for this SF */ - u8 u8GlobalServicesClassName[GLOBAL_SF_CLASSNAME_LENGTH]; - /* 8bit Indicates whether or not SN feedback is enabled for the conn */ - u8 u8SNFeedbackEnabled; - /* Indicates the size of the Fragment Sequence Number for the connection */ - u8 u8FSNSize; - /* 8bit Number of CIDs in active BS list */ - u8 u8CIDAllocation4activeBSsLength; - /* CIDs of BS in the active list */ - u8 u8CIDAllocation4activeBSs[MAX_NUM_ACTIVE_BS]; - /* Specifies if PDU extended subheader should be applied on every PDU on this conn */ - u8 u8PDUSNExtendedSubheader4HarqReordering; - /* 8bit Specifies whether the connection uses HARQ or not */ - u8 u8HARQServiceFlows; - /* Specifies the length of Authorization token */ - u8 u8AuthTokenLength; - /* Specifies the Authorization token */ - u8 u8AuthToken[AUTH_TOKEN_LENGTH]; - /* specifes Number of HARQ channels used to carry data length */ - u8 u8HarqChannelMappingLength; - /* specifes HARQ channels used to carry data */ - u8 u8HARQChannelMapping[NUM_HARQ_CHANNELS]; - /* 8bit Length of Vendor Specific QoS Params */ - u8 u8VendorSpecificQoSParamLength; - /* 1byte Vendor Specific QoS Param Of The Service Flow */ - u8 u8VendorSpecificQoSParam[VENDOR_SPECIF_QOS_PARAM]; - /* indicates total classifiers in the SF */ - u8 u8TotalClassifiers; /* < Total number of valid classifiers */ - u8 bValid; /* < Validity flag */ - u8 u8Padding; /* < Padding byte */ - /* - * Structure for Convergence SubLayer Types with a maximum of 4 classifiers - */ - struct bcm_convergence_types cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF]; -}; - -struct bcm_add_request { - u8 u8Type; /* < Type */ - u8 eConnectionDir; /* < Connection direction */ - /* brief 16 bit TID */ - u16 u16TID; /* < 16bit TID */ - /* brief 16bitCID */ - u16 u16CID; /* < 16bit CID */ - /* brief 16bitVCID */ - u16 u16VCID; /* < 16bit VCID */ - struct bcm_connect_mgr_params *psfParameterSet; /* < connection manager parameters */ -}; - -struct bcm_add_indication { - u8 u8Type; /* < Type */ - u8 eConnectionDir; /* < Connection Direction */ - /* brief 16 bit TID */ - u16 u16TID; /* < TID */ - /* brief 16bitCID */ - u16 u16CID; /* < 16bitCID */ - /* brief 16bitVCID */ - u16 u16VCID; /* < 16bitVCID */ - struct bcm_connect_mgr_params *psfAuthorizedSet; /* Authorized set of connection manager parameters */ - struct bcm_connect_mgr_params *psfAdmittedSet; /* Admitted set of connection manager parameters */ - struct bcm_connect_mgr_params *psfActiveSet; /* Activeset of connection manager parameters */ - u8 u8CC; /* <Confirmation Code */ - u8 u8Padd; /* < 8-bit Padding */ - u16 u16Padd; /* < 16 bit Padding */ -}; - -struct bcm_del_request { - u8 u8Type; /* < Type */ - u8 u8Padding; /* < Padding byte */ - u16 u16TID; /* < TID */ - /* brief 32bitSFID */ - u32 u32SFID; /* < SFID */ -}; - -struct bcm_del_indication { - u8 u8Type; /* < Type */ - u8 u8Padding; /* < Padding */ - u16 u16TID; /* < TID */ - /* brief 16bitCID */ - u16 u16CID; /* < CID */ - /* brief 16bitVCID */ - u16 u16VCID; /* < VCID */ - /* brief 32bitSFID */ - u32 u32SFID; /* < SFID */ - /* brief 8bit Confirmation code */ - u8 u8ConfirmationCode; /* < Confirmation code */ - u8 u8Padding1[3]; /* < 3 byte Padding */ -}; - -struct bcm_stim_sfhostnotify { - u32 SFID; /* SFID of the service flow */ - u16 newCID; /* the new/changed CID */ - u16 VCID; /* Get new Vcid if the flow has been made active in CID update TLV, but was inactive earlier or the orig vcid */ - u8 RetainSF; /* Indication to Host if the SF is to be retained or deleted; if TRUE-retain else delete */ - u8 QoSParamSet; /* QoS paramset of the retained SF */ - u16 u16reserved; /* For byte alignment */ -}; - -#endif diff --git a/drivers/staging/bcm/headers.h b/drivers/staging/bcm/headers.h deleted file mode 100644 index a7d4af5ea9a7..000000000000 --- a/drivers/staging/bcm/headers.h +++ /dev/null @@ -1,78 +0,0 @@ - -/******************************************************************* -* Headers.h -*******************************************************************/ -#ifndef __HEADERS_H__ -#define __HEADERS_H__ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/types.h> -#include <linux/netdevice.h> -#include <linux/skbuff.h> -#include <linux/socket.h> -#include <linux/netfilter.h> -#include <linux/netfilter_ipv4.h> -#include <linux/if_arp.h> -#include <linux/delay.h> -#include <linux/spinlock.h> -#include <linux/fs.h> -#include <linux/file.h> -#include <linux/string.h> -#include <linux/etherdevice.h> -#include <linux/wait.h> -#include <linux/proc_fs.h> -#include <linux/interrupt.h> -#include <linux/stddef.h> -#include <linux/stat.h> -#include <linux/fcntl.h> -#include <linux/unistd.h> -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/pagemap.h> -#include <linux/kthread.h> -#include <linux/tcp.h> -#include <linux/udp.h> -#include <linux/usb.h> -#include <linux/uaccess.h> -#include <net/ip.h> - -#include "Typedefs.h" -#include "Macros.h" -#include "HostMIBSInterface.h" -#include "cntrl_SignalingInterface.h" -#include "PHSDefines.h" -#include "led_control.h" -#include "Ioctl.h" -#include "nvm.h" -#include "target_params.h" -#include "Adapter.h" -#include "CmHost.h" -#include "DDRInit.h" -#include "Debug.h" -#include "IPv6ProtocolHdr.h" -#include "PHSModule.h" -#include "Protocol.h" -#include "Prototypes.h" -#include "Queue.h" -#include "vendorspecificextn.h" - -#include "InterfaceMacros.h" -#include "InterfaceAdapter.h" -#include "InterfaceIsr.h" -#include "InterfaceMisc.h" -#include "InterfaceRx.h" -#include "InterfaceTx.h" -#include "InterfaceIdleMode.h" -#include "InterfaceInit.h" - -#define DRV_NAME "beceem" -#define DEV_NAME "tarang" -#define DRV_DESCRIPTION "Beceem Communications Inc. WiMAX driver" -#define DRV_COPYRIGHT "Copyright 2010. Beceem Communications Inc" -#define DRV_VERSION "5.2.45" -#define PFX DRV_NAME " " - -extern struct class *bcm_class; - -#endif diff --git a/drivers/staging/bcm/hostmibs.c b/drivers/staging/bcm/hostmibs.c deleted file mode 100644 index f9b08a5d8ce8..000000000000 --- a/drivers/staging/bcm/hostmibs.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * File Name: hostmibs.c - * - * Author: Beceem Communications Pvt. Ltd - * - * Abstract: This file contains the routines to copy the statistics used by - * the driver to the Host MIBS structure and giving the same to Application. - */ - -#include "headers.h" - -INT ProcessGetHostMibs(struct bcm_mini_adapter *Adapter, - struct bcm_host_stats_mibs *pstHostMibs) -{ - struct bcm_phs_entry *pstServiceFlowEntry = NULL; - struct bcm_phs_rule *pstPhsRule = NULL; - struct bcm_phs_classifier_table *pstClassifierTable = NULL; - struct bcm_phs_classifier_entry *pstClassifierRule = NULL; - struct bcm_phs_extension *pDeviceExtension = &Adapter->stBCMPhsContext; - struct bcm_mibs_host_info *host_info; - UINT nClassifierIndex = 0; - UINT nPhsTableIndex = 0; - UINT nSfIndex = 0; - UINT uiIndex = 0; - - if (pDeviceExtension == NULL) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, HOST_MIBS, - DBG_LVL_ALL, "Invalid Device Extension\n"); - return STATUS_FAILURE; - } - - /* Copy the classifier Table */ - for (nClassifierIndex = 0; nClassifierIndex < MAX_CLASSIFIERS; - nClassifierIndex++) { - if (Adapter->astClassifierTable[nClassifierIndex].bUsed == TRUE) - memcpy(&pstHostMibs->astClassifierTable[nClassifierIndex], - &Adapter->astClassifierTable[nClassifierIndex], - sizeof(struct bcm_mibs_classifier_rule)); - } - - /* Copy the SF Table */ - for (nSfIndex = 0; nSfIndex < NO_OF_QUEUES; nSfIndex++) { - if (Adapter->PackInfo[nSfIndex].bValid) { - memcpy(&pstHostMibs->astSFtable[nSfIndex], - &Adapter->PackInfo[nSfIndex], - sizeof(struct bcm_mibs_table)); - } else { - /* If index in not valid, - * don't process this for the PHS table. - * Go For the next entry. - */ - continue; - } - - /* Retrieve the SFID Entry Index for requested Service Flow */ - if (PHS_INVALID_TABLE_INDEX == - GetServiceFlowEntry(pDeviceExtension-> - pstServiceFlowPhsRulesTable, - Adapter->PackInfo[nSfIndex]. - usVCID_Value, &pstServiceFlowEntry)) - - continue; - - pstClassifierTable = pstServiceFlowEntry->pstClassifierTable; - - for (uiIndex = 0; uiIndex < MAX_PHSRULE_PER_SF; uiIndex++) { - pstClassifierRule = &pstClassifierTable->stActivePhsRulesList[uiIndex]; - - if (pstClassifierRule->bUsed) { - pstPhsRule = pstClassifierRule->pstPhsRule; - - pstHostMibs->astPhsRulesTable[nPhsTableIndex]. - ulSFID = Adapter->PackInfo[nSfIndex].ulSFID; - - memcpy(&pstHostMibs->astPhsRulesTable[nPhsTableIndex].u8PHSI, - &pstPhsRule->u8PHSI, - sizeof(struct bcm_phs_rule)); - nPhsTableIndex++; - - } - - } - - } - - /* Copy other Host Statistics parameters */ - host_info = &pstHostMibs->stHostInfo; - host_info->GoodTransmits = Adapter->dev->stats.tx_packets; - host_info->GoodReceives = Adapter->dev->stats.rx_packets; - host_info->CurrNumFreeDesc = atomic_read(&Adapter->CurrNumFreeTxDesc); - host_info->BEBucketSize = Adapter->BEBucketSize; - host_info->rtPSBucketSize = Adapter->rtPSBucketSize; - host_info->TimerActive = Adapter->TimerActive; - host_info->u32TotalDSD = Adapter->u32TotalDSD; - - memcpy(host_info->aTxPktSizeHist, Adapter->aTxPktSizeHist, - sizeof(UINT32) * MIBS_MAX_HIST_ENTRIES); - memcpy(host_info->aRxPktSizeHist, Adapter->aRxPktSizeHist, - sizeof(UINT32) * MIBS_MAX_HIST_ENTRIES); - - return STATUS_SUCCESS; -} - -VOID GetDroppedAppCntrlPktMibs(struct bcm_host_stats_mibs *pstHostMibs, - struct bcm_tarang_data *pTarang) -{ - memcpy(&(pstHostMibs->stDroppedAppCntrlMsgs), - &(pTarang->stDroppedAppCntrlMsgs), - sizeof(struct bcm_mibs_dropped_cntrl_msg)); -} - -VOID CopyMIBSExtendedSFParameters(struct bcm_mini_adapter *Adapter, - struct bcm_connect_mgr_params *psfLocalSet, - UINT uiSearchRuleIndex) -{ - struct bcm_mibs_parameters *t = - &Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable; - - t->wmanIfSfid = psfLocalSet->u32SFID; - t->wmanIfCmnCpsMaxSustainedRate = - psfLocalSet->u32MaxSustainedTrafficRate; - t->wmanIfCmnCpsMaxTrafficBurst = psfLocalSet->u32MaxTrafficBurst; - t->wmanIfCmnCpsMinReservedRate = psfLocalSet->u32MinReservedTrafficRate; - t->wmanIfCmnCpsToleratedJitter = psfLocalSet->u32ToleratedJitter; - t->wmanIfCmnCpsMaxLatency = psfLocalSet->u32MaximumLatency; - t->wmanIfCmnCpsFixedVsVariableSduInd = - psfLocalSet->u8FixedLengthVSVariableLengthSDUIndicator; - t->wmanIfCmnCpsFixedVsVariableSduInd = - ntohl(t->wmanIfCmnCpsFixedVsVariableSduInd); - t->wmanIfCmnCpsSduSize = psfLocalSet->u8SDUSize; - t->wmanIfCmnCpsSduSize = ntohl(t->wmanIfCmnCpsSduSize); - t->wmanIfCmnCpsSfSchedulingType = - psfLocalSet->u8ServiceFlowSchedulingType; - t->wmanIfCmnCpsSfSchedulingType = - ntohl(t->wmanIfCmnCpsSfSchedulingType); - t->wmanIfCmnCpsArqEnable = psfLocalSet->u8ARQEnable; - t->wmanIfCmnCpsArqEnable = ntohl(t->wmanIfCmnCpsArqEnable); - t->wmanIfCmnCpsArqWindowSize = ntohs(psfLocalSet->u16ARQWindowSize); - t->wmanIfCmnCpsArqWindowSize = ntohl(t->wmanIfCmnCpsArqWindowSize); - t->wmanIfCmnCpsArqBlockLifetime = - ntohs(psfLocalSet->u16ARQBlockLifeTime); - t->wmanIfCmnCpsArqBlockLifetime = - ntohl(t->wmanIfCmnCpsArqBlockLifetime); - t->wmanIfCmnCpsArqSyncLossTimeout = - ntohs(psfLocalSet->u16ARQSyncLossTimeOut); - t->wmanIfCmnCpsArqSyncLossTimeout = - ntohl(t->wmanIfCmnCpsArqSyncLossTimeout); - t->wmanIfCmnCpsArqDeliverInOrder = psfLocalSet->u8ARQDeliverInOrder; - t->wmanIfCmnCpsArqDeliverInOrder = - ntohl(t->wmanIfCmnCpsArqDeliverInOrder); - t->wmanIfCmnCpsArqRxPurgeTimeout = - ntohs(psfLocalSet->u16ARQRxPurgeTimeOut); - t->wmanIfCmnCpsArqRxPurgeTimeout = - ntohl(t->wmanIfCmnCpsArqRxPurgeTimeout); - t->wmanIfCmnCpsArqBlockSize = ntohs(psfLocalSet->u16ARQBlockSize); - t->wmanIfCmnCpsArqBlockSize = ntohl(t->wmanIfCmnCpsArqBlockSize); - t->wmanIfCmnCpsReqTxPolicy = psfLocalSet->u8RequesttransmissionPolicy; - t->wmanIfCmnCpsReqTxPolicy = ntohl(t->wmanIfCmnCpsReqTxPolicy); - t->wmanIfCmnSfCsSpecification = psfLocalSet->u8CSSpecification; - t->wmanIfCmnSfCsSpecification = ntohl(t->wmanIfCmnSfCsSpecification); - t->wmanIfCmnCpsTargetSaid = ntohs(psfLocalSet->u16TargetSAID); - t->wmanIfCmnCpsTargetSaid = ntohl(t->wmanIfCmnCpsTargetSaid); - -} diff --git a/drivers/staging/bcm/led_control.c b/drivers/staging/bcm/led_control.c deleted file mode 100644 index 074fc39ed678..000000000000 --- a/drivers/staging/bcm/led_control.c +++ /dev/null @@ -1,952 +0,0 @@ -#include "headers.h" - -#define STATUS_IMAGE_CHECKSUM_MISMATCH -199 -#define EVENT_SIGNALED 1 - -static B_UINT16 CFG_CalculateChecksum(B_UINT8 *pu8Buffer, B_UINT32 u32Size) -{ - B_UINT16 u16CheckSum = 0; - - while (u32Size--) { - u16CheckSum += (B_UINT8)~(*pu8Buffer); - pu8Buffer++; - } - return u16CheckSum; -} - -bool IsReqGpioIsLedInNVM(struct bcm_mini_adapter *Adapter, UINT gpios) -{ - INT Status; - - Status = (Adapter->gpioBitMap & gpios) ^ gpios; - if (Status) - return false; - else - return TRUE; -} - -static INT LED_Blink(struct bcm_mini_adapter *Adapter, - UINT GPIO_Num, - UCHAR uiLedIndex, - ULONG timeout, - INT num_of_time, - enum bcm_led_events currdriverstate) -{ - int Status = STATUS_SUCCESS; - bool bInfinite = false; - - /* Check if num_of_time is -ve. If yes, blink led in infinite loop */ - if (num_of_time < 0) { - bInfinite = TRUE; - num_of_time = 1; - } - while (num_of_time) { - if (currdriverstate == Adapter->DriverState) - TURN_ON_LED(Adapter, GPIO_Num, uiLedIndex); - - /* Wait for timeout after setting on the LED */ - Status = wait_event_interruptible_timeout( - Adapter->LEDInfo.notify_led_event, - currdriverstate != Adapter->DriverState || - kthread_should_stop(), - msecs_to_jiffies(timeout)); - - if (kthread_should_stop()) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, - "Led thread got signal to exit..hence exiting"); - Adapter->LEDInfo.led_thread_running = - BCM_LED_THREAD_DISABLED; - TURN_OFF_LED(Adapter, GPIO_Num, uiLedIndex); - Status = EVENT_SIGNALED; - break; - } - if (Status) { - TURN_OFF_LED(Adapter, GPIO_Num, uiLedIndex); - Status = EVENT_SIGNALED; - break; - } - - TURN_OFF_LED(Adapter, GPIO_Num, uiLedIndex); - Status = wait_event_interruptible_timeout( - Adapter->LEDInfo.notify_led_event, - currdriverstate != Adapter->DriverState || - kthread_should_stop(), - msecs_to_jiffies(timeout)); - if (bInfinite == false) - num_of_time--; - } - return Status; -} - -static INT ScaleRateofTransfer(ULONG rate) -{ - if (rate <= 3) - return rate; - else if ((rate > 3) && (rate <= 100)) - return 5; - else if ((rate > 100) && (rate <= 200)) - return 6; - else if ((rate > 200) && (rate <= 300)) - return 7; - else if ((rate > 300) && (rate <= 400)) - return 8; - else if ((rate > 400) && (rate <= 500)) - return 9; - else if ((rate > 500) && (rate <= 600)) - return 10; - else - return MAX_NUM_OF_BLINKS; -} - -static INT blink_in_normal_bandwidth(struct bcm_mini_adapter *ad, - INT *time, - INT *time_tx, - INT *time_rx, - UCHAR GPIO_Num_tx, - UCHAR uiTxLedIndex, - UCHAR GPIO_Num_rx, - UCHAR uiRxLedIndex, - enum bcm_led_events currdriverstate, - ulong *timeout) -{ - /* - * Assign minimum number of blinks of - * either Tx or Rx. - */ - *time = (*time_tx > *time_rx ? *time_rx : *time_tx); - - if (*time > 0) { - /* Blink both Tx and Rx LEDs */ - if ((LED_Blink(ad, 1 << GPIO_Num_tx, uiTxLedIndex, *timeout, - *time, currdriverstate) == EVENT_SIGNALED) || - (LED_Blink(ad, 1 << GPIO_Num_rx, uiRxLedIndex, *timeout, - *time, currdriverstate) == EVENT_SIGNALED)) - return EVENT_SIGNALED; - } - - if (*time == *time_tx) { - /* Blink pending rate of Rx */ - if (LED_Blink(ad, (1 << GPIO_Num_rx), uiRxLedIndex, *timeout, - *time_rx - *time, - currdriverstate) == EVENT_SIGNALED) - return EVENT_SIGNALED; - - *time = *time_rx; - } else { - /* Blink pending rate of Tx */ - if (LED_Blink(ad, 1 << GPIO_Num_tx, uiTxLedIndex, *timeout, - *time_tx - *time, - currdriverstate) == EVENT_SIGNALED) - return EVENT_SIGNALED; - - *time = *time_tx; - } - - return 0; -} - -static INT LED_Proportional_Blink(struct bcm_mini_adapter *Adapter, - UCHAR GPIO_Num_tx, - UCHAR uiTxLedIndex, - UCHAR GPIO_Num_rx, - UCHAR uiRxLedIndex, - enum bcm_led_events currdriverstate) -{ - /* Initial values of TX and RX packets */ - ULONG64 Initial_num_of_packts_tx = 0, Initial_num_of_packts_rx = 0; - /* values of TX and RX packets after 1 sec */ - ULONG64 Final_num_of_packts_tx = 0, Final_num_of_packts_rx = 0; - /* Rate of transfer of Tx and Rx in 1 sec */ - ULONG64 rate_of_transfer_tx = 0, rate_of_transfer_rx = 0; - int Status = STATUS_SUCCESS; - INT num_of_time = 0, num_of_time_tx = 0, num_of_time_rx = 0; - UINT remDelay = 0; - /* UINT GPIO_num = DISABLE_GPIO_NUM; */ - ulong timeout = 0; - - /* Read initial value of packets sent/received */ - Initial_num_of_packts_tx = Adapter->dev->stats.tx_packets; - Initial_num_of_packts_rx = Adapter->dev->stats.rx_packets; - - /* Scale the rate of transfer to no of blinks. */ - num_of_time_tx = ScaleRateofTransfer((ULONG)rate_of_transfer_tx); - num_of_time_rx = ScaleRateofTransfer((ULONG)rate_of_transfer_rx); - - while ((Adapter->device_removed == false)) { - timeout = 50; - - if (EVENT_SIGNALED == blink_in_normal_bandwidth(Adapter, - &num_of_time, - &num_of_time_tx, - &num_of_time_rx, - GPIO_Num_tx, - uiTxLedIndex, - GPIO_Num_rx, - uiRxLedIndex, - currdriverstate, - &timeout)) - return EVENT_SIGNALED; - - - /* - * If Tx/Rx rate is less than maximum blinks per second, - * wait till delay completes to 1 second - */ - remDelay = MAX_NUM_OF_BLINKS - num_of_time; - if (remDelay > 0) { - timeout = 100 * remDelay; - Status = wait_event_interruptible_timeout( - Adapter->LEDInfo.notify_led_event, - currdriverstate != Adapter->DriverState - || kthread_should_stop(), - msecs_to_jiffies(timeout)); - - if (kthread_should_stop()) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - LED_DUMP_INFO, DBG_LVL_ALL, - "Led thread got signal to exit..hence exiting"); - Adapter->LEDInfo.led_thread_running = - BCM_LED_THREAD_DISABLED; - return EVENT_SIGNALED; - } - if (Status) - return EVENT_SIGNALED; - } - - /* Turn off both Tx and Rx LEDs before next second */ - TURN_OFF_LED(Adapter, 1 << GPIO_Num_tx, uiTxLedIndex); - TURN_OFF_LED(Adapter, 1 << GPIO_Num_rx, uiTxLedIndex); - - /* - * Read the Tx & Rx packets transmission after 1 second and - * calculate rate of transfer - */ - Final_num_of_packts_tx = Adapter->dev->stats.tx_packets; - Final_num_of_packts_rx = Adapter->dev->stats.rx_packets; - - rate_of_transfer_tx = Final_num_of_packts_tx - - Initial_num_of_packts_tx; - rate_of_transfer_rx = Final_num_of_packts_rx - - Initial_num_of_packts_rx; - - /* Read initial value of packets sent/received */ - Initial_num_of_packts_tx = Final_num_of_packts_tx; - Initial_num_of_packts_rx = Final_num_of_packts_rx; - - /* Scale the rate of transfer to no of blinks. */ - num_of_time_tx = - ScaleRateofTransfer((ULONG)rate_of_transfer_tx); - num_of_time_rx = - ScaleRateofTransfer((ULONG)rate_of_transfer_rx); - - } - return Status; -} - -/* - * ----------------------------------------------------------------------------- - * Procedure: ValidateDSDParamsChecksum - * - * Description: Reads DSD Params and validates checkusm. - * - * Arguments: - * Adapter - Pointer to Adapter structure. - * ulParamOffset - Start offset of the DSD parameter to be read and - * validated. - * usParamLen - Length of the DSD Parameter. - * - * Returns: - * <OSAL_STATUS_CODE> - * ----------------------------------------------------------------------------- - */ -static INT ValidateDSDParamsChecksum(struct bcm_mini_adapter *Adapter, - ULONG ulParamOffset, - USHORT usParamLen) -{ - INT Status = STATUS_SUCCESS; - PUCHAR puBuffer = NULL; - USHORT usChksmOrg = 0; - USHORT usChecksumCalculated = 0; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, - "LED Thread:ValidateDSDParamsChecksum: 0x%lx 0x%X", - ulParamOffset, usParamLen); - - puBuffer = kmalloc(usParamLen, GFP_KERNEL); - if (!puBuffer) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, - "LED Thread: ValidateDSDParamsChecksum Allocation failed"); - return -ENOMEM; - - } - - /* Read the DSD data from the parameter offset. */ - if (STATUS_SUCCESS != BeceemNVMRead(Adapter, (PUINT)puBuffer, - ulParamOffset, usParamLen)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, - "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed"); - Status = STATUS_IMAGE_CHECKSUM_MISMATCH; - goto exit; - } - - /* Calculate the checksum of the data read from the DSD parameter. */ - usChecksumCalculated = CFG_CalculateChecksum(puBuffer, usParamLen); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, - "LED Thread: usCheckSumCalculated = 0x%x\n", - usChecksumCalculated); - - /* - * End of the DSD parameter will have a TWO bytes checksum stored in it. - * Read it and compare with the calculated Checksum. - */ - if (STATUS_SUCCESS != BeceemNVMRead(Adapter, (PUINT)&usChksmOrg, - ulParamOffset+usParamLen, 2)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, - "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed"); - Status = STATUS_IMAGE_CHECKSUM_MISMATCH; - goto exit; - } - usChksmOrg = ntohs(usChksmOrg); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, - "LED Thread: usChksmOrg = 0x%x", usChksmOrg); - - /* - * Compare the checksum calculated with the checksum read - * from DSD section - */ - if (usChecksumCalculated ^ usChksmOrg) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, - "LED Thread: ValidateDSDParamsChecksum: Checksums don't match"); - Status = STATUS_IMAGE_CHECKSUM_MISMATCH; - goto exit; - } - -exit: - kfree(puBuffer); - return Status; -} - - -/* - * ----------------------------------------------------------------------------- - * Procedure: ValidateHWParmStructure - * - * Description: Validates HW Parameters. - * - * Arguments: - * Adapter - Pointer to Adapter structure. - * ulHwParamOffset - Start offset of the HW parameter Section to be read - * and validated. - * - * Returns: - * <OSAL_STATUS_CODE> - * ----------------------------------------------------------------------------- - */ -static INT ValidateHWParmStructure(struct bcm_mini_adapter *Adapter, - ULONG ulHwParamOffset) -{ - - INT Status = STATUS_SUCCESS; - USHORT HwParamLen = 0; - /* - * Add DSD start offset to the hwParamOffset to get - * the actual address. - */ - ulHwParamOffset += DSD_START_OFFSET; - - /* Read the Length of HW_PARAM structure */ - BeceemNVMRead(Adapter, (PUINT)&HwParamLen, ulHwParamOffset, 2); - HwParamLen = ntohs(HwParamLen); - if (0 == HwParamLen || HwParamLen > Adapter->uiNVMDSDSize) - return STATUS_IMAGE_CHECKSUM_MISMATCH; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, - "LED Thread:HwParamLen = 0x%x", HwParamLen); - Status = ValidateDSDParamsChecksum(Adapter, ulHwParamOffset, - HwParamLen); - return Status; -} /* ValidateHWParmStructure() */ - -static int ReadLEDInformationFromEEPROM(struct bcm_mini_adapter *Adapter, - UCHAR GPIO_Array[]) -{ - int Status = STATUS_SUCCESS; - - ULONG dwReadValue = 0; - USHORT usHwParamData = 0; - USHORT usEEPROMVersion = 0; - UCHAR ucIndex = 0; - UCHAR ucGPIOInfo[32] = {0}; - - BeceemNVMRead(Adapter, (PUINT)&usEEPROMVersion, - EEPROM_VERSION_OFFSET, 2); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, - "usEEPROMVersion: Minor:0x%X Major:0x%x", - usEEPROMVersion & 0xFF, - ((usEEPROMVersion >> 8) & 0xFF)); - - - if (((usEEPROMVersion>>8)&0xFF) < EEPROM_MAP5_MAJORVERSION) { - BeceemNVMRead(Adapter, (PUINT)&usHwParamData, - EEPROM_HW_PARAM_POINTER_ADDRESS, 2); - usHwParamData = ntohs(usHwParamData); - dwReadValue = usHwParamData; - } else { - /* - * Validate Compatibility section and then read HW param - * if compatibility section is valid. - */ - Status = ValidateDSDParamsChecksum(Adapter, - DSD_START_OFFSET, - COMPATIBILITY_SECTION_LENGTH_MAP5); - - if (Status != STATUS_SUCCESS) - return Status; - - BeceemNVMRead(Adapter, (PUINT)&dwReadValue, - EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5, 4); - dwReadValue = ntohl(dwReadValue); - } - - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, - "LED Thread: Start address of HW_PARAM structure = 0x%lx", - dwReadValue); - - /* - * Validate if the address read out is within the DSD. - * Adapter->uiNVMDSDSize gives whole DSD size inclusive of Autoinit. - * lower limit should be above DSD_START_OFFSET and - * upper limit should be below (Adapter->uiNVMDSDSize-DSD_START_OFFSET) - */ - if (dwReadValue < DSD_START_OFFSET || - dwReadValue > (Adapter->uiNVMDSDSize-DSD_START_OFFSET)) - return STATUS_IMAGE_CHECKSUM_MISMATCH; - - Status = ValidateHWParmStructure(Adapter, dwReadValue); - if (Status) - return Status; - - /* - * Add DSD_START_OFFSET to the offset read from the EEPROM. - * This will give the actual start HW Parameters start address. - * To read GPIO section, add GPIO offset further. - */ - - dwReadValue += DSD_START_OFFSET; - /* = start address of hw param section. */ - dwReadValue += GPIO_SECTION_START_OFFSET; - /* = GPIO start offset within HW Param section. */ - - /* - * Read the GPIO values for 32 GPIOs from EEPROM and map the function - * number to GPIO pin number to GPIO_Array - */ - BeceemNVMRead(Adapter, (UINT *)ucGPIOInfo, dwReadValue, 32); - for (ucIndex = 0; ucIndex < 32; ucIndex++) { - - switch (ucGPIOInfo[ucIndex]) { - case RED_LED: - GPIO_Array[RED_LED] = ucIndex; - Adapter->gpioBitMap |= (1 << ucIndex); - break; - case BLUE_LED: - GPIO_Array[BLUE_LED] = ucIndex; - Adapter->gpioBitMap |= (1 << ucIndex); - break; - case YELLOW_LED: - GPIO_Array[YELLOW_LED] = ucIndex; - Adapter->gpioBitMap |= (1 << ucIndex); - break; - case GREEN_LED: - GPIO_Array[GREEN_LED] = ucIndex; - Adapter->gpioBitMap |= (1 << ucIndex); - break; - default: - break; - } - - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, - "GPIO's bit map correspond to LED :0x%X", - Adapter->gpioBitMap); - return Status; -} - - -static int ReadConfigFileStructure(struct bcm_mini_adapter *Adapter, - bool *bEnableThread) -{ - int Status = STATUS_SUCCESS; - /* Array to store GPIO numbers from EEPROM */ - UCHAR GPIO_Array[NUM_OF_LEDS+1]; - UINT uiIndex = 0; - UINT uiNum_of_LED_Type = 0; - PUCHAR puCFGData = NULL; - UCHAR bData = 0; - struct bcm_led_state_info *curr_led_state; - - memset(GPIO_Array, DISABLE_GPIO_NUM, NUM_OF_LEDS+1); - - if (!Adapter->pstargetparams || IS_ERR(Adapter->pstargetparams)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, "Target Params not Avail.\n"); - return -ENOENT; - } - - /* Populate GPIO_Array with GPIO numbers for LED functions */ - /* Read the GPIO numbers from EEPROM */ - Status = ReadLEDInformationFromEEPROM(Adapter, GPIO_Array); - if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH) { - *bEnableThread = false; - return STATUS_SUCCESS; - } else if (Status) { - *bEnableThread = false; - return Status; - } - - /* - * CONFIG file read successfully. Deallocate the memory of - * uiFileNameBufferSize - */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, - "LED Thread: Config file read successfully\n"); - puCFGData = (PUCHAR) &Adapter->pstargetparams->HostDrvrConfig1; - - /* - * Offset for HostDrvConfig1, HostDrvConfig2, HostDrvConfig3 which - * will have the information of LED type, LED on state for different - * driver state and LED blink state. - */ - - for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { - bData = *puCFGData; - curr_led_state = &Adapter->LEDInfo.LEDState[uiIndex]; - - /* - * Check Bit 8 for polarity. If it is set, - * polarity is reverse polarity - */ - if (bData & 0x80) { - curr_led_state->BitPolarity = 0; - /* unset the bit 8 */ - bData = bData & 0x7f; - } - - curr_led_state->LED_Type = bData; - if (bData <= NUM_OF_LEDS) - curr_led_state->GPIO_Num = GPIO_Array[bData]; - else - curr_led_state->GPIO_Num = DISABLE_GPIO_NUM; - - puCFGData++; - bData = *puCFGData; - curr_led_state->LED_On_State = bData; - puCFGData++; - bData = *puCFGData; - curr_led_state->LED_Blink_State = bData; - puCFGData++; - } - - /* - * Check if all the LED settings are disabled. If it is disabled, - * dont launch the LED control thread. - */ - for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { - curr_led_state = &Adapter->LEDInfo.LEDState[uiIndex]; - - if ((curr_led_state->LED_Type == DISABLE_GPIO_NUM) || - (curr_led_state->LED_Type == 0x7f) || - (curr_led_state->LED_Type == 0)) - uiNum_of_LED_Type++; - } - if (uiNum_of_LED_Type >= NUM_OF_LEDS) - *bEnableThread = false; - - return Status; -} - -/* - * ----------------------------------------------------------------------------- - * Procedure: LedGpioInit - * - * Description: Initializes LED GPIOs. Makes the LED GPIOs to OUTPUT mode - * and make the initial state to be OFF. - * - * Arguments: - * Adapter - Pointer to MINI_ADAPTER structure. - * - * Returns: VOID - * - * ----------------------------------------------------------------------------- - */ -static VOID LedGpioInit(struct bcm_mini_adapter *Adapter) -{ - UINT uiResetValue = 0; - UINT uiIndex = 0; - struct bcm_led_state_info *curr_led_state; - - /* Set all LED GPIO Mode to output mode */ - if (rdmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue, - sizeof(uiResetValue)) < 0) - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, "LED Thread: RDM Failed\n"); - for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { - curr_led_state = &Adapter->LEDInfo.LEDState[uiIndex]; - - if (curr_led_state->GPIO_Num != DISABLE_GPIO_NUM) - uiResetValue |= (1 << curr_led_state->GPIO_Num); - - TURN_OFF_LED(Adapter, 1 << curr_led_state->GPIO_Num, uiIndex); - - } - if (wrmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue, - sizeof(uiResetValue)) < 0) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, "LED Thread: WRM Failed\n"); - - Adapter->LEDInfo.bIdle_led_off = false; -} - -static INT BcmGetGPIOPinInfo(struct bcm_mini_adapter *Adapter, - UCHAR *GPIO_num_tx, - UCHAR *GPIO_num_rx, - UCHAR *uiLedTxIndex, - UCHAR *uiLedRxIndex, - enum bcm_led_events currdriverstate) -{ - UINT uiIndex = 0; - struct bcm_led_state_info *led_state_info; - - *GPIO_num_tx = DISABLE_GPIO_NUM; - *GPIO_num_rx = DISABLE_GPIO_NUM; - - for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { - led_state_info = &Adapter->LEDInfo.LEDState[uiIndex]; - - if (((currdriverstate == NORMAL_OPERATION) || - (currdriverstate == IDLEMODE_EXIT) || - (currdriverstate == FW_DOWNLOAD)) && - (led_state_info->LED_Blink_State & currdriverstate) && - (led_state_info->GPIO_Num != DISABLE_GPIO_NUM)) { - if (*GPIO_num_tx == DISABLE_GPIO_NUM) { - *GPIO_num_tx = led_state_info->GPIO_Num; - *uiLedTxIndex = uiIndex; - } else { - *GPIO_num_rx = led_state_info->GPIO_Num; - *uiLedRxIndex = uiIndex; - } - } else { - if ((led_state_info->LED_On_State & currdriverstate) && - (led_state_info->GPIO_Num != DISABLE_GPIO_NUM)) { - *GPIO_num_tx = led_state_info->GPIO_Num; - *uiLedTxIndex = uiIndex; - } - } - } - return STATUS_SUCCESS; -} - -static void handle_adapter_driver_state(struct bcm_mini_adapter *ad, - enum bcm_led_events currdriverstate, - UCHAR GPIO_num, - UCHAR dummyGPIONum, - UCHAR uiLedIndex, - UCHAR dummyIndex, - ulong timeout, - UINT uiResetValue, - UINT uiIndex) -{ - switch (ad->DriverState) { - case DRIVER_INIT: - currdriverstate = DRIVER_INIT; - /* ad->DriverState; */ - BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum, - &uiLedIndex, &dummyIndex, - currdriverstate); - - if (GPIO_num != DISABLE_GPIO_NUM) - TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex); - - break; - case FW_DOWNLOAD: - /* - * BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, - * LED_DUMP_INFO, DBG_LVL_ALL, - * "LED Thread: FW_DN_DONE called\n"); - */ - currdriverstate = FW_DOWNLOAD; - BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum, - &uiLedIndex, &dummyIndex, - currdriverstate); - - if (GPIO_num != DISABLE_GPIO_NUM) { - timeout = 50; - LED_Blink(ad, 1 << GPIO_num, uiLedIndex, timeout, - -1, currdriverstate); - } - break; - case FW_DOWNLOAD_DONE: - currdriverstate = FW_DOWNLOAD_DONE; - BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum, - &uiLedIndex, &dummyIndex, currdriverstate); - if (GPIO_num != DISABLE_GPIO_NUM) - TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex); - break; - - case SHUTDOWN_EXIT: - /* - * no break, continue to NO_NETWORK_ENTRY - * state as well. - */ - case NO_NETWORK_ENTRY: - currdriverstate = NO_NETWORK_ENTRY; - BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum, - &uiLedIndex, &dummyGPIONum, currdriverstate); - if (GPIO_num != DISABLE_GPIO_NUM) - TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex); - break; - case NORMAL_OPERATION: - { - UCHAR GPIO_num_tx = DISABLE_GPIO_NUM; - UCHAR GPIO_num_rx = DISABLE_GPIO_NUM; - UCHAR uiLEDTx = 0; - UCHAR uiLEDRx = 0; - - currdriverstate = NORMAL_OPERATION; - ad->LEDInfo.bIdle_led_off = false; - - BcmGetGPIOPinInfo(ad, &GPIO_num_tx, &GPIO_num_rx, - &uiLEDTx, &uiLEDRx, currdriverstate); - if ((GPIO_num_tx == DISABLE_GPIO_NUM) && - (GPIO_num_rx == DISABLE_GPIO_NUM)) { - GPIO_num = DISABLE_GPIO_NUM; - } else { - /* - * If single LED is selected, use same - * for both Tx and Rx - */ - if (GPIO_num_tx == DISABLE_GPIO_NUM) { - GPIO_num_tx = GPIO_num_rx; - uiLEDTx = uiLEDRx; - } else if (GPIO_num_rx == DISABLE_GPIO_NUM) { - GPIO_num_rx = GPIO_num_tx; - uiLEDRx = uiLEDTx; - } - /* - * Blink the LED in proportionate - * to Tx and Rx transmissions. - */ - LED_Proportional_Blink(ad, - GPIO_num_tx, uiLEDTx, - GPIO_num_rx, uiLEDRx, - currdriverstate); - } - } - break; - case LOWPOWER_MODE_ENTER: - currdriverstate = LOWPOWER_MODE_ENTER; - if (DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING == - ad->ulPowerSaveMode) { - /* Turn OFF all the LED */ - uiResetValue = 0; - for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { - if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM) - TURN_OFF_LED(ad, - (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num), - uiIndex); - } - - } - /* Turn off LED And WAKE-UP for Sendinf IDLE mode ACK */ - ad->LEDInfo.bLedInitDone = false; - ad->LEDInfo.bIdle_led_off = TRUE; - wake_up(&ad->LEDInfo.idleModeSyncEvent); - GPIO_num = DISABLE_GPIO_NUM; - break; - case IDLEMODE_CONTINUE: - currdriverstate = IDLEMODE_CONTINUE; - GPIO_num = DISABLE_GPIO_NUM; - break; - case IDLEMODE_EXIT: - break; - case DRIVER_HALT: - currdriverstate = DRIVER_HALT; - GPIO_num = DISABLE_GPIO_NUM; - for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { - if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num != - DISABLE_GPIO_NUM) - TURN_OFF_LED(ad, - (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num), - uiIndex); - } - /* ad->DriverState = DRIVER_INIT; */ - break; - case LED_THREAD_INACTIVE: - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, "InActivating LED thread..."); - currdriverstate = LED_THREAD_INACTIVE; - ad->LEDInfo.led_thread_running = - BCM_LED_THREAD_RUNNING_INACTIVELY; - ad->LEDInfo.bLedInitDone = false; - /* disable ALL LED */ - for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { - if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num != - DISABLE_GPIO_NUM) - TURN_OFF_LED(ad, - (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num), - uiIndex); - } - break; - case LED_THREAD_ACTIVE: - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, "Activating LED thread again..."); - if (ad->LinkUpStatus == false) - ad->DriverState = NO_NETWORK_ENTRY; - else - ad->DriverState = NORMAL_OPERATION; - - ad->LEDInfo.led_thread_running = - BCM_LED_THREAD_RUNNING_ACTIVELY; - break; - /* return; */ - default: - break; - } -} - -static VOID LEDControlThread(struct bcm_mini_adapter *Adapter) -{ - UINT uiIndex = 0; - UCHAR GPIO_num = 0; - UCHAR uiLedIndex = 0; - UINT uiResetValue = 0; - enum bcm_led_events currdriverstate = 0; - ulong timeout = 0; - - INT Status = 0; - - UCHAR dummyGPIONum = 0; - UCHAR dummyIndex = 0; - - /* currdriverstate = Adapter->DriverState; */ - Adapter->LEDInfo.bIdleMode_tx_from_host = false; - - /* - * Wait till event is triggered - * - * wait_event(Adapter->LEDInfo.notify_led_event, - * currdriverstate!= Adapter->DriverState); - */ - - GPIO_num = DISABLE_GPIO_NUM; - - while (TRUE) { - /* Wait till event is triggered */ - if ((GPIO_num == DISABLE_GPIO_NUM) - || - ((currdriverstate != FW_DOWNLOAD) && - (currdriverstate != NORMAL_OPERATION) && - (currdriverstate != LOWPOWER_MODE_ENTER)) - || - (currdriverstate == LED_THREAD_INACTIVE)) - Status = wait_event_interruptible( - Adapter->LEDInfo.notify_led_event, - currdriverstate != Adapter->DriverState - || kthread_should_stop()); - - if (kthread_should_stop() || Adapter->device_removed) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, - "Led thread got signal to exit..hence exiting"); - Adapter->LEDInfo.led_thread_running = - BCM_LED_THREAD_DISABLED; - TURN_OFF_LED(Adapter, 1 << GPIO_num, uiLedIndex); - return; /* STATUS_FAILURE; */ - } - - if (GPIO_num != DISABLE_GPIO_NUM) - TURN_OFF_LED(Adapter, 1 << GPIO_num, uiLedIndex); - - if (Adapter->LEDInfo.bLedInitDone == false) { - LedGpioInit(Adapter); - Adapter->LEDInfo.bLedInitDone = TRUE; - } - - handle_adapter_driver_state(Adapter, - currdriverstate, - GPIO_num, - dummyGPIONum, - uiLedIndex, - dummyIndex, - timeout, - uiResetValue, - uiIndex - ); - } - Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED; -} - -int InitLedSettings(struct bcm_mini_adapter *Adapter) -{ - int Status = STATUS_SUCCESS; - bool bEnableThread = TRUE; - UCHAR uiIndex = 0; - - /* - * Initially set BitPolarity to normal polarity. The bit 8 of LED type - * is used to change the polarity of the LED. - */ - - for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) - Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 1; - - /* - * Read the LED settings of CONFIG file and map it - * to GPIO numbers in EEPROM - */ - Status = ReadConfigFileStructure(Adapter, &bEnableThread); - if (STATUS_SUCCESS != Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, - "LED Thread: FAILED in ReadConfigFileStructure\n"); - return Status; - } - - if (Adapter->LEDInfo.led_thread_running) { - if (bEnableThread) { - ; - } else { - Adapter->DriverState = DRIVER_HALT; - wake_up(&Adapter->LEDInfo.notify_led_event); - Adapter->LEDInfo.led_thread_running = - BCM_LED_THREAD_DISABLED; - } - - } else if (bEnableThread) { - /* Create secondary thread to handle the LEDs */ - init_waitqueue_head(&Adapter->LEDInfo.notify_led_event); - init_waitqueue_head(&Adapter->LEDInfo.idleModeSyncEvent); - Adapter->LEDInfo.led_thread_running = - BCM_LED_THREAD_RUNNING_ACTIVELY; - Adapter->LEDInfo.bIdle_led_off = false; - Adapter->LEDInfo.led_cntrl_threadid = - kthread_run((int (*)(void *)) LEDControlThread, - Adapter, "led_control_thread"); - if (IS_ERR(Adapter->LEDInfo.led_cntrl_threadid)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, - "Not able to spawn Kernel Thread\n"); - Adapter->LEDInfo.led_thread_running = - BCM_LED_THREAD_DISABLED; - return PTR_ERR(Adapter->LEDInfo.led_cntrl_threadid); - } - } - return Status; -} diff --git a/drivers/staging/bcm/led_control.h b/drivers/staging/bcm/led_control.h deleted file mode 100644 index 1b24bf4658af..000000000000 --- a/drivers/staging/bcm/led_control.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef _LED_CONTROL_H -#define _LED_CONTROL_H - -#define NUM_OF_LEDS 4 -#define DSD_START_OFFSET 0x0200 -#define EEPROM_VERSION_OFFSET 0x020E -#define EEPROM_HW_PARAM_POINTER_ADDRESS 0x0218 -#define EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5 0x0220 -#define GPIO_SECTION_START_OFFSET 0x03 -#define COMPATIBILITY_SECTION_LENGTH 42 -#define COMPATIBILITY_SECTION_LENGTH_MAP5 84 -#define EEPROM_MAP5_MAJORVERSION 5 -#define EEPROM_MAP5_MINORVERSION 0 -#define MAX_NUM_OF_BLINKS 10 -#define NUM_OF_GPIO_PINS 16 -#define DISABLE_GPIO_NUM 0xFF -#define EVENT_SIGNALED 1 -#define MAX_FILE_NAME_BUFFER_SIZE 100 - -#define TURN_ON_LED(ad, GPIO, index) do { \ - unsigned int gpio_val = GPIO; \ - (ad->LEDInfo.LEDState[index].BitPolarity == 1) ? \ - wrmaltWithLock(ad, BCM_GPIO_OUTPUT_SET_REG, &gpio_val, sizeof(gpio_val)) : \ - wrmaltWithLock(ad, BCM_GPIO_OUTPUT_CLR_REG, &gpio_val, sizeof(gpio_val)); \ - } while (0) - -#define TURN_OFF_LED(ad, GPIO, index) do { \ - unsigned int gpio_val = GPIO; \ - (ad->LEDInfo.LEDState[index].BitPolarity == 1) ? \ - wrmaltWithLock(ad, BCM_GPIO_OUTPUT_CLR_REG, &gpio_val, sizeof(gpio_val)) : \ - wrmaltWithLock(ad, BCM_GPIO_OUTPUT_SET_REG, &gpio_val, sizeof(gpio_val)); \ - } while (0) - -enum bcm_led_colors { - RED_LED = 1, - BLUE_LED = 2, - YELLOW_LED = 3, - GREEN_LED = 4 -}; - -enum bcm_led_events { - SHUTDOWN_EXIT = 0x00, - DRIVER_INIT = 0x1, - FW_DOWNLOAD = 0x2, - FW_DOWNLOAD_DONE = 0x4, - NO_NETWORK_ENTRY = 0x8, - NORMAL_OPERATION = 0x10, - LOWPOWER_MODE_ENTER = 0x20, - IDLEMODE_CONTINUE = 0x40, - IDLEMODE_EXIT = 0x80, - LED_THREAD_INACTIVE = 0x100, /* Makes the LED thread Inactivce. It wil be equivallent to putting the thread on hold. */ - LED_THREAD_ACTIVE = 0x200, /* Makes the LED Thread Active back. */ - DRIVER_HALT = 0xff -}; /* Enumerated values of different driver states */ - -/* - * Structure which stores the information of different LED types - * and corresponding LED state information of driver states - */ -struct bcm_led_state_info { - unsigned char LED_Type; /* specify GPIO number - use 0xFF if not used */ - unsigned char LED_On_State; /* Bits set or reset for different states */ - unsigned char LED_Blink_State; /* Bits set or reset for blinking LEDs for different states */ - unsigned char GPIO_Num; - unsigned char BitPolarity; /* To represent whether H/W is normal polarity or reverse polarity */ -}; - -struct bcm_led_info { - struct bcm_led_state_info LEDState[NUM_OF_LEDS]; - bool bIdleMode_tx_from_host; /* Variable to notify whether driver came out from idlemode due to Host or target */ - bool bIdle_led_off; - wait_queue_head_t notify_led_event; - wait_queue_head_t idleModeSyncEvent; - struct task_struct *led_cntrl_threadid; - int led_thread_running; - bool bLedInitDone; -}; - -/* LED Thread state. */ -#define BCM_LED_THREAD_DISABLED 0 /* LED Thread is not running. */ -#define BCM_LED_THREAD_RUNNING_ACTIVELY 1 /* LED thread is running. */ -#define BCM_LED_THREAD_RUNNING_INACTIVELY 2 /* LED thread has been put on hold */ - -#endif diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c deleted file mode 100644 index ce09473fbb1f..000000000000 --- a/drivers/staging/bcm/nvm.c +++ /dev/null @@ -1,4661 +0,0 @@ -#include "headers.h" - -#define DWORD unsigned int - -static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, - unsigned int offset); -static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter); -static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter); -static unsigned int BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter); -static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter); -static unsigned int BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, - unsigned int FlashSectorSizeSig, - unsigned int FlashSectorSize); - -static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter); -static int BcmGetNvmSize(struct bcm_mini_adapter *Adapter); -static unsigned int BcmGetFlashSize(struct bcm_mini_adapter *Adapter); -static enum bcm_nvm_type BcmGetNvmType(struct bcm_mini_adapter *Adapter); - -static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, - enum bcm_flash2x_section_val eFlash2xSectionVal); - -static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, - unsigned int uiOffset); -static int IsSectionWritable(struct bcm_mini_adapter *Adapter, - enum bcm_flash2x_section_val Section); -static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, - enum bcm_flash2x_section_val section); - -static int ReadDSDPriority(struct bcm_mini_adapter *Adapter, - enum bcm_flash2x_section_val dsd); -static int ReadDSDSignature(struct bcm_mini_adapter *Adapter, - enum bcm_flash2x_section_val dsd); -static int ReadISOPriority(struct bcm_mini_adapter *Adapter, - enum bcm_flash2x_section_val iso); -static int ReadISOSignature(struct bcm_mini_adapter *Adapter, - enum bcm_flash2x_section_val iso); - -static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, - enum bcm_flash2x_section_val eFlash2xSectionVal); -static int CorruptISOSig(struct bcm_mini_adapter *Adapter, - enum bcm_flash2x_section_val eFlash2xSectionVal); -static int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, - PUCHAR pBuff, - unsigned int uiSectAlignAddr); -static int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, - PUINT pBuff, - enum bcm_flash2x_section_val eFlash2xSectionVal, - unsigned int uiOffset, - unsigned int uiNumBytes); -static enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter); -static enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter); - -static int BeceemFlashBulkRead( - struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - unsigned int uiOffset, - unsigned int uiNumBytes); - -static int BeceemFlashBulkWrite( - struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - unsigned int uiOffset, - unsigned int uiNumBytes, - bool bVerify); - -static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter); - -static int ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, unsigned int dwAddress, unsigned int *pdwData, unsigned int dwNumData); - -/* Procedure: ReadEEPROMStatusRegister - * - * Description: Reads the standard EEPROM Status Register. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * Returns: - * OSAL_STATUS_CODE - */ -static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter) -{ - UCHAR uiData = 0; - DWORD dwRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY; - unsigned int uiStatus = 0; - unsigned int value = 0; - unsigned int value1 = 0; - - /* Read the EEPROM status register */ - value = EEPROM_READ_STATUS_REGISTER; - wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); - - while (dwRetries != 0) { - value = 0; - uiStatus = 0; - rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus)); - if (Adapter->device_removed == TRUE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting...."); - break; - } - - /* Wait for Avail bit to be set. */ - if ((uiStatus & EEPROM_READ_DATA_AVAIL) != 0) { - /* Clear the Avail/Full bits - which ever is set. */ - value = uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL); - wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - - value = 0; - rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value)); - uiData = (UCHAR)value; - - break; - } - - dwRetries--; - if (dwRetries == 0) { - rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG, &value1, sizeof(value1)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "0x3004 = %x 0x3008 = %x, retries = %d failed.\n", value, value1, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY); - return uiData; - } - if (!(dwRetries%RETRIES_PER_DELAY)) - udelay(1000); - uiStatus = 0; - } - return uiData; -} /* ReadEEPROMStatusRegister */ - -/* - * Procedure: ReadBeceemEEPROMBulk - * - * Description: This routine reads 16Byte data from EEPROM - * - * Arguments: - * Adapter - ptr to Adapter object instance - * dwAddress - EEPROM Offset to read the data from. - * pdwData - Pointer to double word where data needs to be stored in. // dwNumWords - Number of words. Valid values are 4 ONLY. - * - * Returns: - * OSAL_STATUS_CODE: - */ - -static int ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, - DWORD dwAddress, - DWORD *pdwData, - DWORD dwNumWords) -{ - DWORD dwIndex = 0; - DWORD dwRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY; - unsigned int uiStatus = 0; - unsigned int value = 0; - unsigned int value1 = 0; - UCHAR *pvalue; - - /* Flush the read and cmd queue. */ - value = (EEPROM_READ_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH); - wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); - value = 0; - wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); - - /* Clear the Avail/Full bits. */ - value = (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL); - wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - - value = dwAddress | ((dwNumWords == 4) ? EEPROM_16_BYTE_PAGE_READ : EEPROM_4_BYTE_PAGE_READ); - wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); - - while (dwRetries != 0) { - uiStatus = 0; - rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus)); - if (Adapter->device_removed == TRUE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got Removed.hence exiting from loop..."); - return -ENODEV; - } - - /* If we are reading 16 bytes we want to be sure that the queue - * is full before we read. In the other cases we are ok if the - * queue has data available - */ - if (dwNumWords == 4) { - if ((uiStatus & EEPROM_READ_DATA_FULL) != 0) { - /* Clear the Avail/Full bits - which ever is set. */ - value = (uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL)); - wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - break; - } - } else if (dwNumWords == 1) { - if ((uiStatus & EEPROM_READ_DATA_AVAIL) != 0) { - /* We just got Avail and we have to read 32bits so we - * need this sleep for Cardbus kind of devices. - */ - if (Adapter->chip_id == 0xBECE0210) - udelay(800); - - /* Clear the Avail/Full bits - which ever is set. */ - value = (uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL)); - wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - break; - } - } - - uiStatus = 0; - - dwRetries--; - if (dwRetries == 0) { - value = 0; - value1 = 0; - rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG, &value1, sizeof(value1)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "dwNumWords %d 0x3004 = %x 0x3008 = %x retries = %d failed.\n", - dwNumWords, value, value1, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY); - return STATUS_FAILURE; - } - - if (!(dwRetries%RETRIES_PER_DELAY)) - udelay(1000); - } - - for (dwIndex = 0; dwIndex < dwNumWords; dwIndex++) { - /* We get only a byte at a time - from LSB to MSB. We shift it into an integer. */ - pvalue = (PUCHAR)(pdwData + dwIndex); - - value = 0; - rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value)); - - pvalue[0] = value; - - value = 0; - rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value)); - - pvalue[1] = value; - - value = 0; - rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value)); - - pvalue[2] = value; - - value = 0; - rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value)); - - pvalue[3] = value; - } - - return STATUS_SUCCESS; -} /* ReadBeceemEEPROMBulk() */ - -/* - * Procedure: ReadBeceemEEPROM - * - * Description: This routine reads 4 data from EEPROM. It uses 1 or 2 page - * reads to do this operation. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * uiOffset - EEPROM Offset to read the data from. - * pBuffer - Pointer to word where data needs to be stored in. - * - * Returns: - * OSAL_STATUS_CODE: - */ - -int ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter, - DWORD uiOffset, - DWORD *pBuffer) -{ - unsigned int uiData[8] = {0}; - unsigned int uiByteOffset = 0; - unsigned int uiTempOffset = 0; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ====> "); - - uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE); - uiByteOffset = uiOffset - uiTempOffset; - - ReadBeceemEEPROMBulk(Adapter, uiTempOffset, (PUINT)&uiData[0], 4); - - /* A word can overlap at most over 2 pages. In that case we read the - * next page too. - */ - if (uiByteOffset > 12) - ReadBeceemEEPROMBulk(Adapter, uiTempOffset + MAX_RW_SIZE, (PUINT)&uiData[4], 4); - - memcpy((PUCHAR)pBuffer, (((PUCHAR)&uiData[0]) + uiByteOffset), 4); - - return STATUS_SUCCESS; -} /* ReadBeceemEEPROM() */ - -int ReadMacAddressFromNVM(struct bcm_mini_adapter *Adapter) -{ - int Status; - unsigned char puMacAddr[6]; - - Status = BeceemNVMRead(Adapter, - (PUINT)&puMacAddr[0], - INIT_PARAMS_1_MACADDRESS_ADDRESS, - MAC_ADDRESS_SIZE); - - if (Status == STATUS_SUCCESS) - memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE); - - return Status; -} - -/* - * Procedure: BeceemEEPROMBulkRead - * - * Description: Reads the EEPROM and returns the Data. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * pBuffer - Buffer to store the data read from EEPROM - * uiOffset - Offset of EEPROM from where data should be read - * uiNumBytes - Number of bytes to be read from the EEPROM. - * - * Returns: - * OSAL_STATUS_SUCCESS - if EEPROM read is successful. - * <FAILURE> - if failed. - */ - -int BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - unsigned int uiOffset, - unsigned int uiNumBytes) -{ - unsigned int uiData[4] = {0}; - /* unsigned int uiAddress = 0; */ - unsigned int uiBytesRemaining = uiNumBytes; - unsigned int uiIndex = 0; - unsigned int uiTempOffset = 0; - unsigned int uiExtraBytes = 0; - unsigned int uiFailureRetries = 0; - PUCHAR pcBuff = (PUCHAR)pBuffer; - - if (uiOffset % MAX_RW_SIZE && uiBytesRemaining) { - uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE); - uiExtraBytes = uiOffset - uiTempOffset; - ReadBeceemEEPROMBulk(Adapter, uiTempOffset, (PUINT)&uiData[0], 4); - if (uiBytesRemaining >= (MAX_RW_SIZE - uiExtraBytes)) { - memcpy(pBuffer, (((PUCHAR)&uiData[0]) + uiExtraBytes), MAX_RW_SIZE - uiExtraBytes); - uiBytesRemaining -= (MAX_RW_SIZE - uiExtraBytes); - uiIndex += (MAX_RW_SIZE - uiExtraBytes); - uiOffset += (MAX_RW_SIZE - uiExtraBytes); - } else { - memcpy(pBuffer, (((PUCHAR)&uiData[0]) + uiExtraBytes), uiBytesRemaining); - uiIndex += uiBytesRemaining; - uiOffset += uiBytesRemaining; - uiBytesRemaining = 0; - } - } - - while (uiBytesRemaining && uiFailureRetries != 128) { - if (Adapter->device_removed) - return -1; - - if (uiBytesRemaining >= MAX_RW_SIZE) { - /* For the requests more than or equal to 16 bytes, use bulk - * read function to make the access faster. - * We read 4 Dwords of data - */ - if (ReadBeceemEEPROMBulk(Adapter, uiOffset, &uiData[0], 4) == 0) { - memcpy(pcBuff + uiIndex, &uiData[0], MAX_RW_SIZE); - uiOffset += MAX_RW_SIZE; - uiBytesRemaining -= MAX_RW_SIZE; - uiIndex += MAX_RW_SIZE; - } else { - uiFailureRetries++; - mdelay(3); /* sleep for a while before retry... */ - } - } else if (uiBytesRemaining >= 4) { - if (ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0]) == 0) { - memcpy(pcBuff + uiIndex, &uiData[0], 4); - uiOffset += 4; - uiBytesRemaining -= 4; - uiIndex += 4; - } else { - uiFailureRetries++; - mdelay(3); /* sleep for a while before retry... */ - } - } else { - /* Handle the reads less than 4 bytes... */ - PUCHAR pCharBuff = (PUCHAR)pBuffer; - - pCharBuff += uiIndex; - if (ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0]) == 0) { - memcpy(pCharBuff, &uiData[0], uiBytesRemaining); /* copy only bytes requested. */ - uiBytesRemaining = 0; - } else { - uiFailureRetries++; - mdelay(3); /* sleep for a while before retry... */ - } - } - } - - return 0; -} - -/* - * Procedure: BeceemFlashBulkRead - * - * Description: Reads the FLASH and returns the Data. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * pBuffer - Buffer to store the data read from FLASH - * uiOffset - Offset of FLASH from where data should be read - * uiNumBytes - Number of bytes to be read from the FLASH. - * - * Returns: - * OSAL_STATUS_SUCCESS - if FLASH read is successful. - * <FAILURE> - if failed. - */ - -static int BeceemFlashBulkRead(struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - unsigned int uiOffset, - unsigned int uiNumBytes) -{ - unsigned int uiIndex = 0; - unsigned int uiBytesToRead = uiNumBytes; - int Status = 0; - unsigned int uiPartOffset = 0; - int bytes; - - if (Adapter->device_removed) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device Got Removed"); - return -ENODEV; - } - - /* Adding flash Base address - * uiOffset = uiOffset + GetFlashBaseAddr(Adapter); - */ - #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) - Status = bcmflash_raw_read((uiOffset/FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes); - return Status; - #endif - - Adapter->SelectedChip = RESET_CHIP_SELECT; - - if (uiOffset % MAX_RW_SIZE) { - BcmDoChipSelect(Adapter, uiOffset); - uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); - - uiBytesToRead = MAX_RW_SIZE - (uiOffset % MAX_RW_SIZE); - uiBytesToRead = MIN(uiNumBytes, uiBytesToRead); - - bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer + uiIndex, uiBytesToRead); - if (bytes < 0) { - Status = bytes; - Adapter->SelectedChip = RESET_CHIP_SELECT; - return Status; - } - - uiIndex += uiBytesToRead; - uiOffset += uiBytesToRead; - uiNumBytes -= uiBytesToRead; - } - - while (uiNumBytes) { - BcmDoChipSelect(Adapter, uiOffset); - uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); - - uiBytesToRead = MIN(uiNumBytes, MAX_RW_SIZE); - - bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer + uiIndex, uiBytesToRead); - if (bytes < 0) { - Status = bytes; - break; - } - - uiIndex += uiBytesToRead; - uiOffset += uiBytesToRead; - uiNumBytes -= uiBytesToRead; - } - Adapter->SelectedChip = RESET_CHIP_SELECT; - return Status; -} - -/* - * Procedure: BcmGetFlashSize - * - * Description: Finds the size of FLASH. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * - * Returns: - * unsigned int - size of the FLASH Storage. - * - */ - -static unsigned int BcmGetFlashSize(struct bcm_mini_adapter *Adapter) -{ - if (IsFlash2x(Adapter)) - return Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header); - else - return 32 * 1024; -} - -/* - * Procedure: BcmGetEEPROMSize - * - * Description: Finds the size of EEPROM. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * - * Returns: - * unsigned int - size of the EEPROM Storage. - * - */ - -static unsigned int BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter) -{ - unsigned int uiData = 0; - unsigned int uiIndex = 0; - - /* - * if EEPROM is present and already Calibrated,it will have - * 'BECM' string at 0th offset. - * To find the EEPROM size read the possible boundaries of the - * EEPROM like 4K,8K etc..accessing the EEPROM beyond its size will - * result in wrap around. So when we get the End of the EEPROM we will - * get 'BECM' string which is indeed at offset 0. - */ - BeceemEEPROMBulkRead(Adapter, &uiData, 0x0, 4); - if (uiData == BECM) { - for (uiIndex = 2; uiIndex <= 256; uiIndex *= 2) { - BeceemEEPROMBulkRead(Adapter, &uiData, uiIndex * 1024, 4); - if (uiData == BECM) - return uiIndex * 1024; - } - } else { - /* - * EEPROM may not be present or not programmed - */ - uiData = 0xBABEFACE; - if (BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&uiData, 0, 4, TRUE) == 0) { - uiData = 0; - for (uiIndex = 2; uiIndex <= 256; uiIndex *= 2) { - BeceemEEPROMBulkRead(Adapter, &uiData, uiIndex * 1024, 4); - if (uiData == 0xBABEFACE) - return uiIndex * 1024; - } - } - } - return 0; -} - -/* - * Procedure: FlashSectorErase - * - * Description: Finds the sector size of the FLASH. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * addr - sector start address - * numOfSectors - number of sectors to be erased. - * - * Returns: - * OSAL_STATUS_CODE - * - */ - -static int FlashSectorErase(struct bcm_mini_adapter *Adapter, - unsigned int addr, - unsigned int numOfSectors) -{ - unsigned int iIndex = 0, iRetries = 0; - unsigned int uiStatus = 0; - unsigned int value; - int bytes; - - for (iIndex = 0; iIndex < numOfSectors; iIndex++) { - value = 0x06000000; - wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); - - value = (0xd8000000 | (addr & 0xFFFFFF)); - wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); - iRetries = 0; - - do { - value = (FLASH_CMD_STATUS_REG_READ << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); - return STATUS_FAILURE; - } - - bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)); - if (bytes < 0) { - uiStatus = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails"); - return uiStatus; - } - iRetries++; - /* After every try lets make the CPU free for 10 ms. generally time taken by the - * the sector erase cycle is 500 ms to 40000 msec. hence sleeping 10 ms - * won't hamper performance in any case. - */ - mdelay(10); - } while ((uiStatus & 0x1) && (iRetries < 400)); - - if (uiStatus & 0x1) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "iRetries crossing the limit of 80000\n"); - return STATUS_FAILURE; - } - - addr += Adapter->uiSectorSize; - } - return 0; -} -/* - * Procedure: flashByteWrite - * - * Description: Performs Byte by Byte write to flash - * - * Arguments: - * Adapter - ptr to Adapter object instance - * uiOffset - Offset of the flash where data needs to be written to. - * pData - Address of Data to be written. - * Returns: - * OSAL_STATUS_CODE - * - */ - -static int flashByteWrite(struct bcm_mini_adapter *Adapter, - unsigned int uiOffset, - PVOID pData) -{ - unsigned int uiStatus = 0; - int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ - unsigned int value; - ULONG ulData = *(PUCHAR)pData; - int bytes; - /* - * need not write 0xFF because write requires an erase and erase will - * make whole sector 0xFF. - */ - - if (0xFF == ulData) - return STATUS_SUCCESS; - - /* DumpDebug(NVM_RW,("flashWrite ====>\n")); */ - value = (FLASH_CMD_WRITE_ENABLE << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write enable in FLASH_SPI_CMDQ_REG register fails"); - return STATUS_FAILURE; - } - - if (wrm(Adapter, FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DATA Write on FLASH_SPI_WRITEQ_REG fails"); - return STATUS_FAILURE; - } - value = (0x02000000 | (uiOffset & 0xFFFFFF)); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programming of FLASH_SPI_CMDQ_REG fails"); - return STATUS_FAILURE; - } - - /* __udelay(950); */ - - do { - value = (FLASH_CMD_STATUS_REG_READ << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); - return STATUS_FAILURE; - } - /* __udelay(1); */ - bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)); - if (bytes < 0) { - uiStatus = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails"); - return uiStatus; - } - iRetries--; - if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) - udelay(1000); - - } while ((uiStatus & 0x1) && (iRetries > 0)); - - if (uiStatus & 0x1) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times."); - return STATUS_FAILURE; - } - - return STATUS_SUCCESS; -} - -/* - * Procedure: flashWrite - * - * Description: Performs write to flash - * - * Arguments: - * Adapter - ptr to Adapter object instance - * uiOffset - Offset of the flash where data needs to be written to. - * pData - Address of Data to be written. - * Returns: - * OSAL_STATUS_CODE - * - */ - -static int flashWrite(struct bcm_mini_adapter *Adapter, - unsigned int uiOffset, - PVOID pData) -{ - /* unsigned int uiStatus = 0; - * int iRetries = 0; - * unsigned int uiReadBack = 0; - */ - unsigned int uiStatus = 0; - int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ - unsigned int value; - unsigned int uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; - int bytes; - /* - * need not write 0xFFFFFFFF because write requires an erase and erase will - * make whole sector 0xFFFFFFFF. - */ - if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE)) - return 0; - - value = (FLASH_CMD_WRITE_ENABLE << 24); - - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write Enable of FLASH_SPI_CMDQ_REG fails"); - return STATUS_FAILURE; - } - - if (wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Data write fails..."); - return STATUS_FAILURE; - } - - /* __udelay(950); */ - do { - value = (FLASH_CMD_STATUS_REG_READ << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); - return STATUS_FAILURE; - } - /* __udelay(1); */ - bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)); - if (bytes < 0) { - uiStatus = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails"); - return uiStatus; - } - - iRetries--; - /* this will ensure that in there will be no changes in the current path. - * currently one rdm/wrm takes 125 us. - * Hence 125 *2 * FLASH_PER_RETRIES_DELAY > 3 ms(worst case delay) - * Hence current implementation cycle will intoduce no delay in current path - */ - if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) - udelay(1000); - } while ((uiStatus & 0x1) && (iRetries > 0)); - - if (uiStatus & 0x1) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times."); - return STATUS_FAILURE; - } - - return STATUS_SUCCESS; -} - -/*----------------------------------------------------------------------------- - * Procedure: flashByteWriteStatus - * - * Description: Performs byte by byte write to flash with write done status check - * - * Arguments: - * Adapter - ptr to Adapter object instance - * uiOffset - Offset of the flash where data needs to be written to. - * pData - Address of the Data to be written. - * Returns: - * OSAL_STATUS_CODE - * - */ -static int flashByteWriteStatus(struct bcm_mini_adapter *Adapter, - unsigned int uiOffset, - PVOID pData) -{ - unsigned int uiStatus = 0; - int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ - ULONG ulData = *(PUCHAR)pData; - unsigned int value; - int bytes; - - /* - * need not write 0xFFFFFFFF because write requires an erase and erase will - * make whole sector 0xFFFFFFFF. - */ - - if (0xFF == ulData) - return STATUS_SUCCESS; - - /* DumpDebug(NVM_RW,("flashWrite ====>\n")); */ - - value = (FLASH_CMD_WRITE_ENABLE << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write enable in FLASH_SPI_CMDQ_REG register fails"); - return STATUS_SUCCESS; - } - if (wrm(Adapter, FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DATA Write on FLASH_SPI_WRITEQ_REG fails"); - return STATUS_FAILURE; - } - value = (0x02000000 | (uiOffset & 0xFFFFFF)); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programming of FLASH_SPI_CMDQ_REG fails"); - return STATUS_FAILURE; - } - - /* msleep(1); */ - - do { - value = (FLASH_CMD_STATUS_REG_READ << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); - return STATUS_FAILURE; - } - /* __udelay(1); */ - bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)); - if (bytes < 0) { - uiStatus = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails"); - return uiStatus; - } - - iRetries--; - if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) - udelay(1000); - - } while ((uiStatus & 0x1) && (iRetries > 0)); - - if (uiStatus & 0x1) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times."); - return STATUS_FAILURE; - } - - return STATUS_SUCCESS; -} -/* - * Procedure: flashWriteStatus - * - * Description: Performs write to flash with write done status check - * - * Arguments: - * Adapter - ptr to Adapter object instance - * uiOffset - Offset of the flash where data needs to be written to. - * pData - Address of the Data to be written. - * Returns: - * OSAL_STATUS_CODE - * - */ - -static int flashWriteStatus(struct bcm_mini_adapter *Adapter, - unsigned int uiOffset, - PVOID pData) -{ - unsigned int uiStatus = 0; - int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ - /* unsigned int uiReadBack = 0; */ - unsigned int value; - unsigned int uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; - int bytes; - - /* - * need not write 0xFFFFFFFF because write requires an erase and erase will - * make whole sector 0xFFFFFFFF. - */ - if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE)) - return 0; - - value = (FLASH_CMD_WRITE_ENABLE << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write Enable of FLASH_SPI_CMDQ_REG fails"); - return STATUS_FAILURE; - } - - if (wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Data write fails..."); - return STATUS_FAILURE; - } - /* __udelay(1); */ - - do { - value = (FLASH_CMD_STATUS_REG_READ << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); - return STATUS_FAILURE; - } - /* __udelay(1); */ - bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)); - if (bytes < 0) { - uiStatus = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails"); - return uiStatus; - } - iRetries--; - /* this will ensure that in there will be no changes in the current path. - * currently one rdm/wrm takes 125 us. - * Hence 125 *2 * FLASH_PER_RETRIES_DELAY >3 ms(worst case delay) - * Hence current implementation cycle will intoduce no delay in current path - */ - if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) - udelay(1000); - - } while ((uiStatus & 0x1) && (iRetries > 0)); - - if (uiStatus & 0x1) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times."); - return STATUS_FAILURE; - } - - return STATUS_SUCCESS; -} - -/* - * Procedure: BcmRestoreBlockProtectStatus - * - * Description: Restores the original block protection status. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * ulWriteStatus -Original status - * Returns: - * <VOID> - * - */ - -static VOID BcmRestoreBlockProtectStatus(struct bcm_mini_adapter *Adapter, ULONG ulWriteStatus) -{ - unsigned int value; - - value = (FLASH_CMD_WRITE_ENABLE << 24); - wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); - - udelay(20); - value = (FLASH_CMD_STATUS_REG_WRITE << 24) | (ulWriteStatus << 16); - wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); - udelay(20); -} - -/* - * Procedure: BcmFlashUnProtectBlock - * - * Description: UnProtects appropriate blocks for writing. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * uiOffset - Offset of the flash where data needs to be written to. This should be Sector aligned. - * Returns: - * ULONG - Status value before UnProtect. - * - */ - -static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter, unsigned int uiOffset, unsigned int uiLength) -{ - ULONG ulStatus = 0; - ULONG ulWriteStatus = 0; - unsigned int value; - - uiOffset = uiOffset&0x000FFFFF; - /* - * Implemented only for 1MB Flash parts. - */ - if (FLASH_PART_SST25VF080B == Adapter->ulFlashID) { - /* - * Get Current BP status. - */ - value = (FLASH_CMD_STATUS_REG_READ << 24); - wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); - udelay(10); - /* - * Read status will be WWXXYYZZ. We have to take only WW. - */ - rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulStatus, sizeof(ulStatus)); - ulStatus >>= 24; - ulWriteStatus = ulStatus; - /* - * Bits [5-2] give current block level protection status. - * Bit5: BP3 - DONT CARE - * BP2-BP0: 0 - NO PROTECTION, 1 - UPPER 1/16, 2 - UPPER 1/8, 3 - UPPER 1/4 - * 4 - UPPER 1/2. 5 to 7 - ALL BLOCKS - */ - - if (ulStatus) { - if ((uiOffset+uiLength) <= 0x80000) { - /* - * Offset comes in lower half of 1MB. Protect the upper half. - * Clear BP1 and BP0 and set BP2. - */ - ulWriteStatus |= (0x4<<2); - ulWriteStatus &= ~(0x3<<2); - } else if ((uiOffset + uiLength) <= 0xC0000) { - /* - * Offset comes below Upper 1/4. Upper 1/4 can be protected. - * Clear BP2 and set BP1 and BP0. - */ - ulWriteStatus |= (0x3<<2); - ulWriteStatus &= ~(0x1<<4); - } else if ((uiOffset + uiLength) <= 0xE0000) { - /* - * Offset comes below Upper 1/8. Upper 1/8 can be protected. - * Clear BP2 and BP0 and set BP1 - */ - ulWriteStatus |= (0x1<<3); - ulWriteStatus &= ~(0x5<<2); - } else if ((uiOffset + uiLength) <= 0xF0000) { - /* - * Offset comes below Upper 1/16. Only upper 1/16 can be protected. - * Set BP0 and Clear BP2,BP1. - */ - ulWriteStatus |= (0x1<<2); - ulWriteStatus &= ~(0x3<<3); - } else { - /* - * Unblock all. - * Clear BP2,BP1 and BP0. - */ - ulWriteStatus &= ~(0x7<<2); - } - - value = (FLASH_CMD_WRITE_ENABLE << 24); - wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); - udelay(20); - value = (FLASH_CMD_STATUS_REG_WRITE << 24) | (ulWriteStatus << 16); - wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); - udelay(20); - } - } - return ulStatus; -} - -static int bulk_read_complete_sector(struct bcm_mini_adapter *ad, - UCHAR read_bk[], - PCHAR tmpbuff, - unsigned int offset, - unsigned int partoff) -{ - unsigned int i; - int j; - int bulk_read_stat; - FP_FLASH_WRITE_STATUS writef = - ad->fpFlashWriteWithStatusCheck; - - for (i = 0; i < ad->uiSectorSize; i += MAX_RW_SIZE) { - bulk_read_stat = BeceemFlashBulkRead(ad, - (PUINT)read_bk, - offset + i, - MAX_RW_SIZE); - - if (bulk_read_stat != STATUS_SUCCESS) - continue; - - if (ad->ulFlashWriteSize == 1) { - for (j = 0; j < 16; j++) { - if ((read_bk[j] != tmpbuff[i + j]) && - (STATUS_SUCCESS != (*writef)(ad, partoff + i + j, &tmpbuff[i + j]))) { - return STATUS_FAILURE; - } - } - } else { - if ((memcmp(read_bk, &tmpbuff[i], MAX_RW_SIZE)) && - (STATUS_SUCCESS != (*writef)(ad, partoff + i, &tmpbuff[i]))) { - return STATUS_FAILURE; - } - } - } - - return STATUS_SUCCESS; -} - -/* - * Procedure: BeceemFlashBulkWrite - * - * Description: Performs write to the flash - * - * Arguments: - * Adapter - ptr to Adapter object instance - * pBuffer - Data to be written. - * uiOffset - Offset of the flash where data needs to be written to. - * uiNumBytes - Number of bytes to be written. - * bVerify - read verify flag. - * Returns: - * OSAL_STATUS_CODE - * - */ - -static int BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - unsigned int uiOffset, - unsigned int uiNumBytes, - bool bVerify) -{ - PCHAR pTempBuff = NULL; - PUCHAR pcBuffer = (PUCHAR)pBuffer; - unsigned int uiIndex = 0; - unsigned int uiOffsetFromSectStart = 0; - unsigned int uiSectAlignAddr = 0; - unsigned int uiCurrSectOffsetAddr = 0; - unsigned int uiSectBoundary = 0; - unsigned int uiNumSectTobeRead = 0; - UCHAR ucReadBk[16] = {0}; - ULONG ulStatus = 0; - int Status = STATUS_SUCCESS; - unsigned int uiTemp = 0; - unsigned int index = 0; - unsigned int uiPartOffset = 0; - - #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) - Status = bcmflash_raw_write((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes); - return Status; - #endif - - uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1); - - /* Adding flash Base address - * uiOffset = uiOffset + GetFlashBaseAddr(Adapter); - */ - - uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); - uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1); - uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize; - - pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL); - if (!pTempBuff) - goto BeceemFlashBulkWrite_EXIT; - /* - * check if the data to be written is overlapped across sectors - */ - if (uiOffset+uiNumBytes < uiSectBoundary) { - uiNumSectTobeRead = 1; - } else { - /* Number of sectors = Last sector start address/First sector start address */ - uiNumSectTobeRead = (uiCurrSectOffsetAddr + uiNumBytes) / Adapter->uiSectorSize; - if ((uiCurrSectOffsetAddr + uiNumBytes)%Adapter->uiSectorSize) - uiNumSectTobeRead++; - } - /* Check whether Requested sector is writable or not in case of flash2x write. But if write call is - * for DSD calibration, allow it without checking of sector permission - */ - - if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == false)) { - index = 0; - uiTemp = uiNumSectTobeRead; - while (uiTemp) { - if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == false) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Sector Starting at offset <0X%X> is not writable", - (uiOffsetFromSectStart + index * Adapter->uiSectorSize)); - Status = SECTOR_IS_NOT_WRITABLE; - goto BeceemFlashBulkWrite_EXIT; - } - uiTemp = uiTemp - 1; - index = index + 1; - } - } - Adapter->SelectedChip = RESET_CHIP_SELECT; - while (uiNumSectTobeRead) { - /* do_gettimeofday(&tv1); - * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\nTime In start of write :%ld ms\n",(tv1.tv_sec *1000 + tv1.tv_usec /1000)); - */ - uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); - - BcmDoChipSelect(Adapter, uiSectAlignAddr); - - if (0 != BeceemFlashBulkRead(Adapter, - (PUINT)pTempBuff, - uiOffsetFromSectStart, - Adapter->uiSectorSize)) { - Status = -1; - goto BeceemFlashBulkWrite_EXIT; - } - - /* do_gettimeofday(&tr); - * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Read :%ld ms\n", (tr.tv_sec *1000 + tr.tv_usec/1000) - (tv1.tv_sec *1000 + tv1.tv_usec/1000)); - */ - ulStatus = BcmFlashUnProtectBlock(Adapter, uiSectAlignAddr, Adapter->uiSectorSize); - - if (uiNumSectTobeRead > 1) { - memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)); - pcBuffer += ((uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr))); - uiNumBytes -= (uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)); - } else { - memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiNumBytes); - } - - if (IsFlash2x(Adapter)) - SaveHeaderIfPresent(Adapter, (PUCHAR)pTempBuff, uiOffsetFromSectStart); - - FlashSectorErase(Adapter, uiPartOffset, 1); - /* do_gettimeofday(&te); - * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Erase :%ld ms\n", (te.tv_sec *1000 + te.tv_usec/1000) - (tr.tv_sec *1000 + tr.tv_usec/1000)); - */ - for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += Adapter->ulFlashWriteSize) { - if (Adapter->device_removed) { - Status = -1; - goto BeceemFlashBulkWrite_EXIT; - } - - if (STATUS_SUCCESS != (*Adapter->fpFlashWrite)(Adapter, uiPartOffset + uiIndex, (&pTempBuff[uiIndex]))) { - Status = -1; - goto BeceemFlashBulkWrite_EXIT; - } - } - - /* do_gettimeofday(&tw); - * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash :%ld ms\n", (tw.tv_sec *1000 + tw.tv_usec/1000) - (te.tv_sec *1000 + te.tv_usec/1000)); - */ - - if (STATUS_FAILURE == bulk_read_complete_sector(Adapter, - ucReadBk, - pTempBuff, - uiOffsetFromSectStart, - uiPartOffset)) { - Status = STATUS_FAILURE; - goto BeceemFlashBulkWrite_EXIT; - } - - /* do_gettimeofday(&twv); - * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash verification :%ld ms\n", (twv.tv_sec *1000 + twv.tv_usec/1000) - (tw.tv_sec *1000 + tw.tv_usec/1000)); - */ - if (ulStatus) { - BcmRestoreBlockProtectStatus(Adapter, ulStatus); - ulStatus = 0; - } - - uiCurrSectOffsetAddr = 0; - uiSectAlignAddr = uiSectBoundary; - uiSectBoundary += Adapter->uiSectorSize; - uiOffsetFromSectStart += Adapter->uiSectorSize; - uiNumSectTobeRead--; - } - /* do_gettimeofday(&tv2); - * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Time after Write :%ld ms\n",(tv2.tv_sec *1000 + tv2.tv_usec/1000)); - * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by in Write is :%ld ms\n", (tv2.tv_sec *1000 + tv2.tv_usec/1000) - (tv1.tv_sec *1000 + tv1.tv_usec/1000)); - * - * Cleanup. - */ -BeceemFlashBulkWrite_EXIT: - if (ulStatus) - BcmRestoreBlockProtectStatus(Adapter, ulStatus); - - kfree(pTempBuff); - - Adapter->SelectedChip = RESET_CHIP_SELECT; - return Status; -} - -/* - * Procedure: BeceemFlashBulkWriteStatus - * - * Description: Writes to Flash. Checks the SPI status after each write. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * pBuffer - Data to be written. - * uiOffset - Offset of the flash where data needs to be written to. - * uiNumBytes - Number of bytes to be written. - * bVerify - read verify flag. - * Returns: - * OSAL_STATUS_CODE - * - */ - -static int BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - unsigned int uiOffset, - unsigned int uiNumBytes, - bool bVerify) -{ - PCHAR pTempBuff = NULL; - PUCHAR pcBuffer = (PUCHAR)pBuffer; - unsigned int uiIndex = 0; - unsigned int uiOffsetFromSectStart = 0; - unsigned int uiSectAlignAddr = 0; - unsigned int uiCurrSectOffsetAddr = 0; - unsigned int uiSectBoundary = 0; - unsigned int uiNumSectTobeRead = 0; - UCHAR ucReadBk[16] = {0}; - ULONG ulStatus = 0; - unsigned int Status = STATUS_SUCCESS; - unsigned int uiTemp = 0; - unsigned int index = 0; - unsigned int uiPartOffset = 0; - - uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1); - - /* uiOffset += Adapter->ulFlashCalStart; - * Adding flash Base address - * uiOffset = uiOffset + GetFlashBaseAddr(Adapter); - */ - uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); - uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1); - uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize; - - pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL); - if (!pTempBuff) - goto BeceemFlashBulkWriteStatus_EXIT; - - /* - * check if the data to be written is overlapped across sectors - */ - if (uiOffset+uiNumBytes < uiSectBoundary) { - uiNumSectTobeRead = 1; - } else { - /* Number of sectors = Last sector start address/First sector start address */ - uiNumSectTobeRead = (uiCurrSectOffsetAddr + uiNumBytes) / Adapter->uiSectorSize; - if ((uiCurrSectOffsetAddr + uiNumBytes)%Adapter->uiSectorSize) - uiNumSectTobeRead++; - } - - if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == false)) { - index = 0; - uiTemp = uiNumSectTobeRead; - while (uiTemp) { - if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == false) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Sector Starting at offset <0X%x> is not writable", - (uiOffsetFromSectStart + index * Adapter->uiSectorSize)); - Status = SECTOR_IS_NOT_WRITABLE; - goto BeceemFlashBulkWriteStatus_EXIT; - } - uiTemp = uiTemp - 1; - index = index + 1; - } - } - - Adapter->SelectedChip = RESET_CHIP_SELECT; - while (uiNumSectTobeRead) { - uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); - - BcmDoChipSelect(Adapter, uiSectAlignAddr); - if (0 != BeceemFlashBulkRead(Adapter, - (PUINT)pTempBuff, - uiOffsetFromSectStart, - Adapter->uiSectorSize)) { - Status = -1; - goto BeceemFlashBulkWriteStatus_EXIT; - } - - ulStatus = BcmFlashUnProtectBlock(Adapter, uiOffsetFromSectStart, Adapter->uiSectorSize); - - if (uiNumSectTobeRead > 1) { - memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)); - pcBuffer += ((uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr))); - uiNumBytes -= (uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)); - } else { - memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiNumBytes); - } - - if (IsFlash2x(Adapter)) - SaveHeaderIfPresent(Adapter, (PUCHAR)pTempBuff, uiOffsetFromSectStart); - - FlashSectorErase(Adapter, uiPartOffset, 1); - - for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += Adapter->ulFlashWriteSize) { - if (Adapter->device_removed) { - Status = -1; - goto BeceemFlashBulkWriteStatus_EXIT; - } - - if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset+uiIndex, &pTempBuff[uiIndex])) { - Status = -1; - goto BeceemFlashBulkWriteStatus_EXIT; - } - } - - if (bVerify) { - for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += MAX_RW_SIZE) { - if (STATUS_SUCCESS == BeceemFlashBulkRead(Adapter, (PUINT)ucReadBk, uiOffsetFromSectStart + uiIndex, MAX_RW_SIZE)) { - if (memcmp(ucReadBk, &pTempBuff[uiIndex], MAX_RW_SIZE)) { - Status = STATUS_FAILURE; - goto BeceemFlashBulkWriteStatus_EXIT; - } - } - } - } - - if (ulStatus) { - BcmRestoreBlockProtectStatus(Adapter, ulStatus); - ulStatus = 0; - } - - uiCurrSectOffsetAddr = 0; - uiSectAlignAddr = uiSectBoundary; - uiSectBoundary += Adapter->uiSectorSize; - uiOffsetFromSectStart += Adapter->uiSectorSize; - uiNumSectTobeRead--; - } -/* - * Cleanup. - */ -BeceemFlashBulkWriteStatus_EXIT: - if (ulStatus) - BcmRestoreBlockProtectStatus(Adapter, ulStatus); - - kfree(pTempBuff); - Adapter->SelectedChip = RESET_CHIP_SELECT; - return Status; -} - -/* - * Procedure: PropagateCalParamsFromFlashToMemory - * - * Description: Dumps the calibration section of EEPROM to DDR. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * Returns: - * OSAL_STATUS_CODE - * - */ - -int PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter) -{ - PCHAR pBuff, pPtr; - unsigned int uiEepromSize = 0; - unsigned int uiBytesToCopy = 0; - /* unsigned int uiIndex = 0; */ - unsigned int uiCalStartAddr = EEPROM_CALPARAM_START; - unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; - unsigned int value; - int Status = 0; - - /* - * Write the signature first. This will ensure firmware does not access EEPROM. - */ - value = 0xbeadbead; - wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value)); - value = 0xbeadbead; - wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value)); - - if (0 != BeceemNVMRead(Adapter, &uiEepromSize, EEPROM_SIZE_OFFSET, 4)) - return -1; - - uiEepromSize = ntohl(uiEepromSize); - uiEepromSize >>= 16; - - /* - * subtract the auto init section size - */ - uiEepromSize -= EEPROM_CALPARAM_START; - - if (uiEepromSize > 1024 * 1024) - return -1; - - pBuff = kmalloc(uiEepromSize, GFP_KERNEL); - if (pBuff == NULL) - return -ENOMEM; - - if (0 != BeceemNVMRead(Adapter, (PUINT)pBuff, uiCalStartAddr, uiEepromSize)) { - kfree(pBuff); - return -1; - } - - pPtr = pBuff; - - uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize); - - while (uiBytesToCopy) { - Status = wrm(Adapter, uiMemoryLoc, (PCHAR)pPtr, uiBytesToCopy); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "wrm failed with status :%d", Status); - break; - } - - pPtr += uiBytesToCopy; - uiEepromSize -= uiBytesToCopy; - uiMemoryLoc += uiBytesToCopy; - uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize); - } - - kfree(pBuff); - return Status; -} - -/* - * Procedure: BeceemEEPROMReadBackandVerify - * - * Description: Read back the data written and verifies. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * pBuffer - Data to be written. - * uiOffset - Offset of the flash where data needs to be written to. - * uiNumBytes - Number of bytes to be written. - * Returns: - * OSAL_STATUS_CODE - * - */ - -static int BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - unsigned int uiOffset, - unsigned int uiNumBytes) -{ - unsigned int uiRdbk = 0; - unsigned int uiIndex = 0; - unsigned int uiData = 0; - unsigned int auiData[4] = {0}; - - while (uiNumBytes) { - if (Adapter->device_removed) - return -1; - - if (uiNumBytes >= MAX_RW_SIZE) { - /* for the requests more than or equal to MAX_RW_SIZE bytes, use bulk read function to make the access faster. */ - BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE); - - if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE)) { - /* re-write */ - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, MAX_RW_SIZE, false); - mdelay(3); - BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE); - - if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE)) - return -1; - } - uiOffset += MAX_RW_SIZE; - uiNumBytes -= MAX_RW_SIZE; - uiIndex += 4; - } else if (uiNumBytes >= 4) { - BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4); - if (uiData != pBuffer[uiIndex]) { - /* re-write */ - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, 4, false); - mdelay(3); - BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4); - if (uiData != pBuffer[uiIndex]) - return -1; - } - uiOffset += 4; - uiNumBytes -= 4; - uiIndex++; - } else { - /* Handle the reads less than 4 bytes... */ - uiData = 0; - memcpy(&uiData, ((PUCHAR)pBuffer) + (uiIndex * sizeof(unsigned int)), uiNumBytes); - BeceemEEPROMBulkRead(Adapter, &uiRdbk, uiOffset, 4); - - if (memcmp(&uiData, &uiRdbk, uiNumBytes)) - return -1; - - uiNumBytes = 0; - } - } - - return 0; -} - -static VOID BcmSwapWord(unsigned int *ptr1) -{ - unsigned int tempval = (unsigned int)*ptr1; - char *ptr2 = (char *)&tempval; - char *ptr = (char *)ptr1; - - ptr[0] = ptr2[3]; - ptr[1] = ptr2[2]; - ptr[2] = ptr2[1]; - ptr[3] = ptr2[0]; -} - -/* - * Procedure: BeceemEEPROMWritePage - * - * Description: Performs page write (16bytes) to the EEPROM - * - * Arguments: - * Adapter - ptr to Adapter object instance - * uiData - Data to be written. - * uiOffset - Offset of the EEPROM where data needs to be written to. - * Returns: - * OSAL_STATUS_CODE - * - */ - -static int BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, unsigned int uiData[], unsigned int uiOffset) -{ - unsigned int uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY; - unsigned int uiStatus = 0; - UCHAR uiEpromStatus = 0; - unsigned int value = 0; - - /* Flush the Write/Read/Cmd queues. */ - value = (EEPROM_WRITE_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH | EEPROM_READ_QUEUE_FLUSH); - wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); - value = 0; - wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); - - /* Clear the Empty/Avail/Full bits. After this it has been confirmed - * that the bit was cleared by reading back the register. See NOTE below. - * We also clear the Read queues as we do a EEPROM status register read - * later. - */ - value = (EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL | EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL); - wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - - /* Enable write */ - value = EEPROM_WRITE_ENABLE; - wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); - - /* We can write back to back 8bits * 16 into the queue and as we have - * checked for the queue to be empty we can write in a burst. - */ - - value = uiData[0]; - BcmSwapWord(&value); - wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); - - value = uiData[1]; - BcmSwapWord(&value); - wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); - - value = uiData[2]; - BcmSwapWord(&value); - wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); - - value = uiData[3]; - BcmSwapWord(&value); - wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); - - /* NOTE : After this write, on readback of EEPROM_SPI_Q_STATUS1_REG - * shows that we see 7 for the EEPROM data write. Which means that - * queue got full, also space is available as well as the queue is empty. - * This may happen in sequence. - */ - value = EEPROM_16_BYTE_PAGE_WRITE | uiOffset; - wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); - - /* Ideally we should loop here without tries and eventually succeed. - * What we are checking if the previous write has completed, and this - * may take time. We should wait till the Empty bit is set. - */ - uiStatus = 0; - rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus)); - while ((uiStatus & EEPROM_WRITE_QUEUE_EMPTY) == 0) { - uiRetries--; - if (uiRetries == 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, %d retries failed.\n", uiStatus, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY); - return STATUS_FAILURE; - } - - if (!(uiRetries%RETRIES_PER_DELAY)) - udelay(1000); - - uiStatus = 0; - rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus)); - if (Adapter->device_removed == TRUE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem got removed hence exiting from loop...."); - return -ENODEV; - } - } - - if (uiRetries != 0) { - /* Clear the ones that are set - either, Empty/Full/Avail bits */ - value = (uiStatus & (EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL)); - wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - } - - /* Here we should check if the EEPROM status register is correct before - * proceeding. Bit 0 in the EEPROM Status register should be 0 before - * we proceed further. A 1 at Bit 0 indicates that the EEPROM is busy - * with the previous write. Note also that issuing this read finally - * means the previous write to the EEPROM has completed. - */ - uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY; - uiEpromStatus = 0; - while (uiRetries != 0) { - uiEpromStatus = ReadEEPROMStatusRegister(Adapter); - if (Adapter->device_removed == TRUE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting from loop..."); - return -ENODEV; - } - if ((EEPROM_STATUS_REG_WRITE_BUSY & uiEpromStatus) == 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM status register = %x tries = %d\n", uiEpromStatus, (MAX_EEPROM_RETRIES * RETRIES_PER_DELAY - uiRetries)); - return STATUS_SUCCESS; - } - uiRetries--; - if (uiRetries == 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, for EEPROM status read %d retries failed.\n", uiEpromStatus, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY); - return STATUS_FAILURE; - } - uiEpromStatus = 0; - if (!(uiRetries%RETRIES_PER_DELAY)) - udelay(1000); - } - - return STATUS_SUCCESS; -} /* BeceemEEPROMWritePage */ - -/* - * Procedure: BeceemEEPROMBulkWrite - * - * Description: Performs write to the EEPROM - * - * Arguments: - * Adapter - ptr to Adapter object instance - * pBuffer - Data to be written. - * uiOffset - Offset of the EEPROM where data needs to be written to. - * uiNumBytes - Number of bytes to be written. - * bVerify - read verify flag. - * Returns: - * OSAL_STATUS_CODE - * - */ - -int BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter, - PUCHAR pBuffer, - unsigned int uiOffset, - unsigned int uiNumBytes, - bool bVerify) -{ - unsigned int uiBytesToCopy = uiNumBytes; - /* unsigned int uiRdbk = 0; */ - unsigned int uiData[4] = {0}; - unsigned int uiIndex = 0; - unsigned int uiTempOffset = 0; - unsigned int uiExtraBytes = 0; - /* PUINT puiBuffer = (PUINT)pBuffer; - * int value; - */ - - if (uiOffset % MAX_RW_SIZE && uiBytesToCopy) { - uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE); - uiExtraBytes = uiOffset - uiTempOffset; - - BeceemEEPROMBulkRead(Adapter, &uiData[0], uiTempOffset, MAX_RW_SIZE); - - if (uiBytesToCopy >= (16 - uiExtraBytes)) { - memcpy((((PUCHAR)&uiData[0]) + uiExtraBytes), pBuffer, MAX_RW_SIZE - uiExtraBytes); - - if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiTempOffset)) - return STATUS_FAILURE; - - uiBytesToCopy -= (MAX_RW_SIZE - uiExtraBytes); - uiIndex += (MAX_RW_SIZE - uiExtraBytes); - uiOffset += (MAX_RW_SIZE - uiExtraBytes); - } else { - memcpy((((PUCHAR)&uiData[0]) + uiExtraBytes), pBuffer, uiBytesToCopy); - - if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiTempOffset)) - return STATUS_FAILURE; - - uiIndex += uiBytesToCopy; - uiOffset += uiBytesToCopy; - uiBytesToCopy = 0; - } - } - - while (uiBytesToCopy) { - if (Adapter->device_removed) - return -1; - - if (uiBytesToCopy >= MAX_RW_SIZE) { - if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, (PUINT) &pBuffer[uiIndex], uiOffset)) - return STATUS_FAILURE; - - uiIndex += MAX_RW_SIZE; - uiOffset += MAX_RW_SIZE; - uiBytesToCopy -= MAX_RW_SIZE; - } else { - /* - * To program non 16byte aligned data, read 16byte and then update. - */ - BeceemEEPROMBulkRead(Adapter, &uiData[0], uiOffset, 16); - memcpy(&uiData[0], pBuffer + uiIndex, uiBytesToCopy); - - if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiOffset)) - return STATUS_FAILURE; - - uiBytesToCopy = 0; - } - } - - return 0; -} - -/* - * Procedure: BeceemNVMRead - * - * Description: Reads n number of bytes from NVM. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * pBuffer - Buffer to store the data read from NVM - * uiOffset - Offset of NVM from where data should be read - * uiNumBytes - Number of bytes to be read from the NVM. - * - * Returns: - * OSAL_STATUS_SUCCESS - if NVM read is successful. - * <FAILURE> - if failed. - */ - -int BeceemNVMRead(struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - unsigned int uiOffset, - unsigned int uiNumBytes) -{ - int Status = 0; - - #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) - unsigned int uiTemp = 0, value; - #endif - - if (Adapter->eNVMType == NVM_FLASH) { - if (Adapter->bFlashRawRead == false) { - if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD)) - return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, Adapter->eActiveDSD, uiOffset, uiNumBytes); - - uiOffset = uiOffset + Adapter->ulFlashCalStart; - } - - #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) - Status = bcmflash_raw_read((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes); - #else - rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - value = 0; - wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); - Status = BeceemFlashBulkRead(Adapter, - pBuffer, - uiOffset, - uiNumBytes); - wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - #endif - } else if (Adapter->eNVMType == NVM_EEPROM) { - Status = BeceemEEPROMBulkRead(Adapter, - pBuffer, - uiOffset, - uiNumBytes); - } else { - Status = -1; - } - - return Status; -} - -/* - * Procedure: BeceemNVMWrite - * - * Description: Writes n number of bytes to NVM. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * pBuffer - Buffer contains the data to be written. - * uiOffset - Offset of NVM where data to be written to. - * uiNumBytes - Number of bytes to be written.. - * - * Returns: - * OSAL_STATUS_SUCCESS - if NVM write is successful. - * <FAILURE> - if failed. - */ - -int BeceemNVMWrite(struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - unsigned int uiOffset, - unsigned int uiNumBytes, - bool bVerify) -{ - int Status = 0; - unsigned int uiTemp = 0; - unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; - unsigned int uiIndex = 0; - - #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) - unsigned int value; - #endif - - unsigned int uiFlashOffset = 0; - - if (Adapter->eNVMType == NVM_FLASH) { - if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD)) - Status = vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, Adapter->eActiveDSD, uiOffset, uiNumBytes, bVerify); - else { - uiFlashOffset = uiOffset + Adapter->ulFlashCalStart; - - #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) - Status = bcmflash_raw_write((uiFlashOffset / FLASH_PART_SIZE), (uiFlashOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes); - #else - rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - value = 0; - wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); - - if (Adapter->bStatusWrite == TRUE) - Status = BeceemFlashBulkWriteStatus(Adapter, - pBuffer, - uiFlashOffset, - uiNumBytes , - bVerify); - else - - Status = BeceemFlashBulkWrite(Adapter, - pBuffer, - uiFlashOffset, - uiNumBytes, - bVerify); - #endif - } - - if (uiOffset >= EEPROM_CALPARAM_START) { - uiMemoryLoc += (uiOffset - EEPROM_CALPARAM_START); - while (uiNumBytes) { - if (uiNumBytes > BUFFER_4K) { - wrm(Adapter, (uiMemoryLoc+uiIndex), (PCHAR)(pBuffer + (uiIndex / 4)), BUFFER_4K); - uiNumBytes -= BUFFER_4K; - uiIndex += BUFFER_4K; - } else { - wrm(Adapter, uiMemoryLoc+uiIndex, (PCHAR)(pBuffer + (uiIndex / 4)), uiNumBytes); - uiNumBytes = 0; - break; - } - } - } else { - if ((uiOffset + uiNumBytes) > EEPROM_CALPARAM_START) { - ULONG ulBytesTobeSkipped = 0; - PUCHAR pcBuffer = (PUCHAR)pBuffer; /* char pointer to take care of odd byte cases. */ - - uiNumBytes -= (EEPROM_CALPARAM_START - uiOffset); - ulBytesTobeSkipped += (EEPROM_CALPARAM_START - uiOffset); - uiOffset += (EEPROM_CALPARAM_START - uiOffset); - while (uiNumBytes) { - if (uiNumBytes > BUFFER_4K) { - wrm(Adapter, uiMemoryLoc + uiIndex, (PCHAR)&pcBuffer[ulBytesTobeSkipped + uiIndex], BUFFER_4K); - uiNumBytes -= BUFFER_4K; - uiIndex += BUFFER_4K; - } else { - wrm(Adapter, uiMemoryLoc + uiIndex, (PCHAR)&pcBuffer[ulBytesTobeSkipped + uiIndex], uiNumBytes); - uiNumBytes = 0; - break; - } - } - } - } - /* restore the values. */ - wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - } else if (Adapter->eNVMType == NVM_EEPROM) { - Status = BeceemEEPROMBulkWrite(Adapter, - (PUCHAR)pBuffer, - uiOffset, - uiNumBytes, - bVerify); - if (bVerify) - Status = BeceemEEPROMReadBackandVerify(Adapter, (PUINT)pBuffer, uiOffset, uiNumBytes); - } else { - Status = -1; - } - return Status; -} - -/* - * Procedure: BcmUpdateSectorSize - * - * Description: Updates the sector size to FLASH. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * uiSectorSize - sector size - * - * Returns: - * OSAL_STATUS_SUCCESS - if NVM write is successful. - * <FAILURE> - if failed. - */ - -int BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter, unsigned int uiSectorSize) -{ - int Status = -1; - struct bcm_flash_cs_info sFlashCsInfo = {0}; - unsigned int uiTemp = 0; - unsigned int uiSectorSig = 0; - unsigned int uiCurrentSectorSize = 0; - unsigned int value; - - rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - value = 0; - wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); - - /* - * Before updating the sector size in the reserved area, check if already present. - */ - BeceemFlashBulkRead(Adapter, (PUINT)&sFlashCsInfo, Adapter->ulFlashControlSectionStart, sizeof(sFlashCsInfo)); - uiSectorSig = ntohl(sFlashCsInfo.FlashSectorSizeSig); - uiCurrentSectorSize = ntohl(sFlashCsInfo.FlashSectorSize); - - if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) { - if ((uiCurrentSectorSize <= MAX_SECTOR_SIZE) && (uiCurrentSectorSize >= MIN_SECTOR_SIZE)) { - if (uiSectorSize == uiCurrentSectorSize) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Provided sector size is same as programmed in Flash"); - Status = STATUS_SUCCESS; - goto Restore; - } - } - } - - if ((uiSectorSize <= MAX_SECTOR_SIZE) && (uiSectorSize >= MIN_SECTOR_SIZE)) { - sFlashCsInfo.FlashSectorSize = htonl(uiSectorSize); - sFlashCsInfo.FlashSectorSizeSig = htonl(FLASH_SECTOR_SIZE_SIG); - - Status = BeceemFlashBulkWrite(Adapter, - (PUINT)&sFlashCsInfo, - Adapter->ulFlashControlSectionStart, - sizeof(sFlashCsInfo), - TRUE); - } - -Restore: - /* restore the values. */ - wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - - return Status; -} - -/* - * Procedure: BcmGetFlashSectorSize - * - * Description: Finds the sector size of the FLASH. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * - * Returns: - * unsigned int - sector size. - * - */ - -static unsigned int BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, unsigned int FlashSectorSizeSig, unsigned int FlashSectorSize) -{ - unsigned int uiSectorSize = 0; - unsigned int uiSectorSig = 0; - - if (Adapter->bSectorSizeOverride && - (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && - Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)) { - Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG; - } else { - uiSectorSig = FlashSectorSizeSig; - - if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) { - uiSectorSize = FlashSectorSize; - /* - * If the sector size stored in the FLASH makes sense then use it. - */ - if (uiSectorSize <= MAX_SECTOR_SIZE && uiSectorSize >= MIN_SECTOR_SIZE) { - Adapter->uiSectorSize = uiSectorSize; - } else if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && - Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE) { - /* No valid size in FLASH, check if Config file has it. */ - Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG; - } else { - /* Init to Default, if none of the above works. */ - Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE; - } - } else { - if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && - Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE) - Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG; - else - Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE; - } - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector size :%x\n", Adapter->uiSectorSize); - - return Adapter->uiSectorSize; -} - -/* - * Procedure: BcmInitEEPROMQueues - * - * Description: Initialization of EEPROM queues. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * - * Returns: - * <OSAL_STATUS_CODE> - */ - -static int BcmInitEEPROMQueues(struct bcm_mini_adapter *Adapter) -{ - unsigned int value = 0; - /* CHIP Bug : Clear the Avail bits on the Read queue. The default - * value on this register is supposed to be 0x00001102. - * But we get 0x00001122. - */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Fixing reset value on 0x0f003004 register\n"); - value = EEPROM_READ_DATA_AVAIL; - wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - - /* Flush the all the EEPROM queues. */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Flushing the queues\n"); - value = EEPROM_ALL_QUEUE_FLUSH; - wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); - - value = 0; - wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); - - /* Read the EEPROM Status Register. Just to see, no real purpose. */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "EEPROM Status register value = %x\n", ReadEEPROMStatusRegister(Adapter)); - - return STATUS_SUCCESS; -} /* BcmInitEEPROMQueues() */ - -/* - * Procedure: BcmInitNVM - * - * Description: Initialization of NVM, EEPROM size,FLASH size, sector size etc. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * - * Returns: - * <OSAL_STATUS_CODE> - */ - -int BcmInitNVM(struct bcm_mini_adapter *ps_adapter) -{ - BcmValidateNvmType(ps_adapter); - BcmInitEEPROMQueues(ps_adapter); - - if (ps_adapter->eNVMType == NVM_AUTODETECT) { - ps_adapter->eNVMType = BcmGetNvmType(ps_adapter); - if (ps_adapter->eNVMType == NVM_UNKNOWN) - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_PRINTK, 0, 0, "NVM Type is unknown!!\n"); - } else if (ps_adapter->eNVMType == NVM_FLASH) { - BcmGetFlashCSInfo(ps_adapter); - } - - BcmGetNvmSize(ps_adapter); - - return STATUS_SUCCESS; -} - -/* BcmGetNvmSize : set the EEPROM or flash size in Adapter. - * - * Input Parameter: - * Adapter data structure - * Return Value : - * 0. means success; - */ - -static int BcmGetNvmSize(struct bcm_mini_adapter *Adapter) -{ - if (Adapter->eNVMType == NVM_EEPROM) - Adapter->uiNVMDSDSize = BcmGetEEPROMSize(Adapter); - else if (Adapter->eNVMType == NVM_FLASH) - Adapter->uiNVMDSDSize = BcmGetFlashSize(Adapter); - - return 0; -} - -/* - * Procedure: BcmValidateNvm - * - * Description: Validates the NVM Type option selected against the device - * - * Arguments: - * Adapter - ptr to Adapter object instance - * - * Returns: - * <VOID> - */ - -static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter) -{ - /* - * if forcing the FLASH through CFG file, we should ensure device really has a FLASH. - * Accessing the FLASH address without the FLASH being present can cause hang/freeze etc. - * So if NVM_FLASH is selected for older chipsets, change it to AUTODETECT where EEPROM is 1st choice. - */ - - if (Adapter->eNVMType == NVM_FLASH && - Adapter->chip_id < 0xBECE3300) - Adapter->eNVMType = NVM_AUTODETECT; -} - -/* - * Procedure: BcmReadFlashRDID - * - * Description: Reads ID from Serial Flash - * - * Arguments: - * Adapter - ptr to Adapter object instance - * - * Returns: - * Flash ID - */ - -static ULONG BcmReadFlashRDID(struct bcm_mini_adapter *Adapter) -{ - ULONG ulRDID = 0; - unsigned int value; - - /* - * Read ID Instruction. - */ - value = (FLASH_CMD_READ_ID << 24); - wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); - - /* Delay */ - udelay(10); - - /* - * Read SPI READQ REG. The output will be WWXXYYZZ. - * The ID is 3Bytes long and is WWXXYY. ZZ needs to be Ignored. - */ - rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulRDID, sizeof(ulRDID)); - - return ulRDID >> 8; -} - -int BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) -{ - if (!psAdapter) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL"); - return -EINVAL; - } - psAdapter->psFlashCSInfo = kzalloc(sizeof(struct bcm_flash_cs_info), GFP_KERNEL); - if (psAdapter->psFlashCSInfo == NULL) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 1.x"); - return -ENOMEM; - } - - psAdapter->psFlash2xCSInfo = kzalloc(sizeof(struct bcm_flash2x_cs_info), GFP_KERNEL); - if (!psAdapter->psFlash2xCSInfo) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 2.x"); - kfree(psAdapter->psFlashCSInfo); - return -ENOMEM; - } - - psAdapter->psFlash2xVendorInfo = kzalloc(sizeof(struct bcm_flash2x_vendor_info), GFP_KERNEL); - if (!psAdapter->psFlash2xVendorInfo) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate Vendor Info Memory for Flash 2.x"); - kfree(psAdapter->psFlashCSInfo); - kfree(psAdapter->psFlash2xCSInfo); - return -ENOMEM; - } - - return STATUS_SUCCESS; -} - -int BcmDeAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) -{ - if (!psAdapter) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL"); - return -EINVAL; - } - kfree(psAdapter->psFlashCSInfo); - kfree(psAdapter->psFlash2xCSInfo); - kfree(psAdapter->psFlash2xVendorInfo); - return STATUS_SUCCESS; -} - -static int BcmDumpFlash2XCSStructure(struct bcm_flash2x_cs_info *psFlash2xCSInfo, struct bcm_mini_adapter *Adapter) -{ - unsigned int Index = 0; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "**********************FLASH2X CS Structure *******************"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x", (psFlash2xCSInfo->MagicNumber)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Major Version :%d", MAJOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Minor Version :%d", MINOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ISOImageMajorVersion:0x%x", (psFlash2xCSInfo->ISOImageVersion)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSIFirmwareMajorVersion :0x%x", (psFlash2xCSInfo->SCSIFirmwareVersion)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart1ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForScsiFirmware :0x%x", (psFlash2xCSInfo->OffsetFromZeroForScsiFirmware)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SizeOfScsiFirmware :0x%x", (psFlash2xCSInfo->SizeOfScsiFirmware)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart2ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDStart)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDEnd)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAStart)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAEnd)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionStart)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionData :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionData)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CDLessInactivityTimeout :0x%x", (psFlash2xCSInfo->CDLessInactivityTimeout)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "NewImageSignature :0x%x", (psFlash2xCSInfo->NewImageSignature)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSizeSig :0x%x", (psFlash2xCSInfo->FlashSectorSizeSig)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSize :0x%x", (psFlash2xCSInfo->FlashSectorSize)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashWriteSupportSize :0x%x", (psFlash2xCSInfo->FlashWriteSupportSize)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "TotalFlashSize :0x%X", (psFlash2xCSInfo->TotalFlashSize)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashBaseAddr :0x%x", (psFlash2xCSInfo->FlashBaseAddr)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashPartMaxSize :0x%x", (psFlash2xCSInfo->FlashPartMaxSize)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "IsCDLessDeviceBootSig :0x%x", (psFlash2xCSInfo->IsCDLessDeviceBootSig)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "MassStorageTimeout :0x%x", (psFlash2xCSInfo->MassStorageTimeout)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1Start)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1End)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2Start)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2End)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3Start)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3End)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1Start)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1End)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2Start)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2End)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3Start)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3End)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromDSDStartForDSDHeader :0x%x", (psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1Start)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1End)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2Start)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2End)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1Start)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1End)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2Start)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2End)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector Access Bit Map is Defined as :"); - - for (Index = 0; Index < (FLASH2X_TOTAL_SIZE / (DEFAULT_SECTOR_SIZE * 16)); Index++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectorAccessBitMap[%d] :0x%x", Index, - (psFlash2xCSInfo->SectorAccessBitMap[Index])); - - return STATUS_SUCCESS; -} - -static int ConvertEndianOf2XCSStructure(struct bcm_flash2x_cs_info *psFlash2xCSInfo) -{ - unsigned int Index = 0; - - psFlash2xCSInfo->MagicNumber = ntohl(psFlash2xCSInfo->MagicNumber); - psFlash2xCSInfo->FlashLayoutVersion = ntohl(psFlash2xCSInfo->FlashLayoutVersion); - /* psFlash2xCSInfo->FlashLayoutMinorVersion = ntohs(psFlash2xCSInfo->FlashLayoutMinorVersion); */ - psFlash2xCSInfo->ISOImageVersion = ntohl(psFlash2xCSInfo->ISOImageVersion); - psFlash2xCSInfo->SCSIFirmwareVersion = ntohl(psFlash2xCSInfo->SCSIFirmwareVersion); - psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage); - psFlash2xCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlash2xCSInfo->OffsetFromZeroForScsiFirmware); - psFlash2xCSInfo->SizeOfScsiFirmware = ntohl(psFlash2xCSInfo->SizeOfScsiFirmware); - psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage); - psFlash2xCSInfo->OffsetFromZeroForDSDStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDStart); - psFlash2xCSInfo->OffsetFromZeroForDSDEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDEnd); - psFlash2xCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAStart); - psFlash2xCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAEnd); - psFlash2xCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionStart); - psFlash2xCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionData); - psFlash2xCSInfo->CDLessInactivityTimeout = ntohl(psFlash2xCSInfo->CDLessInactivityTimeout); - psFlash2xCSInfo->NewImageSignature = ntohl(psFlash2xCSInfo->NewImageSignature); - psFlash2xCSInfo->FlashSectorSizeSig = ntohl(psFlash2xCSInfo->FlashSectorSizeSig); - psFlash2xCSInfo->FlashSectorSize = ntohl(psFlash2xCSInfo->FlashSectorSize); - psFlash2xCSInfo->FlashWriteSupportSize = ntohl(psFlash2xCSInfo->FlashWriteSupportSize); - psFlash2xCSInfo->TotalFlashSize = ntohl(psFlash2xCSInfo->TotalFlashSize); - psFlash2xCSInfo->FlashBaseAddr = ntohl(psFlash2xCSInfo->FlashBaseAddr); - psFlash2xCSInfo->FlashPartMaxSize = ntohl(psFlash2xCSInfo->FlashPartMaxSize); - psFlash2xCSInfo->IsCDLessDeviceBootSig = ntohl(psFlash2xCSInfo->IsCDLessDeviceBootSig); - psFlash2xCSInfo->MassStorageTimeout = ntohl(psFlash2xCSInfo->MassStorageTimeout); - psFlash2xCSInfo->OffsetISOImage1Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1Start); - psFlash2xCSInfo->OffsetISOImage1Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1End); - psFlash2xCSInfo->OffsetISOImage1Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2Start); - psFlash2xCSInfo->OffsetISOImage1Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2End); - psFlash2xCSInfo->OffsetISOImage1Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3Start); - psFlash2xCSInfo->OffsetISOImage1Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3End); - psFlash2xCSInfo->OffsetISOImage2Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1Start); - psFlash2xCSInfo->OffsetISOImage2Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1End); - psFlash2xCSInfo->OffsetISOImage2Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2Start); - psFlash2xCSInfo->OffsetISOImage2Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2End); - psFlash2xCSInfo->OffsetISOImage2Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3Start); - psFlash2xCSInfo->OffsetISOImage2Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3End); - psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader = ntohl(psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader); - psFlash2xCSInfo->OffsetFromZeroForDSD1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1Start); - psFlash2xCSInfo->OffsetFromZeroForDSD1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1End); - psFlash2xCSInfo->OffsetFromZeroForDSD2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2Start); - psFlash2xCSInfo->OffsetFromZeroForDSD2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2End); - psFlash2xCSInfo->OffsetFromZeroForVSA1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1Start); - psFlash2xCSInfo->OffsetFromZeroForVSA1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1End); - psFlash2xCSInfo->OffsetFromZeroForVSA2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2Start); - psFlash2xCSInfo->OffsetFromZeroForVSA2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2End); - - for (Index = 0; Index < (FLASH2X_TOTAL_SIZE / (DEFAULT_SECTOR_SIZE * 16)); Index++) - psFlash2xCSInfo->SectorAccessBitMap[Index] = ntohl(psFlash2xCSInfo->SectorAccessBitMap[Index]); - - return STATUS_SUCCESS; -} - -static int ConvertEndianOfCSStructure(struct bcm_flash_cs_info *psFlashCSInfo) -{ - /* unsigned int Index = 0; */ - psFlashCSInfo->MagicNumber = ntohl(psFlashCSInfo->MagicNumber); - psFlashCSInfo->FlashLayoutVersion = ntohl(psFlashCSInfo->FlashLayoutVersion); - psFlashCSInfo->ISOImageVersion = ntohl(psFlashCSInfo->ISOImageVersion); - /* won't convert according to old assumption */ - psFlashCSInfo->SCSIFirmwareVersion = (psFlashCSInfo->SCSIFirmwareVersion); - psFlashCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart1ISOImage); - psFlashCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlashCSInfo->OffsetFromZeroForScsiFirmware); - psFlashCSInfo->SizeOfScsiFirmware = ntohl(psFlashCSInfo->SizeOfScsiFirmware); - psFlashCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart2ISOImage); - psFlashCSInfo->OffsetFromZeroForCalibrationStart = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationStart); - psFlashCSInfo->OffsetFromZeroForCalibrationEnd = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationEnd); - psFlashCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlashCSInfo->OffsetFromZeroForVSAStart); - psFlashCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlashCSInfo->OffsetFromZeroForVSAEnd); - psFlashCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionStart); - psFlashCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionData); - psFlashCSInfo->CDLessInactivityTimeout = ntohl(psFlashCSInfo->CDLessInactivityTimeout); - psFlashCSInfo->NewImageSignature = ntohl(psFlashCSInfo->NewImageSignature); - psFlashCSInfo->FlashSectorSizeSig = ntohl(psFlashCSInfo->FlashSectorSizeSig); - psFlashCSInfo->FlashSectorSize = ntohl(psFlashCSInfo->FlashSectorSize); - psFlashCSInfo->FlashWriteSupportSize = ntohl(psFlashCSInfo->FlashWriteSupportSize); - psFlashCSInfo->TotalFlashSize = ntohl(psFlashCSInfo->TotalFlashSize); - psFlashCSInfo->FlashBaseAddr = ntohl(psFlashCSInfo->FlashBaseAddr); - psFlashCSInfo->FlashPartMaxSize = ntohl(psFlashCSInfo->FlashPartMaxSize); - psFlashCSInfo->IsCDLessDeviceBootSig = ntohl(psFlashCSInfo->IsCDLessDeviceBootSig); - psFlashCSInfo->MassStorageTimeout = ntohl(psFlashCSInfo->MassStorageTimeout); - - return STATUS_SUCCESS; -} - -static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section) -{ - return (Adapter->uiVendorExtnFlag && - (Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) && - (Adapter->psFlash2xVendorInfo->VendorSection[section].OffsetFromZeroForSectionStart != UNINIT_PTR_IN_CS)); -} - -static VOID UpdateVendorInfo(struct bcm_mini_adapter *Adapter) -{ - B_UINT32 i = 0; - unsigned int uiSizeSection = 0; - - Adapter->uiVendorExtnFlag = false; - - for (i = 0; i < TOTAL_SECTIONS; i++) - Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart = UNINIT_PTR_IN_CS; - - if (STATUS_SUCCESS != vendorextnGetSectionInfo(Adapter, Adapter->psFlash2xVendorInfo)) - return; - - i = 0; - while (i < TOTAL_SECTIONS) { - if (!(Adapter->psFlash2xVendorInfo->VendorSection[i].AccessFlags & FLASH2X_SECTION_PRESENT)) { - i++; - continue; - } - - Adapter->uiVendorExtnFlag = TRUE; - uiSizeSection = (Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionEnd - - Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart); - - switch (i) { - case DSD0: - if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header))) && - (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = UNINIT_PTR_IN_CS; - break; - - case DSD1: - if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header))) && - (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = UNINIT_PTR_IN_CS; - break; - - case DSD2: - if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header))) && - (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = UNINIT_PTR_IN_CS; - break; - case VSA0: - if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = UNINIT_PTR_IN_CS; - break; - - case VSA1: - if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = UNINIT_PTR_IN_CS; - break; - case VSA2: - if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = UNINIT_PTR_IN_CS; - break; - - default: - break; - } - i++; - } -} - -/* - * Procedure: BcmGetFlashCSInfo - * - * Description: Reads control structure and gets Cal section addresses. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * - * Returns: - * <VOID> - */ - -static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter) -{ - /* struct bcm_flash_cs_info sFlashCsInfo = {0}; */ - - #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) - unsigned int value; - #endif - - unsigned int uiFlashLayoutMajorVersion; - - Adapter->uiFlashLayoutMinorVersion = 0; - Adapter->uiFlashLayoutMajorVersion = 0; - Adapter->ulFlashControlSectionStart = FLASH_CS_INFO_START_ADDR; - - Adapter->uiFlashBaseAdd = 0; - Adapter->ulFlashCalStart = 0; - memset(Adapter->psFlashCSInfo, 0 , sizeof(struct bcm_flash_cs_info)); - memset(Adapter->psFlash2xCSInfo, 0 , sizeof(struct bcm_flash2x_cs_info)); - - if (!Adapter->bDDRInitDone) { - value = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT; - wrmalt(Adapter, 0xAF00A080, &value, sizeof(value)); - } - - /* Reading first 8 Bytes to get the Flash Layout - * MagicNumber(4 bytes) +FlashLayoutMinorVersion(2 Bytes) +FlashLayoutMajorVersion(2 Bytes) - */ - BeceemFlashBulkRead(Adapter, (PUINT)Adapter->psFlashCSInfo, Adapter->ulFlashControlSectionStart, 8); - - Adapter->psFlashCSInfo->FlashLayoutVersion = ntohl(Adapter->psFlashCSInfo->FlashLayoutVersion); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Version :%X", (Adapter->psFlashCSInfo->FlashLayoutVersion)); - /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Minor Version :%d\n", ntohs(sFlashCsInfo.FlashLayoutMinorVersion)); */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x\n", ntohl(Adapter->psFlashCSInfo->MagicNumber)); - - if (FLASH_CONTROL_STRUCT_SIGNATURE == ntohl(Adapter->psFlashCSInfo->MagicNumber)) { - uiFlashLayoutMajorVersion = MAJOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion)); - Adapter->uiFlashLayoutMinorVersion = MINOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion)); - } else { - Adapter->uiFlashLayoutMinorVersion = 0; - uiFlashLayoutMajorVersion = 0; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FLASH LAYOUT MAJOR VERSION :%X", uiFlashLayoutMajorVersion); - - if (uiFlashLayoutMajorVersion < FLASH_2X_MAJOR_NUMBER) { - BeceemFlashBulkRead(Adapter, (PUINT)Adapter->psFlashCSInfo, Adapter->ulFlashControlSectionStart, sizeof(struct bcm_flash_cs_info)); - ConvertEndianOfCSStructure(Adapter->psFlashCSInfo); - Adapter->ulFlashCalStart = (Adapter->psFlashCSInfo->OffsetFromZeroForCalibrationStart); - - if (!((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))) - Adapter->ulFlashControlSectionStart = Adapter->psFlashCSInfo->OffsetFromZeroForControlSectionStart; - - if ((FLASH_CONTROL_STRUCT_SIGNATURE == (Adapter->psFlashCSInfo->MagicNumber)) && - (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlashCSInfo->SCSIFirmwareVersion)) && - (FLASH_SECTOR_SIZE_SIG == (Adapter->psFlashCSInfo->FlashSectorSizeSig)) && - (BYTE_WRITE_SUPPORT == (Adapter->psFlashCSInfo->FlashWriteSupportSize))) { - Adapter->ulFlashWriteSize = (Adapter->psFlashCSInfo->FlashWriteSupportSize); - Adapter->fpFlashWrite = flashByteWrite; - Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus; - } else { - Adapter->ulFlashWriteSize = MAX_RW_SIZE; - Adapter->fpFlashWrite = flashWrite; - Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus; - } - - BcmGetFlashSectorSize(Adapter, (Adapter->psFlashCSInfo->FlashSectorSizeSig), - (Adapter->psFlashCSInfo->FlashSectorSize)); - Adapter->uiFlashBaseAdd = Adapter->psFlashCSInfo->FlashBaseAddr & 0xFCFFFFFF; - } else { - if (BcmFlash2xBulkRead(Adapter, (PUINT)Adapter->psFlash2xCSInfo, NO_SECTION_VAL, - Adapter->ulFlashControlSectionStart, sizeof(struct bcm_flash2x_cs_info))) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Unable to read CS structure\n"); - return STATUS_FAILURE; - } - - ConvertEndianOf2XCSStructure(Adapter->psFlash2xCSInfo); - BcmDumpFlash2XCSStructure(Adapter->psFlash2xCSInfo, Adapter); - if ((FLASH_CONTROL_STRUCT_SIGNATURE == Adapter->psFlash2xCSInfo->MagicNumber) && - (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlash2xCSInfo->SCSIFirmwareVersion)) && - (FLASH_SECTOR_SIZE_SIG == Adapter->psFlash2xCSInfo->FlashSectorSizeSig) && - (BYTE_WRITE_SUPPORT == Adapter->psFlash2xCSInfo->FlashWriteSupportSize)) { - Adapter->ulFlashWriteSize = Adapter->psFlash2xCSInfo->FlashWriteSupportSize; - Adapter->fpFlashWrite = flashByteWrite; - Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus; - } else { - Adapter->ulFlashWriteSize = MAX_RW_SIZE; - Adapter->fpFlashWrite = flashWrite; - Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus; - } - - BcmGetFlashSectorSize(Adapter, Adapter->psFlash2xCSInfo->FlashSectorSizeSig, - Adapter->psFlash2xCSInfo->FlashSectorSize); - - UpdateVendorInfo(Adapter); - - BcmGetActiveDSD(Adapter); - BcmGetActiveISO(Adapter); - Adapter->uiFlashBaseAdd = Adapter->psFlash2xCSInfo->FlashBaseAddr & 0xFCFFFFFF; - Adapter->ulFlashControlSectionStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart; - } - /* - * Concerns: what if CS sector size does not match with this sector size ??? - * what is the indication of AccessBitMap in CS in flash 2.x ???? - */ - Adapter->ulFlashID = BcmReadFlashRDID(Adapter); - Adapter->uiFlashLayoutMajorVersion = uiFlashLayoutMajorVersion; - - return STATUS_SUCCESS; -} - -/* - * Procedure: BcmGetNvmType - * - * Description: Finds the type of NVM used. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * - * Returns: - * NVM_TYPE - * - */ - -static enum bcm_nvm_type BcmGetNvmType(struct bcm_mini_adapter *Adapter) -{ - unsigned int uiData = 0; - - BeceemEEPROMBulkRead(Adapter, &uiData, 0x0, 4); - if (uiData == BECM) - return NVM_EEPROM; - - /* - * Read control struct and get cal addresses before accessing the flash - */ - BcmGetFlashCSInfo(Adapter); - - BeceemFlashBulkRead(Adapter, &uiData, 0x0 + Adapter->ulFlashCalStart, 4); - if (uiData == BECM) - return NVM_FLASH; - - /* - * even if there is no valid signature on EEPROM/FLASH find out if they really exist. - * if exist select it. - */ - if (BcmGetEEPROMSize(Adapter)) - return NVM_EEPROM; - - /* TBD for Flash. */ - return NVM_UNKNOWN; -} - -/* - * BcmGetSectionValStartOffset - this will calculate the section's starting offset if section val is given - * @Adapter : Drivers Private Data structure - * @eFlashSectionVal : Flash secion value defined in enum bcm_flash2x_section_val - * - * Return value:- - * On success it return the start offset of the provided section val - * On Failure -returns STATUS_FAILURE - */ - -int BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal) -{ - /* - * Considering all the section for which end offset can be calculated or directly given - * in CS Structure. if matching case does not exist, return STATUS_FAILURE indicating section - * endoffset can't be calculated or given in CS Structure. - */ - - int SectStartOffset = 0; - - SectStartOffset = INVALID_OFFSET; - - if (IsSectionExistInVendorInfo(Adapter, eFlashSectionVal)) - return Adapter->psFlash2xVendorInfo->VendorSection[eFlashSectionVal].OffsetFromZeroForSectionStart; - - switch (eFlashSectionVal) { - case ISO_IMAGE1: - if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == false)) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start); - break; - case ISO_IMAGE2: - if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == false)) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start); - break; - case DSD0: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart); - break; - case DSD1: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start); - break; - case DSD2: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start); - break; - case VSA0: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart); - break; - case VSA1: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start); - break; - case VSA2: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start); - break; - case SCSI: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware); - break; - case CONTROL_SECTION: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart); - break; - case ISO_IMAGE1_PART2: - if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start); - break; - case ISO_IMAGE1_PART3: - if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); - break; - case ISO_IMAGE2_PART2: - if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start); - break; - case ISO_IMAGE2_PART3: - if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); - break; - default: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x"); - SectStartOffset = INVALID_OFFSET; - } - - return SectStartOffset; -} - -/* - * BcmGetSectionValEndOffset - this will calculate the section's Ending offset if section val is given - * @Adapter : Drivers Private Data structure - * @eFlashSectionVal : Flash secion value defined in enum bcm_flash2x_section_val - * - * Return value:- - * On success it return the end offset of the provided section val - * On Failure -returns STATUS_FAILURE - */ - -static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal) -{ - int SectEndOffset = 0; - - SectEndOffset = INVALID_OFFSET; - if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal)) - return Adapter->psFlash2xVendorInfo->VendorSection[eFlash2xSectionVal].OffsetFromZeroForSectionEnd; - - switch (eFlash2xSectionVal) { - case ISO_IMAGE1: - if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == false)) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End); - break; - case ISO_IMAGE2: - if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == false)) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End); - break; - case DSD0: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd); - break; - case DSD1: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End); - break; - case DSD2: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End); - break; - case VSA0: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd); - break; - case VSA1: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End); - break; - case VSA2: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End); - break; - case SCSI: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) - SectEndOffset = ((Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) + - (Adapter->psFlash2xCSInfo->SizeOfScsiFirmware)); - break; - case CONTROL_SECTION: - /* Not Clear So Putting failure. confirm and fix it. */ - SectEndOffset = STATUS_FAILURE; - break; - case ISO_IMAGE1_PART2: - if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End); - break; - case ISO_IMAGE1_PART3: - if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End); - break; - case ISO_IMAGE2_PART2: - if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End); - break; - case ISO_IMAGE2_PART3: - if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End); - break; - default: - SectEndOffset = INVALID_OFFSET; - } - - return SectEndOffset; -} - -/* - * BcmFlash2xBulkRead:- Read API for Flash Map 2.x . - * @Adapter :Driver Private Data Structure - * @pBuffer : Buffer where data has to be put after reading - * @eFlashSectionVal :Flash Section Val defined in enum bcm_flash2x_section_val - * @uiOffsetWithinSectionVal :- Offset with in provided section - * @uiNumBytes : Number of Bytes for Read - * - * Return value:- - * return true on success and STATUS_FAILURE on fail. - */ - -int BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - enum bcm_flash2x_section_val eFlash2xSectionVal, - unsigned int uiOffsetWithinSectionVal, - unsigned int uiNumBytes) -{ - int Status = STATUS_SUCCESS; - int SectionStartOffset = 0; - unsigned int uiAbsoluteOffset = 0; - unsigned int uiTemp = 0, value = 0; - - if (!Adapter) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL"); - return -EINVAL; - } - if (Adapter->device_removed) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed"); - return -ENODEV; - } - - /* NO_SECTION_VAL means absolute offset is given. */ - if (eFlash2xSectionVal == NO_SECTION_VAL) - SectionStartOffset = 0; - else - SectionStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal); - - if (SectionStartOffset == STATUS_FAILURE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exist in Flash 2.x Map ", eFlash2xSectionVal); - return -EINVAL; - } - - if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal)) - return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectionVal, uiOffsetWithinSectionVal, uiNumBytes); - - /* calculating the absolute offset from FLASH; */ - uiAbsoluteOffset = uiOffsetWithinSectionVal + SectionStartOffset; - rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - value = 0; - wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); - Status = BeceemFlashBulkRead(Adapter, pBuffer, uiAbsoluteOffset, uiNumBytes); - wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Read Failed with Status :%d", Status); - return Status; - } - - return Status; -} - -/* - * BcmFlash2xBulkWrite :-API for Writing on the Flash Map 2.x. - * @Adapter :Driver Private Data Structure - * @pBuffer : Buffer From where data has to taken for writing - * @eFlashSectionVal :Flash Section Val defined in enum bcm_flash2x_section_val - * @uiOffsetWithinSectionVal :- Offset with in provided section - * @uiNumBytes : Number of Bytes for Write - * - * Return value:- - * return true on success and STATUS_FAILURE on fail. - * - */ - -int BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - enum bcm_flash2x_section_val eFlash2xSectVal, - unsigned int uiOffset, - unsigned int uiNumBytes, - unsigned int bVerify) -{ - int Status = STATUS_SUCCESS; - unsigned int FlashSectValStartOffset = 0; - unsigned int uiTemp = 0, value = 0; - - if (!Adapter) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL"); - return -EINVAL; - } - - if (Adapter->device_removed) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed"); - return -ENODEV; - } - - /* NO_SECTION_VAL means absolute offset is given. */ - if (eFlash2xSectVal == NO_SECTION_VAL) - FlashSectValStartOffset = 0; - else - FlashSectValStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectVal); - - if (FlashSectValStartOffset == STATUS_FAILURE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exist in Flash Map 2.x", eFlash2xSectVal); - return -EINVAL; - } - - if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectVal)) - return vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectVal, uiOffset, uiNumBytes, bVerify); - - /* calculating the absolute offset from FLASH; */ - uiOffset = uiOffset + FlashSectValStartOffset; - - rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - value = 0; - wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); - - Status = BeceemFlashBulkWrite(Adapter, pBuffer, uiOffset, uiNumBytes, bVerify); - - wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write failed with Status :%d", Status); - return Status; - } - - return Status; -} - -/* - * BcmGetActiveDSD : Set the Active DSD in Adapter Structure which has to be dumped in DDR - * @Adapter :-Drivers private Data Structure - * - * Return Value:- - * Return STATUS_SUCESS if get success in setting the right DSD else negative error code - * - */ - -static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter) -{ - enum bcm_flash2x_section_val uiHighestPriDSD = 0; - - uiHighestPriDSD = getHighestPriDSD(Adapter); - Adapter->eActiveDSD = uiHighestPriDSD; - - if (DSD0 == uiHighestPriDSD) - Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart; - if (DSD1 == uiHighestPriDSD) - Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start; - if (DSD2 == uiHighestPriDSD) - Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start; - if (Adapter->eActiveDSD) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active DSD :%d", Adapter->eActiveDSD); - if (Adapter->eActiveDSD == 0) { - /* if No DSD gets Active, Make Active the DSD with WR permission */ - if (IsSectionWritable(Adapter, DSD2)) { - Adapter->eActiveDSD = DSD2; - Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start; - } else if (IsSectionWritable(Adapter, DSD1)) { - Adapter->eActiveDSD = DSD1; - Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start; - } else if (IsSectionWritable(Adapter, DSD0)) { - Adapter->eActiveDSD = DSD0; - Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart; - } - } - - return STATUS_SUCCESS; -} - -/* - * BcmGetActiveISO :- Set the Active ISO in Adapter Data Structue - * @Adapter : Driver private Data Structure - * - * Return Value:- - * Sucsess:- STATUS_SUCESS - * Failure- : negative erro code - * - */ - -static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter) -{ - int HighestPriISO = 0; - - HighestPriISO = getHighestPriISO(Adapter); - - Adapter->eActiveISO = HighestPriISO; - if (Adapter->eActiveISO == ISO_IMAGE2) - Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start); - else if (Adapter->eActiveISO == ISO_IMAGE1) - Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start); - - if (Adapter->eActiveISO) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active ISO :%x", Adapter->eActiveISO); - - return STATUS_SUCCESS; -} - -/* - * IsOffsetWritable :- it will tell the access permission of the sector having passed offset - * @Adapter : Drivers Private Data Structure - * @uiOffset : Offset provided in the Flash - * - * Return Value:- - * Success:-TRUE , offset is writable - * Failure:-false, offset is RO - * - */ - -static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset) -{ - unsigned int uiSectorNum = 0; - unsigned int uiWordOfSectorPermission = 0; - unsigned int uiBitofSectorePermission = 0; - B_UINT32 permissionBits = 0; - - uiSectorNum = uiOffset/Adapter->uiSectorSize; - - /* calculating the word having this Sector Access permission from SectorAccessBitMap Array */ - uiWordOfSectorPermission = Adapter->psFlash2xCSInfo->SectorAccessBitMap[uiSectorNum / 16]; - - /* calculating the bit index inside the word for this sector */ - uiBitofSectorePermission = 2 * (15 - uiSectorNum % 16); - - /* Setting Access permission */ - permissionBits = uiWordOfSectorPermission & (0x3 << uiBitofSectorePermission); - permissionBits = (permissionBits >> uiBitofSectorePermission) & 0x3; - if (permissionBits == SECTOR_READWRITE_PERMISSION) - return TRUE; - else - return false; -} - -static int BcmDumpFlash2xSectionBitMap(struct bcm_flash2x_bitmap *psFlash2xBitMap) -{ - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "***************Flash 2.x Section Bitmap***************"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO_IMAGE1 :0X%x", psFlash2xBitMap->ISO_IMAGE1); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO_IMAGE2 :0X%x", psFlash2xBitMap->ISO_IMAGE2); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD0 :0X%x", psFlash2xBitMap->DSD0); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD1 :0X%x", psFlash2xBitMap->DSD1); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD2 :0X%x", psFlash2xBitMap->DSD2); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA0 :0X%x", psFlash2xBitMap->VSA0); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA1 :0X%x", psFlash2xBitMap->VSA1); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA2 :0X%x", psFlash2xBitMap->VSA2); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSI :0X%x", psFlash2xBitMap->SCSI); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CONTROL_SECTION :0X%x", psFlash2xBitMap->CONTROL_SECTION); - - return STATUS_SUCCESS; -} - -/* - * BcmGetFlash2xSectionalBitMap :- It will provide the bit map of all the section present in Flash - * 8bit has been assigned to every section. - * bit[0] :Section present or not - * bit[1] :section is valid or not - * bit[2] : Secton is read only or has write permission too. - * bit[3] : Active Section - - * bit[7...4] = Reserved . - * - * @Adapter:-Driver private Data Structure - * - * Return value:- - * Success:- STATUS_SUCESS - * Failure:- negative error code - */ - -int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_bitmap *psFlash2xBitMap) -{ - struct bcm_flash2x_cs_info *psFlash2xCSInfo = Adapter->psFlash2xCSInfo; - enum bcm_flash2x_section_val uiHighestPriDSD = 0; - enum bcm_flash2x_section_val uiHighestPriISO = 0; - bool SetActiveDSDDone = false; - bool SetActiveISODone = false; - - /* For 1.x map all the section except DSD0 will be shown as not present - * This part will be used by calibration tool to detect the number of DSD present in Flash. - */ - if (IsFlash2x(Adapter) == false) { - psFlash2xBitMap->ISO_IMAGE2 = 0; - psFlash2xBitMap->ISO_IMAGE1 = 0; - psFlash2xBitMap->DSD0 = FLASH2X_SECTION_VALID | FLASH2X_SECTION_ACT | FLASH2X_SECTION_PRESENT; /* 0xF; 0000(Reseved)1(Active)0(RW)1(valid)1(present) */ - psFlash2xBitMap->DSD1 = 0; - psFlash2xBitMap->DSD2 = 0; - psFlash2xBitMap->VSA0 = 0; - psFlash2xBitMap->VSA1 = 0; - psFlash2xBitMap->VSA2 = 0; - psFlash2xBitMap->CONTROL_SECTION = 0; - psFlash2xBitMap->SCSI = 0; - psFlash2xBitMap->Reserved0 = 0; - psFlash2xBitMap->Reserved1 = 0; - psFlash2xBitMap->Reserved2 = 0; - - return STATUS_SUCCESS; - } - - uiHighestPriDSD = getHighestPriDSD(Adapter); - uiHighestPriISO = getHighestPriISO(Adapter); - - /* - * IS0 IMAGE 2 - */ - if ((psFlash2xCSInfo->OffsetISOImage2Part1Start) != UNINIT_PTR_IN_CS) { - /* Setting the 0th Bit representing the Section is present or not. */ - psFlash2xBitMap->ISO_IMAGE2 = psFlash2xBitMap->ISO_IMAGE2 | FLASH2X_SECTION_PRESENT; - - if (ReadISOSignature(Adapter, ISO_IMAGE2) == ISO_IMAGE_MAGIC_NUMBER) - psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_VALID; - - /* Calculation for extrating the Access permission */ - if (IsSectionWritable(Adapter, ISO_IMAGE2) == false) - psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_RO; - - if (SetActiveISODone == false && uiHighestPriISO == ISO_IMAGE2) { - psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_ACT; - SetActiveISODone = TRUE; - } - } - - /* - * IS0 IMAGE 1 - */ - if ((psFlash2xCSInfo->OffsetISOImage1Part1Start) != UNINIT_PTR_IN_CS) { - /* Setting the 0th Bit representing the Section is present or not. */ - psFlash2xBitMap->ISO_IMAGE1 = psFlash2xBitMap->ISO_IMAGE1 | FLASH2X_SECTION_PRESENT; - - if (ReadISOSignature(Adapter, ISO_IMAGE1) == ISO_IMAGE_MAGIC_NUMBER) - psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_VALID; - - /* Calculation for extrating the Access permission */ - if (IsSectionWritable(Adapter, ISO_IMAGE1) == false) - psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_RO; - - if (SetActiveISODone == false && uiHighestPriISO == ISO_IMAGE1) { - psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_ACT; - SetActiveISODone = TRUE; - } - } - - /* - * DSD2 - */ - if ((psFlash2xCSInfo->OffsetFromZeroForDSD2Start) != UNINIT_PTR_IN_CS) { - /* Setting the 0th Bit representing the Section is present or not. */ - psFlash2xBitMap->DSD2 = psFlash2xBitMap->DSD2 | FLASH2X_SECTION_PRESENT; - - if (ReadDSDSignature(Adapter, DSD2) == DSD_IMAGE_MAGIC_NUMBER) - psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_VALID; - - /* Calculation for extrating the Access permission */ - if (IsSectionWritable(Adapter, DSD2) == false) { - psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_RO; - } else { - /* Means section is writable */ - if ((SetActiveDSDDone == false) && (uiHighestPriDSD == DSD2)) { - psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_ACT; - SetActiveDSDDone = TRUE; - } - } - } - - /* - * DSD 1 - */ - if ((psFlash2xCSInfo->OffsetFromZeroForDSD1Start) != UNINIT_PTR_IN_CS) { - /* Setting the 0th Bit representing the Section is present or not. */ - psFlash2xBitMap->DSD1 = psFlash2xBitMap->DSD1 | FLASH2X_SECTION_PRESENT; - - if (ReadDSDSignature(Adapter, DSD1) == DSD_IMAGE_MAGIC_NUMBER) - psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_VALID; - - /* Calculation for extrating the Access permission */ - if (IsSectionWritable(Adapter, DSD1) == false) { - psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_RO; - } else { - /* Means section is writable */ - if ((SetActiveDSDDone == false) && (uiHighestPriDSD == DSD1)) { - psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_ACT; - SetActiveDSDDone = TRUE; - } - } - } - - /* - * For DSD 0 - */ - if ((psFlash2xCSInfo->OffsetFromZeroForDSDStart) != UNINIT_PTR_IN_CS) { - /* Setting the 0th Bit representing the Section is present or not. */ - psFlash2xBitMap->DSD0 = psFlash2xBitMap->DSD0 | FLASH2X_SECTION_PRESENT; - - if (ReadDSDSignature(Adapter, DSD0) == DSD_IMAGE_MAGIC_NUMBER) - psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_VALID; - - /* Setting Access permission */ - if (IsSectionWritable(Adapter, DSD0) == false) { - psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_RO; - } else { - /* Means section is writable */ - if ((SetActiveDSDDone == false) && (uiHighestPriDSD == DSD0)) { - psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_ACT; - SetActiveDSDDone = TRUE; - } - } - } - - /* - * VSA 0 - */ - if ((psFlash2xCSInfo->OffsetFromZeroForVSAStart) != UNINIT_PTR_IN_CS) { - /* Setting the 0th Bit representing the Section is present or not. */ - psFlash2xBitMap->VSA0 = psFlash2xBitMap->VSA0 | FLASH2X_SECTION_PRESENT; - - /* Setting the Access Bit. Map is not defined hece setting it always valid */ - psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_VALID; - - /* Calculation for extrating the Access permission */ - if (IsSectionWritable(Adapter, VSA0) == false) - psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_RO; - - /* By Default section is Active */ - psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_ACT; - } - - /* - * VSA 1 - */ - if ((psFlash2xCSInfo->OffsetFromZeroForVSA1Start) != UNINIT_PTR_IN_CS) { - /* Setting the 0th Bit representing the Section is present or not. */ - psFlash2xBitMap->VSA1 = psFlash2xBitMap->VSA1 | FLASH2X_SECTION_PRESENT; - - /* Setting the Access Bit. Map is not defined hece setting it always valid */ - psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_VALID; - - /* Checking For Access permission */ - if (IsSectionWritable(Adapter, VSA1) == false) - psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_RO; - - /* By Default section is Active */ - psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_ACT; - } - - /* - * VSA 2 - */ - if ((psFlash2xCSInfo->OffsetFromZeroForVSA2Start) != UNINIT_PTR_IN_CS) { - /* Setting the 0th Bit representing the Section is present or not. */ - psFlash2xBitMap->VSA2 = psFlash2xBitMap->VSA2 | FLASH2X_SECTION_PRESENT; - - /* Setting the Access Bit. Map is not defined hece setting it always valid */ - psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_VALID; - - /* Checking For Access permission */ - if (IsSectionWritable(Adapter, VSA2) == false) - psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_RO; - - /* By Default section is Active */ - psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_ACT; - } - - /* - * SCSI Section - */ - if ((psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) != UNINIT_PTR_IN_CS) { - /* Setting the 0th Bit representing the Section is present or not. */ - psFlash2xBitMap->SCSI = psFlash2xBitMap->SCSI | FLASH2X_SECTION_PRESENT; - - /* Setting the Access Bit. Map is not defined hece setting it always valid */ - psFlash2xBitMap->SCSI |= FLASH2X_SECTION_VALID; - - /* Checking For Access permission */ - if (IsSectionWritable(Adapter, SCSI) == false) - psFlash2xBitMap->SCSI |= FLASH2X_SECTION_RO; - - /* By Default section is Active */ - psFlash2xBitMap->SCSI |= FLASH2X_SECTION_ACT; - } - - /* - * Control Section - */ - if ((psFlash2xCSInfo->OffsetFromZeroForControlSectionStart) != UNINIT_PTR_IN_CS) { - /* Setting the 0th Bit representing the Section is present or not. */ - psFlash2xBitMap->CONTROL_SECTION = psFlash2xBitMap->CONTROL_SECTION | (FLASH2X_SECTION_PRESENT); - - /* Setting the Access Bit. Map is not defined hece setting it always valid */ - psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_VALID; - - /* Checking For Access permission */ - if (IsSectionWritable(Adapter, CONTROL_SECTION) == false) - psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_RO; - - /* By Default section is Active */ - psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_ACT; - } - - /* - * For Reserved Sections - */ - psFlash2xBitMap->Reserved0 = 0; - psFlash2xBitMap->Reserved0 = 0; - psFlash2xBitMap->Reserved0 = 0; - BcmDumpFlash2xSectionBitMap(psFlash2xBitMap); - - return STATUS_SUCCESS; -} - -/* - * BcmSetActiveSection :- Set Active section is used to make priority field highest over other - * section of same type. - * - * @Adapater :- Bcm Driver Private Data Structure - * @eFlash2xSectionVal :- Flash section val whose priority has to be made highest. - * - * Return Value:- Make the priorit highest else return erorr code - * - */ - -int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectVal) -{ - unsigned int SectImagePriority = 0; - int Status = STATUS_SUCCESS; - - /* struct bcm_dsd_header sDSD = {0}; - * struct bcm_iso_header sISO = {0}; - */ - int HighestPriDSD = 0; - int HighestPriISO = 0; - - Status = IsSectionWritable(Adapter, eFlash2xSectVal); - if (Status != TRUE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Provided Section <%d> is not writable", eFlash2xSectVal); - return STATUS_FAILURE; - } - - Adapter->bHeaderChangeAllowed = TRUE; - switch (eFlash2xSectVal) { - case ISO_IMAGE1: - case ISO_IMAGE2: - if (ReadISOSignature(Adapter, eFlash2xSectVal) == ISO_IMAGE_MAGIC_NUMBER) { - HighestPriISO = getHighestPriISO(Adapter); - - if (HighestPriISO == eFlash2xSectVal) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given ISO<%x> already has highest priority", eFlash2xSectVal); - Status = STATUS_SUCCESS; - break; - } - - SectImagePriority = ReadISOPriority(Adapter, HighestPriISO) + 1; - - if ((SectImagePriority == 0) && IsSectionWritable(Adapter, HighestPriISO)) { - /* This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF. - * We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO - * by user - */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal); - SectImagePriority = htonl(0x1); - Status = BcmFlash2xBulkWrite(Adapter, - &SectImagePriority, - HighestPriISO, - 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImagePriority), - SIGNATURE_SIZE, - TRUE); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); - Status = STATUS_FAILURE; - break; - } - - HighestPriISO = getHighestPriISO(Adapter); - - if (HighestPriISO == eFlash2xSectVal) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given ISO<%x> already has highest priority", eFlash2xSectVal); - Status = STATUS_SUCCESS; - break; - } - - SectImagePriority = 2; - } - - SectImagePriority = htonl(SectImagePriority); - - Status = BcmFlash2xBulkWrite(Adapter, - &SectImagePriority, - eFlash2xSectVal, - 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImagePriority), - SIGNATURE_SIZE, - TRUE); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); - break; - } - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority"); - Status = STATUS_FAILURE; - break; - } - break; - case DSD0: - case DSD1: - case DSD2: - if (ReadDSDSignature(Adapter, eFlash2xSectVal) == DSD_IMAGE_MAGIC_NUMBER) { - HighestPriDSD = getHighestPriDSD(Adapter); - if (HighestPriDSD == eFlash2xSectVal) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given DSD<%x> already has highest priority", eFlash2xSectVal); - Status = STATUS_SUCCESS; - break; - } - - SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1; - if (SectImagePriority == 0) { - /* This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF. - * We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD - * by user - */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal); - SectImagePriority = htonl(0x1); - - Status = BcmFlash2xBulkWrite(Adapter, - &SectImagePriority, - HighestPriDSD, - Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority), - SIGNATURE_SIZE, - TRUE); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); - break; - } - - HighestPriDSD = getHighestPriDSD(Adapter); - - if (HighestPriDSD == eFlash2xSectVal) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Made the DSD: %x highest by reducing priority of other\n", eFlash2xSectVal); - Status = STATUS_SUCCESS; - break; - } - - SectImagePriority = htonl(0x2); - Status = BcmFlash2xBulkWrite(Adapter, - &SectImagePriority, - HighestPriDSD, - Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority), - SIGNATURE_SIZE, - TRUE); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); - break; - } - - HighestPriDSD = getHighestPriDSD(Adapter); - if (HighestPriDSD == eFlash2xSectVal) { - Status = STATUS_SUCCESS; - break; - } - - SectImagePriority = 3; - } - SectImagePriority = htonl(SectImagePriority); - Status = BcmFlash2xBulkWrite(Adapter, - &SectImagePriority, - eFlash2xSectVal, - Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority), - SIGNATURE_SIZE, - TRUE); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); - Status = STATUS_FAILURE; - break; - } - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority"); - Status = STATUS_FAILURE; - break; - } - break; - case VSA0: - case VSA1: - case VSA2: - /* Has to be decided */ - break; - default: - Status = STATUS_FAILURE; - break; - } - - Adapter->bHeaderChangeAllowed = false; - return Status; -} - -/* - * BcmCopyISO - Used only for copying the ISO section - * @Adapater :- Bcm Driver Private Data Structure - * @sCopySectStrut :- Section copy structure - * - * Return value:- SUCCESS if copies successfully else negative error code - * - */ - -int BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section sCopySectStrut) -{ - PCHAR Buff = NULL; - enum bcm_flash2x_section_val eISOReadPart = 0, eISOWritePart = 0; - unsigned int uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0; - unsigned int uiTotalDataToCopy = 0; - bool IsThisHeaderSector = false; - unsigned int sigOffset = 0; - unsigned int ISOLength = 0; - unsigned int Status = STATUS_SUCCESS; - unsigned int SigBuff[MAX_RW_SIZE]; - unsigned int i = 0; - - if (ReadISOSignature(Adapter, sCopySectStrut.SrcSection) != ISO_IMAGE_MAGIC_NUMBER) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature"); - return STATUS_FAILURE; - } - - Status = BcmFlash2xBulkRead(Adapter, &ISOLength, - sCopySectStrut.SrcSection, - 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageSize), - 4); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO\n"); - return Status; - } - - ISOLength = htonl(ISOLength); - if (ISOLength % Adapter->uiSectorSize) - ISOLength = Adapter->uiSectorSize * (1 + ISOLength/Adapter->uiSectorSize); - - sigOffset = FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageMagicNumber); - - Buff = kzalloc(Adapter->uiSectorSize, GFP_KERNEL); - - if (!Buff) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed for section size"); - return -ENOMEM; - } - - if (sCopySectStrut.SrcSection == ISO_IMAGE1 && sCopySectStrut.DstSection == ISO_IMAGE2) { - eISOReadPart = ISO_IMAGE1; - eISOWritePart = ISO_IMAGE2; - uiReadOffsetWithinPart = 0; - uiWriteOffsetWithinPart = 0; - - uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) + - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start) + - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); - - if (uiTotalDataToCopy < ISOLength) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature"); - Status = STATUS_FAILURE; - goto out; - } - - uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) + - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start) + - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); - - if (uiTotalDataToCopy < ISOLength) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size"); - Status = STATUS_FAILURE; - goto out; - } - - uiTotalDataToCopy = ISOLength; - - CorruptISOSig(Adapter, ISO_IMAGE2); - while (uiTotalDataToCopy) { - if (uiTotalDataToCopy == Adapter->uiSectorSize) { - /* Setting for write of first sector. First sector is assumed to be written in last */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector"); - eISOReadPart = ISO_IMAGE1; - uiReadOffsetWithinPart = 0; - eISOWritePart = ISO_IMAGE2; - uiWriteOffsetWithinPart = 0; - IsThisHeaderSector = TRUE; - } else { - uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize; - uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize; - - if ((eISOReadPart == ISO_IMAGE1) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) { - eISOReadPart = ISO_IMAGE1_PART2; - uiReadOffsetWithinPart = 0; - } - - if ((eISOReadPart == ISO_IMAGE1_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) { - eISOReadPart = ISO_IMAGE1_PART3; - uiReadOffsetWithinPart = 0; - } - - if ((eISOWritePart == ISO_IMAGE2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) { - eISOWritePart = ISO_IMAGE2_PART2; - uiWriteOffsetWithinPart = 0; - } - - if ((eISOWritePart == ISO_IMAGE2_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) { - eISOWritePart = ISO_IMAGE2_PART3; - uiWriteOffsetWithinPart = 0; - } - } - - Status = BcmFlash2xBulkRead(Adapter, - (PUINT)Buff, - eISOReadPart, - uiReadOffsetWithinPart, - Adapter->uiSectorSize); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart); - break; - } - - if (IsThisHeaderSector == TRUE) { - /* If this is header sector write 0xFFFFFFFF at the sig time and in last write sig */ - memcpy(SigBuff, Buff + sigOffset, sizeof(SigBuff)); - - for (i = 0; i < MAX_RW_SIZE; i++) - *(Buff + sigOffset + i) = 0xFF; - } - Adapter->bHeaderChangeAllowed = TRUE; - Status = BcmFlash2xBulkWrite(Adapter, - (PUINT)Buff, - eISOWritePart, - uiWriteOffsetWithinPart, - Adapter->uiSectorSize, - TRUE); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart); - break; - } - - Adapter->bHeaderChangeAllowed = false; - if (IsThisHeaderSector == TRUE) { - WriteToFlashWithoutSectorErase(Adapter, - SigBuff, - eISOWritePart, - sigOffset, - MAX_RW_SIZE); - IsThisHeaderSector = false; - } - /* subtracting the written Data */ - uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize; - } - } - - if (sCopySectStrut.SrcSection == ISO_IMAGE2 && sCopySectStrut.DstSection == ISO_IMAGE1) { - eISOReadPart = ISO_IMAGE2; - eISOWritePart = ISO_IMAGE1; - uiReadOffsetWithinPart = 0; - uiWriteOffsetWithinPart = 0; - - uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) + - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start) + - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); - - if (uiTotalDataToCopy < ISOLength) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature"); - Status = STATUS_FAILURE; - goto out; - } - - uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) + - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start) + - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); - - if (uiTotalDataToCopy < ISOLength) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size"); - Status = STATUS_FAILURE; - goto out; - } - - uiTotalDataToCopy = ISOLength; - - CorruptISOSig(Adapter, ISO_IMAGE1); - - while (uiTotalDataToCopy) { - if (uiTotalDataToCopy == Adapter->uiSectorSize) { - /* Setting for write of first sector. First sector is assumed to be written in last */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector"); - eISOReadPart = ISO_IMAGE2; - uiReadOffsetWithinPart = 0; - eISOWritePart = ISO_IMAGE1; - uiWriteOffsetWithinPart = 0; - IsThisHeaderSector = TRUE; - } else { - uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize; - uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize; - - if ((eISOReadPart == ISO_IMAGE2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) { - eISOReadPart = ISO_IMAGE2_PART2; - uiReadOffsetWithinPart = 0; - } - - if ((eISOReadPart == ISO_IMAGE2_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) { - eISOReadPart = ISO_IMAGE2_PART3; - uiReadOffsetWithinPart = 0; - } - - if ((eISOWritePart == ISO_IMAGE1) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) { - eISOWritePart = ISO_IMAGE1_PART2; - uiWriteOffsetWithinPart = 0; - } - - if ((eISOWritePart == ISO_IMAGE1_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) { - eISOWritePart = ISO_IMAGE1_PART3; - uiWriteOffsetWithinPart = 0; - } - } - - Status = BcmFlash2xBulkRead(Adapter, - (PUINT)Buff, - eISOReadPart, - uiReadOffsetWithinPart, - Adapter->uiSectorSize); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart); - break; - } - - if (IsThisHeaderSector == TRUE) { - /* If this is header sector write 0xFFFFFFFF at the sig time and in last write sig */ - memcpy(SigBuff, Buff + sigOffset, sizeof(SigBuff)); - - for (i = 0; i < MAX_RW_SIZE; i++) - *(Buff + sigOffset + i) = 0xFF; - } - Adapter->bHeaderChangeAllowed = TRUE; - Status = BcmFlash2xBulkWrite(Adapter, - (PUINT)Buff, - eISOWritePart, - uiWriteOffsetWithinPart, - Adapter->uiSectorSize, - TRUE); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart); - break; - } - - Adapter->bHeaderChangeAllowed = false; - if (IsThisHeaderSector == TRUE) { - WriteToFlashWithoutSectorErase(Adapter, - SigBuff, - eISOWritePart, - sigOffset, - MAX_RW_SIZE); - - IsThisHeaderSector = false; - } - - /* subtracting the written Data */ - uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize; - } - } -out: - kfree(Buff); - - return Status; -} - -/* - * BcmFlash2xCorruptSig : this API is used to corrupt the written sig in Bcm Header present in flash section. - * It will corrupt the sig, if Section is writable, by making first bytes as zero. - * @Adapater :- Bcm Driver Private Data Structure - * @eFlash2xSectionVal :- Flash section val which has header - * - * Return Value :- - * Success :- If Section is present and writable, corrupt the sig and return STATUS_SUCCESS - * Failure :-Return negative error code - */ - -int BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal) -{ - int Status = STATUS_SUCCESS; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Value :%x\n", eFlash2xSectionVal); - - if ((eFlash2xSectionVal == DSD0) || (eFlash2xSectionVal == DSD1) || (eFlash2xSectionVal == DSD2)) { - Status = CorruptDSDSig(Adapter, eFlash2xSectionVal); - } else if (eFlash2xSectionVal == ISO_IMAGE1 || eFlash2xSectionVal == ISO_IMAGE2) { - Status = CorruptISOSig(Adapter, eFlash2xSectionVal); - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given Section <%d>does not have Header", eFlash2xSectionVal); - return STATUS_SUCCESS; - } - return Status; -} - -/* - *BcmFlash2xWriteSig :-this API is used to Write the sig if requested Section has - * header and Write Permission. - * @Adapater :- Bcm Driver Private Data Structure - * @eFlashSectionVal :- Flash section val which has header - * - * Return Value :- - * Success :- If Section is present and writable write the sig and return STATUS_SUCCESS - * Failure :-Return negative error code - */ - -int BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal) -{ - unsigned int uiSignature = 0; - unsigned int uiOffset = 0; - - /* struct bcm_dsd_header dsdHeader = {0}; */ - if (Adapter->bSigCorrupted == false) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is not corrupted by driver, hence not restoring\n"); - return STATUS_SUCCESS; - } - - if (Adapter->bAllDSDWriteAllow == false) { - if (IsSectionWritable(Adapter, eFlashSectionVal) == false) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Write signature"); - return SECTOR_IS_NOT_WRITABLE; - } - } - - if ((eFlashSectionVal == DSD0) || (eFlashSectionVal == DSD1) || (eFlashSectionVal == DSD2)) { - uiSignature = htonl(DSD_IMAGE_MAGIC_NUMBER); - uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader; - - uiOffset += FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber); - - if ((ReadDSDSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Corrupted Pattern is not there. Hence won't write sig"); - return STATUS_FAILURE; - } - } else if ((eFlashSectionVal == ISO_IMAGE1) || (eFlashSectionVal == ISO_IMAGE2)) { - uiSignature = htonl(ISO_IMAGE_MAGIC_NUMBER); - /* uiOffset = 0; */ - uiOffset = FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageMagicNumber); - if ((ReadISOSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Currupted Pattern is not there. Hence won't write sig"); - return STATUS_FAILURE; - } - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "GIVEN SECTION< %d > IS NOT VALID FOR SIG WRITE...", eFlashSectionVal); - return STATUS_FAILURE; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Restoring the signature"); - - Adapter->bHeaderChangeAllowed = TRUE; - Adapter->bSigCorrupted = false; - BcmFlash2xBulkWrite(Adapter, &uiSignature, eFlashSectionVal, uiOffset, SIGNATURE_SIZE, TRUE); - Adapter->bHeaderChangeAllowed = false; - - return STATUS_SUCCESS; -} - -/* - * validateFlash2xReadWrite :- This API is used to validate the user request for Read/Write. - * if requested Bytes goes beyond the Requested section, it reports error. - * @Adapater :- Bcm Driver Private Data Structure - * @psFlash2xReadWrite :-Flash2x Read/write structure pointer - * - * Return values:-Return TRUE is request is valid else false. - */ - -int validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_readwrite *psFlash2xReadWrite) -{ - unsigned int uiNumOfBytes = 0; - unsigned int uiSectStartOffset = 0; - unsigned int uiSectEndOffset = 0; - - uiNumOfBytes = psFlash2xReadWrite->numOfBytes; - - if (IsSectionExistInFlash(Adapter, psFlash2xReadWrite->Section) != TRUE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%x> does not exist in Flash", psFlash2xReadWrite->Section); - return false; - } - uiSectStartOffset = BcmGetSectionValStartOffset(Adapter, psFlash2xReadWrite->Section); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Start offset :%x ,section :%d\n", uiSectStartOffset, psFlash2xReadWrite->Section); - if ((psFlash2xReadWrite->Section == ISO_IMAGE1) || (psFlash2xReadWrite->Section == ISO_IMAGE2)) { - if (psFlash2xReadWrite->Section == ISO_IMAGE1) { - uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1) - - BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1) + - BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1_PART2) - - BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1_PART2) + - BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1_PART3) - - BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1_PART3); - } else if (psFlash2xReadWrite->Section == ISO_IMAGE2) { - uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2) - - BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2) + - BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2_PART2) - - BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART2) + - BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2_PART3) - - BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART3); - } - - /* since this uiSectEndoffset is the size of iso Image. hence for calculating the virtual endoffset - * it should be added in startoffset. so that check done in last of this function can be valued. - */ - uiSectEndOffset = uiSectStartOffset + uiSectEndOffset; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Total size of the ISO Image :%x", uiSectEndOffset); - } else - uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, psFlash2xReadWrite->Section); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "End offset :%x\n", uiSectEndOffset); - - /* psFlash2xReadWrite->offset and uiNumOfBytes are user controlled and can lead to integer overflows */ - if (psFlash2xReadWrite->offset > uiSectEndOffset) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request...."); - return false; - } - if (uiNumOfBytes > uiSectEndOffset) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request...."); - return false; - } - /* Checking the boundary condition */ - if ((uiSectStartOffset + psFlash2xReadWrite->offset + uiNumOfBytes) <= uiSectEndOffset) - return TRUE; - else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request...."); - return false; - } -} - -/* - * IsFlash2x :- check for Flash 2.x - * Adapater :- Bcm Driver Private Data Structure - * - * Return value:- - * return TRUE if flah2.x of hgher version else return false. - */ - -int IsFlash2x(struct bcm_mini_adapter *Adapter) -{ - if (Adapter->uiFlashLayoutMajorVersion >= FLASH_2X_MAJOR_NUMBER) - return TRUE; - else - return false; -} - -/* - * GetFlashBaseAddr :- Calculate the Flash Base address - * @Adapater :- Bcm Driver Private Data Structure - * - * Return Value:- - * Success :- Base Address of the Flash - */ - -static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter) -{ - unsigned int uiBaseAddr = 0; - - if (Adapter->bDDRInitDone) { - /* - * For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr - * In case of Raw Read... use the default value - */ - if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == false) && - !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))) - uiBaseAddr = Adapter->uiFlashBaseAdd; - else - uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT; - } else { - /* - * For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr - * In case of Raw Read... use the default value - */ - if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == false) && - !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))) - uiBaseAddr = Adapter->uiFlashBaseAdd | FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT; - else - uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT; - } - - return uiBaseAddr; -} - -/* - * BcmCopySection :- This API is used to copy the One section in another. Both section should - * be contiuous and of same size. Hence this Will not be applicabe to copy ISO. - * - * @Adapater :- Bcm Driver Private Data Structure - * @SrcSection :- Source section From where data has to be copied - * @DstSection :- Destination section to which data has to be copied - * @offset :- Offset from/to where data has to be copied from one section to another. - * @numOfBytes :- number of byes that has to be copyed from one section to another at given offset. - * in case of numofBytes equal zero complete section will be copied. - * Return Values- - * Success : Return STATUS_SUCCESS - * Faillure :- return negative error code - */ - -int BcmCopySection(struct bcm_mini_adapter *Adapter, - enum bcm_flash2x_section_val SrcSection, - enum bcm_flash2x_section_val DstSection, - unsigned int offset, - unsigned int numOfBytes) -{ - unsigned int BuffSize = 0; - unsigned int BytesToBeCopied = 0; - PUCHAR pBuff = NULL; - int Status = STATUS_SUCCESS; - - if (SrcSection == DstSection) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source and Destination should be different ...try again"); - return -EINVAL; - } - - if ((SrcSection != DSD0) && (SrcSection != DSD1) && (SrcSection != DSD2)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source should be DSD subsection"); - return -EINVAL; - } - - if ((DstSection != DSD0) && (DstSection != DSD1) && (DstSection != DSD2)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Destination should be DSD subsection"); - return -EINVAL; - } - - /* if offset zero means have to copy complete secton */ - if (numOfBytes == 0) { - numOfBytes = BcmGetSectionValEndOffset(Adapter, SrcSection) - - BcmGetSectionValStartOffset(Adapter, SrcSection); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Section Size :0x%x", numOfBytes); - } - - if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, SrcSection) - - BcmGetSectionValStartOffset(Adapter, SrcSection)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, " Input parameters going beyond the section offS: %x numB: %x of Source Section\n", - offset, numOfBytes); - return -EINVAL; - } - - if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, DstSection) - - BcmGetSectionValStartOffset(Adapter, DstSection)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Input parameters going beyond the section offS: %x numB: %x of Destination Section\n", - offset, numOfBytes); - return -EINVAL; - } - - if (numOfBytes > Adapter->uiSectorSize) - BuffSize = Adapter->uiSectorSize; - else - BuffSize = numOfBytes; - - pBuff = kzalloc(BuffSize, GFP_KERNEL); - if (!pBuff) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed.. "); - return -ENOMEM; - } - - BytesToBeCopied = Adapter->uiSectorSize; - if (offset % Adapter->uiSectorSize) - BytesToBeCopied = Adapter->uiSectorSize - (offset % Adapter->uiSectorSize); - if (BytesToBeCopied > numOfBytes) - BytesToBeCopied = numOfBytes; - - Adapter->bHeaderChangeAllowed = TRUE; - - do { - Status = BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, SrcSection , offset, BytesToBeCopied); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed at offset :%d for NOB :%d", SrcSection, BytesToBeCopied); - break; - } - Status = BcmFlash2xBulkWrite(Adapter, (PUINT)pBuff, DstSection, offset, BytesToBeCopied, false); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed at offset :%d for NOB :%d", DstSection, BytesToBeCopied); - break; - } - offset = offset + BytesToBeCopied; - numOfBytes = numOfBytes - BytesToBeCopied; - if (numOfBytes) { - if (numOfBytes > Adapter->uiSectorSize) - BytesToBeCopied = Adapter->uiSectorSize; - else - BytesToBeCopied = numOfBytes; - } - } while (numOfBytes > 0); - - kfree(pBuff); - Adapter->bHeaderChangeAllowed = false; - - return Status; -} - -/* - * SaveHeaderIfPresent :- This API is use to Protect the Header in case of Header Sector write - * @Adapater :- Bcm Driver Private Data Structure - * @pBuff :- Data buffer that has to be written in sector having the header map. - * @uiOffset :- Flash offset that has to be written. - * - * Return value :- - * Success :- On success return STATUS_SUCCESS - * Faillure :- Return negative error code - */ - -static int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned int uiOffset) -{ - unsigned int offsetToProtect = 0, HeaderSizeToProtect = 0; - bool bHasHeader = false; - PUCHAR pTempBuff = NULL; - unsigned int uiSectAlignAddr = 0; - unsigned int sig = 0; - - /* making the offset sector aligned */ - uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); - - if ((uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD2) - Adapter->uiSectorSize) || - (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD1) - Adapter->uiSectorSize) || - (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD0) - Adapter->uiSectorSize)) { - /* offset from the sector boundary having the header map */ - offsetToProtect = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader % Adapter->uiSectorSize; - HeaderSizeToProtect = sizeof(struct bcm_dsd_header); - bHasHeader = TRUE; - } - - if (uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1) || - uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2)) { - offsetToProtect = 0; - HeaderSizeToProtect = sizeof(struct bcm_iso_header); - bHasHeader = TRUE; - } - /* If Header is present overwrite passed buffer with this */ - if (bHasHeader && (Adapter->bHeaderChangeAllowed == false)) { - pTempBuff = kzalloc(HeaderSizeToProtect, GFP_KERNEL); - if (!pTempBuff) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed"); - return -ENOMEM; - } - /* Read header */ - BeceemFlashBulkRead(Adapter, (PUINT)pTempBuff, (uiSectAlignAddr + offsetToProtect), HeaderSizeToProtect); - BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pTempBuff, HeaderSizeToProtect); - /* Replace Buffer content with Header */ - memcpy(pBuff + offsetToProtect, pTempBuff, HeaderSizeToProtect); - - kfree(pTempBuff); - } - if (bHasHeader && Adapter->bSigCorrupted) { - sig = *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber))); - sig = ntohl(sig); - if ((sig & 0xFF000000) != CORRUPTED_PATTERN) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Desired pattern is not at sig offset. Hence won't restore"); - Adapter->bSigCorrupted = false; - return STATUS_SUCCESS; - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Corrupted sig is :%X", sig); - *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber))) = htonl(DSD_IMAGE_MAGIC_NUMBER); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Restoring the signature in Header Write only"); - Adapter->bSigCorrupted = false; - } - - return STATUS_SUCCESS; -} - -/* - * BcmDoChipSelect : This will selcet the appropriate chip for writing. - * @Adapater :- Bcm Driver Private Data Structure - * - * OutPut:- - * Select the Appropriate chip and retrn status Success - */ -static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, unsigned int offset) -{ - unsigned int FlashConfig = 0; - int ChipNum = 0; - unsigned int GPIOConfig = 0; - unsigned int PartNum = 0; - - ChipNum = offset / FLASH_PART_SIZE; - - /* - * Chip Select mapping to enable flash0. - * To select flash 0, we have to OR with (0<<12). - * ORing 0 will have no impact so not doing that part. - * In future if Chip select value changes from 0 to non zero, - * That needs be taken care with backward comaptibility. No worries for now. - */ - - /* - * SelectedChip Variable is the selection that the host is 100% Sure the same as what the register will hold. This can be ONLY ensured - * if the Chip doesn't goes to low power mode while the flash operation is in progress (NVMRdmWrmLock is taken) - * Before every new Flash Write operation, we reset the variable. This is to ensure that after any wake-up from - * power down modes (Idle mode/shutdown mode), the values in the register will be different. - */ - - if (Adapter->SelectedChip == ChipNum) - return STATUS_SUCCESS; - - /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Selected Chip :%x", ChipNum); */ - Adapter->SelectedChip = ChipNum; - - /* bit[13..12] will select the appropriate chip */ - rdmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4); - rdmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4); - { - switch (ChipNum) { - case 0: - PartNum = 0; - break; - case 1: - PartNum = 3; - GPIOConfig |= (0x4 << CHIP_SELECT_BIT12); - break; - case 2: - PartNum = 1; - GPIOConfig |= (0x1 << CHIP_SELECT_BIT12); - break; - case 3: - PartNum = 2; - GPIOConfig |= (0x2 << CHIP_SELECT_BIT12); - break; - } - } - /* In case the bits already written in the FLASH_CONFIG_REG is same as what the user desired, - * nothing to do... can return immediately. - * ASSUMPTION: FLASH_GPIO_CONFIG_REG will be in sync with FLASH_CONFIG_REG. - * Even if the chip goes to low power mode, it should wake with values in each register in sync with each other. - * These values are not written by host other than during CHIP_SELECT. - */ - if (PartNum == ((FlashConfig >> CHIP_SELECT_BIT12) & 0x3)) - return STATUS_SUCCESS; - - /* clearing the bit[13..12] */ - FlashConfig &= 0xFFFFCFFF; - FlashConfig = (FlashConfig | (PartNum<<CHIP_SELECT_BIT12)); /* 00 */ - - wrmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4); - udelay(100); - - wrmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4); - udelay(100); - - return STATUS_SUCCESS; -} - -static int ReadDSDSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd) -{ - unsigned int uiDSDsig = 0; - /* unsigned int sigoffsetInMap = 0; - * struct bcm_dsd_header dsdHeader = {0}; - */ - - /* sigoffsetInMap =(PUCHAR)&(dsdHeader.DSDImageMagicNumber) -(PUCHAR)&dsdHeader; */ - - if (dsd != DSD0 && dsd != DSD1 && dsd != DSD2) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "passed section value is not for DSDs"); - return STATUS_FAILURE; - } - BcmFlash2xBulkRead(Adapter, - &uiDSDsig, - dsd, - Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber), - SIGNATURE_SIZE); - - uiDSDsig = ntohl(uiDSDsig); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD SIG :%x", uiDSDsig); - - return uiDSDsig; -} - -static int ReadDSDPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd) -{ - /* unsigned int priOffsetInMap = 0 ; */ - unsigned int uiDSDPri = STATUS_FAILURE; - /* struct bcm_dsd_header dsdHeader = {0}; - * priOffsetInMap = (PUCHAR)&(dsdHeader.DSDImagePriority) -(PUCHAR)&dsdHeader; - */ - if (IsSectionWritable(Adapter, dsd)) { - if (ReadDSDSignature(Adapter, dsd) == DSD_IMAGE_MAGIC_NUMBER) { - BcmFlash2xBulkRead(Adapter, - &uiDSDPri, - dsd, - Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority), - 4); - - uiDSDPri = ntohl(uiDSDPri); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD<%x> Priority :%x", dsd, uiDSDPri); - } - } - - return uiDSDPri; -} - -static enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter) -{ - int DSDHighestPri = STATUS_FAILURE; - int DsdPri = 0; - enum bcm_flash2x_section_val HighestPriDSD = 0; - - if (IsSectionWritable(Adapter, DSD2)) { - DSDHighestPri = ReadDSDPriority(Adapter, DSD2); - HighestPriDSD = DSD2; - } - - if (IsSectionWritable(Adapter, DSD1)) { - DsdPri = ReadDSDPriority(Adapter, DSD1); - if (DSDHighestPri < DsdPri) { - DSDHighestPri = DsdPri; - HighestPriDSD = DSD1; - } - } - - if (IsSectionWritable(Adapter, DSD0)) { - DsdPri = ReadDSDPriority(Adapter, DSD0); - if (DSDHighestPri < DsdPri) { - DSDHighestPri = DsdPri; - HighestPriDSD = DSD0; - } - } - if (HighestPriDSD) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Highest DSD :%x , and its Pri :%x", HighestPriDSD, DSDHighestPri); - - return HighestPriDSD; -} - -static int ReadISOSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso) -{ - unsigned int uiISOsig = 0; - /* unsigned int sigoffsetInMap = 0; - * struct bcm_iso_header ISOHeader = {0}; - * sigoffsetInMap =(PUCHAR)&(ISOHeader.ISOImageMagicNumber) -(PUCHAR)&ISOHeader; - */ - if (iso != ISO_IMAGE1 && iso != ISO_IMAGE2) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "passed section value is not for ISOs"); - return STATUS_FAILURE; - } - BcmFlash2xBulkRead(Adapter, - &uiISOsig, - iso, - 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageMagicNumber), - SIGNATURE_SIZE); - - uiISOsig = ntohl(uiISOsig); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO SIG :%x", uiISOsig); - - return uiISOsig; -} - -static int ReadISOPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso) -{ - unsigned int ISOPri = STATUS_FAILURE; - - if (IsSectionWritable(Adapter, iso)) { - if (ReadISOSignature(Adapter, iso) == ISO_IMAGE_MAGIC_NUMBER) { - BcmFlash2xBulkRead(Adapter, - &ISOPri, - iso, - 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImagePriority), - 4); - - ISOPri = ntohl(ISOPri); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO<%x> Priority :%x", iso, ISOPri); - } - } - - return ISOPri; -} - -static enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter) -{ - int ISOHighestPri = STATUS_FAILURE; - int ISOPri = 0; - enum bcm_flash2x_section_val HighestPriISO = NO_SECTION_VAL; - - if (IsSectionWritable(Adapter, ISO_IMAGE2)) { - ISOHighestPri = ReadISOPriority(Adapter, ISO_IMAGE2); - HighestPriISO = ISO_IMAGE2; - } - - if (IsSectionWritable(Adapter, ISO_IMAGE1)) { - ISOPri = ReadISOPriority(Adapter, ISO_IMAGE1); - if (ISOHighestPri < ISOPri) { - ISOHighestPri = ISOPri; - HighestPriISO = ISO_IMAGE1; - } - } - if (HighestPriISO) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Highest ISO :%x and its Pri :%x", HighestPriISO, ISOHighestPri); - - return HighestPriISO; -} - -static int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, - PUINT pBuff, - enum bcm_flash2x_section_val eFlash2xSectionVal, - unsigned int uiOffset, - unsigned int uiNumBytes) -{ - #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) - unsigned int uiTemp = 0, value = 0; - unsigned int i = 0; - unsigned int uiPartOffset = 0; - #endif - unsigned int uiStartOffset = 0; - /* Adding section start address */ - int Status = STATUS_SUCCESS; - PUCHAR pcBuff = (PUCHAR)pBuff; - - if (uiNumBytes % Adapter->ulFlashWriteSize) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Writing without Sector Erase for non-FlashWriteSize number of bytes 0x%x\n", uiNumBytes); - return STATUS_FAILURE; - } - - uiStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal); - - if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal)) - return vendorextnWriteSectionWithoutErase(Adapter, pcBuff, eFlash2xSectionVal, uiOffset, uiNumBytes); - - uiOffset = uiOffset + uiStartOffset; - - #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) - Status = bcmflash_raw_writenoerase((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), pcBuff, uiNumBytes); - #else - rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - value = 0; - wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); - - Adapter->SelectedChip = RESET_CHIP_SELECT; - BcmDoChipSelect(Adapter, uiOffset); - uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); - - for (i = 0; i < uiNumBytes; i += Adapter->ulFlashWriteSize) { - if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT) - Status = flashByteWrite(Adapter, uiPartOffset, pcBuff); - else - Status = flashWrite(Adapter, uiPartOffset, pcBuff); - - if (Status != STATUS_SUCCESS) - break; - - pcBuff = pcBuff + Adapter->ulFlashWriteSize; - uiPartOffset = uiPartOffset + Adapter->ulFlashWriteSize; - } - wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - Adapter->SelectedChip = RESET_CHIP_SELECT; - #endif - - return Status; -} - -bool IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section) -{ - bool SectionPresent = false; - - switch (section) { - case ISO_IMAGE1: - if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == false)) - SectionPresent = TRUE; - break; - case ISO_IMAGE2: - if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == false)) - SectionPresent = TRUE; - break; - case DSD0: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - case DSD1: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - case DSD2: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - case VSA0: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - case VSA1: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - case VSA2: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - case SCSI: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - case CONTROL_SECTION: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - default: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x"); - SectionPresent = false; - } - - return SectionPresent; -} - -static int IsSectionWritable(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val Section) -{ - int offset = STATUS_FAILURE; - int Status = false; - - if (IsSectionExistInFlash(Adapter, Section) == false) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section <%d> does not exist", Section); - return false; - } - - offset = BcmGetSectionValStartOffset(Adapter, Section); - if (offset == INVALID_OFFSET) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%d> does not exist", Section); - return false; - } - - if (IsSectionExistInVendorInfo(Adapter, Section)) - return !(Adapter->psFlash2xVendorInfo->VendorSection[Section].AccessFlags & FLASH2X_SECTION_RO); - - Status = IsOffsetWritable(Adapter, offset); - return Status; -} - -static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal) -{ - PUCHAR pBuff = NULL; - unsigned int sig = 0; - unsigned int uiOffset = 0; - unsigned int BlockStatus = 0; - unsigned int uiSectAlignAddr = 0; - - Adapter->bSigCorrupted = false; - if (Adapter->bAllDSDWriteAllow == false) { - if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature"); - return SECTOR_IS_NOT_WRITABLE; - } - } - - pBuff = kzalloc(MAX_RW_SIZE, GFP_KERNEL); - if (!pBuff) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey"); - return -ENOMEM; - } - - uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header); - uiOffset -= MAX_RW_SIZE; - - BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, MAX_RW_SIZE); - - sig = *((PUINT)(pBuff + 12)); - sig = ntohl(sig); - BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pBuff, MAX_RW_SIZE); - /* Now corrupting the sig by corrupting 4th last Byte. */ - *(pBuff + 12) = 0; - - if (sig == DSD_IMAGE_MAGIC_NUMBER) { - Adapter->bSigCorrupted = TRUE; - if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT) { - uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); - BlockStatus = BcmFlashUnProtectBlock(Adapter, uiSectAlignAddr, Adapter->uiSectorSize); - - WriteToFlashWithoutSectorErase(Adapter, (PUINT)(pBuff + 12), eFlash2xSectionVal, - (uiOffset + 12), BYTE_WRITE_SUPPORT); - if (BlockStatus) { - BcmRestoreBlockProtectStatus(Adapter, BlockStatus); - BlockStatus = 0; - } - } else { - WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal, - uiOffset, MAX_RW_SIZE); - } - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header"); - kfree(pBuff); - - return STATUS_FAILURE; - } - - kfree(pBuff); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Corrupted the signature"); - - return STATUS_SUCCESS; -} - -static int CorruptISOSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal) -{ - PUCHAR pBuff = NULL; - unsigned int sig = 0; - unsigned int uiOffset = 0; - - Adapter->bSigCorrupted = false; - - if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature"); - return SECTOR_IS_NOT_WRITABLE; - } - - pBuff = kzalloc(MAX_RW_SIZE, GFP_KERNEL); - if (!pBuff) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey"); - return -ENOMEM; - } - - uiOffset = 0; - - BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, MAX_RW_SIZE); - - sig = *((PUINT)pBuff); - sig = ntohl(sig); - - /* corrupt signature */ - *pBuff = 0; - - if (sig == ISO_IMAGE_MAGIC_NUMBER) { - Adapter->bSigCorrupted = TRUE; - WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal, - uiOffset, Adapter->ulFlashWriteSize); - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header"); - kfree(pBuff); - - return STATUS_FAILURE; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Corrupted the signature"); - BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pBuff, MAX_RW_SIZE); - - kfree(pBuff); - return STATUS_SUCCESS; -} - -bool IsNonCDLessDevice(struct bcm_mini_adapter *Adapter) -{ - if (Adapter->psFlash2xCSInfo->IsCDLessDeviceBootSig == NON_CDLESS_DEVICE_BOOT_SIG) - return TRUE; - else - return false; -} diff --git a/drivers/staging/bcm/nvm.h b/drivers/staging/bcm/nvm.h deleted file mode 100644 index e765cca5d966..000000000000 --- a/drivers/staging/bcm/nvm.h +++ /dev/null @@ -1,286 +0,0 @@ -/*************************************************************************************** - * - * Copyright (c) Beceem Communications Inc. - * - * Module Name: - * NVM.h - * - * Abstract: - * This file has the prototypes,preprocessors and definitions various NVM libraries. - * - * - * Revision History: - * Who When What - * -------- -------- ---------------------------------------------- - * Name Date Created/reviewed/modified - * - * Notes: - * - ****************************************************************************************/ - -#ifndef _NVM_H_ -#define _NVM_H_ - -struct bcm_flash_cs_info { - u32 MagicNumber; - /* let the magic number be 0xBECE-F1A5 - F1A5 for "flas-h" */ - u32 FlashLayoutVersion; - u32 ISOImageVersion; - u32 SCSIFirmwareVersion; - u32 OffsetFromZeroForPart1ISOImage; - u32 OffsetFromZeroForScsiFirmware; - u32 SizeOfScsiFirmware; - u32 OffsetFromZeroForPart2ISOImage; - u32 OffsetFromZeroForCalibrationStart; - u32 OffsetFromZeroForCalibrationEnd; - u32 OffsetFromZeroForVSAStart; - u32 OffsetFromZeroForVSAEnd; - u32 OffsetFromZeroForControlSectionStart; - u32 OffsetFromZeroForControlSectionData; - u32 CDLessInactivityTimeout; - u32 NewImageSignature; - u32 FlashSectorSizeSig; - u32 FlashSectorSize; - u32 FlashWriteSupportSize; - u32 TotalFlashSize; - u32 FlashBaseAddr; - u32 FlashPartMaxSize; - u32 IsCDLessDeviceBootSig; - /* MSC Timeout after reset to switch from MSC to NW Mode */ - u32 MassStorageTimeout; -}; - -#define FLASH2X_TOTAL_SIZE (64 * 1024 * 1024) -#define DEFAULT_SECTOR_SIZE (64 * 1024) - -struct bcm_flash2x_cs_info { - /* magic number as 0xBECE-F1A5 - F1A5 for "flas-h" */ - u32 MagicNumber; - u32 FlashLayoutVersion; - u32 ISOImageVersion; - u32 SCSIFirmwareVersion; - u32 OffsetFromZeroForPart1ISOImage; - u32 OffsetFromZeroForScsiFirmware; - u32 SizeOfScsiFirmware; - u32 OffsetFromZeroForPart2ISOImage; - u32 OffsetFromZeroForDSDStart; - u32 OffsetFromZeroForDSDEnd; - u32 OffsetFromZeroForVSAStart; - u32 OffsetFromZeroForVSAEnd; - u32 OffsetFromZeroForControlSectionStart; - u32 OffsetFromZeroForControlSectionData; - /* NO Data Activity timeout to switch from MSC to NW Mode */ - u32 CDLessInactivityTimeout; - u32 NewImageSignature; - u32 FlashSectorSizeSig; - u32 FlashSectorSize; - u32 FlashWriteSupportSize; - u32 TotalFlashSize; - u32 FlashBaseAddr; - u32 FlashPartMaxSize; - u32 IsCDLessDeviceBootSig; - /* MSC Timeout after reset to switch from MSC to NW Mode */ - u32 MassStorageTimeout; - /* Flash Map 2.0 Field */ - u32 OffsetISOImage1Part1Start; - u32 OffsetISOImage1Part1End; - u32 OffsetISOImage1Part2Start; - u32 OffsetISOImage1Part2End; - u32 OffsetISOImage1Part3Start; - u32 OffsetISOImage1Part3End; - u32 OffsetISOImage2Part1Start; - u32 OffsetISOImage2Part1End; - u32 OffsetISOImage2Part2Start; - u32 OffsetISOImage2Part2End; - u32 OffsetISOImage2Part3Start; - u32 OffsetISOImage2Part3End; - /* DSD Header offset from start of DSD */ - u32 OffsetFromDSDStartForDSDHeader; - u32 OffsetFromZeroForDSD1Start; - u32 OffsetFromZeroForDSD1End; - u32 OffsetFromZeroForDSD2Start; - u32 OffsetFromZeroForDSD2End; - u32 OffsetFromZeroForVSA1Start; - u32 OffsetFromZeroForVSA1End; - u32 OffsetFromZeroForVSA2Start; - u32 OffsetFromZeroForVSA2End; - /* - * ACCESS_BITS_PER_SECTOR 2 - * ACCESS_RW 0 - * ACCESS_RO 1 - * ACCESS_RESVD 2 - * ACCESS_RESVD 3 - */ - u32 SectorAccessBitMap[FLASH2X_TOTAL_SIZE / (DEFAULT_SECTOR_SIZE * 16)]; - /* All expansions to the control data structure should add here */ -}; - -struct bcm_vendor_section_info { - u32 OffsetFromZeroForSectionStart; - u32 OffsetFromZeroForSectionEnd; - u32 AccessFlags; - u32 Reserved[16]; -}; - -struct bcm_flash2x_vendor_info { - struct bcm_vendor_section_info VendorSection[TOTAL_SECTIONS]; - u32 Reserved[16]; -}; - -struct bcm_dsd_header { - u32 DSDImageSize; - u32 DSDImageCRC; - u32 DSDImagePriority; - /* We should not consider right now. Reading reserve is worthless. */ - u32 Reserved[252]; /* Resvd for DSD Header */ - u32 DSDImageMagicNumber; -}; - -struct bcm_iso_header { - u32 ISOImageMagicNumber; - u32 ISOImageSize; - u32 ISOImageCRC; - u32 ISOImagePriority; - /* We should not consider right now. Reading reserve is worthless. */ - u32 Reserved[60]; /* Resvd for ISO Header extension */ -}; - -#define EEPROM_BEGIN_CIS (0) -#define EEPROM_BEGIN_NON_CIS (0x200) -#define EEPROM_END (0x2000) -#define INIT_PARAMS_SIGNATURE (0x95a7a597) -#define MAX_INIT_PARAMS_LENGTH (2048) -#define MAC_ADDRESS_OFFSET 0x200 - -#define INIT_PARAMS_1_SIGNATURE_ADDRESS EEPROM_BEGIN_NON_CIS -#define INIT_PARAMS_1_DATA_ADDRESS (INIT_PARAMS_1_SIGNATURE_ADDRESS+16) -#define INIT_PARAMS_1_MACADDRESS_ADDRESS (MAC_ADDRESS_OFFSET) -#define INIT_PARAMS_1_LENGTH_ADDRESS (INIT_PARAMS_1_SIGNATURE_ADDRESS+4) - -#define INIT_PARAMS_2_SIGNATURE_ADDRESS (EEPROM_BEGIN_NON_CIS + 2048 + 16) -#define INIT_PARAMS_2_DATA_ADDRESS (INIT_PARAMS_2_SIGNATURE_ADDRESS + 16) -#define INIT_PARAMS_2_MACADDRESS_ADDRESS (INIT_PARAMS_2_SIGNATURE_ADDRESS + 8) -#define INIT_PARAMS_2_LENGTH_ADDRESS (INIT_PARAMS_2_SIGNATURE_ADDRESS + 4) - -#define EEPROM_SPI_DEV_CONFIG_REG 0x0F003000 -#define EEPROM_SPI_Q_STATUS1_REG 0x0F003004 -#define EEPROM_SPI_Q_STATUS1_MASK_REG 0x0F00300C - -#define EEPROM_SPI_Q_STATUS_REG 0x0F003008 -#define EEPROM_CMDQ_SPI_REG 0x0F003018 -#define EEPROM_WRITE_DATAQ_REG 0x0F00301C -#define EEPROM_READ_DATAQ_REG 0x0F003020 -#define SPI_FLUSH_REG 0x0F00304C - -#define EEPROM_WRITE_ENABLE 0x06000000 -#define EEPROM_READ_STATUS_REGISTER 0x05000000 -#define EEPROM_16_BYTE_PAGE_WRITE 0xFA000000 -#define EEPROM_WRITE_QUEUE_EMPTY 0x00001000 -#define EEPROM_WRITE_QUEUE_AVAIL 0x00002000 -#define EEPROM_WRITE_QUEUE_FULL 0x00004000 -#define EEPROM_16_BYTE_PAGE_READ 0xFB000000 -#define EEPROM_4_BYTE_PAGE_READ 0x3B000000 - -#define EEPROM_CMD_QUEUE_FLUSH 0x00000001 -#define EEPROM_WRITE_QUEUE_FLUSH 0x00000002 -#define EEPROM_READ_QUEUE_FLUSH 0x00000004 -#define EEPROM_ETH_QUEUE_FLUSH 0x00000008 -#define EEPROM_ALL_QUEUE_FLUSH 0x0000000f -#define EEPROM_READ_ENABLE 0x06000000 -#define EEPROM_16_BYTE_PAGE_WRITE 0xFA000000 -#define EEPROM_READ_DATA_FULL 0x00000010 -#define EEPROM_READ_DATA_AVAIL 0x00000020 -#define EEPROM_READ_QUEUE_EMPTY 0x00000002 -#define EEPROM_CMD_QUEUE_EMPTY 0x00000100 -#define EEPROM_CMD_QUEUE_AVAIL 0x00000200 -#define EEPROM_CMD_QUEUE_FULL 0x00000400 - -/* Most EEPROM status register bit 0 indicates if the EEPROM is busy - * with a write if set 1. See the details of the EEPROM Status Register - * in the EEPROM data sheet. - */ -#define EEPROM_STATUS_REG_WRITE_BUSY 0x00000001 - -/* We will have 1 mSec for every RETRIES_PER_DELAY count and have a max attempts of MAX_EEPROM_RETRIES - * This will give us 80 mSec minimum of delay = 80mSecs - */ -#define MAX_EEPROM_RETRIES 80 -#define RETRIES_PER_DELAY 64 -#define MAX_RW_SIZE 0x10 -#define MAX_READ_SIZE 0x10 -#define MAX_SECTOR_SIZE (512 * 1024) -#define MIN_SECTOR_SIZE (1024) -#define FLASH_SECTOR_SIZE_OFFSET 0xEFFFC -#define FLASH_SECTOR_SIZE_SIG_OFFSET 0xEFFF8 -#define FLASH_SECTOR_SIZE_SIG 0xCAFEBABE -#define FLASH_CS_INFO_START_ADDR 0xFF0000 -#define FLASH_CONTROL_STRUCT_SIGNATURE 0xBECEF1A5 -#define SCSI_FIRMWARE_MAJOR_VERSION 0x1 -#define SCSI_FIRMWARE_MINOR_VERSION 0x5 -#define BYTE_WRITE_SUPPORT 0x1 -#define FLASH_AUTO_INIT_BASE_ADDR 0xF00000 -#define FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT 0x1C000000 -#define FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT 0x1F000000 -#define FLASH_CONTIGIOUS_START_ADDR_BCS350 0x08000000 -#define FLASH_CONTIGIOUS_END_ADDR_BCS350 0x08FFFFFF -#define FLASH_SIZE_ADDR 0xFFFFEC -#define FLASH_SPI_CMDQ_REG 0xAF003040 -#define FLASH_SPI_WRITEQ_REG 0xAF003044 -#define FLASH_SPI_READQ_REG 0xAF003048 -#define FLASH_CONFIG_REG 0xAF003050 -#define FLASH_GPIO_CONFIG_REG 0xAF000030 -#define FLASH_CMD_WRITE_ENABLE 0x06 -#define FLASH_CMD_READ_ENABLE 0x03 -#define FLASH_CMD_RESET_WRITE_ENABLE 0x04 -#define FLASH_CMD_STATUS_REG_READ 0x05 -#define FLASH_CMD_STATUS_REG_WRITE 0x01 -#define FLASH_CMD_READ_ID 0x9F -#define PAD_SELECT_REGISTER 0xAF000410 -#define FLASH_PART_SST25VF080B 0xBF258E -#define EEPROM_CAL_DATA_INTERNAL_LOC 0xbFB00008 -#define EEPROM_CALPARAM_START 0x200 -#define EEPROM_SIZE_OFFSET 524 - -/* As Read/Write time vaires from 1.5 to 3.0 ms. - * so After Ignoring the rdm/wrm time(that is dependent on many factor like interface etc.), - * here time calculated meets the worst case delay, 3.0 ms - */ -#define MAX_FLASH_RETRIES 4 -#define FLASH_PER_RETRIES_DELAY 16 -#define EEPROM_MAX_CAL_AREA_SIZE 0xF0000 -#define BECM ntohl(0x4245434d) -#define FLASH_2X_MAJOR_NUMBER 0x2 -#define DSD_IMAGE_MAGIC_NUMBER 0xBECE0D5D -#define ISO_IMAGE_MAGIC_NUMBER 0xBECE0150 -#define NON_CDLESS_DEVICE_BOOT_SIG 0xBECEB007 - -#define MINOR_VERSION(x) ((x >> 16) & 0xFFFF) -#define MAJOR_VERSION(x) (x & 0xFFFF) - -#define CORRUPTED_PATTERN 0x0 -#define UNINIT_PTR_IN_CS 0xBBBBDDDD -#define VENDOR_PTR_IN_CS 0xAAAACCCC -#define FLASH2X_SECTION_PRESENT (1 << 0) -#define FLASH2X_SECTION_VALID (1 << 1) -#define FLASH2X_SECTION_RO (1 << 2) -#define FLASH2X_SECTION_ACT (1 << 3) -#define SECTOR_IS_NOT_WRITABLE STATUS_FAILURE -#define INVALID_OFFSET STATUS_FAILURE -#define INVALID_SECTION STATUS_FAILURE -#define SECTOR_1K 1024 -#define SECTOR_64K (64 * SECTOR_1K) -#define SECTOR_128K (2 * SECTOR_64K) -#define SECTOR_256k (2 * SECTOR_128K) -#define SECTOR_512K (2 * SECTOR_256k) -#define FLASH_PART_SIZE (16 * 1024 * 1024) -#define RESET_CHIP_SELECT -1 -#define CHIP_SELECT_BIT12 12 -#define SECTOR_READWRITE_PERMISSION 0 -#define SECTOR_READONLY 1 -#define SIGNATURE_SIZE 4 -#define DEFAULT_BUFF_SIZE 0x10000 - -#define FIELD_OFFSET_IN_HEADER(HeaderPointer, Field) ((u8 *)&((HeaderPointer)(NULL))->Field - (u8 *)(NULL)) - -#endif - diff --git a/drivers/staging/bcm/sort.c b/drivers/staging/bcm/sort.c deleted file mode 100644 index ca0b17991512..000000000000 --- a/drivers/staging/bcm/sort.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "headers.h" -#include <linux/sort.h> - -/* - * File Name: sort.c - * - * Author: Beceem Communications Pvt. Ltd - * - * Abstract: This file contains the routines sorting the classification rules. - * - * Copyright (c) 2007 Beceem Communications Pvt. Ltd - */ - -static int compare_packet_info(void const *a, void const *b) -{ - struct bcm_packet_info const *pa = a; - struct bcm_packet_info const *pb = b; - - if (!pa->bValid || !pb->bValid) - return 0; - - return pa->u8TrafficPriority - pb->u8TrafficPriority; -} - -VOID SortPackInfo(struct bcm_mini_adapter *Adapter) -{ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, - DBG_LVL_ALL, "<======="); - - sort(Adapter->PackInfo, NO_OF_QUEUES, sizeof(struct bcm_packet_info), - compare_packet_info, NULL); -} - -static int compare_classifiers(void const *a, void const *b) -{ - struct bcm_classifier_rule const *pa = a; - struct bcm_classifier_rule const *pb = b; - - if (!pa->bUsed || !pb->bUsed) - return 0; - - return pa->u8ClassifierRulePriority - pb->u8ClassifierRulePriority; -} - -VOID SortClassifiers(struct bcm_mini_adapter *Adapter) -{ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, - DBG_LVL_ALL, "<======="); - - sort(Adapter->astClassifierTable, MAX_CLASSIFIERS, - sizeof(struct bcm_classifier_rule), compare_classifiers, NULL); -} diff --git a/drivers/staging/bcm/target_params.h b/drivers/staging/bcm/target_params.h deleted file mode 100644 index dc45f9ab854d..000000000000 --- a/drivers/staging/bcm/target_params.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef TARGET_PARAMS_H -#define TARGET_PARAMS_H - -struct bcm_target_params { - u32 m_u32CfgVersion; - u32 m_u32CenterFrequency; - u32 m_u32BandAScan; - u32 m_u32BandBScan; - u32 m_u32BandCScan; - u32 m_u32ErtpsOptions; - u32 m_u32PHSEnable; - u32 m_u32HoEnable; - u32 m_u32HoReserved1; - u32 m_u32HoReserved2; - u32 m_u32MimoEnable; - u32 m_u32SecurityEnable; - u32 m_u32PowerSavingModesEnable; /* bit 1: 1 Idlemode enable; bit2: 1 Sleepmode Enable */ - /* PowerSaving Mode Options: - * bit 0 = 1: CPE mode - to keep pcmcia if alive; - * bit 1 = 1: CINR reporting in Idlemode Msg - * bit 2 = 1: Default PSC Enable in sleepmode - */ - u32 m_u32PowerSavingModeOptions; - u32 m_u32ArqEnable; - /* From Version #3, the HARQ section renamed as general */ - u32 m_u32HarqEnable; - u32 m_u32EEPROMFlag; - /* BINARY TYPE - 4th MSByte: Interface Type - 3rd MSByte: Vendor Type - 2nd MSByte - * Unused - LSByte - */ - u32 m_u32Customize; - u32 m_u32ConfigBW; /* In Hz */ - u32 m_u32ShutDownInitThresholdTimer; - u32 m_u32RadioParameter; - u32 m_u32PhyParameter1; - u32 m_u32PhyParameter2; - u32 m_u32PhyParameter3; - u32 m_u32TestOptions; /* in eval mode only; lower 16bits = basic cid for testing; then bit 16 is test cqich,bit 17 test init rang; bit 18 test periodic rang and bit 19 is test harq ack/nack */ - u32 m_u32MaxMACDataperDLFrame; - u32 m_u32MaxMACDataperULFrame; - u32 m_u32Corr2MacFlags; - u32 HostDrvrConfig1; - u32 HostDrvrConfig2; - u32 HostDrvrConfig3; - u32 HostDrvrConfig4; - u32 HostDrvrConfig5; - u32 HostDrvrConfig6; - u32 m_u32SegmentedPUSCenable; - /* removed SHUT down related 'unused' params from here to sync 4.x and 5.x CFG files.. - * BAMC Related Parameters - * Bit 0-15 Band AMC signaling configuration: Bit 1 = 1 – Enable Band AMC signaling. - * bit 16-31 Band AMC Data configuration: Bit 16 = 1 – Band AMC 2x3 support. - */ - u32 m_u32BandAMCEnable; -}; - -#endif diff --git a/drivers/staging/bcm/vendorspecificextn.c b/drivers/staging/bcm/vendorspecificextn.c deleted file mode 100644 index 1d9bef6e4273..000000000000 --- a/drivers/staging/bcm/vendorspecificextn.c +++ /dev/null @@ -1,145 +0,0 @@ -#include "headers.h" -/* - * Procedure: vendorextnGetSectionInfo - * - * Description: Finds the type of NVM used. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * pNVMType - ptr to NVM type. - * Returns: - * STATUS_SUCCESS/STATUS_FAILURE - * - */ -INT vendorextnGetSectionInfo(PVOID pContext, - struct bcm_flash2x_vendor_info *pVendorInfo) -{ - return STATUS_FAILURE; -} - -/* - * Procedure: vendorextnInit - * - * Description: Initializing the vendor extension NVM interface - * - * Arguments: - * Adapter - Pointer to MINI Adapter Structure - * Returns: - * STATUS_SUCCESS/STATUS_FAILURE - * - * - */ -INT vendorextnInit(struct bcm_mini_adapter *Adapter) -{ - return STATUS_SUCCESS; -} - -/* - * Procedure: vendorextnExit - * - * Description: Free the resource associated with vendor extension NVM interface - * - * Arguments: - * - * Returns: - * STATUS_SUCCESS/STATUS_FAILURE - * - * - */ -INT vendorextnExit(struct bcm_mini_adapter *Adapter) -{ - return STATUS_SUCCESS; -} - -/* - * Procedure: vendorextnIoctl - * - * Description: execute the vendor extension specific ioctl - * - * Arguments: - * Adapter -Beceem private Adapter Structure - * cmd -vendor extension specific Ioctl commad - * arg -input parameter sent by vendor - * - * Returns: - * CONTINUE_COMMON_PATH in case it is not meant to be processed - * by vendor ioctls - * STATUS_SUCCESS/STATUS_FAILURE as per the IOCTL return value - */ - -INT vendorextnIoctl(struct bcm_mini_adapter *Adapter, UINT cmd, ULONG arg) -{ - return CONTINUE_COMMON_PATH; -} - - - -/* - * Procedure: vendorextnReadSection - * - * Description: Reads from a section of NVM - * - * Arguments: - * pContext - ptr to Adapter object instance - * pBuffer - Read the data from Vendor Area to this buffer - * SectionVal - Value of type of Section - * Offset - Read from the Offset of the Vendor Section. - * numOfBytes - Read numOfBytes from the Vendor section to Buffer - * - * Returns: - * STATUS_SUCCESS/STATUS_FAILURE - */ - -INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, - enum bcm_flash2x_section_val SectionVal, UINT offset, UINT numOfBytes) -{ - return STATUS_FAILURE; -} - - - -/* - * Procedure: vendorextnWriteSection - * - * Description: Write to a Section of NVM - * - * Arguments: - * pContext - ptr to Adapter object instance - * pBuffer - Write the data provided in the buffer - * SectionVal - Value of type of Section - * Offset - Writes to the Offset of the Vendor Section. - * numOfBytes - Write num Bytes after reading from pBuffer. - * bVerify - the Buffer Written should be verified. - * - * Returns: - * STATUS_SUCCESS/STATUS_FAILURE - */ -INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, - enum bcm_flash2x_section_val SectionVal, UINT offset, - UINT numOfBytes, bool bVerify) -{ - return STATUS_FAILURE; -} - - - -/* - * Procedure: vendorextnWriteSectionWithoutErase - * - * Description: Write to a Section of NVM without erasing the sector - * - * Arguments: - * pContext - ptr to Adapter object instance - * pBuffer - Write the data provided in the buffer - * SectionVal - Value of type of Section - * Offset - Writes to the Offset of the Vendor Section. - * numOfBytes - Write num Bytes after reading from pBuffer. - * - * Returns: - * STATUS_SUCCESS/STATUS_FAILURE - */ -INT vendorextnWriteSectionWithoutErase(PVOID pContext, PUCHAR pBuffer, - enum bcm_flash2x_section_val SectionVal, UINT offset, UINT numOfBytes) -{ - return STATUS_FAILURE; -} diff --git a/drivers/staging/bcm/vendorspecificextn.h b/drivers/staging/bcm/vendorspecificextn.h deleted file mode 100644 index ff57f0570451..000000000000 --- a/drivers/staging/bcm/vendorspecificextn.h +++ /dev/null @@ -1,18 +0,0 @@ - -#ifndef __VENDOR_EXTN_NVM_H__ -#define __VENDOR_EXTN_NVM_H__ - -#define CONTINUE_COMMON_PATH 0xFFFF - -INT vendorextnGetSectionInfo(PVOID pContext, struct bcm_flash2x_vendor_info *pVendorInfo); -INT vendorextnExit(struct bcm_mini_adapter *Adapter); -INT vendorextnInit(struct bcm_mini_adapter *Adapter); -INT vendorextnIoctl(struct bcm_mini_adapter *Adapter, UINT cmd, ULONG arg); -INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal, - UINT offset, UINT numOfBytes); -INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal, - UINT offset, UINT numOfBytes, bool bVerify); -INT vendorextnWriteSectionWithoutErase(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal, - UINT offset, UINT numOfBytes); - -#endif /* */ diff --git a/drivers/staging/clocking-wizard/Kconfig b/drivers/staging/clocking-wizard/Kconfig new file mode 100644 index 000000000000..357af02c562c --- /dev/null +++ b/drivers/staging/clocking-wizard/Kconfig @@ -0,0 +1,9 @@ +# +# Xilinx Clocking Wizard Driver +# + +config COMMON_CLK_XLNX_CLKWZRD + tristate "Xilinx Clocking Wizard" + depends on COMMON_CLK && OF + ---help--- + Support for the Xilinx Clocking Wizard IP core clock generator. diff --git a/drivers/staging/clocking-wizard/Makefile b/drivers/staging/clocking-wizard/Makefile new file mode 100644 index 000000000000..5ad352f521fe --- /dev/null +++ b/drivers/staging/clocking-wizard/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD) += clk-xlnx-clock-wizard.o diff --git a/drivers/staging/clocking-wizard/TODO b/drivers/staging/clocking-wizard/TODO new file mode 100644 index 000000000000..ebe99db7d153 --- /dev/null +++ b/drivers/staging/clocking-wizard/TODO @@ -0,0 +1,12 @@ +TODO: + - support for fractional multiplier + - support for fractional divider (output 0 only) + - support for set_rate() operations (may benefit from Stephen Boyd's + refactoring of the clk primitives: https://lkml.org/lkml/2014/9/5/766) + - review arithmetic + - overflow after multiplication? + - maximize accuracy before divisions + +Patches to: + Greg Kroah-Hartman <gregkh@linuxfoundation.org> + Sören Brinkmann <soren.brinkmann@xilinx.com> diff --git a/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c b/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c new file mode 100644 index 000000000000..471d0877f382 --- /dev/null +++ b/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c @@ -0,0 +1,341 @@ +/* + * Xilinx 'Clocking Wizard' driver + * + * Copyright (C) 2013 - 2014 Xilinx + * + * Sören Brinkmann <soren.brinkmann@xilinx.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License v2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/platform_device.h> +#include <linux/clk-provider.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/module.h> +#include <linux/err.h> + +#define WZRD_NUM_OUTPUTS 7 +#define WZRD_ACLK_MAX_FREQ 250000000UL + +#define WZRD_CLK_CFG_REG(n) (0x200 + 4 * (n)) + +#define WZRD_CLkOUT0_FRAC_EN BIT(18) +#define WZRD_CLkFBOUT_FRAC_EN BIT(26) + +#define WZRD_CLKFBOUT_MULT_SHIFT 8 +#define WZRD_CLKFBOUT_MULT_MASK (0xff << WZRD_CLKFBOUT_MULT_SHIFT) +#define WZRD_DIVCLK_DIVIDE_SHIFT 0 +#define WZRD_DIVCLK_DIVIDE_MASK (0xff << WZRD_DIVCLK_DIVIDE_SHIFT) +#define WZRD_CLKOUT_DIVIDE_SHIFT 0 +#define WZRD_CLKOUT_DIVIDE_MASK (0xff << WZRD_DIVCLK_DIVIDE_SHIFT) + +enum clk_wzrd_int_clks { + wzrd_clk_mul, + wzrd_clk_mul_div, + wzrd_clk_int_max +}; + +/** + * struct clk_wzrd: + * @clk_data: Clock data + * @nb: Notifier block + * @base: Memory base + * @clk_in1: Handle to input clock 'clk_in1' + * @axi_clk: Handle to input clock 's_axi_aclk' + * @clks_internal: Internal clocks + * @clkout: Output clocks + * @speed_grade: Speed grade of the device + * @suspended: Flag indicating power state of the device + */ +struct clk_wzrd { + struct clk_onecell_data clk_data; + struct notifier_block nb; + void __iomem *base; + struct clk *clk_in1; + struct clk *axi_clk; + struct clk *clks_internal[wzrd_clk_int_max]; + struct clk *clkout[WZRD_NUM_OUTPUTS]; + int speed_grade; + bool suspended; +}; +#define to_clk_wzrd(_nb) container_of(_nb, struct clk_wzrd, nb) + +/* maximum frequencies for input/output clocks per speed grade */ +static const unsigned long clk_wzrd_max_freq[] = { + 800000000UL, + 933000000UL, + 1066000000UL +}; + +static int clk_wzrd_clk_notifier(struct notifier_block *nb, unsigned long event, + void *data) +{ + unsigned long max; + struct clk_notifier_data *ndata = data; + struct clk_wzrd *clk_wzrd = to_clk_wzrd(nb); + + if (clk_wzrd->suspended) + return NOTIFY_OK; + + if (ndata->clk == clk_wzrd->clk_in1) + max = clk_wzrd_max_freq[clk_wzrd->speed_grade - 1]; + if (ndata->clk == clk_wzrd->axi_clk) + max = WZRD_ACLK_MAX_FREQ; + + switch (event) { + case PRE_RATE_CHANGE: + if (ndata->new_rate > max) + return NOTIFY_BAD; + return NOTIFY_OK; + case POST_RATE_CHANGE: + case ABORT_RATE_CHANGE: + default: + return NOTIFY_DONE; + } +} + +static int __maybe_unused clk_wzrd_suspend(struct device *dev) +{ + struct clk_wzrd *clk_wzrd = dev_get_drvdata(dev); + + clk_disable_unprepare(clk_wzrd->axi_clk); + clk_wzrd->suspended = true; + + return 0; +} + +static int __maybe_unused clk_wzrd_resume(struct device *dev) +{ + int ret; + struct clk_wzrd *clk_wzrd = dev_get_drvdata(dev); + + ret = clk_prepare_enable(clk_wzrd->axi_clk); + if (ret) { + dev_err(dev, "unable to enable s_axi_aclk\n"); + return ret; + } + + clk_wzrd->suspended = false; + + return 0; +} + +static SIMPLE_DEV_PM_OPS(clk_wzrd_dev_pm_ops, clk_wzrd_suspend, + clk_wzrd_resume); + +static int clk_wzrd_probe(struct platform_device *pdev) +{ + int i, ret; + u32 reg; + unsigned long rate; + const char *clk_name; + struct clk_wzrd *clk_wzrd; + struct resource *mem; + struct device_node *np = pdev->dev.of_node; + + clk_wzrd = devm_kzalloc(&pdev->dev, sizeof(*clk_wzrd), GFP_KERNEL); + if (!clk_wzrd) + return -ENOMEM; + platform_set_drvdata(pdev, clk_wzrd); + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + clk_wzrd->base = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(clk_wzrd->base)) + return PTR_ERR(clk_wzrd->base); + + ret = of_property_read_u32(np, "speed-grade", &clk_wzrd->speed_grade); + if (!ret) { + if (clk_wzrd->speed_grade < 1 || clk_wzrd->speed_grade > 3) { + dev_warn(&pdev->dev, "invalid speed grade '%d'\n", + clk_wzrd->speed_grade); + clk_wzrd->speed_grade = 0; + } + } + + clk_wzrd->clk_in1 = devm_clk_get(&pdev->dev, "clk_in1"); + if (IS_ERR(clk_wzrd->clk_in1)) { + if (clk_wzrd->clk_in1 != ERR_PTR(-EPROBE_DEFER)) + dev_err(&pdev->dev, "clk_in1 not found\n"); + return PTR_ERR(clk_wzrd->clk_in1); + } + + clk_wzrd->axi_clk = devm_clk_get(&pdev->dev, "s_axi_aclk"); + if (IS_ERR(clk_wzrd->axi_clk)) { + if (clk_wzrd->axi_clk != ERR_PTR(-EPROBE_DEFER)) + dev_err(&pdev->dev, "s_axi_aclk not found\n"); + return PTR_ERR(clk_wzrd->axi_clk); + } + ret = clk_prepare_enable(clk_wzrd->axi_clk); + if (ret) { + dev_err(&pdev->dev, "enabling s_axi_aclk failed\n"); + return ret; + } + rate = clk_get_rate(clk_wzrd->axi_clk); + if (rate > WZRD_ACLK_MAX_FREQ) { + dev_err(&pdev->dev, "s_axi_aclk frequency (%lu) too high\n", + rate); + ret = -EINVAL; + goto err_disable_clk; + } + + /* we don't support fractional div/mul yet */ + reg = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(0)) & + WZRD_CLkFBOUT_FRAC_EN; + reg |= readl(clk_wzrd->base + WZRD_CLK_CFG_REG(2)) & + WZRD_CLkOUT0_FRAC_EN; + if (reg) + dev_warn(&pdev->dev, "fractional div/mul not supported\n"); + + /* register multiplier */ + reg = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(0)) & + WZRD_CLKFBOUT_MULT_MASK) >> WZRD_CLKFBOUT_MULT_SHIFT; + clk_name = kasprintf(GFP_KERNEL, "%s_mul", dev_name(&pdev->dev)); + if (!clk_name) { + ret = -ENOMEM; + goto err_disable_clk; + } + clk_wzrd->clks_internal[wzrd_clk_mul] = clk_register_fixed_factor( + &pdev->dev, clk_name, + __clk_get_name(clk_wzrd->clk_in1), + 0, reg, 1); + kfree(clk_name); + if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul])) { + dev_err(&pdev->dev, "unable to register fixed-factor clock\n"); + ret = PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul]); + goto err_disable_clk; + } + + /* register div */ + reg = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(0)) & + WZRD_DIVCLK_DIVIDE_MASK) >> WZRD_DIVCLK_DIVIDE_SHIFT; + clk_name = kasprintf(GFP_KERNEL, "%s_mul_div", dev_name(&pdev->dev)); + if (!clk_name) { + ret = -ENOMEM; + goto err_rm_int_clk; + } + + clk_wzrd->clks_internal[wzrd_clk_mul_div] = clk_register_fixed_factor( + &pdev->dev, clk_name, + __clk_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]), + 0, 1, reg); + if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div])) { + dev_err(&pdev->dev, "unable to register divider clock\n"); + ret = PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div]); + goto err_rm_int_clk; + } + + /* register div per output */ + for (i = WZRD_NUM_OUTPUTS - 1; i >= 0 ; i--) { + const char *clkout_name; + if (of_property_read_string_index(np, "clock-output-names", i, + &clkout_name)) { + dev_err(&pdev->dev, + "clock output name not specified\n"); + ret = -EINVAL; + goto err_rm_int_clks; + } + reg = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(2) + i * 12); + reg &= WZRD_CLKOUT_DIVIDE_MASK; + reg >>= WZRD_CLKOUT_DIVIDE_SHIFT; + clk_wzrd->clkout[i] = clk_register_fixed_factor(&pdev->dev, + clkout_name, clk_name, 0, 1, reg); + if (IS_ERR(clk_wzrd->clkout[i])) { + int j; + + for (j = i + 1; j < WZRD_NUM_OUTPUTS; j++) + clk_unregister(clk_wzrd->clkout[j]); + dev_err(&pdev->dev, + "unable to register divider clock\n"); + ret = PTR_ERR(clk_wzrd->clkout[i]); + goto err_rm_int_clks; + } + } + + kfree(clk_name); + + clk_wzrd->clk_data.clks = clk_wzrd->clkout; + clk_wzrd->clk_data.clk_num = ARRAY_SIZE(clk_wzrd->clkout); + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_wzrd->clk_data); + + if (clk_wzrd->speed_grade) { + clk_wzrd->nb.notifier_call = clk_wzrd_clk_notifier; + + ret = clk_notifier_register(clk_wzrd->clk_in1, + &clk_wzrd->nb); + if (ret) + dev_warn(&pdev->dev, + "unable to register clock notifier\n"); + + ret = clk_notifier_register(clk_wzrd->axi_clk, &clk_wzrd->nb); + if (ret) + dev_warn(&pdev->dev, + "unable to register clock notifier\n"); + } + + return 0; + +err_rm_int_clks: + clk_unregister(clk_wzrd->clks_internal[1]); +err_rm_int_clk: + kfree(clk_name); + clk_unregister(clk_wzrd->clks_internal[0]); +err_disable_clk: + clk_disable_unprepare(clk_wzrd->axi_clk); + + return ret; +} + +static int clk_wzrd_remove(struct platform_device *pdev) +{ + int i; + struct clk_wzrd *clk_wzrd = platform_get_drvdata(pdev); + + of_clk_del_provider(pdev->dev.of_node); + + for (i = 0; i < WZRD_NUM_OUTPUTS; i++) + clk_unregister(clk_wzrd->clkout[i]); + for (i = 0; i < wzrd_clk_int_max; i++) + clk_unregister(clk_wzrd->clks_internal[i]); + + if (clk_wzrd->speed_grade) { + clk_notifier_unregister(clk_wzrd->axi_clk, &clk_wzrd->nb); + clk_notifier_unregister(clk_wzrd->clk_in1, &clk_wzrd->nb); + } + + clk_disable_unprepare(clk_wzrd->axi_clk); + + return 0; +} + +static const struct of_device_id clk_wzrd_ids[] = { + { .compatible = "xlnx,clocking-wizard" }, + { }, +}; +MODULE_DEVICE_TABLE(of, clk_wzrd_ids); + +static struct platform_driver clk_wzrd_driver = { + .driver = { + .name = "clk-wizard", + .of_match_table = clk_wzrd_ids, + .pm = &clk_wzrd_dev_pm_ops, + }, + .probe = clk_wzrd_probe, + .remove = clk_wzrd_remove, +}; +module_platform_driver(clk_wzrd_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Soeren Brinkmann <soren.brinkmann@xilinx.com"); +MODULE_DESCRIPTION("Driver for the Xilinx Clocking Wizard IP core"); diff --git a/drivers/staging/clocking-wizard/dt-binding.txt b/drivers/staging/clocking-wizard/dt-binding.txt new file mode 100644 index 000000000000..723271e93316 --- /dev/null +++ b/drivers/staging/clocking-wizard/dt-binding.txt @@ -0,0 +1,30 @@ +Binding for Xilinx Clocking Wizard IP Core + +This binding uses the common clock binding[1]. Details about the devices can be +found in the product guide[2]. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Clocking Wizard Product Guide +http://www.xilinx.com/support/documentation/ip_documentation/clk_wiz/v5_1/pg065-clk-wiz.pdf + +Required properties: + - compatible: Must be 'xlnx,clocking-wizard' + - reg: Base and size of the cores register space + - clocks: Handle to input clock + - clock-names: Tuple containing 'clk_in1' and 's_axi_aclk' + - clock-output-names: Names for the output clocks + +Optional properties: + - speed-grade: Speed grade of the device (valid values are 1..3) + +Example: + clock-generator@40040000 { + reg = <0x40040000 0x1000>; + compatible = "xlnx,clocking-wizard"; + speed-grade = <1>; + clock-names = "clk_in1", "s_axi_aclk"; + clocks = <&clkc 15>, <&clkc 15>; + clock-output-names = "clk_out0", "clk_out1", "clk_out2", + "clk_out3", "clk_out4", "clk_out5", + "clk_out6", "clk_out7"; + }; diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 152f4c12ea43..a8201fe87512 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -384,6 +384,7 @@ config COMEDI_DT282X config COMEDI_DMM32AT tristate "Diamond Systems MM-32-AT PC/104 board support" + select COMEDI_8255 ---help--- Enable support for Diamond Systems MM-32-AT PC/104 boards @@ -564,11 +565,14 @@ config COMEDI_S526 endif # COMEDI_ISA_DRIVERS menuconfig COMEDI_PCI_DRIVERS - bool "Comedi PCI drivers" + tristate "Comedi PCI drivers" depends on PCI ---help--- Enable support for comedi PCI drivers. + To compile this support as a module, choose M here: the module will + be called comedi_pci. + if COMEDI_PCI_DRIVERS config COMEDI_8255_PCI @@ -595,14 +599,6 @@ config COMEDI_ADDI_WATCHDOG boards. This module will be automatically selected when needed. The module will be called addi_watchdog. -config COMEDI_ADDI_APCI_035 - tristate "ADDI-DATA APCI_035 support" - ---help--- - Enable support for ADDI-DATA APCI_035 cards - - To compile this driver as a module, choose M here: the module will be - called addi_apci_035. - config COMEDI_ADDI_APCI_1032 tristate "ADDI-DATA APCI_1032 support" ---help--- @@ -939,11 +935,11 @@ config COMEDI_CB_PCIDDA called cb_pcidda. config COMEDI_CB_PCIMDAS - tristate "MeasurementComputing PCIM-DAS1602/16 support" + tristate "MeasurementComputing PCIM-DAS1602/16, PCIe-DAS1602/16 support" select COMEDI_8255 ---help--- Enable support for ComputerBoards/MeasurementComputing PCI Migration - series PCIM-DAS1602/16 + series PCIM-DAS1602/16 and PCIe-DAS1602/16. To compile this driver as a module, choose M here: the module will be called cb_pcimdas. @@ -1084,11 +1080,14 @@ config COMEDI_NI_TIOCMD endif # COMEDI_PCI_DRIVERS menuconfig COMEDI_PCMCIA_DRIVERS - bool "Comedi PCMCIA drivers" + tristate "Comedi PCMCIA drivers" depends on PCMCIA ---help--- Enable support for comedi PCMCIA drivers. + To compile this support as a module, choose M here: the module will + be called comedi_pcmcia. + if COMEDI_PCMCIA_DRIVERS config COMEDI_CB_DAS16_CS @@ -1160,11 +1159,14 @@ config COMEDI_QUATECH_DAQP_CS endif # COMEDI_PCMCIA_DRIVERS menuconfig COMEDI_USB_DRIVERS - bool "Comedi USB drivers" + tristate "Comedi USB drivers" depends on USB ---help--- Enable support for comedi USB drivers. + To compile this support as a module, choose M here: the module will + be called comedi_usb. + if COMEDI_USB_DRIVERS config COMEDI_DT9812 diff --git a/drivers/staging/comedi/Makefile b/drivers/staging/comedi/Makefile index fae2d9090006..7f9dfb3923ab 100644 --- a/drivers/staging/comedi/Makefile +++ b/drivers/staging/comedi/Makefile @@ -2,12 +2,13 @@ ccflags-$(CONFIG_COMEDI_DEBUG) := -DDEBUG comedi-y := comedi_fops.o range.o drivers.o \ comedi_buf.o -comedi-$(CONFIG_COMEDI_PCI_DRIVERS) += comedi_pci.o -comedi-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += comedi_pcmcia.o -comedi-$(CONFIG_COMEDI_USB_DRIVERS) += comedi_usb.o comedi-$(CONFIG_PROC_FS) += proc.o comedi-$(CONFIG_COMPAT) += comedi_compat32.o +obj-$(CONFIG_COMEDI_PCI_DRIVERS) += comedi_pci.o +obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += comedi_pcmcia.o +obj-$(CONFIG_COMEDI_USB_DRIVERS) += comedi_usb.o + obj-$(CONFIG_COMEDI) += comedi.o obj-$(CONFIG_COMEDI) += kcomedilib/ diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index c8c99e65423b..745574077352 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -367,6 +367,8 @@ enum comedi_support_level { #define COMEDI_BUFCONFIG _IOR(CIO, 13, struct comedi_bufconfig) #define COMEDI_BUFINFO _IOWR(CIO, 14, struct comedi_bufinfo) #define COMEDI_POLL _IO(CIO, 15) +#define COMEDI_SETRSUBD _IO(CIO, 16) +#define COMEDI_SETWSUBD _IO(CIO, 17) /* structures */ @@ -514,17 +516,6 @@ struct comedi_bufinfo { #define COMEDI_MIN_SPEED ((unsigned int)0xffffffff) -/* callback stuff */ -/* only relevant to kernel modules. */ - -#define COMEDI_CB_EOS 1 /* end of scan */ -#define COMEDI_CB_EOA 2 /* end of acquisition/output */ -#define COMEDI_CB_BLOCK 4 /* data has arrived: - * wakes up read() / write() */ -#define COMEDI_CB_EOBUF 8 /* DEPRECATED: end of buffer */ -#define COMEDI_CB_ERROR 16 /* card error during acquisition */ -#define COMEDI_CB_OVERFLOW 32 /* buffer overflow/underflow */ - /**********************************************************/ /* everything after this line is ALPHA */ /**********************************************************/ diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index c60a45ad12b9..19e7b229d15e 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -236,6 +236,7 @@ void comedi_buf_reset(struct comedi_subdevice *s) async->buf_read_ptr = 0; async->cur_chan = 0; + async->scans_done = 0; async->scan_progress = 0; async->munge_chan = 0; async->munge_count = 0; @@ -252,15 +253,15 @@ static unsigned int comedi_buf_write_n_available(struct comedi_subdevice *s) return free_end - async->buf_write_alloc_count; } -static unsigned int __comedi_buf_write_alloc(struct comedi_subdevice *s, - unsigned int nbytes, - int strict) +/* allocates chunk for the writer from free buffer space */ +unsigned int comedi_buf_write_alloc(struct comedi_subdevice *s, + unsigned int nbytes) { struct comedi_async *async = s->async; unsigned int available = comedi_buf_write_n_available(s); if (nbytes > available) - nbytes = strict ? 0 : available; + nbytes = available; async->buf_write_alloc_count += nbytes; @@ -272,13 +273,6 @@ static unsigned int __comedi_buf_write_alloc(struct comedi_subdevice *s, return nbytes; } - -/* allocates chunk for the writer from free buffer space */ -unsigned int comedi_buf_write_alloc(struct comedi_subdevice *s, - unsigned int nbytes) -{ - return __comedi_buf_write_alloc(s, nbytes, 0); -} EXPORT_SYMBOL_GPL(comedi_buf_write_alloc); /* @@ -290,7 +284,7 @@ static unsigned int comedi_buf_munge(struct comedi_subdevice *s, { struct comedi_async *async = s->async; unsigned int count = 0; - const unsigned num_sample_bytes = bytes_per_sample(s); + const unsigned num_sample_bytes = comedi_bytes_per_sample(s); if (!s->munge || (async->cmd.flags & CMDF_RAWDATA)) { async->munge_count += num_bytes; @@ -427,43 +421,11 @@ unsigned int comedi_buf_read_free(struct comedi_subdevice *s, } EXPORT_SYMBOL_GPL(comedi_buf_read_free); -int comedi_buf_put(struct comedi_subdevice *s, unsigned short x) -{ - struct comedi_async *async = s->async; - unsigned int n = __comedi_buf_write_alloc(s, sizeof(short), 1); - - if (n < sizeof(short)) { - async->events |= COMEDI_CB_ERROR; - return 0; - } - *(unsigned short *)(async->prealloc_buf + async->buf_write_ptr) = x; - comedi_buf_write_free(s, sizeof(short)); - return 1; -} -EXPORT_SYMBOL_GPL(comedi_buf_put); - -int comedi_buf_get(struct comedi_subdevice *s, unsigned short *x) +static void comedi_buf_memcpy_to(struct comedi_subdevice *s, + const void *data, unsigned int num_bytes) { struct comedi_async *async = s->async; - unsigned int n = comedi_buf_read_n_available(s); - - if (n < sizeof(short)) - return 0; - comedi_buf_read_alloc(s, sizeof(short)); - *x = *(unsigned short *)(async->prealloc_buf + async->buf_read_ptr); - comedi_buf_read_free(s, sizeof(short)); - return 1; -} -EXPORT_SYMBOL_GPL(comedi_buf_get); - -void comedi_buf_memcpy_to(struct comedi_subdevice *s, unsigned int offset, - const void *data, unsigned int num_bytes) -{ - struct comedi_async *async = s->async; - unsigned int write_ptr = async->buf_write_ptr + offset; - - if (write_ptr >= async->prealloc_bufsz) - write_ptr %= async->prealloc_bufsz; + unsigned int write_ptr = async->buf_write_ptr; while (num_bytes) { unsigned int block_size; @@ -481,17 +443,13 @@ void comedi_buf_memcpy_to(struct comedi_subdevice *s, unsigned int offset, write_ptr = 0; } } -EXPORT_SYMBOL_GPL(comedi_buf_memcpy_to); -void comedi_buf_memcpy_from(struct comedi_subdevice *s, unsigned int offset, - void *dest, unsigned int nbytes) +static void comedi_buf_memcpy_from(struct comedi_subdevice *s, + void *dest, unsigned int nbytes) { void *src; struct comedi_async *async = s->async; - unsigned int read_ptr = async->buf_read_ptr + offset; - - if (read_ptr >= async->prealloc_bufsz) - read_ptr %= async->prealloc_bufsz; + unsigned int read_ptr = async->buf_read_ptr; while (nbytes) { unsigned int block_size; @@ -509,69 +467,84 @@ void comedi_buf_memcpy_from(struct comedi_subdevice *s, unsigned int offset, read_ptr = 0; } } -EXPORT_SYMBOL_GPL(comedi_buf_memcpy_from); /** - * comedi_write_array_to_buffer - write data to comedi buffer + * comedi_buf_write_samples - write sample data to comedi buffer * @s: comedi_subdevice struct - * @data: destination - * @num_bytes: number of bytes to write + * @data: samples + * @nsamples: number of samples * - * Writes up to num_bytes bytes of data to the comedi buffer associated with - * the subdevice, marks it as written and updates the acquisition scan - * progress. + * Writes nsamples to the comedi buffer associated with the subdevice, marks + * it as written and updates the acquisition scan progress. * * Returns the amount of data written in bytes. */ -unsigned int comedi_write_array_to_buffer(struct comedi_subdevice *s, - const void *data, - unsigned int num_bytes) +unsigned int comedi_buf_write_samples(struct comedi_subdevice *s, + const void *data, unsigned int nsamples) { - struct comedi_async *async = s->async; - unsigned int retval; - - if (num_bytes == 0) - return 0; + unsigned int max_samples; + unsigned int nbytes; - retval = comedi_buf_write_alloc(s, num_bytes); - if (retval != num_bytes) { + /* + * Make sure there is enough room in the buffer for all the samples. + * If not, clamp the nsamples to the number that will fit, flag the + * buffer overrun and add the samples that fit. + */ + max_samples = comedi_bytes_to_samples(s, + comedi_buf_write_n_available(s)); + if (nsamples > max_samples) { dev_warn(s->device->class_dev, "buffer overrun\n"); - async->events |= COMEDI_CB_OVERFLOW; - return 0; + s->async->events |= COMEDI_CB_OVERFLOW; + nsamples = max_samples; } - comedi_buf_memcpy_to(s, 0, data, num_bytes); - comedi_buf_write_free(s, num_bytes); - comedi_inc_scan_progress(s, num_bytes); - async->events |= COMEDI_CB_BLOCK; + if (nsamples == 0) + return 0; - return num_bytes; + nbytes = comedi_buf_write_alloc(s, + comedi_samples_to_bytes(s, nsamples)); + comedi_buf_memcpy_to(s, data, nbytes); + comedi_buf_write_free(s, nbytes); + comedi_inc_scan_progress(s, nbytes); + s->async->events |= COMEDI_CB_BLOCK; + + return nbytes; } -EXPORT_SYMBOL_GPL(comedi_write_array_to_buffer); +EXPORT_SYMBOL_GPL(comedi_buf_write_samples); /** - * comedi_read_array_from_buffer - read data from comedi buffer + * comedi_buf_read_samples - read sample data from comedi buffer * @s: comedi_subdevice struct * @data: destination - * @num_bytes: number of bytes to read + * @nsamples: maximum number of samples to read * - * Reads up to num_bytes bytes of data from the comedi buffer associated with - * the subdevice, marks it as read and updates the acquisition scan progress. + * Reads up to nsamples from the comedi buffer associated with the subdevice, + * marks it as read and updates the acquisition scan progress. * * Returns the amount of data read in bytes. */ -unsigned int comedi_read_array_from_buffer(struct comedi_subdevice *s, - void *data, unsigned int num_bytes) +unsigned int comedi_buf_read_samples(struct comedi_subdevice *s, + void *data, unsigned int nsamples) { - if (num_bytes == 0) + unsigned int max_samples; + unsigned int nbytes; + + /* clamp nsamples to the number of full samples available */ + max_samples = comedi_bytes_to_samples(s, + comedi_buf_read_n_available(s)); + if (nsamples > max_samples) + nsamples = max_samples; + + if (nsamples == 0) return 0; - num_bytes = comedi_buf_read_alloc(s, num_bytes); - comedi_buf_memcpy_from(s, 0, data, num_bytes); - comedi_buf_read_free(s, num_bytes); - comedi_inc_scan_progress(s, num_bytes); + nbytes = comedi_buf_read_alloc(s, + comedi_samples_to_bytes(s, nsamples)); + comedi_buf_memcpy_from(s, data, nbytes); + comedi_buf_read_free(s, nbytes); + comedi_inc_scan_progress(s, nbytes); s->async->events |= COMEDI_CB_BLOCK; - return num_bytes; + return nbytes; } -EXPORT_SYMBOL_GPL(comedi_read_array_from_buffer); +EXPORT_SYMBOL_GPL(comedi_buf_read_samples); diff --git a/drivers/staging/comedi/comedi_compat32.c b/drivers/staging/comedi/comedi_compat32.c index 9b6f96f1591c..5a4c74f703b3 100644 --- a/drivers/staging/comedi/comedi_compat32.c +++ b/drivers/staging/comedi/comedi_compat32.c @@ -416,6 +416,8 @@ static inline int raw_ioctl(struct file *file, unsigned int cmd, case COMEDI_UNLOCK: case COMEDI_CANCEL: case COMEDI_POLL: + case COMEDI_SETRSUBD: + case COMEDI_SETWSUBD: /* No translation needed. */ rc = translated_ioctl(file, cmd, arg); break; diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 9c32f0276009..f143cb64d69e 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -43,6 +43,22 @@ #include "comedi_internal.h" +/** + * struct comedi_file - per-file private data for comedi device + * @dev: comedi_device struct + * @read_subdev: current "read" subdevice + * @write_subdev: current "write" subdevice + * @last_detach_count: last known detach count + * @last_attached: last known attached/detached state + */ +struct comedi_file { + struct comedi_device *dev; + struct comedi_subdevice *read_subdev; + struct comedi_subdevice *write_subdev; + unsigned int last_detach_count; + bool last_attached:1; +}; + #define COMEDI_NUM_MINORS 0x100 #define COMEDI_NUM_SUBDEVICE_MINORS \ (COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS) @@ -239,6 +255,54 @@ comedi_write_subdevice(const struct comedi_device *dev, unsigned int minor) return dev->write_subdev; } +static void comedi_file_reset(struct file *file) +{ + struct comedi_file *cfp = file->private_data; + struct comedi_device *dev = cfp->dev; + struct comedi_subdevice *s, *read_s, *write_s; + unsigned int minor = iminor(file_inode(file)); + + read_s = dev->read_subdev; + write_s = dev->write_subdev; + if (minor >= COMEDI_NUM_BOARD_MINORS) { + s = comedi_subdevice_from_minor(dev, minor); + if (s == NULL || s->subdev_flags & SDF_CMD_READ) + read_s = s; + if (s == NULL || s->subdev_flags & SDF_CMD_WRITE) + write_s = s; + } + cfp->last_attached = dev->attached; + cfp->last_detach_count = dev->detach_count; + ACCESS_ONCE(cfp->read_subdev) = read_s; + ACCESS_ONCE(cfp->write_subdev) = write_s; +} + +static void comedi_file_check(struct file *file) +{ + struct comedi_file *cfp = file->private_data; + struct comedi_device *dev = cfp->dev; + + if (cfp->last_attached != dev->attached || + cfp->last_detach_count != dev->detach_count) + comedi_file_reset(file); +} + +static struct comedi_subdevice *comedi_file_read_subdevice(struct file *file) +{ + struct comedi_file *cfp = file->private_data; + + comedi_file_check(file); + return ACCESS_ONCE(cfp->read_subdev); +} + +static struct comedi_subdevice *comedi_file_write_subdevice(struct file *file) +{ + struct comedi_file *cfp = file->private_data; + + comedi_file_check(file); + return ACCESS_ONCE(cfp->write_subdev); +} + static int resize_async_buffer(struct comedi_device *dev, struct comedi_subdevice *s, unsigned new_size) { @@ -776,7 +840,6 @@ static int do_devinfo_ioctl(struct comedi_device *dev, struct comedi_devinfo __user *arg, struct file *file) { - const unsigned minor = iminor(file_inode(file)); struct comedi_subdevice *s; struct comedi_devinfo devinfo; @@ -788,13 +851,13 @@ static int do_devinfo_ioctl(struct comedi_device *dev, strlcpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN); strlcpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN); - s = comedi_read_subdevice(dev, minor); + s = comedi_file_read_subdevice(file); if (s) devinfo.read_subdevice = s->index; else devinfo.read_subdevice = -1; - s = comedi_write_subdevice(dev, minor); + s = comedi_file_write_subdevice(file); if (s) devinfo.write_subdevice = s->index; else @@ -991,7 +1054,7 @@ static int do_bufinfo_ioctl(struct comedi_device *dev, if (s->busy != file) return -EACCES; - if (bi.bytes_read && (s->subdev_flags & SDF_CMD_READ)) { + if (bi.bytes_read && !(async->cmd.flags & CMDF_WRITE)) { bi.bytes_read = comedi_buf_read_alloc(s, bi.bytes_read); comedi_buf_read_free(s, bi.bytes_read); @@ -1001,7 +1064,7 @@ static int do_bufinfo_ioctl(struct comedi_device *dev, } } - if (bi.bytes_written && (s->subdev_flags & SDF_CMD_WRITE)) { + if (bi.bytes_written && (async->cmd.flags & CMDF_WRITE)) { bi.bytes_written = comedi_buf_write_alloc(s, bi.bytes_written); comedi_buf_write_free(s, bi.bytes_written); @@ -1451,6 +1514,21 @@ static int __comedi_get_user_cmd(struct comedi_device *dev, return -EINVAL; } + /* + * Set the CMDF_WRITE flag to the correct state if the subdevice + * supports only "read" commands or only "write" commands. + */ + switch (s->subdev_flags & (SDF_CMD_READ | SDF_CMD_WRITE)) { + case SDF_CMD_READ: + cmd->flags &= ~CMDF_WRITE; + break; + case SDF_CMD_WRITE: + cmd->flags |= CMDF_WRITE; + break; + default: + break; + } + return 0; } @@ -1552,9 +1630,7 @@ static int do_cmd_ioctl(struct comedi_device *dev, comedi_buf_reset(s); - async->cb_mask = - COMEDI_CB_EOA | COMEDI_CB_BLOCK | COMEDI_CB_ERROR | - COMEDI_CB_OVERFLOW; + async->cb_mask = COMEDI_CB_BLOCK | COMEDI_CB_CANCEL_MASK; if (async->cmd.flags & CMDF_WAKE_EOS) async->cb_mask |= COMEDI_CB_EOS; @@ -1720,7 +1796,6 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned long arg, void *file) { struct comedi_subdevice *s; - int ret; if (arg >= dev->n_subdevices) return -EINVAL; @@ -1734,9 +1809,7 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned long arg, if (s->busy != file) return -EBUSY; - ret = do_cancel(dev, s); - - return ret; + return do_cancel(dev, s); } /* @@ -1774,11 +1847,96 @@ static int do_poll_ioctl(struct comedi_device *dev, unsigned long arg, return -EINVAL; } +/* + * COMEDI_SETRSUBD ioctl + * sets the current "read" subdevice on a per-file basis + * + * arg: + * subdevice number + * + * reads: + * nothing + * + * writes: + * nothing + */ +static int do_setrsubd_ioctl(struct comedi_device *dev, unsigned long arg, + struct file *file) +{ + struct comedi_file *cfp = file->private_data; + struct comedi_subdevice *s_old, *s_new; + + if (arg >= dev->n_subdevices) + return -EINVAL; + + s_new = &dev->subdevices[arg]; + s_old = comedi_file_read_subdevice(file); + if (s_old == s_new) + return 0; /* no change */ + + if (!(s_new->subdev_flags & SDF_CMD_READ)) + return -EINVAL; + + /* + * Check the file isn't still busy handling a "read" command on the + * old subdevice (if any). + */ + if (s_old && s_old->busy == file && s_old->async && + !(s_old->async->cmd.flags & CMDF_WRITE)) + return -EBUSY; + + ACCESS_ONCE(cfp->read_subdev) = s_new; + return 0; +} + +/* + * COMEDI_SETWSUBD ioctl + * sets the current "write" subdevice on a per-file basis + * + * arg: + * subdevice number + * + * reads: + * nothing + * + * writes: + * nothing + */ +static int do_setwsubd_ioctl(struct comedi_device *dev, unsigned long arg, + struct file *file) +{ + struct comedi_file *cfp = file->private_data; + struct comedi_subdevice *s_old, *s_new; + + if (arg >= dev->n_subdevices) + return -EINVAL; + + s_new = &dev->subdevices[arg]; + s_old = comedi_file_write_subdevice(file); + if (s_old == s_new) + return 0; /* no change */ + + if (!(s_new->subdev_flags & SDF_CMD_WRITE)) + return -EINVAL; + + /* + * Check the file isn't still busy handling a "write" command on the + * old subdevice (if any). + */ + if (s_old && s_old->busy == file && s_old->async && + (s_old->async->cmd.flags & CMDF_WRITE)) + return -EBUSY; + + ACCESS_ONCE(cfp->write_subdev) = s_new; + return 0; +} + static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - const unsigned minor = iminor(file_inode(file)); - struct comedi_device *dev = file->private_data; + unsigned minor = iminor(file_inode(file)); + struct comedi_file *cfp = file->private_data; + struct comedi_device *dev = cfp->dev; int rc; mutex_lock(&dev->mutex); @@ -1867,6 +2025,12 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, case COMEDI_POLL: rc = do_poll_ioctl(dev, arg, file); break; + case COMEDI_SETRSUBD: + rc = do_setrsubd_ioctl(dev, arg, file); + break; + case COMEDI_SETWSUBD: + rc = do_setwsubd_ioctl(dev, arg, file); + break; default: rc = -ENOTTY; break; @@ -1900,8 +2064,8 @@ static struct vm_operations_struct comedi_vm_ops = { static int comedi_mmap(struct file *file, struct vm_area_struct *vma) { - const unsigned minor = iminor(file_inode(file)); - struct comedi_device *dev = file->private_data; + struct comedi_file *cfp = file->private_data; + struct comedi_device *dev = cfp->dev; struct comedi_subdevice *s; struct comedi_async *async; struct comedi_buf_map *bm = NULL; @@ -1927,9 +2091,9 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma) } if (vma->vm_flags & VM_WRITE) - s = comedi_write_subdevice(dev, minor); + s = comedi_file_write_subdevice(file); else - s = comedi_read_subdevice(dev, minor); + s = comedi_file_read_subdevice(file); if (!s) { retval = -EINVAL; goto done; @@ -1992,8 +2156,8 @@ done: static unsigned int comedi_poll(struct file *file, poll_table *wait) { unsigned int mask = 0; - const unsigned minor = iminor(file_inode(file)); - struct comedi_device *dev = file->private_data; + struct comedi_file *cfp = file->private_data; + struct comedi_device *dev = cfp->dev; struct comedi_subdevice *s; mutex_lock(&dev->mutex); @@ -2003,21 +2167,23 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait) goto done; } - s = comedi_read_subdevice(dev, minor); + s = comedi_file_read_subdevice(file); if (s && s->async) { poll_wait(file, &s->async->wait_head, wait); if (!s->busy || !comedi_is_subdevice_running(s) || + (s->async->cmd.flags & CMDF_WRITE) || comedi_buf_read_n_available(s) > 0) mask |= POLLIN | POLLRDNORM; } - s = comedi_write_subdevice(dev, minor); + s = comedi_file_write_subdevice(file); if (s && s->async) { - unsigned int bps = bytes_per_sample(s); + unsigned int bps = comedi_bytes_per_sample(s); poll_wait(file, &s->async->wait_head, wait); comedi_buf_write_alloc(s, s->async->prealloc_bufsz); if (!s->busy || !comedi_is_subdevice_running(s) || + !(s->async->cmd.flags & CMDF_WRITE) || comedi_buf_write_n_allocated(s) >= bps) mask |= POLLOUT | POLLWRNORM; } @@ -2034,8 +2200,8 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, struct comedi_async *async; int n, m, count = 0, retval = 0; DECLARE_WAITQUEUE(wait, current); - const unsigned minor = iminor(file_inode(file)); - struct comedi_device *dev = file->private_data; + struct comedi_file *cfp = file->private_data; + struct comedi_device *dev = cfp->dev; bool on_wait_queue = false; bool attach_locked; unsigned int old_detach_count; @@ -2051,7 +2217,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, goto out; } - s = comedi_write_subdevice(dev, minor); + s = comedi_file_write_subdevice(file); if (!s || !s->async) { retval = -EIO; goto out; @@ -2065,6 +2231,10 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, retval = -EACCES; goto out; } + if (!(async->cmd.flags & CMDF_WRITE)) { + retval = -EINVAL; + goto out; + } add_wait_queue(&async->wait_head, &wait); on_wait_queue = true; @@ -2099,7 +2269,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, * meantime!), but check the subdevice pointer * as well just in case. */ - new_s = comedi_write_subdevice(dev, minor); + new_s = comedi_file_write_subdevice(file); if (dev->attached && old_detach_count == dev->detach_count && s == new_s && new_s->async == async) @@ -2136,6 +2306,10 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, retval = -EACCES; break; } + if (!(async->cmd.flags & CMDF_WRITE)) { + retval = -EINVAL; + break; + } continue; } @@ -2170,8 +2344,8 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, struct comedi_async *async; int n, m, count = 0, retval = 0; DECLARE_WAITQUEUE(wait, current); - const unsigned minor = iminor(file_inode(file)); - struct comedi_device *dev = file->private_data; + struct comedi_file *cfp = file->private_data; + struct comedi_device *dev = cfp->dev; unsigned int old_detach_count; bool become_nonbusy = false; bool attach_locked; @@ -2187,7 +2361,7 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, goto out; } - s = comedi_read_subdevice(dev, minor); + s = comedi_file_read_subdevice(file); if (!s || !s->async) { retval = -EIO; goto out; @@ -2200,6 +2374,10 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, retval = -EACCES; goto out; } + if (async->cmd.flags & CMDF_WRITE) { + retval = -EINVAL; + goto out; + } add_wait_queue(&async->wait_head, &wait); while (nbytes > 0 && !retval) { @@ -2239,6 +2417,10 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, retval = -EACCES; break; } + if (async->cmd.flags & CMDF_WRITE) { + retval = -EINVAL; + break; + } continue; } m = copy_to_user(buf, async->prealloc_buf + @@ -2276,7 +2458,7 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, * meantime!), but check the subdevice pointer as well just in * case. */ - new_s = comedi_read_subdevice(dev, minor); + new_s = comedi_file_read_subdevice(file); if (dev->attached && old_detach_count == dev->detach_count && s == new_s && new_s->async == async) { if (become_nonbusy || comedi_buf_n_bytes_ready(s) == 0) @@ -2294,6 +2476,7 @@ out: static int comedi_open(struct inode *inode, struct file *file) { const unsigned minor = iminor(inode); + struct comedi_file *cfp; struct comedi_device *dev = comedi_dev_get_from_minor(minor); int rc; @@ -2302,6 +2485,12 @@ static int comedi_open(struct inode *inode, struct file *file) return -ENODEV; } + cfp = kzalloc(sizeof(*cfp), GFP_KERNEL); + if (!cfp) + return -ENOMEM; + + cfp->dev = dev; + mutex_lock(&dev->mutex); if (!dev->attached && !capable(CAP_NET_ADMIN)) { dev_dbg(dev->class_dev, "not attached and not CAP_NET_ADMIN\n"); @@ -2323,26 +2512,31 @@ static int comedi_open(struct inode *inode, struct file *file) } dev->use_count++; - file->private_data = dev; + file->private_data = cfp; + comedi_file_reset(file); rc = 0; out: mutex_unlock(&dev->mutex); - if (rc) + if (rc) { comedi_dev_put(dev); + kfree(cfp); + } return rc; } static int comedi_fasync(int fd, struct file *file, int on) { - struct comedi_device *dev = file->private_data; + struct comedi_file *cfp = file->private_data; + struct comedi_device *dev = cfp->dev; return fasync_helper(fd, file, on, &dev->async_queue); } static int comedi_close(struct inode *inode, struct file *file) { - struct comedi_device *dev = file->private_data; + struct comedi_file *cfp = file->private_data; + struct comedi_device *dev = cfp->dev; struct comedi_subdevice *s = NULL; int i; @@ -2368,6 +2562,7 @@ static int comedi_close(struct inode *inode, struct file *file) mutex_unlock(&dev->mutex); comedi_dev_put(dev); + kfree(cfp); return 0; } @@ -2395,14 +2590,14 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) if (!comedi_is_subdevice_running(s)) return; - if (s-> - async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | - COMEDI_CB_OVERFLOW)) { + if (s->async->events & COMEDI_CB_CANCEL_MASK) runflags_mask |= SRF_RUNNING; - } - /* remember if an error event has occurred, so an error - * can be returned the next time the user does a read() */ - if (s->async->events & (COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) { + + /* + * Remember if an error event has occurred, so an error + * can be returned the next time the user does a read(). + */ + if (s->async->events & COMEDI_CB_ERROR_MASK) { runflags_mask |= SRF_ERROR; runflags |= SRF_ERROR; } diff --git a/drivers/staging/comedi/comedi_pci.c b/drivers/staging/comedi/comedi_pci.c index aa0795a2660e..6ba59c977006 100644 --- a/drivers/staging/comedi/comedi_pci.c +++ b/drivers/staging/comedi/comedi_pci.c @@ -16,6 +16,7 @@ * GNU General Public License for more details. */ +#include <linux/module.h> #include <linux/pci.h> #include <linux/interrupt.h> @@ -168,3 +169,18 @@ void comedi_pci_driver_unregister(struct comedi_driver *comedi_driver, comedi_driver_unregister(comedi_driver); } EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister); + +static int __init comedi_pci_init(void) +{ + return 0; +} +module_init(comedi_pci_init); + +static void __exit comedi_pci_exit(void) +{ +} +module_exit(comedi_pci_exit); + +MODULE_AUTHOR("http://www.comedi.org"); +MODULE_DESCRIPTION("Comedi PCI interface module"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/comedi_pcmcia.c b/drivers/staging/comedi/comedi_pcmcia.c index 9d49d5d01ad9..0529bae8e5ac 100644 --- a/drivers/staging/comedi/comedi_pcmcia.c +++ b/drivers/staging/comedi/comedi_pcmcia.c @@ -16,6 +16,7 @@ * GNU General Public License for more details. */ +#include <linux/module.h> #include <linux/kernel.h> #include <pcmcia/cistpl.h> @@ -154,3 +155,18 @@ void comedi_pcmcia_driver_unregister(struct comedi_driver *comedi_driver, comedi_driver_unregister(comedi_driver); } EXPORT_SYMBOL_GPL(comedi_pcmcia_driver_unregister); + +static int __init comedi_pcmcia_init(void) +{ + return 0; +} +module_init(comedi_pcmcia_init); + +static void __exit comedi_pcmcia_exit(void) +{ +} +module_exit(comedi_pcmcia_exit); + +MODULE_AUTHOR("http://www.comedi.org"); +MODULE_DESCRIPTION("Comedi PCMCIA interface module"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/comedi_usb.c b/drivers/staging/comedi/comedi_usb.c index 13f18bef6091..0b862a64c049 100644 --- a/drivers/staging/comedi/comedi_usb.c +++ b/drivers/staging/comedi/comedi_usb.c @@ -16,6 +16,7 @@ * GNU General Public License for more details. */ +#include <linux/module.h> #include <linux/usb.h> #include "comedidev.h" @@ -114,3 +115,18 @@ void comedi_usb_driver_unregister(struct comedi_driver *comedi_driver, comedi_driver_unregister(comedi_driver); } EXPORT_SYMBOL_GPL(comedi_usb_driver_unregister); + +static int __init comedi_usb_init(void) +{ + return 0; +} +module_init(comedi_usb_init); + +static void __exit comedi_usb_exit(void) +{ +} +module_exit(comedi_usb_exit); + +MODULE_AUTHOR("http://www.comedi.org"); +MODULE_DESCRIPTION("Comedi USB interface module"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 1b2bbd56f6ef..77be191988ca 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -121,6 +121,7 @@ struct comedi_buf_map { * @buf_read_ptr: buffer position for reader * @cur_chan: current position in chanlist for scan (for those * drivers that use it) + * @scans_done: the number of scans completed (COMEDI_CB_EOS) * @scan_progress: amount received or sent for current scan (in bytes) * @munge_chan: current position in chanlist for "munging" * @munge_count: "munge" count (in bytes, modulo 2**32) @@ -201,6 +202,7 @@ struct comedi_async { unsigned int buf_write_ptr; unsigned int buf_read_ptr; unsigned int cur_chan; + unsigned int scans_done; unsigned int scan_progress; unsigned int munge_chan; unsigned int munge_count; @@ -213,6 +215,28 @@ struct comedi_async { unsigned int x); }; +/** + * comedi_async callback "events" + * @COMEDI_CB_EOS: end-of-scan + * @COMEDI_CB_EOA: end-of-acquisition/output + * @COMEDI_CB_BLOCK: data has arrived, wakes up read() / write() + * @COMEDI_CB_EOBUF: DEPRECATED: end of buffer + * @COMEDI_CB_ERROR: card error during acquisition + * @COMEDI_CB_OVERFLOW: buffer overflow/underflow + * + * @COMEDI_CB_ERROR_MASK: events that indicate an error has occurred + * @COMEDI_CB_CANCEL_MASK: events that will cancel an async command + */ +#define COMEDI_CB_EOS (1 << 0) +#define COMEDI_CB_EOA (1 << 1) +#define COMEDI_CB_BLOCK (1 << 2) +#define COMEDI_CB_EOBUF (1 << 3) +#define COMEDI_CB_ERROR (1 << 4) +#define COMEDI_CB_OVERFLOW (1 << 5) + +#define COMEDI_CB_ERROR_MASK (COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW) +#define COMEDI_CB_CANCEL_MASK (COMEDI_CB_EOA | COMEDI_CB_ERROR_MASK) + struct comedi_driver { struct comedi_driver *next; @@ -391,12 +415,61 @@ static inline unsigned int comedi_offset_munge(struct comedi_subdevice *s, return val ^ s->maxdata ^ (s->maxdata >> 1); } -static inline unsigned int bytes_per_sample(const struct comedi_subdevice *subd) +/** + * comedi_bytes_per_sample - determine subdevice sample size + * @s: comedi_subdevice struct + * + * The sample size will be 4 (sizeof int) or 2 (sizeof short) depending on + * whether the SDF_LSAMPL subdevice flag is set or not. + * + * Returns the subdevice sample size. + */ +static inline unsigned int comedi_bytes_per_sample(struct comedi_subdevice *s) +{ + return s->subdev_flags & SDF_LSAMPL ? sizeof(int) : sizeof(short); +} + +/** + * comedi_sample_shift - determine log2 of subdevice sample size + * @s: comedi_subdevice struct + * + * The sample size will be 4 (sizeof int) or 2 (sizeof short) depending on + * whether the SDF_LSAMPL subdevice flag is set or not. The log2 of the + * sample size will be 2 or 1 and can be used as the right operand of a + * bit-shift operator to multiply or divide something by the sample size. + * + * Returns log2 of the subdevice sample size. + */ +static inline unsigned int comedi_sample_shift(struct comedi_subdevice *s) { - if (subd->subdev_flags & SDF_LSAMPL) - return sizeof(unsigned int); + return s->subdev_flags & SDF_LSAMPL ? 2 : 1; +} - return sizeof(short); +/** + * comedi_bytes_to_samples - converts a number of bytes to a number of samples + * @s: comedi_subdevice struct + * @nbytes: number of bytes + * + * Returns the number of bytes divided by the subdevice sample size. + */ +static inline unsigned int comedi_bytes_to_samples(struct comedi_subdevice *s, + unsigned int nbytes) +{ + return nbytes >> comedi_sample_shift(s); +} + +/** + * comedi_samples_to_bytes - converts a number of samples to a number of bytes + * @s: comedi_subdevice struct + * @nsamples: number of samples + * + * Returns the number of samples multiplied by the subdevice sample size. + * Does not check for arithmetic overflow. + */ +static inline unsigned int comedi_samples_to_bytes(struct comedi_subdevice *s, + unsigned int nsamples) +{ + return nsamples << comedi_sample_shift(s); } /* @@ -419,18 +492,10 @@ unsigned int comedi_buf_read_n_available(struct comedi_subdevice *s); unsigned int comedi_buf_read_alloc(struct comedi_subdevice *s, unsigned int n); unsigned int comedi_buf_read_free(struct comedi_subdevice *s, unsigned int n); -int comedi_buf_put(struct comedi_subdevice *s, unsigned short x); -int comedi_buf_get(struct comedi_subdevice *s, unsigned short *x); - -void comedi_buf_memcpy_to(struct comedi_subdevice *s, unsigned int offset, - const void *source, unsigned int num_bytes); -void comedi_buf_memcpy_from(struct comedi_subdevice *s, unsigned int offset, - void *destination, unsigned int num_bytes); -unsigned int comedi_write_array_to_buffer(struct comedi_subdevice *s, - const void *data, - unsigned int num_bytes); -unsigned int comedi_read_array_from_buffer(struct comedi_subdevice *s, - void *data, unsigned int num_bytes); +unsigned int comedi_buf_write_samples(struct comedi_subdevice *s, + const void *data, unsigned int nsamples); +unsigned int comedi_buf_read_samples(struct comedi_subdevice *s, + void *data, unsigned int nsamples); /* drivers.c - general comedi driver functions */ @@ -451,6 +516,10 @@ int comedi_dio_insn_config(struct comedi_device *, struct comedi_subdevice *, unsigned int comedi_dio_update_state(struct comedi_subdevice *, unsigned int *data); unsigned int comedi_bytes_per_scan(struct comedi_subdevice *s); +unsigned int comedi_nscans_left(struct comedi_subdevice *s, + unsigned int nscans); +unsigned int comedi_nsamples_left(struct comedi_subdevice *s, + unsigned int nsamples); void comedi_inc_scan_progress(struct comedi_subdevice *s, unsigned int num_bytes); @@ -493,8 +562,6 @@ void comedi_driver_unregister(struct comedi_driver *); module_driver(__comedi_driver, comedi_driver_register, \ comedi_driver_unregister) -#ifdef CONFIG_COMEDI_PCI_DRIVERS - /* comedi_pci.c - comedi PCI driver specific functions */ /* @@ -538,36 +605,6 @@ void comedi_pci_driver_unregister(struct comedi_driver *, struct pci_driver *); module_driver(__comedi_driver, comedi_pci_driver_register, \ comedi_pci_driver_unregister, &(__pci_driver)) -#else - -/* - * Some of the comedi mixed ISA/PCI drivers call the PCI specific - * functions. Provide some dummy functions if CONFIG_COMEDI_PCI_DRIVERS - * is not enabled. - */ - -static inline struct pci_dev *comedi_to_pci_dev(struct comedi_device *dev) -{ - return NULL; -} - -static inline int comedi_pci_enable(struct comedi_device *dev) -{ - return -ENOSYS; -} - -static inline void comedi_pci_disable(struct comedi_device *dev) -{ -} - -static inline void comedi_pci_detach(struct comedi_device *dev) -{ -} - -#endif /* CONFIG_COMEDI_PCI_DRIVERS */ - -#ifdef CONFIG_COMEDI_PCMCIA_DRIVERS - /* comedi_pcmcia.c - comedi PCMCIA driver specific functions */ struct pcmcia_driver; @@ -601,10 +638,6 @@ void comedi_pcmcia_driver_unregister(struct comedi_driver *, module_driver(__comedi_driver, comedi_pcmcia_driver_register, \ comedi_pcmcia_driver_unregister, &(__pcmcia_driver)) -#endif /* CONFIG_COMEDI_PCMCIA_DRIVERS */ - -#ifdef CONFIG_COMEDI_USB_DRIVERS - /* comedi_usb.c - comedi USB driver specific functions */ struct usb_driver; @@ -634,6 +667,4 @@ void comedi_usb_driver_unregister(struct comedi_driver *, struct usb_driver *); module_driver(__comedi_driver, comedi_usb_driver_register, \ comedi_usb_driver_unregister, &(__usb_driver)) -#endif /* CONFIG_COMEDI_USB_DRIVERS */ - #endif /* _COMEDIDEV_H */ diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 3e5bccbc9c39..61802d7947ae 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -109,6 +109,10 @@ int comedi_alloc_subdev_readback(struct comedi_subdevice *s) s->readback = kcalloc(s->n_chan, sizeof(*s->readback), GFP_KERNEL); if (!s->readback) return -ENOMEM; + + if (!s->insn_read) + s->insn_read = comedi_readback_insn_read; + return 0; } EXPORT_SYMBOL_GPL(comedi_alloc_subdev_readback); @@ -316,19 +320,91 @@ unsigned int comedi_bytes_per_scan(struct comedi_subdevice *s) case COMEDI_SUBD_DI: case COMEDI_SUBD_DO: case COMEDI_SUBD_DIO: - bits_per_sample = 8 * bytes_per_sample(s); - num_samples = (cmd->chanlist_len + bits_per_sample - 1) / - bits_per_sample; + bits_per_sample = 8 * comedi_bytes_per_sample(s); + num_samples = DIV_ROUND_UP(cmd->scan_end_arg, bits_per_sample); break; default: - num_samples = cmd->chanlist_len; + num_samples = cmd->scan_end_arg; break; } - return num_samples * bytes_per_sample(s); + return comedi_samples_to_bytes(s, num_samples); } EXPORT_SYMBOL_GPL(comedi_bytes_per_scan); /** + * comedi_nscans_left - return the number of scans left in the command + * @s: comedi_subdevice struct + * @nscans: the expected number of scans + * + * If nscans is 0, the number of scans available in the async buffer will be + * used. Otherwise the expected number of scans will be used. + * + * If the async command has a stop_src of TRIG_COUNT, the nscans will be + * checked against the number of scans left in the command. + * + * The return value will then be either the expected number of scans or the + * number of scans remaining in the command. + */ +unsigned int comedi_nscans_left(struct comedi_subdevice *s, + unsigned int nscans) +{ + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; + + if (nscans == 0) { + unsigned int nbytes = comedi_buf_read_n_available(s); + + nscans = nbytes / comedi_bytes_per_scan(s); + } + + if (cmd->stop_src == TRIG_COUNT) { + unsigned int scans_left = 0; + + if (async->scans_done < cmd->stop_arg) + scans_left = cmd->stop_arg - async->scans_done; + + if (nscans > scans_left) + nscans = scans_left; + } + return nscans; +} +EXPORT_SYMBOL_GPL(comedi_nscans_left); + +/** + * comedi_nsamples_left - return the number of samples left in the command + * @s: comedi_subdevice struct + * @nsamples: the expected number of samples + * + * Returns the expected number of samples of the number of samples remaining + * in the command. + */ +unsigned int comedi_nsamples_left(struct comedi_subdevice *s, + unsigned int nsamples) +{ + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; + + if (cmd->stop_src == TRIG_COUNT) { + /* +1 to force comedi_nscans_left() to return the scans left */ + unsigned int nscans = (nsamples / cmd->scan_end_arg) + 1; + unsigned int scans_left = comedi_nscans_left(s, nscans); + unsigned int scan_pos = + comedi_bytes_to_samples(s, async->scan_progress); + unsigned long long samples_left = 0; + + if (scans_left) { + samples_left = ((unsigned long long)scans_left * + cmd->scan_end_arg) - scan_pos; + } + + if (samples_left < nsamples) + nsamples = samples_left; + } + return nsamples; +} +EXPORT_SYMBOL_GPL(comedi_nsamples_left); + +/** * comedi_inc_scan_progress - update scan progress in asynchronous command * @s: comedi_subdevice struct * @num_bytes: amount of data in bytes to increment scan progress @@ -342,10 +418,24 @@ void comedi_inc_scan_progress(struct comedi_subdevice *s, unsigned int num_bytes) { struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; unsigned int scan_length = comedi_bytes_per_scan(s); + /* track the 'cur_chan' for non-SDF_PACKED subdevices */ + if (!(s->subdev_flags & SDF_PACKED)) { + async->cur_chan += comedi_bytes_to_samples(s, num_bytes); + async->cur_chan %= cmd->chanlist_len; + } + async->scan_progress += num_bytes; if (async->scan_progress >= scan_length) { + unsigned int nscans = async->scan_progress / scan_length; + + if (async->scans_done < (UINT_MAX - nscans)) + async->scans_done += nscans; + else + async->scans_done = UINT_MAX; + async->scan_progress %= scan_length; async->events |= COMEDI_CB_EOS; } @@ -376,7 +466,7 @@ unsigned int comedi_handle_events(struct comedi_device *dev, if (events == 0) return events; - if (events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) + if (events & COMEDI_CB_CANCEL_MASK) s->cancel(dev, s); comedi_event(dev, s); diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index 6bc9ef3b25b3..84fdf20ca986 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -60,7 +60,6 @@ obj-$(CONFIG_COMEDI_S526) += s526.o # Comedi PCI drivers obj-$(CONFIG_COMEDI_8255_PCI) += 8255_pci.o obj-$(CONFIG_COMEDI_ADDI_WATCHDOG) += addi_watchdog.o -obj-$(CONFIG_COMEDI_ADDI_APCI_035) += addi_apci_035.o obj-$(CONFIG_COMEDI_ADDI_APCI_1032) += addi_apci_1032.o obj-$(CONFIG_COMEDI_ADDI_APCI_1500) += addi_apci_1500.o obj-$(CONFIG_COMEDI_ADDI_APCI_1516) += addi_apci_1516.o diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c deleted file mode 100644 index 2e7fb218340f..000000000000 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ /dev/null @@ -1,274 +0,0 @@ -/** -@verbatim - -Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - - ADDI-DATA GmbH - Dieselstrasse 3 - D-77833 Ottersweier - Tel: +19(0)7223/9493-0 - Fax: +49(0)7223/9493-92 - http://www.addi-data.com - info@addi-data.com - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; either version 2 of the License, or (at your option) any later -version. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A -PARTICULAR PURPOSE. See the GNU General Public License for more details. - -@endverbatim -*/ -/* - - +-----------------------------------------------------------------------+ - | (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier | - +-----------------------------------------------------------------------+ - | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | - | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | - +-----------------------------------------------------------------------+ - | Project : ADDI DATA | Compiler : GCC | - | Modulname : addi_common.c | Version : 2.96 | - +-------------------------------+---------------------------------------+ - | Author : | Date : | - +-----------------------------------------------------------------------+ - | Description : ADDI COMMON Main Module | - +-----------------------------------------------------------------------+ -*/ - -static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - const struct addi_board *this_board = dev->board_ptr; - struct addi_private *devpriv = dev->private; - unsigned short w_Address = CR_CHAN(insn->chanspec); - unsigned short w_Data; - - w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc, - this_board->pc_EepromChip, 2 * w_Address); - data[0] = w_Data; - - return insn->n; -} - -static irqreturn_t v_ADDI_Interrupt(int irq, void *d) -{ - struct comedi_device *dev = d; - const struct addi_board *this_board = dev->board_ptr; - - this_board->interrupt(irq, d); - return IRQ_RETVAL(1); -} - -static int i_ADDI_Reset(struct comedi_device *dev) -{ - const struct addi_board *this_board = dev->board_ptr; - - this_board->reset(dev); - return 0; -} - -static int addi_auto_attach(struct comedi_device *dev, - unsigned long context_unused) -{ - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct addi_board *this_board = dev->board_ptr; - struct addi_private *devpriv; - struct comedi_subdevice *s; - int ret, n_subdevices; - unsigned int dw_Dummy; - - dev->board_name = this_board->pc_DriverName; - - devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); - if (!devpriv) - return -ENOMEM; - - ret = comedi_pci_enable(dev); - if (ret) - return ret; - - if (this_board->i_IorangeBase1) - dev->iobase = pci_resource_start(pcidev, 1); - else - dev->iobase = pci_resource_start(pcidev, 0); - - devpriv->iobase = dev->iobase; - devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); - devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); - devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); - - /* Initialize parameters that can be overridden in EEPROM */ - devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel; - devpriv->s_EeParameters.i_NbrAoChannel = this_board->i_NbrAoChannel; - devpriv->s_EeParameters.i_AiMaxdata = this_board->i_AiMaxdata; - devpriv->s_EeParameters.i_AoMaxdata = this_board->i_AoMaxdata; - devpriv->s_EeParameters.i_NbrDiChannel = this_board->i_NbrDiChannel; - devpriv->s_EeParameters.i_NbrDoChannel = this_board->i_NbrDoChannel; - devpriv->s_EeParameters.i_DoMaxdata = this_board->i_DoMaxdata; - devpriv->s_EeParameters.i_Timer = this_board->i_Timer; - devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = - this_board->ui_MinAcquisitiontimeNs; - devpriv->s_EeParameters.ui_MinDelaytimeNs = - this_board->ui_MinDelaytimeNs; - - /* ## */ - - if (pcidev->irq > 0) { - ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, - dev->board_name, dev); - if (ret == 0) - dev->irq = pcidev->irq; - } - - /* Read eepeom and fill addi_board Structure */ - - if (this_board->i_PCIEeprom) { - if (!(strcmp(this_board->pc_EepromChip, "S5920"))) { - /* Set 3 wait stait */ - if (!(strcmp(dev->board_name, "apci035"))) - outl(0x80808082, devpriv->i_IobaseAmcc + 0x60); - else - outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); - - /* Enable the interrupt for the controller */ - dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); - outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); - } - addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); - } - - n_subdevices = 7; - ret = comedi_alloc_subdevices(dev, n_subdevices); - if (ret) - return ret; - - /* Allocate and Initialise AI Subdevice Structures */ - s = &dev->subdevices[0]; - if ((devpriv->s_EeParameters.i_NbrAiChannel) - || (this_board->i_NbrAiChannelDiff)) { - dev->read_subdev = s; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = - SDF_READABLE | SDF_COMMON | SDF_GROUND - | SDF_DIFF; - if (devpriv->s_EeParameters.i_NbrAiChannel) - s->n_chan = devpriv->s_EeParameters.i_NbrAiChannel; - else - s->n_chan = this_board->i_NbrAiChannelDiff; - s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; - s->len_chanlist = this_board->i_AiChannelList; - s->range_table = this_board->pr_AiRangelist; - - s->insn_config = this_board->ai_config; - s->insn_read = this_board->ai_read; - s->insn_write = this_board->ai_write; - s->insn_bits = this_board->ai_bits; - s->do_cmdtest = this_board->ai_cmdtest; - s->do_cmd = this_board->ai_cmd; - s->cancel = this_board->ai_cancel; - - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - /* Allocate and Initialise AO Subdevice Structures */ - s = &dev->subdevices[1]; - if (devpriv->s_EeParameters.i_NbrAoChannel) { - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel; - s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrAoChannel; - s->insn_write = this_board->ao_write; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - /* Allocate and Initialise DI Subdevice Structures */ - s = &dev->subdevices[2]; - if (devpriv->s_EeParameters.i_NbrDiChannel) { - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel; - s->maxdata = 1; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrDiChannel; - s->range_table = &range_digital; - s->insn_config = this_board->di_config; - s->insn_read = this_board->di_read; - s->insn_write = this_board->di_write; - s->insn_bits = this_board->di_bits; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - /* Allocate and Initialise DO Subdevice Structures */ - s = &dev->subdevices[3]; - if (devpriv->s_EeParameters.i_NbrDoChannel) { - s->type = COMEDI_SUBD_DO; - s->subdev_flags = - SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel; - s->maxdata = devpriv->s_EeParameters.i_DoMaxdata; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrDoChannel; - s->range_table = &range_digital; - - /* insn_config - for digital output memory */ - s->insn_config = this_board->do_config; - s->insn_write = this_board->do_write; - s->insn_bits = this_board->do_bits; - s->insn_read = this_board->do_read; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - /* Allocate and Initialise Timer Subdevice Structures */ - s = &dev->subdevices[4]; - if (devpriv->s_EeParameters.i_Timer) { - s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = 1; - s->maxdata = 0; - s->len_chanlist = 1; - s->range_table = &range_digital; - - s->insn_write = this_board->timer_write; - s->insn_read = this_board->timer_read; - s->insn_config = this_board->timer_config; - s->insn_bits = this_board->timer_bits; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - /* Allocate and Initialise TTL */ - s = &dev->subdevices[5]; - s->type = COMEDI_SUBD_UNUSED; - - /* EEPROM */ - s = &dev->subdevices[6]; - if (this_board->i_PCIEeprom) { - s->type = COMEDI_SUBD_MEMORY; - s->subdev_flags = SDF_READABLE | SDF_INTERNAL; - s->n_chan = 256; - s->maxdata = 0xffff; - s->insn_read = i_ADDIDATA_InsnReadEeprom; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - i_ADDI_Reset(dev); - return 0; -} - -static void i_ADDI_Detach(struct comedi_device *dev) -{ - if (dev->iobase) - i_ADDI_Reset(dev); - comedi_pci_detach(dev); -} diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h deleted file mode 100644 index e2a3ffeee5cf..000000000000 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include <linux/sched.h> -#include <linux/interrupt.h> - -struct addi_board { - const char *pc_DriverName; /* driver name */ - int i_IorangeBase1; - int i_PCIEeprom; /* eeprom present or not */ - char *pc_EepromChip; /* type of chip */ - int i_NbrAiChannel; /* num of A/D chans */ - int i_NbrAiChannelDiff; /* num of A/D chans in diff mode */ - int i_AiChannelList; /* len of chanlist */ - int i_NbrAoChannel; /* num of D/A chans */ - int i_AiMaxdata; /* resolution of A/D */ - int i_AoMaxdata; /* resolution of D/A */ - const struct comedi_lrange *pr_AiRangelist; /* rangelist for A/D */ - - int i_NbrDiChannel; /* Number of DI channels */ - int i_NbrDoChannel; /* Number of DO channels */ - int i_DoMaxdata; /* data to set all channels high */ - - int i_Timer; /* timer subdevice present or not */ - unsigned int ui_MinAcquisitiontimeNs; /* Minimum Acquisition in Nano secs */ - unsigned int ui_MinDelaytimeNs; /* Minimum Delay in Nano secs */ - - /* interrupt and reset */ - void (*interrupt)(int irq, void *d); - int (*reset)(struct comedi_device *); - - /* Subdevice functions */ - - /* ANALOG INPUT */ - int (*ai_config)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*ai_read)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*ai_write)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*ai_bits)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*ai_cmdtest)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_cmd *); - int (*ai_cmd)(struct comedi_device *, struct comedi_subdevice *); - int (*ai_cancel)(struct comedi_device *, struct comedi_subdevice *); - - /* Analog Output */ - int (*ao_write)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - - /* Digital Input */ - int (*di_config)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*di_read)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*di_write)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*di_bits)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - - /* Digital Output */ - int (*do_config)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*do_write)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*do_bits)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*do_read)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - - /* TIMER */ - int (*timer_config)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*timer_write)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*timer_read)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*timer_bits)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); -}; - -struct addi_private { - int iobase; - int i_IobaseAmcc; /* base+size for AMCC chip */ - int i_IobaseAddon; /* addon base address */ - int i_IobaseReserved; - unsigned int ui_AiActualScan; /* how many scans we finished */ - unsigned int ui_AiNbrofChannels; /* how many channels is measured */ - unsigned int ui_AiChannelList[32]; /* actual chanlist */ - unsigned int ui_AiReadData[32]; - unsigned short us_UseDma; /* To use Dma or not */ - unsigned char b_DmaDoubleBuffer; /* we can use double buffering */ - unsigned int ui_DmaActualBuffer; /* which buffer is used now */ - unsigned short *ul_DmaBufferVirtual[2]; /* pointers to DMA buffer */ - dma_addr_t ul_DmaBufferHw[2]; /* hw address of DMA buff */ - unsigned int ui_DmaBufferSize[2]; /* size of dma buffer in bytes */ - unsigned int ui_DmaBufferUsesize[2]; /* which size we may now used for transfer */ - unsigned char b_DigitalOutputRegister; /* Digital Output Register */ - unsigned char b_OutputMemoryStatus; - unsigned char b_TimerSelectMode; /* Contain data written at iobase + 0C */ - unsigned char b_ModeSelectRegister; /* Contain data written at iobase + 0E */ - unsigned short us_OutputRegister; /* Contain data written at iobase + 0 */ - unsigned char b_Timer2Mode; /* Specify the timer 2 mode */ - unsigned char b_Timer2Interrupt; /* Timer2 interrupt enable or disable */ - unsigned int ai_running:1; - unsigned char b_InterruptMode; /* eoc eos or dma */ - unsigned char b_EocEosInterrupt; /* Enable disable eoc eos interrupt */ - unsigned int ui_EocEosConversionTime; - unsigned char b_ExttrigEnable; /* To enable or disable external trigger */ - - /* Pointer to the current process */ - struct task_struct *tsk_Current; - - /* Parameters read from EEPROM overriding static board info */ - struct { - int i_NbrAiChannel; /* num of A/D chans */ - int i_NbrAoChannel; /* num of D/A chans */ - int i_AiMaxdata; /* resolution of A/D */ - int i_AoMaxdata; /* resolution of D/A */ - int i_NbrDiChannel; /* Number of DI channels */ - int i_NbrDoChannel; /* Number of DO channels */ - int i_DoMaxdata; /* data to set all channels high */ - int i_Timer; /* timer subdevice present or not */ - unsigned int ui_MinAcquisitiontimeNs; - /* Minimum Acquisition in Nano secs */ - unsigned int ui_MinDelaytimeNs; - /* Minimum Delay in Nano secs */ - } s_EeParameters; -}; diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c deleted file mode 100644 index b731856c27da..000000000000 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ /dev/null @@ -1,360 +0,0 @@ -/* - * addi_eeprom.c - ADDI EEPROM Module - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * Project manager: Eric Stolz - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#include <linux/delay.h> - -#define NVRAM_USER_DATA_START 0x100 - -#define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */ -#define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */ -#define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */ - -#define EE93C76_CLK_BIT (1 << 0) -#define EE93C76_CS_BIT (1 << 1) -#define EE93C76_DOUT_BIT (1 << 2) -#define EE93C76_DIN_BIT (1 << 3) -#define EE93C76_READ_CMD (0x0180 << 4) -#define EE93C76_CMD_LEN 13 - -#define EEPROM_DIGITALINPUT 0 -#define EEPROM_DIGITALOUTPUT 1 -#define EEPROM_ANALOGINPUT 2 -#define EEPROM_ANALOGOUTPUT 3 -#define EEPROM_TIMER 4 -#define EEPROM_WATCHDOG 5 -#define EEPROM_TIMER_WATCHDOG_COUNTER 10 - -static void addi_eeprom_clk_93c76(unsigned long iobase, unsigned int val) -{ - outl(val & ~EE93C76_CLK_BIT, iobase); - udelay(100); - - outl(val | EE93C76_CLK_BIT, iobase); - udelay(100); -} - -static unsigned int addi_eeprom_cmd_93c76(unsigned long iobase, - unsigned int cmd, - unsigned char len) -{ - unsigned int val = EE93C76_CS_BIT; - int i; - - /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ - outl(val, iobase); - udelay(100); - - /* Send EEPROM command - one bit at a time */ - for (i = (len - 1); i >= 0; i--) { - if (cmd & (1 << i)) - val |= EE93C76_DOUT_BIT; - else - val &= ~EE93C76_DOUT_BIT; - - /* Write the command */ - outl(val, iobase); - udelay(100); - - addi_eeprom_clk_93c76(iobase, val); - } - return val; -} - -static unsigned short addi_eeprom_readw_93c76(unsigned long iobase, - unsigned short addr) -{ - unsigned short val = 0; - unsigned int cmd; - unsigned int tmp; - int i; - - /* Send EEPROM read command and offset to EEPROM */ - cmd = EE93C76_READ_CMD | (addr / 2); - cmd = addi_eeprom_cmd_93c76(iobase, cmd, EE93C76_CMD_LEN); - - /* Get the 16-bit value */ - for (i = 0; i < 16; i++) { - addi_eeprom_clk_93c76(iobase, cmd); - - tmp = inl(iobase); - udelay(100); - - val <<= 1; - if (tmp & EE93C76_DIN_BIT) - val |= 0x1; - } - - /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ - outl(0, iobase); - udelay(100); - - return val; -} - -static void addi_eeprom_nvram_wait(unsigned long iobase) -{ - unsigned char val; - - do { - val = inb(iobase + AMCC_OP_REG_MCSR_NVCMD); - } while (val & 0x80); -} - -static unsigned short addi_eeprom_readw_nvram(unsigned long iobase, - unsigned short addr) -{ - unsigned short val = 0; - unsigned char tmp; - unsigned char i; - - for (i = 0; i < 2; i++) { - /* Load the low 8 bit address */ - outb(NVCMD_LOAD_LOW, iobase + AMCC_OP_REG_MCSR_NVCMD); - addi_eeprom_nvram_wait(iobase); - outb((addr + i) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA); - addi_eeprom_nvram_wait(iobase); - - /* Load the high 8 bit address */ - outb(NVCMD_LOAD_HIGH, iobase + AMCC_OP_REG_MCSR_NVCMD); - addi_eeprom_nvram_wait(iobase); - outb(((addr + i) >> 8) & 0xff, - iobase + AMCC_OP_REG_MCSR_NVDATA); - addi_eeprom_nvram_wait(iobase); - - /* Read the eeprom data byte */ - outb(NVCMD_BEGIN_READ, iobase + AMCC_OP_REG_MCSR_NVCMD); - addi_eeprom_nvram_wait(iobase); - tmp = inb(iobase + AMCC_OP_REG_MCSR_NVDATA); - addi_eeprom_nvram_wait(iobase); - - if (i == 0) - val |= tmp; - else - val |= (tmp << 8); - } - - return val; -} - -static unsigned short addi_eeprom_readw(unsigned long iobase, - char *type, - unsigned short addr) -{ - unsigned short val = 0; - - /* Add the offset to the start of the user data */ - addr += NVRAM_USER_DATA_START; - - if (!strcmp(type, "S5920") || !strcmp(type, "S5933")) - val = addi_eeprom_readw_nvram(iobase, addr); - - if (!strcmp(type, "93C76")) - val = addi_eeprom_readw_93c76(iobase, addr); - - return val; -} - -static void addi_eeprom_read_di_info(struct comedi_device *dev, - unsigned long iobase, - unsigned short addr) -{ - const struct addi_board *this_board = dev->board_ptr; - struct addi_private *devpriv = dev->private; - char *type = this_board->pc_EepromChip; - unsigned short tmp; - - /* Number of channels */ - tmp = addi_eeprom_readw(iobase, type, addr + 6); - devpriv->s_EeParameters.i_NbrDiChannel = tmp; - - /* Interruptible or not */ - tmp = addi_eeprom_readw(iobase, type, addr + 8); - tmp = (tmp >> 7) & 0x01; - - /* How many interruptible logic */ - tmp = addi_eeprom_readw(iobase, type, addr + 10); -} - -static void addi_eeprom_read_do_info(struct comedi_device *dev, - unsigned long iobase, - unsigned short addr) -{ - const struct addi_board *this_board = dev->board_ptr; - struct addi_private *devpriv = dev->private; - char *type = this_board->pc_EepromChip; - unsigned short tmp; - - /* Number of channels */ - tmp = addi_eeprom_readw(iobase, type, addr + 6); - devpriv->s_EeParameters.i_NbrDoChannel = tmp; - - devpriv->s_EeParameters.i_DoMaxdata = 0xffffffff >> (32 - tmp); -} - -static void addi_eeprom_read_timer_info(struct comedi_device *dev, - unsigned long iobase, - unsigned short addr) -{ - struct addi_private *devpriv = dev->private; -#if 0 - const struct addi_board *this_board = dev->board_ptr; - char *type = this_board->pc_EepromChip; - unsigned short offset = 0; - unsigned short ntimers; - unsigned short tmp; - int i; - - /* Number of Timers */ - ntimers = addi_eeprom_readw(iobase, type, addr + 6); - - /* Read header size */ - for (i = 0; i < ntimers; i++) { - unsigned short size; - unsigned short res; - unsigned short mode; - unsigned short min_timing; - unsigned short timebase; - - size = addi_eeprom_readw(iobase, type, addr + 8 + offset + 0); - - /* Resolution / Mode */ - tmp = addi_eeprom_readw(iobase, type, addr + 8 + offset + 2); - res = (tmp >> 10) & 0x3f; - mode = (tmp >> 4) & 0x3f; - - /* MinTiming / Timebase */ - tmp = addi_eeprom_readw(iobase, type, addr + 8 + offset + 4); - min_timing = (tmp >> 6) & 0x3ff; - Timebase = tmp & 0x3f; - - offset += size; - } -#endif - /* Timer subdevice present */ - devpriv->s_EeParameters.i_Timer = 1; -} - -static void addi_eeprom_read_ao_info(struct comedi_device *dev, - unsigned long iobase, - unsigned short addr) -{ - const struct addi_board *this_board = dev->board_ptr; - struct addi_private *devpriv = dev->private; - char *type = this_board->pc_EepromChip; - unsigned short tmp; - - /* No of channels for 1st hard component */ - tmp = addi_eeprom_readw(iobase, type, addr + 10); - devpriv->s_EeParameters.i_NbrAoChannel = (tmp >> 4) & 0x3ff; - - /* Resolution for 1st hard component */ - tmp = addi_eeprom_readw(iobase, type, addr + 16); - tmp = (tmp >> 8) & 0xff; - devpriv->s_EeParameters.i_AoMaxdata = 0xfff >> (16 - tmp); -} - -static void addi_eeprom_read_ai_info(struct comedi_device *dev, - unsigned long iobase, - unsigned short addr) -{ - const struct addi_board *this_board = dev->board_ptr; - struct addi_private *devpriv = dev->private; - char *type = this_board->pc_EepromChip; - unsigned short offset; - unsigned short tmp; - - /* No of channels for 1st hard component */ - tmp = addi_eeprom_readw(iobase, type, addr + 10); - devpriv->s_EeParameters.i_NbrAiChannel = (tmp >> 4) & 0x3ff; - if (!strcmp(this_board->pc_DriverName, "apci3200")) - devpriv->s_EeParameters.i_NbrAiChannel *= 4; - - tmp = addi_eeprom_readw(iobase, type, addr + 16); - devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = tmp * 1000; - - tmp = addi_eeprom_readw(iobase, type, addr + 30); - devpriv->s_EeParameters.ui_MinDelaytimeNs = tmp * 1000; - - tmp = addi_eeprom_readw(iobase, type, addr + 20); - /* dma = (tmp >> 13) & 0x01; */ - - tmp = addi_eeprom_readw(iobase, type, addr + 72) & 0xff; - if (tmp) { /* > 0 */ - /* offset of first analog input single header */ - offset = 74 + (2 * tmp) + (10 * (1 + (tmp / 16))); - } else { /* = 0 */ - offset = 74; - } - - /* Resolution */ - tmp = addi_eeprom_readw(iobase, type, addr + offset + 2) & 0x1f; - devpriv->s_EeParameters.i_AiMaxdata = 0xffff >> (16 - tmp); -} - -static void addi_eeprom_read_info(struct comedi_device *dev, - unsigned long iobase) -{ - const struct addi_board *this_board = dev->board_ptr; - char *type = this_board->pc_EepromChip; - unsigned short size; - unsigned char nfuncs; - int i; - - size = addi_eeprom_readw(iobase, type, 8); - nfuncs = addi_eeprom_readw(iobase, type, 10) & 0xff; - - /* Read functionality details */ - for (i = 0; i < nfuncs; i++) { - unsigned short offset = i * 4; - unsigned short addr; - unsigned char func; - - func = addi_eeprom_readw(iobase, type, 12 + offset) & 0x3f; - addr = addi_eeprom_readw(iobase, type, 14 + offset); - - switch (func) { - case EEPROM_DIGITALINPUT: - addi_eeprom_read_di_info(dev, iobase, addr); - break; - - case EEPROM_DIGITALOUTPUT: - addi_eeprom_read_do_info(dev, iobase, addr); - break; - - case EEPROM_ANALOGINPUT: - addi_eeprom_read_ai_info(dev, iobase, addr); - break; - - case EEPROM_ANALOGOUTPUT: - addi_eeprom_read_ao_info(dev, iobase, addr); - break; - - case EEPROM_TIMER: - case EEPROM_WATCHDOG: - case EEPROM_TIMER_WATCHDOG_COUNTER: - addi_eeprom_read_timer_info(dev, iobase, addr); - break; - } - } -} diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c deleted file mode 100644 index 53bb51bd77b5..000000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c +++ /dev/null @@ -1,480 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - */ - -/* Card Specific information */ -#define APCI035_ADDRESS_RANGE 255 - -/* Timer / Watchdog Related Defines */ -#define APCI035_TCW_SYNC_ENABLEDISABLE 0 -#define APCI035_TCW_RELOAD_VALUE 4 -#define APCI035_TCW_TIMEBASE 8 -#define APCI035_TCW_PROG 12 -#define APCI035_TCW_TRIG_STATUS 16 -#define APCI035_TCW_IRQ 20 -#define APCI035_TCW_WARN_TIMEVAL 24 -#define APCI035_TCW_WARN_TIMEBASE 28 - -#define ADDIDATA_TIMER 0 -/* #define ADDIDATA_WATCHDOG 1 */ - -#define APCI035_TW1 0 -#define APCI035_TW2 32 -#define APCI035_TW3 64 -#define APCI035_TW4 96 - -#define APCI035_AI_OFFSET 0 -#define APCI035_TEMP 128 -#define APCI035_ALR_SEQ 4 -#define APCI035_START_STOP_INDEX 8 -#define APCI035_ALR_START_STOP 12 -#define APCI035_ALR_IRQ 16 -#define APCI035_EOS 20 -#define APCI035_CHAN_NO 24 -#define APCI035_CHAN_VAL 28 -#define APCI035_CONV_TIME_TIME_BASE 36 -#define APCI035_RELOAD_CONV_TIME_VAL 32 -#define APCI035_DELAY_TIME_TIME_BASE 44 -#define APCI035_RELOAD_DELAY_TIME_VAL 40 -#define ENABLE_EXT_TRIG 1 -#define ENABLE_EXT_GATE 2 -#define ENABLE_EXT_TRIG_GATE 3 - -#define ANALOG_INPUT 0 -#define TEMPERATURE 1 -#define RESISTANCE 2 - -#define ADDIDATA_GREATER_THAN_TEST 0 -#define ADDIDATA_LESS_THAN_TEST 1 - -#define APCI035_MAXVOLT 2.5 - -#define ADDIDATA_UNIPOLAR 1 -#define ADDIDATA_BIPOLAR 2 - -/* ANALOG INPUT RANGE */ -static struct comedi_lrange range_apci035_ai = { - 8, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2), - BIP_RANGE(1), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2), - UNI_RANGE(1) - } -}; - -static int i_WatchdogNbr; -static int i_Temp; -static int i_Flag = 1; - -/* - * Configures The Timer , Counter or Watchdog - * - * data[0] 0 = Configure As Timer, 1 = Configure As Watchdog - * data[1] Watchdog number - * data[2] Time base Unit - * data[3] Reload Value - * data[4] External Trigger, 1 = Enable, 0 = Disable - * data[5] External Trigger Level - * 00 = Trigger Disabled - * 01 = Trigger Enabled (Low level) - * 10 = Trigger Enabled (High Level) - * 11 = Trigger Enabled (High/Low level) - * data[6] External Gate, 1 = Enable, 0 = Disable - * data[7] External Gate level - * 00 = Gate Disabled - * 01 = Gate Enabled (Low level) - * 10 = Gate Enabled (High Level) - * data[8] Warning Relay, 1 = Enable, 0 = Disable - * data[9] Warning Delay available - * data[10] Warning Relay Time unit - * data[11] Warning Relay Time Reload value - * data[12] Reset Relay, 1 = Enable, 0 = Disable - * data[13] Interrupt, 1 = Enable, 0 = Disable - */ -static int apci035_timer_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_Status; - unsigned int ui_Command; - unsigned int ui_Mode; - - i_Temp = 0; - devpriv->tsk_Current = current; - devpriv->b_TimerSelectMode = data[0]; - i_WatchdogNbr = data[1]; - if (data[0] == 0) - ui_Mode = 2; - else - ui_Mode = 0; - - ui_Command = 0; - outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - /* Set the reload value */ - outl(data[3], devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 4); - - /* Set the time unit */ - outl(data[2], devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 8); - if (data[0] == ADDIDATA_TIMER) { - - /* Set the mode : */ - /* - Disable the hardware */ - /* - Disable the counter mode */ - /* - Disable the warning */ - /* - Disable the reset */ - /* - Enable the timer mode */ - /* - Set the timer mode */ - - ui_Command = - (ui_Command & 0xFFF719E2UL) | ui_Mode << 13UL | 0x10UL; - - } else if (data[0] == ADDIDATA_WATCHDOG) { - - /* Set the mode : */ - /* - Disable the hardware */ - /* - Disable the counter mode */ - /* - Disable the warning */ - /* - Disable the reset */ - /* - Disable the timer mode */ - - ui_Command = ui_Command & 0xFFF819E2UL; - - } else { - dev_err(dev->class_dev, "The parameter for Timer/watchdog selection is in error\n"); - return -EINVAL; - } - - outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - /* Disable the hardware trigger */ - ui_Command = ui_Command & 0xFFFFF89FUL; - if (data[4] == 1) { - /* Set the hardware trigger level */ - ui_Command = ui_Command | (data[5] << 5); - } - outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - /* Disable the hardware gate */ - ui_Command = ui_Command & 0xFFFFF87FUL; - if (data[6] == 1) { - /* Set the hardware gate level */ - ui_Command = ui_Command | (data[7] << 7); - } - outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - /* Disable the hardware output */ - ui_Command = ui_Command & 0xFFFFF9FBUL; - - /* Set the hardware output level */ - ui_Command = ui_Command | (data[8] << 2); - outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - if (data[9] == 1) { - /* Set the reload value */ - outl(data[11], - devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 24); - - /* Set the time unite */ - outl(data[10], - devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 28); - } - - ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - /* Disable the hardware output */ - ui_Command = ui_Command & 0xFFFFF9F7UL; - - /* Set the hardware output level */ - ui_Command = ui_Command | (data[12] << 3); - outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - /* Enable the watchdog interrupt */ - ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - /* Set the interrupt selection */ - ui_Status = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 16); - - ui_Command = (ui_Command & 0xFFFFF9FDUL) | (data[13] << 1); - outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - return insn->n; -} - -/* - * Start / Stop The Selected Timer , or Watchdog - * - * data[0] - * 0 - Stop Selected Timer/Watchdog - * 1 - Start Selected Timer/Watch*dog - * 2 - Trigger Selected Timer/Watchdog - * 3 - Stop All Timer/Watchdog - * 4 - Start All Timer/Watchdog - * 5 - Trigger All Timer/Watchdog - */ -static int apci035_timer_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_Command; - int i_Count; - - if (data[0] == 1) { - ui_Command = - inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - /* Start the hardware */ - ui_Command = (ui_Command & 0xFFFFF9FFUL) | 0x1UL; - outl(ui_Command, - devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - } - if (data[0] == 2) { - ui_Command = - inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - /* Set the trigger command */ - ui_Command = (ui_Command & 0xFFFFF9FFUL) | 0x200UL; - outl(ui_Command, - devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - } - - if (data[0] == 0) { - /* Stop The Watchdog */ - ui_Command = 0; - /* - * ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12); - * ui_Command = ui_Command & 0xFFFFF9FEUL; - */ - outl(ui_Command, - devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - } - if (data[0] == 3) { - /* stop all Watchdogs */ - ui_Command = 0; - for (i_Count = 1; i_Count <= 4; i_Count++) { - if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) - ui_Command = 0x2UL; - else - ui_Command = 0x10UL; - - i_WatchdogNbr = i_Count; - outl(ui_Command, - devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + - 0); - } - - } - if (data[0] == 4) { - /* start all Watchdogs */ - ui_Command = 0; - for (i_Count = 1; i_Count <= 4; i_Count++) { - if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) - ui_Command = 0x1UL; - else - ui_Command = 0x8UL; - - i_WatchdogNbr = i_Count; - outl(ui_Command, - devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + - 0); - } - } - if (data[0] == 5) { - /* trigger all Watchdogs */ - ui_Command = 0; - for (i_Count = 1; i_Count <= 4; i_Count++) { - if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) - ui_Command = 0x4UL; - else - ui_Command = 0x20UL; - - i_WatchdogNbr = i_Count; - outl(ui_Command, - devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + - 0); - } - i_Temp = 1; - } - return insn->n; -} - -/* - * Read The Selected Timer , Counter or Watchdog - * - * data[0] software trigger status - * data[1] hardware trigger status - * data[2] Software clear status - * data[3] Overflow status - * data[4] Timer actual value - */ -static int apci035_timer_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_Status; /* Status register */ - - i_WatchdogNbr = insn->unused[0]; - - /* Get the status */ - ui_Status = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 16); - - /* Get the software trigger status */ - data[0] = ((ui_Status >> 1) & 1); - - /* Get the hardware trigger status */ - data[1] = ((ui_Status >> 2) & 1); - - /* Get the software clear status */ - data[2] = ((ui_Status >> 3) & 1); - - /* Get the overflow status */ - data[3] = ((ui_Status >> 0) & 1); - if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) - data[4] = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 0); - - return insn->n; -} - -/* - * Configures The Analog Input Subdevice - * - * data[0] Warning delay value - */ -static int apci035_ai_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - - devpriv->tsk_Current = current; - outl(0x200 | 0, devpriv->iobase + 128 + 0x4); - outl(0, devpriv->iobase + 128 + 0); - - /* Initialise the warning value */ - outl(0x300 | 0, devpriv->iobase + 128 + 0x4); - outl((data[0] << 8), devpriv->iobase + 128 + 0); - outl(0x200000UL, devpriv->iobase + 128 + 12); - - return insn->n; -} - -/* - * Read value of the selected channel - * - * data[0] Digital Value Of Input - */ -static int apci035_ai_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_CommandRegister; - - /* Set the start */ - ui_CommandRegister = 0x80000; - - /* Write the command register */ - outl(ui_CommandRegister, devpriv->iobase + 128 + 8); - - /* Read the digital value of the input */ - data[0] = inl(devpriv->iobase + 128 + 28); - return insn->n; -} - -static int apci035_reset(struct comedi_device *dev) -{ - struct addi_private *devpriv = dev->private; - int i_Count; - - for (i_Count = 1; i_Count <= 4; i_Count++) { - i_WatchdogNbr = i_Count; - - /* stop all timers */ - outl(0x0, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 0); - } - outl(0x0, devpriv->iobase + 128 + 12); /* Disable the warning delay */ - - return 0; -} - -static void apci035_interrupt(int irq, void *d) -{ - struct comedi_device *dev = d; - struct addi_private *devpriv = dev->private; - unsigned int ui_StatusRegister1; - unsigned int ui_StatusRegister2; - unsigned int ui_ReadCommand; - unsigned int ui_ChannelNumber; - unsigned int ui_DigitalTemperature; - - if (i_Temp == 1) { - i_WatchdogNbr = i_Flag; - i_Flag = i_Flag + 1; - } - - /* Read the interrupt status register of temperature Warning */ - ui_StatusRegister1 = inl(devpriv->iobase + 128 + 16); - - /* Read the interrupt status register for Watchdog/timer */ - ui_StatusRegister2 = - inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 20); - - /* Test if warning relay interrupt */ - if ((((ui_StatusRegister1) & 0x8) == 0x8)) { - - /* Disable the temperature warning */ - ui_ReadCommand = inl(devpriv->iobase + 128 + 12); - ui_ReadCommand = ui_ReadCommand & 0xFFDF0000UL; - outl(ui_ReadCommand, devpriv->iobase + 128 + 12); - - /* Read the channel number */ - ui_ChannelNumber = inl(devpriv->iobase + 128 + 60); - - /* Read the digital temperature value */ - ui_DigitalTemperature = inl(devpriv->iobase + 128 + 60); - - /* send signal to the sample */ - send_sig(SIGIO, devpriv->tsk_Current, 0); - - } else if ((ui_StatusRegister2 & 0x1) == 0x1) { - /* send signal to the sample */ - send_sig(SIGIO, devpriv->tsk_Current, 0); - } -} diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c index 0ea081e1e119..bfa9228c833f 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c @@ -158,7 +158,7 @@ static int apci1500_di_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; int i_PatternPolarity = 0, i_PatternTransition = 0, i_PatternMask = 0; int i_MaxChannel = 0, i_Count = 0, i_EventMask = 0; int i_PatternTransitionCount = 0, i_RegValue; @@ -466,7 +466,7 @@ static int apci1500_di_write(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; int i_Event1InterruptStatus = 0, i_Event2InterruptStatus = 0, i_RegValue; @@ -653,7 +653,7 @@ static int apci1500_di_read(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; int i_DummyRead = 0; /* Software reset */ @@ -789,7 +789,7 @@ static int apci1500_di_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; data[1] = inw(devpriv->i_IobaseAddon + APCI1500_DIGITAL_IP); @@ -807,7 +807,7 @@ static int apci1500_do_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; devpriv->b_OutputMemoryStatus = data[0]; return insn->n; @@ -821,7 +821,7 @@ static int apci1500_do_write(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; static unsigned int ui_Temp; unsigned int ui_Temp1; unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ @@ -981,7 +981,7 @@ static int apci1500_timer_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; int i_TimerCounterMode, i_MasterConfiguration; devpriv->tsk_Current = current; @@ -1471,7 +1471,7 @@ static int apci1500_timer_write(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; int i_CommandAndStatusValue; switch (data[0]) { @@ -1731,7 +1731,7 @@ static int apci1500_timer_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; int i_CommandAndStatusValue; switch (data[0]) { @@ -1895,7 +1895,7 @@ static int apci1500_do_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; unsigned int ui_Status; int i_RegValue; int i_Constant; @@ -2011,11 +2011,11 @@ static int apci1500_do_bits(struct comedi_device *dev, return insn->n; } -static void apci1500_interrupt(int irq, void *d) +static irqreturn_t apci1500_interrupt(int irq, void *d) { struct comedi_device *dev = d; - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; unsigned int ui_InterruptStatus = 0; int i_RegValue = 0; @@ -2180,11 +2180,13 @@ static void apci1500_interrupt(int irq, void *d) "Interrupt from unknown source\n"); } + + return IRQ_HANDLED; } static int apci1500_reset(struct comedi_device *dev) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; int i_DummyRead = 0; i_TimerCounter1Init = 0; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c index 98de96953a29..fa99c8ca4f95 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c @@ -16,244 +16,189 @@ #define ADDIDATA_TIMER 0 #define ADDIDATA_COUNTER 1 #define ADDIDATA_WATCHDOG 2 -#define APCI1564_COUNTER1 0 -#define APCI1564_COUNTER2 1 -#define APCI1564_COUNTER3 2 -#define APCI1564_COUNTER4 3 - -/* - * devpriv->amcc_iobase Register Map - */ -#define APCI1564_DI_REG 0x04 -#define APCI1564_DI_INT_MODE1_REG 0x08 -#define APCI1564_DI_INT_MODE2_REG 0x0c -#define APCI1564_DI_INT_STATUS_REG 0x10 -#define APCI1564_DI_IRQ_REG 0x14 -#define APCI1564_DO_REG 0x18 -#define APCI1564_DO_INT_CTRL_REG 0x1c -#define APCI1564_DO_INT_STATUS_REG 0x20 -#define APCI1564_DO_IRQ_REG 0x24 -#define APCI1564_WDOG_REG 0x28 -#define APCI1564_WDOG_RELOAD_REG 0x2c -#define APCI1564_WDOG_TIMEBASE_REG 0x30 -#define APCI1564_WDOG_CTRL_REG 0x34 -#define APCI1564_WDOG_STATUS_REG 0x38 -#define APCI1564_WDOG_IRQ_REG 0x3c -#define APCI1564_WDOG_WARN_TIMEVAL_REG 0x40 -#define APCI1564_WDOG_WARN_TIMEBASE_REG 0x44 -#define APCI1564_TIMER_REG 0x48 -#define APCI1564_TIMER_RELOAD_REG 0x4c -#define APCI1564_TIMER_TIMEBASE_REG 0x50 -#define APCI1564_TIMER_CTRL_REG 0x54 -#define APCI1564_TIMER_STATUS_REG 0x58 -#define APCI1564_TIMER_IRQ_REG 0x5c -#define APCI1564_TIMER_WARN_TIMEVAL_REG 0x60 -#define APCI1564_TIMER_WARN_TIMEBASE_REG 0x64 - -/* - * dev->iobase Register Map - */ -#define APCI1564_COUNTER_REG(x) (0x00 + ((x) * 0x20)) -#define APCI1564_COUNTER_RELOAD_REG(x) (0x04 + ((x) * 0x20)) -#define APCI1564_COUNTER_TIMEBASE_REG(x) (0x08 + ((x) * 0x20)) -#define APCI1564_COUNTER_CTRL_REG(x) (0x0c + ((x) * 0x20)) -#define APCI1564_COUNTER_STATUS_REG(x) (0x10 + ((x) * 0x20)) -#define APCI1564_COUNTER_IRQ_REG(x) (0x14 + ((x) * 0x20)) -#define APCI1564_COUNTER_WARN_TIMEVAL_REG(x) (0x18 + ((x) * 0x20)) -#define APCI1564_COUNTER_WARN_TIMEBASE_REG(x) (0x1c + ((x) * 0x20)) - -/* - * Configures The Timer or Counter - * - * data[0] Configure as: 0 = Timer, 1 = Counter - * data[1] 1 = Enable Interrupt, 0 = Disable Interrupt - * data[2] Time Unit - * data[3] Reload Value - * data[4] Timer Mode - * data[5] Timer Counter Watchdog Number - * data[6] Counter Direction - */ -static int apci1564_timer_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) + +static int apci1564_timer_insn_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct apci1564_private *devpriv = dev->private; - unsigned int ul_Command1 = 0; + unsigned int ctrl; devpriv->tsk_current = current; - if (data[0] == ADDIDATA_TIMER) { - /* First Stop The Timer */ - ul_Command1 = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); - ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; - /* Stop The Timer */ - outl(ul_Command1, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); - - devpriv->timer_select_mode = ADDIDATA_TIMER; - if (data[1] == 1) { - /* Enable TIMER int & DISABLE ALL THE OTHER int SOURCES */ - outl(0x02, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); - outl(0x0, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG); - outl(0x0, devpriv->amcc_iobase + APCI1564_DO_IRQ_REG); - outl(0x0, devpriv->amcc_iobase + APCI1564_WDOG_IRQ_REG); - outl(0x0, dev->iobase + - APCI1564_COUNTER_IRQ_REG(APCI1564_COUNTER1)); - outl(0x0, dev->iobase + - APCI1564_COUNTER_IRQ_REG(APCI1564_COUNTER2)); - outl(0x0, dev->iobase + - APCI1564_COUNTER_IRQ_REG(APCI1564_COUNTER3)); - outl(0x0, dev->iobase + - APCI1564_COUNTER_IRQ_REG(APCI1564_COUNTER4)); - } else { - /* disable Timer interrupt */ - outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); - } - /* Loading Timebase */ - outl(data[2], devpriv->amcc_iobase + APCI1564_TIMER_TIMEBASE_REG); - - /* Loading the Reload value */ - outl(data[3], devpriv->amcc_iobase + APCI1564_TIMER_RELOAD_REG); - - ul_Command1 = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); - ul_Command1 = (ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL; - /* mode 2 */ - outl(ul_Command1, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); - } else if (data[0] == ADDIDATA_COUNTER) { - devpriv->timer_select_mode = ADDIDATA_COUNTER; - devpriv->mode_select_register = data[5]; - - /* First Stop The Counter */ - ul_Command1 = inl(dev->iobase + - APCI1564_COUNTER_CTRL_REG(data[5] - 1)); - ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; - /* Stop The Timer */ - outl(ul_Command1, dev->iobase + - APCI1564_COUNTER_CTRL_REG(data[5] - 1)); - - /* Set the reload value */ - outl(data[3], dev->iobase + - APCI1564_COUNTER_RELOAD_REG(data[5] - 1)); - - /* Set the mode : */ - /* - Disable the hardware */ - /* - Disable the counter mode */ - /* - Disable the warning */ - /* - Disable the reset */ - /* - Disable the timer mode */ - /* - Enable the counter mode */ - - ul_Command1 = - (ul_Command1 & 0xFFFC19E2UL) | 0x80000UL | - (unsigned int) ((unsigned int) data[4] << 16UL); - outl(ul_Command1, dev->iobase + - APCI1564_COUNTER_CTRL_REG(data[5] - 1)); - - /* Enable or Disable Interrupt */ - ul_Command1 = (ul_Command1 & 0xFFFFF9FD) | (data[1] << 1); - outl(ul_Command1, dev->iobase + - APCI1564_COUNTER_CTRL_REG(data[5] - 1)); - - /* Set the Up/Down selection */ - ul_Command1 = (ul_Command1 & 0xFFFBF9FFUL) | (data[6] << 18); - outl(ul_Command1, dev->iobase + - APCI1564_COUNTER_CTRL_REG(data[5] - 1)); + /* First Stop The Timer */ + ctrl = inl(devpriv->timer + ADDI_TCW_CTRL_REG); + ctrl &= 0xfffff9fe; + /* Stop The Timer */ + outl(ctrl, devpriv->timer + ADDI_TCW_CTRL_REG); + + if (data[1] == 1) { + /* Enable timer int & disable all the other int sources */ + outl(0x02, devpriv->timer + ADDI_TCW_CTRL_REG); + outl(0x0, dev->iobase + APCI1564_DI_IRQ_REG); + outl(0x0, dev->iobase + APCI1564_DO_IRQ_REG); + outl(0x0, dev->iobase + APCI1564_WDOG_IRQ_REG); + if (devpriv->counters) { + unsigned long iobase; + + iobase = devpriv->counters + ADDI_TCW_IRQ_REG; + outl(0x0, iobase + APCI1564_COUNTER(0)); + outl(0x0, iobase + APCI1564_COUNTER(1)); + outl(0x0, iobase + APCI1564_COUNTER(2)); + } } else { - dev_err(dev->class_dev, "Invalid subdevice.\n"); + /* disable Timer interrupt */ + outl(0x0, devpriv->timer + ADDI_TCW_CTRL_REG); } + + /* Loading Timebase */ + outl(data[2], devpriv->timer + ADDI_TCW_TIMEBASE_REG); + + /* Loading the Reload value */ + outl(data[3], devpriv->timer + ADDI_TCW_RELOAD_REG); + + ctrl = inl(devpriv->timer + ADDI_TCW_CTRL_REG); + ctrl &= 0xfff719e2; + ctrl |= (2 << 13) | 0x10; + /* mode 2 */ + outl(ctrl, devpriv->timer + ADDI_TCW_CTRL_REG); + return insn->n; } -/* - * Start / Stop The Selected Timer or Counter - * - * data[0] Configure as: 0 = Timer, 1 = Counter - * data[1] 0 = Stop, 1 = Start, 2 = Trigger Clear (Only Counter) - */ -static int apci1564_timer_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci1564_timer_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct apci1564_private *devpriv = dev->private; - unsigned int ul_Command1 = 0; + unsigned int ctrl; + + ctrl = inl(devpriv->timer + ADDI_TCW_CTRL_REG); + switch (data[1]) { + case 0: /* Stop The Timer */ + ctrl &= 0xfffff9fe; + break; + case 1: /* Enable the Timer */ + ctrl &= 0xfffff9ff; + ctrl |= 0x1; + break; + } + outl(ctrl, devpriv->timer + ADDI_TCW_CTRL_REG); - if (devpriv->timer_select_mode == ADDIDATA_TIMER) { - if (data[1] == 1) { - ul_Command1 = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); - ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL; + return insn->n; +} - /* Enable the Timer */ - outl(ul_Command1, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); - } else if (data[1] == 0) { - /* Stop The Timer */ +static int apci1564_timer_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct apci1564_private *devpriv = dev->private; + + /* Stores the status of the Timer */ + data[0] = inl(devpriv->timer + ADDI_TCW_STATUS_REG) & 0x1; + + /* Stores the Actual value of the Timer */ + data[1] = inl(devpriv->timer + ADDI_TCW_VAL_REG); - ul_Command1 = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); - ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; - outl(ul_Command1, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); - } - } else if (devpriv->timer_select_mode == ADDIDATA_COUNTER) { - ul_Command1 = - inl(dev->iobase + - APCI1564_COUNTER_CTRL_REG(devpriv->mode_select_register - 1)); - if (data[1] == 1) { - /* Start the Counter subdevice */ - ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL; - } else if (data[1] == 0) { - /* Stops the Counter subdevice */ - ul_Command1 = 0; - - } else if (data[1] == 2) { - /* Clears the Counter subdevice */ - ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x400; - } - outl(ul_Command1, dev->iobase + - APCI1564_COUNTER_CTRL_REG(devpriv->mode_select_register - 1)); - } else { - dev_err(dev->class_dev, "Invalid subdevice.\n"); - } return insn->n; } -/* - * Read The Selected Timer or Counter - */ -static int apci1564_timer_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci1564_counter_insn_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct apci1564_private *devpriv = dev->private; - unsigned int ul_Command1 = 0; - - if (devpriv->timer_select_mode == ADDIDATA_TIMER) { - /* Stores the status of the Timer */ - data[0] = inl(devpriv->amcc_iobase + APCI1564_TIMER_STATUS_REG) & 0x1; - - /* Stores the Actual value of the Timer */ - data[1] = inl(devpriv->amcc_iobase + APCI1564_TIMER_REG); - } else if (devpriv->timer_select_mode == ADDIDATA_COUNTER) { - /* Read the Counter Actual Value. */ - data[0] = - inl(dev->iobase + - APCI1564_COUNTER_REG(devpriv->mode_select_register - 1)); - ul_Command1 = - inl(dev->iobase + - APCI1564_COUNTER_STATUS_REG(devpriv->mode_select_register - 1)); - - /* Get the software trigger status */ - data[1] = (unsigned char) ((ul_Command1 >> 1) & 1); - - /* Get the hardware trigger status */ - data[2] = (unsigned char) ((ul_Command1 >> 2) & 1); - - /* Get the software clear status */ - data[3] = (unsigned char) ((ul_Command1 >> 3) & 1); - - /* Get the overflow status */ - data[4] = (unsigned char) ((ul_Command1 >> 0) & 1); - } else { - dev_err(dev->class_dev, "Invalid subdevice.\n"); + unsigned int chan = CR_CHAN(insn->chanspec); + unsigned long iobase = devpriv->counters + APCI1564_COUNTER(chan); + unsigned int ctrl; + + devpriv->tsk_current = current; + + /* First Stop The Counter */ + ctrl = inl(iobase + ADDI_TCW_CTRL_REG); + ctrl &= 0xfffff9fe; + /* Stop The Timer */ + outl(ctrl, iobase + ADDI_TCW_CTRL_REG); + + /* Set the reload value */ + outl(data[3], iobase + ADDI_TCW_RELOAD_REG); + + /* Set the mode : */ + /* - Disable the hardware */ + /* - Disable the counter mode */ + /* - Disable the warning */ + /* - Disable the reset */ + /* - Disable the timer mode */ + /* - Enable the counter mode */ + + ctrl &= 0xfffc19e2; + ctrl |= 0x80000 | (data[4] << 16); + outl(ctrl, iobase + ADDI_TCW_CTRL_REG); + + /* Enable or Disable Interrupt */ + ctrl &= 0xfffff9fd; + ctrl |= (data[1] << 1); + outl(ctrl, iobase + ADDI_TCW_CTRL_REG); + + /* Set the Up/Down selection */ + ctrl &= 0xfffbf9ff; + ctrl |= (data[6] << 18); + outl(ctrl, iobase + ADDI_TCW_CTRL_REG); + + return insn->n; +} + +static int apci1564_counter_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct apci1564_private *devpriv = dev->private; + unsigned int chan = CR_CHAN(insn->chanspec); + unsigned long iobase = devpriv->counters + APCI1564_COUNTER(chan); + unsigned int ctrl; + + ctrl = inl(iobase + ADDI_TCW_CTRL_REG); + switch (data[1]) { + case 0: /* Stops the Counter subdevice */ + ctrl = 0; + break; + case 1: /* Start the Counter subdevice */ + ctrl &= 0xfffff9ff; + ctrl |= 0x1; + break; + case 2: /* Clears the Counter subdevice */ + ctrl &= 0xfffff9ff; + ctrl |= 0x400; + break; } + outl(ctrl, iobase + ADDI_TCW_CTRL_REG); + + return insn->n; +} + +static int apci1564_counter_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct apci1564_private *devpriv = dev->private; + unsigned int chan = CR_CHAN(insn->chanspec); + unsigned long iobase = devpriv->counters + APCI1564_COUNTER(chan); + unsigned int status; + + /* Read the Counter Actual Value. */ + data[0] = inl(iobase + ADDI_TCW_VAL_REG); + + status = inl(iobase + ADDI_TCW_STATUS_REG); + data[1] = (status >> 1) & 1; /* software trigger status */ + data[2] = (status >> 2) & 1; /* hardware trigger status */ + data[3] = (status >> 3) & 1; /* software clear status */ + data[4] = (status >> 0) & 1; /* overflow status */ + return insn->n; } diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c deleted file mode 100644 index 2950815b65f4..000000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ /dev/null @@ -1,2050 +0,0 @@ -/** -@verbatim - -Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - - ADDI-DATA GmbH - Dieselstrasse 3 - D-77833 Ottersweier - Tel: +19(0)7223/9493-0 - Fax: +49(0)7223/9493-92 - http://www.addi-data.com - info@addi-data.com - -This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -@endverbatim -*/ -/* - +-----------------------------------------------------------------------+ - | (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier | - +-----------------------------------------------------------------------+ - | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | - | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | - +-----------------------------------------------------------------------+ - | Project : APCI-3120 | Compiler : GCC | - | Module name : hwdrv_apci3120.c| Version : 2.96 | - +-------------------------------+---------------------------------------+ - | Project manager: Eric Stolz | Date : 02/12/2002 | - +-----------------------------------------------------------------------+ - | Description :APCI3120 Module. Hardware abstraction Layer for APCI3120| - +-----------------------------------------------------------------------+ - | UPDATE'S | - +-----------------------------------------------------------------------+ - | Date | Author | Description of updates | - +----------+-----------+------------------------------------------------+ - | | | | - | | | | - +----------+-----------+------------------------------------------------+ -*/ - -#include <linux/delay.h> - -/* - * ADDON RELATED ADDITIONS - */ -/* Constant */ -#define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW 0x00 -#define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH 0x1200 -#define APCI3120_A2P_FIFO_MANAGEMENT 0x04000400L -#define APCI3120_AMWEN_ENABLE 0x02 -#define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01 -#define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L -#define APCI3120_ENABLE_WRITE_TC_INT 0x00004000L -#define APCI3120_CLEAR_WRITE_TC_INT 0x00040000L -#define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0 -#define APCI3120_DISABLE_BUS_MASTER_ADD_ON 0x0 -#define APCI3120_DISABLE_BUS_MASTER_PCI 0x0 - -/* ADD_ON ::: this needed since apci supports 16 bit interface to add on */ -#define APCI3120_ADD_ON_AGCSTS_LOW 0x3C -#define APCI3120_ADD_ON_AGCSTS_HIGH (APCI3120_ADD_ON_AGCSTS_LOW + 2) -#define APCI3120_ADD_ON_MWAR_LOW 0x24 -#define APCI3120_ADD_ON_MWAR_HIGH (APCI3120_ADD_ON_MWAR_LOW + 2) -#define APCI3120_ADD_ON_MWTC_LOW 0x058 -#define APCI3120_ADD_ON_MWTC_HIGH (APCI3120_ADD_ON_MWTC_LOW + 2) - -/* AMCC */ -#define APCI3120_AMCC_OP_MCSR 0x3C -#define APCI3120_AMCC_OP_REG_INTCSR 0x38 - -/* for transfer count enable bit */ -#define AGCSTS_TC_ENABLE 0x10000000 - -/* used for test on mixture of BIP/UNI ranges */ -#define APCI3120_BIPOLAR_RANGES 4 - -#define APCI3120_ADDRESS_RANGE 16 - -#define APCI3120_DISABLE 0 -#define APCI3120_ENABLE 1 - -#define APCI3120_START 1 -#define APCI3120_STOP 0 - -#define APCI3120_EOC_MODE 1 -#define APCI3120_EOS_MODE 2 -#define APCI3120_DMA_MODE 3 - -/* DIGITAL INPUT-OUTPUT DEFINE */ - -#define APCI3120_DIGITAL_OUTPUT 0x0d -#define APCI3120_RD_STATUS 0x02 -#define APCI3120_RD_FIFO 0x00 - -/* digital output insn_write ON /OFF selection */ -#define APCI3120_SET4DIGITALOUTPUTON 1 -#define APCI3120_SET4DIGITALOUTPUTOFF 0 - -/* analog output SELECT BIT */ -#define APCI3120_ANALOG_OP_CHANNEL_1 0x0000 -#define APCI3120_ANALOG_OP_CHANNEL_2 0x4000 -#define APCI3120_ANALOG_OP_CHANNEL_3 0x8000 -#define APCI3120_ANALOG_OP_CHANNEL_4 0xc000 -#define APCI3120_ANALOG_OP_CHANNEL_5 0x0000 -#define APCI3120_ANALOG_OP_CHANNEL_6 0x4000 -#define APCI3120_ANALOG_OP_CHANNEL_7 0x8000 -#define APCI3120_ANALOG_OP_CHANNEL_8 0xc000 - -/* Enable external trigger bit in nWrAddress */ -#define APCI3120_ENABLE_EXT_TRIGGER 0x8000 - -/* ANALOG OUTPUT AND INPUT DEFINE */ -#define APCI3120_UNIPOLAR 0x80 -#define APCI3120_BIPOLAR 0x00 -#define APCI3120_ANALOG_OUTPUT_1 0x08 -#define APCI3120_ANALOG_OUTPUT_2 0x0a -#define APCI3120_1_GAIN 0x00 -#define APCI3120_2_GAIN 0x10 -#define APCI3120_5_GAIN 0x20 -#define APCI3120_10_GAIN 0x30 -#define APCI3120_SEQ_RAM_ADDRESS 0x06 -#define APCI3120_RESET_FIFO 0x0c -#define APCI3120_TIMER_0_MODE_2 0x01 -#define APCI3120_TIMER_0_MODE_4 0x2 -#define APCI3120_SELECT_TIMER_0_WORD 0x00 -#define APCI3120_ENABLE_TIMER0 0x1000 -#define APCI3120_CLEAR_PR 0xf0ff -#define APCI3120_CLEAR_PA 0xfff0 -#define APCI3120_CLEAR_PA_PR (APCI3120_CLEAR_PR & APCI3120_CLEAR_PA) - -/* nWrMode_Select */ -#define APCI3120_ENABLE_SCAN 0x8 -#define APCI3120_DISABLE_SCAN (~APCI3120_ENABLE_SCAN) -#define APCI3120_ENABLE_EOS_INT 0x2 - -#define APCI3120_DISABLE_EOS_INT (~APCI3120_ENABLE_EOS_INT) -#define APCI3120_ENABLE_EOC_INT 0x1 -#define APCI3120_DISABLE_EOC_INT (~APCI3120_ENABLE_EOC_INT) -#define APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER \ - (APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT) -#define APCI3120_DISABLE_ALL_INTERRUPT \ - (APCI3120_DISABLE_TIMER_INT & APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT) - -/* status register bits */ -#define APCI3120_EOC 0x8000 -#define APCI3120_EOS 0x2000 - -/* software trigger dummy register */ -#define APCI3120_START_CONVERSION 0x02 - -/* TIMER DEFINE */ -#define APCI3120_QUARTZ_A 70 -#define APCI3120_QUARTZ_B 50 -#define APCI3120_TIMER 1 -#define APCI3120_WATCHDOG 2 -#define APCI3120_TIMER_DISABLE 0 -#define APCI3120_TIMER_ENABLE 1 -#define APCI3120_ENABLE_TIMER2 0x4000 -#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2) -#define APCI3120_ENABLE_TIMER_INT 0x04 -#define APCI3120_DISABLE_TIMER_INT (~APCI3120_ENABLE_TIMER_INT) -#define APCI3120_WRITE_MODE_SELECT 0x0e -#define APCI3120_SELECT_TIMER_0_WORD 0x00 -#define APCI3120_SELECT_TIMER_1_WORD 0x01 -#define APCI3120_TIMER_1_MODE_2 0x4 - -/* $$ BIT FOR MODE IN nCsTimerCtr1 */ -#define APCI3120_TIMER_2_MODE_0 0x0 -#define APCI3120_TIMER_2_MODE_2 0x10 -#define APCI3120_TIMER_2_MODE_5 0x30 - -/* $$ BIT FOR MODE IN nCsTimerCtr0 */ -#define APCI3120_SELECT_TIMER_2_LOW_WORD 0x02 -#define APCI3120_SELECT_TIMER_2_HIGH_WORD 0x03 - -#define APCI3120_TIMER_CRT0 0x0d -#define APCI3120_TIMER_CRT1 0x0c - -#define APCI3120_TIMER_VALUE 0x04 -#define APCI3120_TIMER_STATUS_REGISTER 0x0d -#define APCI3120_RD_STATUS 0x02 -#define APCI3120_WR_ADDRESS 0x00 -#define APCI3120_ENABLE_WATCHDOG 0x20 -#define APCI3120_DISABLE_WATCHDOG (~APCI3120_ENABLE_WATCHDOG) -#define APCI3120_ENABLE_TIMER_COUNTER 0x10 -#define APCI3120_DISABLE_TIMER_COUNTER (~APCI3120_ENABLE_TIMER_COUNTER) -#define APCI3120_FC_TIMER 0x1000 -#define APCI3120_ENABLE_TIMER0 0x1000 -#define APCI3120_ENABLE_TIMER1 0x2000 -#define APCI3120_ENABLE_TIMER2 0x4000 -#define APCI3120_DISABLE_TIMER0 (~APCI3120_ENABLE_TIMER0) -#define APCI3120_DISABLE_TIMER1 (~APCI3120_ENABLE_TIMER1) -#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2) - -#define APCI3120_TIMER2_SELECT_EOS 0xc0 -#define APCI3120_COUNTER 3 -#define APCI3120_DISABLE_ALL_TIMER (APCI3120_DISABLE_TIMER0 & \ - APCI3120_DISABLE_TIMER1 & \ - APCI3120_DISABLE_TIMER2) - -#define MAX_ANALOGINPUT_CHANNELS 32 - -struct str_AnalogReadInformation { - /* EOC or EOS */ - unsigned char b_Type; - /* Interrupt use or not */ - unsigned char b_InterruptFlag; - /* Selection of the conversion time */ - unsigned int ui_ConvertTiming; - /* Number of channel to read */ - unsigned char b_NbrOfChannel; - /* Number of the channel to be read */ - unsigned int ui_ChannelList[MAX_ANALOGINPUT_CHANNELS]; - /* Gain of each channel */ - unsigned int ui_RangeList[MAX_ANALOGINPUT_CHANNELS]; -}; - -/* ANALOG INPUT RANGE */ -static const struct comedi_lrange range_apci3120_ai = { - 8, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2), - BIP_RANGE(1), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2), - UNI_RANGE(1) - } -}; - -/* ANALOG OUTPUT RANGE */ -static const struct comedi_lrange range_apci3120_ao = { - 2, { - BIP_RANGE(10), - UNI_RANGE(10) - } -}; - - -/* FUNCTION DEFINITIONS */ -static int apci3120_ai_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - const struct addi_board *this_board = dev->board_ptr; - struct addi_private *devpriv = dev->private; - unsigned int i; - - if ((data[0] != APCI3120_EOC_MODE) && (data[0] != APCI3120_EOS_MODE)) - return -1; - - /* Check for Conversion time to be added */ - devpriv->ui_EocEosConversionTime = data[2]; - - if (data[0] == APCI3120_EOS_MODE) { - - /* Test the number of the channel */ - for (i = 0; i < data[3]; i++) { - - if (CR_CHAN(data[4 + i]) >= - this_board->i_NbrAiChannel) { - dev_err(dev->class_dev, "bad channel list\n"); - return -2; - } - } - - devpriv->b_InterruptMode = APCI3120_EOS_MODE; - - if (data[1]) - devpriv->b_EocEosInterrupt = APCI3120_ENABLE; - else - devpriv->b_EocEosInterrupt = APCI3120_DISABLE; - /* Copy channel list and Range List to devpriv */ - devpriv->ui_AiNbrofChannels = data[3]; - for (i = 0; i < devpriv->ui_AiNbrofChannels; i++) - devpriv->ui_AiChannelList[i] = data[4 + i]; - - } else { /* EOC */ - devpriv->b_InterruptMode = APCI3120_EOC_MODE; - if (data[1]) - devpriv->b_EocEosInterrupt = APCI3120_ENABLE; - else - devpriv->b_EocEosInterrupt = APCI3120_DISABLE; - } - - return insn->n; -} - -/* - * This function will first check channel list is ok or not and then - * initialize the sequence RAM with the polarity, Gain,Channel number. - * If the last argument of function "check"is 1 then it only checks - * the channel list is ok or not. - */ -static int apci3120_setup_chan_list(struct comedi_device *dev, - struct comedi_subdevice *s, - int n_chan, - unsigned int *chanlist, - char check) -{ - struct addi_private *devpriv = dev->private; - unsigned int i; - unsigned int gain; - unsigned short us_TmpValue; - - /* correct channel and range number check itself comedi/range.c */ - if (n_chan < 1) { - if (!check) - dev_err(dev->class_dev, - "range/channel list is empty!\n"); - return 0; - } - /* All is ok, so we can setup channel/range list */ - if (check) - return 1; - - /* Code to set the PA and PR...Here it set PA to 0 */ - devpriv->us_OutputRegister = - devpriv->us_OutputRegister & APCI3120_CLEAR_PA_PR; - devpriv->us_OutputRegister = ((n_chan - 1) & 0xf) << 8; - outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); - - for (i = 0; i < n_chan; i++) { - /* store range list to card */ - us_TmpValue = CR_CHAN(chanlist[i]); /* get channel number */ - - if (CR_RANGE(chanlist[i]) < APCI3120_BIPOLAR_RANGES) - us_TmpValue &= ((~APCI3120_UNIPOLAR) & 0xff); /* set bipolar */ - else - us_TmpValue |= APCI3120_UNIPOLAR; /* enable unipolar */ - - gain = CR_RANGE(chanlist[i]); /* get gain number */ - us_TmpValue |= ((gain & 0x03) << 4); /* <<4 for G0 and G1 bit in RAM */ - us_TmpValue |= i << 8; /* To select the RAM LOCATION */ - outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS); - } - return 1; /* we can serve this with scan logic */ -} - -/* - * Reads analog input in synchronous mode EOC and EOS is selected - * as per configured if no conversion time is set uses default - * conversion time 10 microsec. - */ -static int apci3120_ai_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - const struct addi_board *this_board = dev->board_ptr; - struct addi_private *devpriv = dev->private; - unsigned short us_ConvertTiming, us_TmpValue, i; - unsigned char b_Tmp; - - /* fix conversion time to 10 us */ - if (!devpriv->ui_EocEosConversionTime) - us_ConvertTiming = 10; - else - us_ConvertTiming = (unsigned short) (devpriv->ui_EocEosConversionTime / 1000); /* nano to useconds */ - - /* Clear software registers */ - devpriv->b_TimerSelectMode = 0; - devpriv->b_ModeSelectRegister = 0; - devpriv->us_OutputRegister = 0; - - if (insn->unused[0] == 222) { /* second insn read */ - for (i = 0; i < insn->n; i++) - data[i] = devpriv->ui_AiReadData[i]; - } else { - devpriv->tsk_Current = current; /* Save the current process task structure */ - - /* - * Testing if board have the new Quartz and calculate the time value - * to set in the timer - */ - us_TmpValue = - (unsigned short) inw(devpriv->iobase + APCI3120_RD_STATUS); - - /* EL250804: Testing if board APCI3120 have the new Quartz or if it is an APCI3001 */ - if ((us_TmpValue & 0x00B0) == 0x00B0 - || !strcmp(this_board->pc_DriverName, "apci3001")) { - us_ConvertTiming = (us_ConvertTiming * 2) - 2; - } else { - us_ConvertTiming = - ((us_ConvertTiming * 12926) / 10000) - 1; - } - - us_TmpValue = (unsigned short) devpriv->b_InterruptMode; - - switch (us_TmpValue) { - - case APCI3120_EOC_MODE: - - /* - * Testing the interrupt flag and set the EOC bit Clears the FIFO - */ - inw(devpriv->iobase + APCI3120_RESET_FIFO); - - /* Initialize the sequence array */ - if (!apci3120_setup_chan_list(dev, s, 1, - &insn->chanspec, 0)) - return -EINVAL; - - /* Initialize Timer 0 mode 4 */ - devpriv->b_TimerSelectMode = - (devpriv-> - b_TimerSelectMode & 0xFC) | - APCI3120_TIMER_0_MODE_4; - outb(devpriv->b_TimerSelectMode, - devpriv->iobase + APCI3120_TIMER_CRT1); - - /* Reset the scan bit and Disables the EOS, DMA, EOC interrupt */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & APCI3120_DISABLE_SCAN; - - if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { - - /* Disables the EOS,DMA and enables the EOC interrupt */ - devpriv->b_ModeSelectRegister = - (devpriv-> - b_ModeSelectRegister & - APCI3120_DISABLE_EOS_INT) | - APCI3120_ENABLE_EOC_INT; - inw(devpriv->iobase); - - } else { - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & - APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER; - } - - outb(devpriv->b_ModeSelectRegister, - devpriv->iobase + APCI3120_WRITE_MODE_SELECT); - - /* Sets gate 0 */ - devpriv->us_OutputRegister = - (devpriv-> - us_OutputRegister & APCI3120_CLEAR_PA_PR) | - APCI3120_ENABLE_TIMER0; - outw(devpriv->us_OutputRegister, - devpriv->iobase + APCI3120_WR_ADDRESS); - - /* Select Timer 0 */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | - APCI3120_SELECT_TIMER_0_WORD; - outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); - - /* Set the conversion time */ - outw(us_ConvertTiming, - devpriv->iobase + APCI3120_TIMER_VALUE); - - us_TmpValue = - (unsigned short) inw(dev->iobase + APCI3120_RD_STATUS); - - if (devpriv->b_EocEosInterrupt == APCI3120_DISABLE) { - - do { - /* Waiting for the end of conversion */ - us_TmpValue = - inw(devpriv->iobase + - APCI3120_RD_STATUS); - } while ((us_TmpValue & APCI3120_EOC) == - APCI3120_EOC); - - /* Read the result in FIFO and put it in insn data pointer */ - us_TmpValue = inw(devpriv->iobase + 0); - *data = us_TmpValue; - - inw(devpriv->iobase + APCI3120_RESET_FIFO); - } - - break; - - case APCI3120_EOS_MODE: - - inw(devpriv->iobase); - /* Clears the FIFO */ - inw(devpriv->iobase + APCI3120_RESET_FIFO); - /* clear PA PR and disable timer 0 */ - - devpriv->us_OutputRegister = - (devpriv-> - us_OutputRegister & APCI3120_CLEAR_PA_PR) | - APCI3120_DISABLE_TIMER0; - - outw(devpriv->us_OutputRegister, - devpriv->iobase + APCI3120_WR_ADDRESS); - - if (!apci3120_setup_chan_list(dev, s, - devpriv->ui_AiNbrofChannels, - devpriv->ui_AiChannelList, 0)) - return -EINVAL; - - /* Initialize Timer 0 mode 2 */ - devpriv->b_TimerSelectMode = - (devpriv-> - b_TimerSelectMode & 0xFC) | - APCI3120_TIMER_0_MODE_2; - outb(devpriv->b_TimerSelectMode, - devpriv->iobase + APCI3120_TIMER_CRT1); - - /* Select Timer 0 */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | - APCI3120_SELECT_TIMER_0_WORD; - outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); - - /* Set the conversion time */ - outw(us_ConvertTiming, - devpriv->iobase + APCI3120_TIMER_VALUE); - - /* Set the scan bit */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister | APCI3120_ENABLE_SCAN; - outb(devpriv->b_ModeSelectRegister, - devpriv->iobase + APCI3120_WRITE_MODE_SELECT); - - /* If Interrupt function is loaded */ - if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { - /* Disables the EOC,DMA and enables the EOS interrupt */ - devpriv->b_ModeSelectRegister = - (devpriv-> - b_ModeSelectRegister & - APCI3120_DISABLE_EOC_INT) | - APCI3120_ENABLE_EOS_INT; - inw(devpriv->iobase); - - } else - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & - APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER; - - outb(devpriv->b_ModeSelectRegister, - devpriv->iobase + APCI3120_WRITE_MODE_SELECT); - - inw(devpriv->iobase + APCI3120_RD_STATUS); - - /* Sets gate 0 */ - devpriv->us_OutputRegister = - devpriv-> - us_OutputRegister | APCI3120_ENABLE_TIMER0; - outw(devpriv->us_OutputRegister, - devpriv->iobase + APCI3120_WR_ADDRESS); - - /* Start conversion */ - outw(0, devpriv->iobase + APCI3120_START_CONVERSION); - - /* Waiting of end of conversion if interrupt is not installed */ - if (devpriv->b_EocEosInterrupt == APCI3120_DISABLE) { - /* Waiting the end of conversion */ - do { - us_TmpValue = - inw(devpriv->iobase + - APCI3120_RD_STATUS); - } while ((us_TmpValue & APCI3120_EOS) != - APCI3120_EOS); - - for (i = 0; i < devpriv->ui_AiNbrofChannels; - i++) { - /* Read the result in FIFO and write them in shared memory */ - us_TmpValue = inw(devpriv->iobase); - data[i] = (unsigned int) us_TmpValue; - } - - devpriv->b_InterruptMode = APCI3120_EOC_MODE; /* Restore defaults */ - } - break; - - default: - dev_err(dev->class_dev, "inputs wrong\n"); - - } - devpriv->ui_EocEosConversionTime = 0; /* re initializing the variable */ - } - - return insn->n; - -} - -static int apci3120_reset(struct comedi_device *dev) -{ - struct addi_private *devpriv = dev->private; - unsigned int i; - unsigned short us_TmpValue; - - devpriv->ai_running = 0; - devpriv->b_EocEosInterrupt = APCI3120_DISABLE; - devpriv->b_InterruptMode = APCI3120_EOC_MODE; - devpriv->ui_EocEosConversionTime = 0; /* set eoc eos conv time to 0 */ - - /* variables used in timer subdevice */ - devpriv->b_Timer2Mode = 0; - devpriv->b_Timer2Interrupt = 0; - devpriv->b_ExttrigEnable = 0; /* Disable ext trigger */ - - /* Disable all interrupts, watchdog for the anolog output */ - devpriv->b_ModeSelectRegister = 0; - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); - - /* Disables all counters, ext trigger and clears PA, PR */ - devpriv->us_OutputRegister = 0; - outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); - - /* - * Code to set the all anolog o/p channel to 0v 8191 is decimal - * value for zero(0 v)volt in bipolar mode(default) - */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_1, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 1 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_2, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 2 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_3, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 3 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_4, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 4 */ - - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_5, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 5 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_6, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 6 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_7, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 7 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_8, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 8 */ - - udelay(10); - - inw(dev->iobase + 0); /* make a dummy read */ - inb(dev->iobase + APCI3120_RESET_FIFO); /* flush FIFO */ - inw(dev->iobase + APCI3120_RD_STATUS); /* flush A/D status register */ - - /* code to reset the RAM sequence */ - for (i = 0; i < 16; i++) { - us_TmpValue = i << 8; /* select the location */ - outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS); - } - return 0; -} - -static int apci3120_exttrig_enable(struct comedi_device *dev) -{ - struct addi_private *devpriv = dev->private; - - devpriv->us_OutputRegister |= APCI3120_ENABLE_EXT_TRIGGER; - outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); - return 0; -} - -static int apci3120_exttrig_disable(struct comedi_device *dev) -{ - struct addi_private *devpriv = dev->private; - - devpriv->us_OutputRegister &= ~APCI3120_ENABLE_EXT_TRIGGER; - outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); - return 0; -} - -static int apci3120_cancel(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - struct addi_private *devpriv = dev->private; - - /* Disable A2P Fifo write and AMWEN signal */ - outw(0, devpriv->i_IobaseAddon + 4); - - /* Disable Bus Master ADD ON */ - outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0); - outw(0, devpriv->i_IobaseAddon + 2); - outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0); - outw(0, devpriv->i_IobaseAddon + 2); - - /* Disable BUS Master PCI */ - outl(0, devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR); - - /* Disable ext trigger */ - apci3120_exttrig_disable(dev); - - devpriv->us_OutputRegister = 0; - /* stop counters */ - outw(devpriv-> - us_OutputRegister & APCI3120_DISABLE_TIMER0 & - APCI3120_DISABLE_TIMER1, dev->iobase + APCI3120_WR_ADDRESS); - - outw(APCI3120_DISABLE_ALL_TIMER, dev->iobase + APCI3120_WR_ADDRESS); - - /* DISABLE_ALL_INTERRUPT */ - outb(APCI3120_DISABLE_ALL_INTERRUPT, - dev->iobase + APCI3120_WRITE_MODE_SELECT); - /* Flush FIFO */ - inb(dev->iobase + APCI3120_RESET_FIFO); - inw(dev->iobase + APCI3120_RD_STATUS); - devpriv->ui_AiActualScan = 0; - s->async->cur_chan = 0; - devpriv->ui_DmaActualBuffer = 0; - - devpriv->ai_running = 0; - devpriv->b_InterruptMode = APCI3120_EOC_MODE; - devpriv->b_EocEosInterrupt = APCI3120_DISABLE; - apci3120_reset(dev); - return 0; -} - -static int apci3120_ai_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd) -{ - int err = 0; - - /* Step 1 : check if triggers are trivially valid */ - - err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); - err |= cfc_check_trigger_src(&cmd->scan_begin_src, - TRIG_TIMER | TRIG_FOLLOW); - err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER); - err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); - err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); - - if (err) - return 1; - - /* Step 2a : make sure trigger sources are unique */ - - err |= cfc_check_trigger_is_unique(cmd->start_src); - err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); - err |= cfc_check_trigger_is_unique(cmd->stop_src); - - /* Step 2b : and mutually compatible */ - - if (err) - return 2; - - /* Step 3: check if arguments are trivially valid */ - - err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - - if (cmd->scan_begin_src == TRIG_TIMER) /* Test Delay timing */ - err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 100000); - - if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->convert_arg) - err |= cfc_check_trigger_arg_min(&cmd->convert_arg, - 10000); - } else { - err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 10000); - } - - err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); - err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); - - if (cmd->stop_src == TRIG_COUNT) - err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); - else /* TRIG_NONE */ - err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); - - if (err) - return 3; - - /* step 4: fix up any arguments */ - - if (cmd->scan_begin_src == TRIG_TIMER && - cmd->scan_begin_arg < cmd->convert_arg * cmd->scan_end_arg) { - cmd->scan_begin_arg = cmd->convert_arg * cmd->scan_end_arg; - err |= -EINVAL; - } - - if (err) - return 4; - - return 0; -} - -/* - * This is used for analog input cyclic acquisition. - * Performs the command operations. - * If DMA is configured does DMA initialization otherwise does the - * acquisition with EOS interrupt. - */ -static int apci3120_cyclic_ai(int mode, - struct comedi_device *dev, - struct comedi_subdevice *s) -{ - const struct addi_board *this_board = dev->board_ptr; - struct addi_private *devpriv = dev->private; - struct comedi_cmd *cmd = &s->async->cmd; - unsigned char b_Tmp; - unsigned int ui_Tmp, ui_DelayTiming = 0, ui_TimerValue1 = 0, dmalen0 = - 0, dmalen1 = 0, ui_TimerValue2 = - 0, ui_TimerValue0, ui_ConvertTiming; - unsigned short us_TmpValue; - - /* Resets the FIFO */ - inb(dev->iobase + APCI3120_RESET_FIFO); - - devpriv->ai_running = 1; - - /* clear software registers */ - devpriv->b_TimerSelectMode = 0; - devpriv->us_OutputRegister = 0; - devpriv->b_ModeSelectRegister = 0; - - /* Clear Timer Write TC int */ - outl(APCI3120_CLEAR_WRITE_TC_INT, - devpriv->i_IobaseAmcc + APCI3120_AMCC_OP_REG_INTCSR); - - /* Disables All Timer */ - /* Sets PR and PA to 0 */ - devpriv->us_OutputRegister = devpriv->us_OutputRegister & - APCI3120_DISABLE_TIMER0 & - APCI3120_DISABLE_TIMER1 & APCI3120_CLEAR_PA_PR; - - outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); - - /* Resets the FIFO */ - /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */ - inb(devpriv->iobase + APCI3120_RESET_FIFO); - /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ - - devpriv->ui_AiActualScan = 0; - s->async->cur_chan = 0; - devpriv->ui_DmaActualBuffer = 0; - - /* value for timer2 minus -2 has to be done */ - ui_TimerValue2 = cmd->stop_arg - 2; - ui_ConvertTiming = cmd->convert_arg; - - if (mode == 2) - ui_DelayTiming = cmd->scan_begin_arg; - - /* Initializes the sequence array */ - if (!apci3120_setup_chan_list(dev, s, devpriv->ui_AiNbrofChannels, - cmd->chanlist, 0)) - return -EINVAL; - - us_TmpValue = (unsigned short) inw(dev->iobase + APCI3120_RD_STATUS); - - /* EL241003 Begin: add this section to replace floats calculation by integer calculations */ - /* EL250804: Testing if board APCI3120 have the new Quartz or if it is an APCI3001 */ - if ((us_TmpValue & 0x00B0) == 0x00B0 - || !strcmp(this_board->pc_DriverName, "apci3001")) { - ui_TimerValue0 = ui_ConvertTiming * 2 - 2000; - ui_TimerValue0 = ui_TimerValue0 / 1000; - - if (mode == 2) { - ui_DelayTiming = ui_DelayTiming / 1000; - ui_TimerValue1 = ui_DelayTiming * 2 - 200; - ui_TimerValue1 = ui_TimerValue1 / 100; - } - } else { - ui_ConvertTiming = ui_ConvertTiming / 1000; - ui_TimerValue0 = ui_ConvertTiming * 12926 - 10000; - ui_TimerValue0 = ui_TimerValue0 / 10000; - - if (mode == 2) { - ui_DelayTiming = ui_DelayTiming / 1000; - ui_TimerValue1 = ui_DelayTiming * 12926 - 1; - ui_TimerValue1 = ui_TimerValue1 / 1000000; - } - } - /* EL241003 End */ - - if (devpriv->b_ExttrigEnable == APCI3120_ENABLE) - apci3120_exttrig_enable(dev); /* activate EXT trigger */ - switch (mode) { - case 1: - /* init timer0 in mode 2 */ - devpriv->b_TimerSelectMode = - (devpriv-> - b_TimerSelectMode & 0xFC) | APCI3120_TIMER_0_MODE_2; - outb(devpriv->b_TimerSelectMode, - dev->iobase + APCI3120_TIMER_CRT1); - - /* Select Timer 0 */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | - APCI3120_SELECT_TIMER_0_WORD; - outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - /* Set the conversion time */ - outw(((unsigned short) ui_TimerValue0), - dev->iobase + APCI3120_TIMER_VALUE); - break; - - case 2: - /* init timer1 in mode 2 */ - devpriv->b_TimerSelectMode = - (devpriv-> - b_TimerSelectMode & 0xF3) | APCI3120_TIMER_1_MODE_2; - outb(devpriv->b_TimerSelectMode, - dev->iobase + APCI3120_TIMER_CRT1); - - /* Select Timer 1 */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | - APCI3120_SELECT_TIMER_1_WORD; - outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - /* Set the conversion time */ - outw(((unsigned short) ui_TimerValue1), - dev->iobase + APCI3120_TIMER_VALUE); - - /* init timer0 in mode 2 */ - devpriv->b_TimerSelectMode = - (devpriv-> - b_TimerSelectMode & 0xFC) | APCI3120_TIMER_0_MODE_2; - outb(devpriv->b_TimerSelectMode, - dev->iobase + APCI3120_TIMER_CRT1); - - /* Select Timer 0 */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | - APCI3120_SELECT_TIMER_0_WORD; - outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - - /* Set the conversion time */ - outw(((unsigned short) ui_TimerValue0), - dev->iobase + APCI3120_TIMER_VALUE); - break; - - } - /* common for all modes */ - /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */ - devpriv->b_ModeSelectRegister = devpriv->b_ModeSelectRegister & - APCI3120_DISABLE_SCAN; - /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ - - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); - - /* If DMA is disabled */ - if (devpriv->us_UseDma == APCI3120_DISABLE) { - /* disable EOC and enable EOS */ - devpriv->b_InterruptMode = APCI3120_EOS_MODE; - devpriv->b_EocEosInterrupt = APCI3120_ENABLE; - - devpriv->b_ModeSelectRegister = - (devpriv-> - b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT) | - APCI3120_ENABLE_EOS_INT; - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); - - if (cmd->stop_src == TRIG_COUNT) { - /* - * configure Timer2 For counting EOS Reset gate 2 of Timer 2 to - * disable it (Set Bit D14 to 0) - */ - devpriv->us_OutputRegister = - devpriv-> - us_OutputRegister & APCI3120_DISABLE_TIMER2; - outw(devpriv->us_OutputRegister, - dev->iobase + APCI3120_WR_ADDRESS); - - /* DISABLE TIMER intERRUPT */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & - APCI3120_DISABLE_TIMER_INT & 0xEF; - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); - - /* (1) Init timer 2 in mode 0 and write timer value */ - devpriv->b_TimerSelectMode = - (devpriv-> - b_TimerSelectMode & 0x0F) | - APCI3120_TIMER_2_MODE_0; - outb(devpriv->b_TimerSelectMode, - dev->iobase + APCI3120_TIMER_CRT1); - - /* Writing LOW unsigned short */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | - APCI3120_SELECT_TIMER_2_LOW_WORD; - outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - outw(ui_TimerValue2 & 0xffff, - dev->iobase + APCI3120_TIMER_VALUE); - - /* Writing HIGH unsigned short */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | - APCI3120_SELECT_TIMER_2_HIGH_WORD; - outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - outw((ui_TimerValue2 >> 16) & 0xffff, - dev->iobase + APCI3120_TIMER_VALUE); - - /* (2) Reset FC_TIMER BIT Clearing timer status register */ - inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); - /* enable timer counter and disable watch dog */ - devpriv->b_ModeSelectRegister = - (devpriv-> - b_ModeSelectRegister | - APCI3120_ENABLE_TIMER_COUNTER) & - APCI3120_DISABLE_WATCHDOG; - /* select EOS clock input for timer 2 */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister | - APCI3120_TIMER2_SELECT_EOS; - /* Enable timer2 interrupt */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister | - APCI3120_ENABLE_TIMER_INT; - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); - devpriv->b_Timer2Mode = APCI3120_COUNTER; - devpriv->b_Timer2Interrupt = APCI3120_ENABLE; - } - } else { - /* If DMA Enabled */ - unsigned int scan_bytes = cmd->scan_end_arg * sizeof(short); - - devpriv->b_InterruptMode = APCI3120_DMA_MODE; - - /* Disables the EOC, EOS interrupt */ - devpriv->b_ModeSelectRegister = devpriv->b_ModeSelectRegister & - APCI3120_DISABLE_EOC_INT & APCI3120_DISABLE_EOS_INT; - - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); - - dmalen0 = devpriv->ui_DmaBufferSize[0]; - dmalen1 = devpriv->ui_DmaBufferSize[1]; - - if (cmd->stop_src == TRIG_COUNT) { - /* - * Must we fill full first buffer? And must we fill - * full second buffer when first is once filled? - */ - if (dmalen0 > (cmd->stop_arg * scan_bytes)) { - dmalen0 = cmd->stop_arg * scan_bytes; - } else if (dmalen1 > (cmd->stop_arg * scan_bytes - - dmalen0)) - dmalen1 = cmd->stop_arg * scan_bytes - - dmalen0; - } - - if (cmd->flags & CMDF_WAKE_EOS) { - /* don't we want wake up every scan? */ - if (dmalen0 > scan_bytes) { - dmalen0 = scan_bytes; - if (cmd->scan_end_arg & 1) - dmalen0 += 2; - } - if (dmalen1 > scan_bytes) { - dmalen1 = scan_bytes; - if (cmd->scan_end_arg & 1) - dmalen1 -= 2; - if (dmalen1 < 4) - dmalen1 = 4; - } - } else { /* isn't output buff smaller that our DMA buff? */ - if (dmalen0 > s->async->prealloc_bufsz) - dmalen0 = s->async->prealloc_bufsz; - if (dmalen1 > s->async->prealloc_bufsz) - dmalen1 = s->async->prealloc_bufsz; - } - devpriv->ui_DmaBufferUsesize[0] = dmalen0; - devpriv->ui_DmaBufferUsesize[1] = dmalen1; - - /* Initialize DMA */ - - /* - * Set Transfer count enable bit and A2P_fifo reset bit in AGCSTS - * register 1 - */ - ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO; - outl(ui_Tmp, devpriv->i_IobaseAmcc + AMCC_OP_REG_AGCSTS); - - /* changed since 16 bit interface for add on */ - /* ENABLE BUS MASTER */ - outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, - devpriv->i_IobaseAddon + 2); - - outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, - devpriv->i_IobaseAddon + 2); - - /* - * TO VERIFIED BEGIN JK 07.05.04: Comparison between WIN32 and Linux - * driver - */ - outw(0x1000, devpriv->i_IobaseAddon + 2); - /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ - - /* 2 No change */ - /* A2P FIFO MANAGEMENT */ - /* A2P fifo reset & transfer control enable */ - outl(APCI3120_A2P_FIFO_MANAGEMENT, devpriv->i_IobaseAmcc + - APCI3120_AMCC_OP_MCSR); - - /* - * 3 - * beginning address of dma buf The 32 bit address of dma buffer - * is converted into two 16 bit addresses Can done by using _attach - * and put into into an array array used may be for differnet pages - */ - - /* DMA Start Address Low */ - outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0); - outw((devpriv->ul_DmaBufferHw[0] & 0xFFFF), - devpriv->i_IobaseAddon + 2); - - /* DMA Start Address High */ - outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0); - outw((devpriv->ul_DmaBufferHw[0] / 65536), - devpriv->i_IobaseAddon + 2); - - /* - * 4 - * amount of bytes to be transferred set transfer count used ADDON - * MWTC register commented testing - */ - - /* Nbr of acquisition LOW */ - outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0); - outw((devpriv->ui_DmaBufferUsesize[0] & 0xFFFF), - devpriv->i_IobaseAddon + 2); - - /* Nbr of acquisition HIGH */ - outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0); - outw((devpriv->ui_DmaBufferUsesize[0] / 65536), - devpriv->i_IobaseAddon + 2); - - /* - * 5 - * To configure A2P FIFO testing outl( - * FIFO_ADVANCE_ON_BYTE_2,devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR); - */ - - /* A2P FIFO RESET */ - /* - * TO VERIFY BEGIN JK 07.05.04: Comparison between WIN32 and Linux - * driver - */ - outl(0x04000000UL, devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR); - /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ - - /* - * 6 - * ENABLE A2P FIFO WRITE AND ENABLE AMWEN AMWEN_ENABLE | - * A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03 - */ - - /* - * 7 - * initialise end of dma interrupt AINT_WRITE_COMPL = - * ENABLE_WRITE_TC_INT(ADDI) - */ - /* A2P FIFO CONFIGURATE, END OF DMA intERRUPT INIT */ - outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 | - APCI3120_ENABLE_WRITE_TC_INT), - devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); - - /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */ - /* ENABLE A2P FIFO WRITE AND ENABLE AMWEN */ - outw(3, devpriv->i_IobaseAddon + 4); - /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ - - /* A2P FIFO RESET */ - /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */ - outl(0x04000000UL, - devpriv->i_IobaseAmcc + APCI3120_AMCC_OP_MCSR); - /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ - } - - if (devpriv->us_UseDma == APCI3120_DISABLE && - cmd->stop_src == TRIG_COUNT) { - /* set gate 2 to start conversion */ - devpriv->us_OutputRegister = - devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER2; - outw(devpriv->us_OutputRegister, - dev->iobase + APCI3120_WR_ADDRESS); - } - - switch (mode) { - case 1: - /* set gate 0 to start conversion */ - devpriv->us_OutputRegister = - devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER0; - outw(devpriv->us_OutputRegister, - dev->iobase + APCI3120_WR_ADDRESS); - break; - case 2: - /* set gate 0 and gate 1 */ - devpriv->us_OutputRegister = - devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER1; - devpriv->us_OutputRegister = - devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER0; - outw(devpriv->us_OutputRegister, - dev->iobase + APCI3120_WR_ADDRESS); - break; - - } - - return 0; - -} - -/* - * Does asynchronous acquisition. - * Determines the mode 1 or 2. - */ -static int apci3120_ai_cmd(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - struct addi_private *devpriv = dev->private; - struct comedi_cmd *cmd = &s->async->cmd; - - /* loading private structure with cmd structure inputs */ - devpriv->ui_AiNbrofChannels = cmd->chanlist_len; - - if (cmd->start_src == TRIG_EXT) - devpriv->b_ExttrigEnable = APCI3120_ENABLE; - else - devpriv->b_ExttrigEnable = APCI3120_DISABLE; - - if (cmd->scan_begin_src == TRIG_FOLLOW) - return apci3120_cyclic_ai(1, dev, s); - /* TRIG_TIMER */ - return apci3120_cyclic_ai(2, dev, s); -} - -/* - * This function copies the data from DMA buffer to the Comedi buffer. - */ -static void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned short *dma_buffer, - unsigned int num_samples) -{ - struct addi_private *devpriv = dev->private; - struct comedi_cmd *cmd = &s->async->cmd; - - devpriv->ui_AiActualScan += - (s->async->cur_chan + num_samples) / cmd->scan_end_arg; - s->async->cur_chan += num_samples; - s->async->cur_chan %= cmd->scan_end_arg; - - cfc_write_array_to_buffer(s, dma_buffer, num_samples * sizeof(short)); -} - -/* - * This is a handler for the DMA interrupt. - * This function copies the data to Comedi Buffer. - * For continuous DMA it reinitializes the DMA operation. - * For single mode DMA it stop the acquisition. - */ -static void apci3120_interrupt_dma(int irq, void *d) -{ - struct comedi_device *dev = d; - struct addi_private *devpriv = dev->private; - struct comedi_subdevice *s = dev->read_subdev; - struct comedi_cmd *cmd = &s->async->cmd; - unsigned int next_dma_buf, samplesinbuf; - unsigned long low_word, high_word, var; - unsigned int ui_Tmp; - - samplesinbuf = - devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer] - - inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_MWTC); - - if (samplesinbuf < - devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer]) { - dev_err(dev->class_dev, "Interrupted DMA transfer!\n"); - } - if (samplesinbuf & 1) { - dev_err(dev->class_dev, "Odd count of bytes in DMA ring!\n"); - apci3120_cancel(dev, s); - return; - } - samplesinbuf = samplesinbuf >> 1; /* number of received samples */ - if (devpriv->b_DmaDoubleBuffer) { - /* switch DMA buffers if is used double buffering */ - next_dma_buf = 1 - devpriv->ui_DmaActualBuffer; - - ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO; - outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS); - - /* changed since 16 bit interface for add on */ - outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, - devpriv->i_IobaseAddon + 2); - outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); /* 0x1000 is out putted in windows driver */ - - var = devpriv->ul_DmaBufferHw[next_dma_buf]; - low_word = var & 0xffff; - var = devpriv->ul_DmaBufferHw[next_dma_buf]; - high_word = var / 65536; - - /* DMA Start Address Low */ - outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0); - outw(low_word, devpriv->i_IobaseAddon + 2); - - /* DMA Start Address High */ - outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0); - outw(high_word, devpriv->i_IobaseAddon + 2); - - var = devpriv->ui_DmaBufferUsesize[next_dma_buf]; - low_word = var & 0xffff; - var = devpriv->ui_DmaBufferUsesize[next_dma_buf]; - high_word = var / 65536; - - /* Nbr of acquisition LOW */ - outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0); - outw(low_word, devpriv->i_IobaseAddon + 2); - - /* Nbr of acquisition HIGH */ - outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0); - outw(high_word, devpriv->i_IobaseAddon + 2); - - /* - * To configure A2P FIFO - * ENABLE A2P FIFO WRITE AND ENABLE AMWEN - * AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03 - */ - outw(3, devpriv->i_IobaseAddon + 4); - /* initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI) */ - outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 | - APCI3120_ENABLE_WRITE_TC_INT), - devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); - - } - if (samplesinbuf) { - v_APCI3120_InterruptDmaMoveBlock16bit(dev, s, - devpriv->ul_DmaBufferVirtual[devpriv-> - ui_DmaActualBuffer], samplesinbuf); - - if (!(cmd->flags & CMDF_WAKE_EOS)) { - s->async->events |= COMEDI_CB_EOS; - comedi_event(dev, s); - } - } - if (cmd->stop_src == TRIG_COUNT) - if (devpriv->ui_AiActualScan >= cmd->stop_arg) { - /* all data sampled */ - apci3120_cancel(dev, s); - s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); - return; - } - - if (devpriv->b_DmaDoubleBuffer) { /* switch dma buffers */ - devpriv->ui_DmaActualBuffer = 1 - devpriv->ui_DmaActualBuffer; - } else { - /* - * restart DMA if is not used double buffering - * ADDED REINITIALISE THE DMA - */ - ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO; - outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS); - - /* changed since 16 bit interface for add on */ - outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, - devpriv->i_IobaseAddon + 2); - outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); - /* - * A2P FIFO MANAGEMENT - * A2P fifo reset & transfer control enable - */ - outl(APCI3120_A2P_FIFO_MANAGEMENT, - devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR); - - var = devpriv->ul_DmaBufferHw[0]; - low_word = var & 0xffff; - var = devpriv->ul_DmaBufferHw[0]; - high_word = var / 65536; - outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0); - outw(low_word, devpriv->i_IobaseAddon + 2); - outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0); - outw(high_word, devpriv->i_IobaseAddon + 2); - - var = devpriv->ui_DmaBufferUsesize[0]; - low_word = var & 0xffff; /* changed */ - var = devpriv->ui_DmaBufferUsesize[0]; - high_word = var / 65536; - outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0); - outw(low_word, devpriv->i_IobaseAddon + 2); - outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0); - outw(high_word, devpriv->i_IobaseAddon + 2); - - /* - * To configure A2P FIFO - * ENABLE A2P FIFO WRITE AND ENABLE AMWEN - * AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03 - */ - outw(3, devpriv->i_IobaseAddon + 4); - /* initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI) */ - outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 | - APCI3120_ENABLE_WRITE_TC_INT), - devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); - } -} - -/* - * This function handles EOS interrupt. - * This function copies the acquired data(from FIFO) to Comedi buffer. - */ -static int apci3120_interrupt_handle_eos(struct comedi_device *dev) -{ - struct addi_private *devpriv = dev->private; - struct comedi_subdevice *s = dev->read_subdev; - int n_chan, i; - int err = 1; - - n_chan = devpriv->ui_AiNbrofChannels; - - for (i = 0; i < n_chan; i++) - err &= comedi_buf_put(s, inw(dev->iobase + 0)); - - s->async->events |= COMEDI_CB_EOS; - - if (err == 0) - s->async->events |= COMEDI_CB_OVERFLOW; - - comedi_event(dev, s); - - return 0; -} - -static void apci3120_interrupt(int irq, void *d) -{ - struct comedi_device *dev = d; - struct addi_private *devpriv = dev->private; - struct comedi_subdevice *s = dev->read_subdev; - unsigned short int_daq; - unsigned int int_amcc, ui_Check, i; - unsigned short us_TmpValue; - unsigned char b_DummyRead; - - ui_Check = 1; - - int_daq = inw(dev->iobase + APCI3120_RD_STATUS) & 0xf000; /* get IRQ reasons */ - int_amcc = inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); /* get AMCC int register */ - - if ((!int_daq) && (!(int_amcc & ANY_S593X_INT))) { - dev_err(dev->class_dev, "IRQ from unknown source\n"); - return; - } - - outl(int_amcc | 0x00ff0000, devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); /* shutdown IRQ reasons in AMCC */ - - int_daq = (int_daq >> 12) & 0xF; - - if (devpriv->b_ExttrigEnable == APCI3120_ENABLE) { - /* Disable ext trigger */ - apci3120_exttrig_disable(dev); - devpriv->b_ExttrigEnable = APCI3120_DISABLE; - } - /* clear the timer 2 interrupt */ - inb(devpriv->i_IobaseAmcc + APCI3120_TIMER_STATUS_REGISTER); - - if (int_amcc & MASTER_ABORT_INT) - dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n"); - if (int_amcc & TARGET_ABORT_INT) - dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n"); - - /* Ckeck if EOC interrupt */ - if (((int_daq & 0x8) == 0) - && (devpriv->b_InterruptMode == APCI3120_EOC_MODE)) { - if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { - - /* Read the AI Value */ - devpriv->ui_AiReadData[0] = - (unsigned int) inw(devpriv->iobase + 0); - devpriv->b_EocEosInterrupt = APCI3120_DISABLE; - send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ - } else { - /* Disable EOC Interrupt */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT; - outb(devpriv->b_ModeSelectRegister, - devpriv->iobase + APCI3120_WRITE_MODE_SELECT); - - } - } - - /* Check If EOS interrupt */ - if ((int_daq & 0x2) && (devpriv->b_InterruptMode == APCI3120_EOS_MODE)) { - - if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { /* enable this in without DMA ??? */ - - if (devpriv->ai_running) { - ui_Check = 0; - apci3120_interrupt_handle_eos(dev); - devpriv->ui_AiActualScan++; - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister | - APCI3120_ENABLE_EOS_INT; - outb(devpriv->b_ModeSelectRegister, - dev->iobase + - APCI3120_WRITE_MODE_SELECT); - } else { - ui_Check = 0; - for (i = 0; i < devpriv->ui_AiNbrofChannels; - i++) { - us_TmpValue = inw(devpriv->iobase + 0); - devpriv->ui_AiReadData[i] = - (unsigned int) us_TmpValue; - } - devpriv->b_EocEosInterrupt = APCI3120_DISABLE; - devpriv->b_InterruptMode = APCI3120_EOC_MODE; - - send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ - - } - - } else { - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT; - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); - devpriv->b_EocEosInterrupt = APCI3120_DISABLE; /* Default settings */ - devpriv->b_InterruptMode = APCI3120_EOC_MODE; - } - - } - /* Timer2 interrupt */ - if (int_daq & 0x1) { - - switch (devpriv->b_Timer2Mode) { - case APCI3120_COUNTER: - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT; - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); - - /* stop timer 2 */ - devpriv->us_OutputRegister = - devpriv-> - us_OutputRegister & APCI3120_DISABLE_ALL_TIMER; - outw(devpriv->us_OutputRegister, - dev->iobase + APCI3120_WR_ADDRESS); - - /* stop timer 0 and timer 1 */ - apci3120_cancel(dev, s); - - /* UPDATE-0.7.57->0.7.68comedi_done(dev,s); */ - s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); - - break; - - case APCI3120_TIMER: - - /* Send a signal to from kernel to user space */ - send_sig(SIGIO, devpriv->tsk_Current, 0); - break; - - case APCI3120_WATCHDOG: - - /* Send a signal to from kernel to user space */ - send_sig(SIGIO, devpriv->tsk_Current, 0); - break; - - default: - - /* disable Timer Interrupt */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & - APCI3120_DISABLE_TIMER_INT; - - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); - - } - - b_DummyRead = inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); - - } - - if ((int_daq & 0x4) && (devpriv->b_InterruptMode == APCI3120_DMA_MODE)) { - if (devpriv->ai_running) { - - /* Clear Timer Write TC int */ - outl(APCI3120_CLEAR_WRITE_TC_INT, - devpriv->i_IobaseAmcc + - APCI3120_AMCC_OP_REG_INTCSR); - - /* Clears the timer status register */ - inw(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); - /* do some data transfer */ - apci3120_interrupt_dma(irq, d); - } else { - /* Stops the Timer */ - outw(devpriv-> - us_OutputRegister & APCI3120_DISABLE_TIMER0 & - APCI3120_DISABLE_TIMER1, - dev->iobase + APCI3120_WR_ADDRESS); - } - - } -} - -/* - * Configure Timer 2 - * - * data[0] = TIMER configure as timer - * = WATCHDOG configure as watchdog - * data[1] = Timer constant - * data[2] = Timer2 interrupt (1)enable or(0) disable - */ -static int apci3120_config_insn_timer(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - const struct addi_board *this_board = dev->board_ptr; - struct addi_private *devpriv = dev->private; - unsigned int ui_Timervalue2; - unsigned short us_TmpValue; - unsigned char b_Tmp; - - if (!data[1]) - dev_err(dev->class_dev, "No timer constant!\n"); - - devpriv->b_Timer2Interrupt = (unsigned char) data[2]; /* save info whether to enable or disable interrupt */ - - ui_Timervalue2 = data[1] / 1000; /* convert nano seconds to u seconds */ - - us_TmpValue = (unsigned short) inw(devpriv->iobase + APCI3120_RD_STATUS); - - /* - * EL250804: Testing if board APCI3120 have the new Quartz or if it - * is an APCI3001 and calculate the time value to set in the timer - */ - if ((us_TmpValue & 0x00B0) == 0x00B0 - || !strcmp(this_board->pc_DriverName, "apci3001")) { - /* Calculate the time value to set in the timer */ - ui_Timervalue2 = ui_Timervalue2 / 50; - } else { - /* Calculate the time value to set in the timer */ - ui_Timervalue2 = ui_Timervalue2 / 70; - } - - /* Reset gate 2 of Timer 2 to disable it (Set Bit D14 to 0) */ - devpriv->us_OutputRegister = - devpriv->us_OutputRegister & APCI3120_DISABLE_TIMER2; - outw(devpriv->us_OutputRegister, devpriv->iobase + APCI3120_WR_ADDRESS); - - /* Disable TIMER Interrupt */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & APCI3120_DISABLE_TIMER_INT & 0xEF; - - /* Disable Eoc and Eos Interrupts */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT & - APCI3120_DISABLE_EOS_INT; - outb(devpriv->b_ModeSelectRegister, - devpriv->iobase + APCI3120_WRITE_MODE_SELECT); - if (data[0] == APCI3120_TIMER) { /* initialize timer */ - /* Set the Timer 2 in mode 2(Timer) */ - devpriv->b_TimerSelectMode = - (devpriv-> - b_TimerSelectMode & 0x0F) | APCI3120_TIMER_2_MODE_2; - outb(devpriv->b_TimerSelectMode, - devpriv->iobase + APCI3120_TIMER_CRT1); - - /* - * Configure the timer 2 for writing the LOW unsigned short of timer - * is Delay value You must make a b_tmp variable with - * DigitalOutPutRegister because at Address_1+APCI3120_TIMER_CRT0 - * you can set the digital output and configure the timer 2,and if - * you don't make this, digital output are erase (Set to 0) - */ - - /* Writing LOW unsigned short */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | - APCI3120_SELECT_TIMER_2_LOW_WORD; - outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); - outw(ui_Timervalue2 & 0xffff, - devpriv->iobase + APCI3120_TIMER_VALUE); - - /* Writing HIGH unsigned short */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | - APCI3120_SELECT_TIMER_2_HIGH_WORD; - outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); - outw((ui_Timervalue2 >> 16) & 0xffff, - devpriv->iobase + APCI3120_TIMER_VALUE); - /* timer2 in Timer mode enabled */ - devpriv->b_Timer2Mode = APCI3120_TIMER; - - } else { /* Initialize Watch dog */ - - /* Set the Timer 2 in mode 5(Watchdog) */ - devpriv->b_TimerSelectMode = - (devpriv-> - b_TimerSelectMode & 0x0F) | APCI3120_TIMER_2_MODE_5; - outb(devpriv->b_TimerSelectMode, - devpriv->iobase + APCI3120_TIMER_CRT1); - - /* - * Configure the timer 2 for writing the LOW unsigned short of timer - * is Delay value You must make a b_tmp variable with - * DigitalOutPutRegister because at Address_1+APCI3120_TIMER_CRT0 - * you can set the digital output and configure the timer 2,and if - * you don't make this, digital output are erase (Set to 0) - */ - - /* Writing LOW unsigned short */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | - APCI3120_SELECT_TIMER_2_LOW_WORD; - outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); - outw(ui_Timervalue2 & 0xffff, - devpriv->iobase + APCI3120_TIMER_VALUE); - - /* Writing HIGH unsigned short */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | - APCI3120_SELECT_TIMER_2_HIGH_WORD; - outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); - - outw((ui_Timervalue2 >> 16) & 0xffff, - devpriv->iobase + APCI3120_TIMER_VALUE); - /* watchdog enabled */ - devpriv->b_Timer2Mode = APCI3120_WATCHDOG; - - } - - return insn->n; - -} - -/* - * To start and stop the timer - * - * data[0] = 1 (start) - * = 0 (stop) - * = 2 (write new value) - * data[1] = new value - * - * devpriv->b_Timer2Mode = 0 DISABLE - * = 1 Timer - * = 2 Watch dog - */ -static int apci3120_write_insn_timer(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - const struct addi_board *this_board = dev->board_ptr; - struct addi_private *devpriv = dev->private; - unsigned int ui_Timervalue2 = 0; - unsigned short us_TmpValue; - unsigned char b_Tmp; - - if ((devpriv->b_Timer2Mode != APCI3120_WATCHDOG) - && (devpriv->b_Timer2Mode != APCI3120_TIMER)) { - dev_err(dev->class_dev, "timer2 not configured\n"); - return -EINVAL; - } - - if (data[0] == 2) { /* write new value */ - if (devpriv->b_Timer2Mode != APCI3120_TIMER) { - dev_err(dev->class_dev, - "timer2 not configured in TIMER MODE\n"); - return -EINVAL; - } - - if (data[1]) - ui_Timervalue2 = data[1]; - else - ui_Timervalue2 = 0; - } - - switch (data[0]) { - case APCI3120_START: - - /* Reset FC_TIMER BIT */ - inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER); - if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* start timer */ - /* Enable Timer */ - devpriv->b_ModeSelectRegister = - devpriv->b_ModeSelectRegister & 0x0B; - } else { /* start watch dog */ - /* Enable WatchDog */ - devpriv->b_ModeSelectRegister = - (devpriv-> - b_ModeSelectRegister & 0x0B) | - APCI3120_ENABLE_WATCHDOG; - } - - /* enable disable interrupt */ - if ((devpriv->b_Timer2Interrupt) == APCI3120_ENABLE) { - - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister | - APCI3120_ENABLE_TIMER_INT; - /* save the task structure to pass info to user */ - devpriv->tsk_Current = current; - } else { - - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & - APCI3120_DISABLE_TIMER_INT; - } - outb(devpriv->b_ModeSelectRegister, - devpriv->iobase + APCI3120_WRITE_MODE_SELECT); - - if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* start timer */ - /* For Timer mode is Gate2 must be activated timer started */ - devpriv->us_OutputRegister = - devpriv-> - us_OutputRegister | APCI3120_ENABLE_TIMER2; - outw(devpriv->us_OutputRegister, - devpriv->iobase + APCI3120_WR_ADDRESS); - } - - break; - - case APCI3120_STOP: - if (devpriv->b_Timer2Mode == APCI3120_TIMER) { - /* Disable timer */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & - APCI3120_DISABLE_TIMER_COUNTER; - } else { - /* Disable WatchDog */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & - APCI3120_DISABLE_WATCHDOG; - } - /* Disable timer interrupt */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & APCI3120_DISABLE_TIMER_INT; - - /* Write above states to register */ - outb(devpriv->b_ModeSelectRegister, - devpriv->iobase + APCI3120_WRITE_MODE_SELECT); - - /* Reset Gate 2 */ - devpriv->us_OutputRegister = - devpriv->us_OutputRegister & APCI3120_DISABLE_TIMER_INT; - outw(devpriv->us_OutputRegister, - devpriv->iobase + APCI3120_WR_ADDRESS); - - /* Reset FC_TIMER BIT */ - inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER); - - break; - - case 2: /* write new value to Timer */ - if (devpriv->b_Timer2Mode != APCI3120_TIMER) { - dev_err(dev->class_dev, - "timer2 not configured in TIMER MODE\n"); - return -EINVAL; - } - us_TmpValue = - (unsigned short) inw(devpriv->iobase + APCI3120_RD_STATUS); - - /* - * EL250804: Testing if board APCI3120 have the new Quartz or if it - * is an APCI3001 and calculate the time value to set in the timer - */ - if ((us_TmpValue & 0x00B0) == 0x00B0 - || !strcmp(this_board->pc_DriverName, "apci3001")) { - /* Calculate the time value to set in the timer */ - ui_Timervalue2 = ui_Timervalue2 / 50; - } else { - /* Calculate the time value to set in the timer */ - ui_Timervalue2 = ui_Timervalue2 / 70; - } - /* Writing LOW unsigned short */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | - APCI3120_SELECT_TIMER_2_LOW_WORD; - outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); - - outw(ui_Timervalue2 & 0xffff, - devpriv->iobase + APCI3120_TIMER_VALUE); - - /* Writing HIGH unsigned short */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | - APCI3120_SELECT_TIMER_2_HIGH_WORD; - outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); - - outw((ui_Timervalue2 >> 16) & 0xffff, - devpriv->iobase + APCI3120_TIMER_VALUE); - - break; - default: - return -EINVAL; /* Not a valid input */ - } - - return insn->n; -} - -/* - * Read the Timer value - * - * for Timer: data[0]= Timer constant - * - * for watchdog: data[0] = 0 (still running) - * = 1 (run down) - */ -static int apci3120_read_insn_timer(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned char b_Tmp; - unsigned short us_TmpValue, us_TmpValue_2, us_StatusValue; - - if ((devpriv->b_Timer2Mode != APCI3120_WATCHDOG) - && (devpriv->b_Timer2Mode != APCI3120_TIMER)) { - dev_err(dev->class_dev, "timer2 not configured\n"); - } - if (devpriv->b_Timer2Mode == APCI3120_TIMER) { - - /* Read the LOW unsigned short of Timer 2 register */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | - APCI3120_SELECT_TIMER_2_LOW_WORD; - outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); - - us_TmpValue = inw(devpriv->iobase + APCI3120_TIMER_VALUE); - - /* Read the HIGH unsigned short of Timer 2 register */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | - APCI3120_SELECT_TIMER_2_HIGH_WORD; - outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); - - us_TmpValue_2 = inw(devpriv->iobase + APCI3120_TIMER_VALUE); - - /* combining both words */ - data[0] = (unsigned int) ((us_TmpValue) | ((us_TmpValue_2) << 16)); - - } else { /* Read watch dog status */ - - us_StatusValue = inw(devpriv->iobase + APCI3120_RD_STATUS); - us_StatusValue = - ((us_StatusValue & APCI3120_FC_TIMER) >> 12) & 1; - if (us_StatusValue == 1) { - /* RESET FC_TIMER BIT */ - inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER); - } - data[0] = us_StatusValue; /* when data[0] = 1 then the watch dog has rundown */ - } - return insn->n; -} - -static int apci3120_di_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int val; - - /* the input channels are bits 11:8 of the status reg */ - val = inw(devpriv->iobase + APCI3120_RD_STATUS); - data[1] = (val >> 8) & 0xf; - - return insn->n; -} - -static int apci3120_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - - if (comedi_dio_update_state(s, data)) { - /* The do channels are bits 7:4 of the do register */ - devpriv->b_DigitalOutputRegister = s->state << 4; - - outb(devpriv->b_DigitalOutputRegister, - devpriv->iobase + APCI3120_DIGITAL_OUTPUT); - } - - data[1] = s->state; - - return insn->n; -} - -static int apci3120_ao_insn_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_Range, ui_Channel; - unsigned short us_TmpValue; - - ui_Range = CR_RANGE(insn->chanspec); - ui_Channel = CR_CHAN(insn->chanspec); - - if (ui_Range) { /* if 1 then unipolar */ - - if (data[0] != 0) - data[0] = - ((((ui_Channel & 0x03) << 14) & 0xC000) | (1 << - 13) | (data[0] + 8191)); - else - data[0] = - ((((ui_Channel & 0x03) << 14) & 0xC000) | (1 << - 13) | 8192); - - } else { /* if 0 then bipolar */ - data[0] = - ((((ui_Channel & 0x03) << 14) & 0xC000) | (0 << 13) | - data[0]); - - } - - do { /* Waiting of DA_READY BIT */ - us_TmpValue = - ((unsigned short) inw(devpriv->iobase + - APCI3120_RD_STATUS)) & 0x0001; - } while (us_TmpValue != 0x0001); - - if (ui_Channel <= 3) - /* - * for channel 0-3 out at the register 1 (wrDac1-8) data[i] - * typecasted to ushort since word write is to be done - */ - outw((unsigned short) data[0], - devpriv->iobase + APCI3120_ANALOG_OUTPUT_1); - else - /* - * for channel 4-7 out at the register 2 (wrDac5-8) data[i] - * typecasted to ushort since word write is to be done - */ - outw((unsigned short) data[0], - devpriv->iobase + APCI3120_ANALOG_OUTPUT_2); - - return insn->n; -} diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c deleted file mode 100644 index 5e321f91172f..000000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c +++ /dev/null @@ -1,3003 +0,0 @@ -/** -@verbatim - -Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - - ADDI-DATA GmbH - Dieselstrasse 3 - D-77833 Ottersweier - Tel: +19(0)7223/9493-0 - Fax: +49(0)7223/9493-92 - http://www.addi-data.com - info@addi-data.com - -This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -@endverbatim -*/ -/* - - +-----------------------------------------------------------------------+ - | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier | - +-----------------------------------------------------------------------+ - | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | - | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | - +-------------------------------+---------------------------------------+ - | Project : APCI-3200 | Compiler : GCC | - | Module name : hwdrv_apci3200.c| Version : 2.96 | - +-------------------------------+---------------------------------------+ - | Project manager: Eric Stolz | Date : 02/12/2002 | - +-------------------------------+---------------------------------------+ - | Description : Hardware Layer Access For APCI-3200 | - +-----------------------------------------------------------------------+ - | UPDATES | - +----------+-----------+------------------------------------------------+ - | Date | Author | Description of updates | - +----------+-----------+------------------------------------------------+ - | 02.07.04 | J. Krauth | Modification from the driver in order to | - | | | correct some errors when using several boards. | - | | | | - | | | | - +----------+-----------+------------------------------------------------+ - | 26.10.04 | J. Krauth | - Update for COMEDI 0.7.68 | - | | | - Read eeprom value | - | | | - Append APCI-3300 | - +----------+-----------+------------------------------------------------+ -*/ - -/* Card Specific information */ -/* #define APCI3200_ADDRESS_RANGE 264 */ - -/* Analog Input related Defines */ -#define APCI3200_AI_OFFSET_GAIN 0 -#define APCI3200_AI_SC_TEST 4 -#define APCI3200_AI_IRQ 8 -#define APCI3200_AI_AUTOCAL 12 -#define APCI3200_RELOAD_CONV_TIME_VAL 32 -#define APCI3200_CONV_TIME_TIME_BASE 36 -#define APCI3200_RELOAD_DELAY_TIME_VAL 40 -#define APCI3200_DELAY_TIME_TIME_BASE 44 -#define APCI3200_AI_MODULE1 0 -#define APCI3200_AI_MODULE2 64 -#define APCI3200_AI_MODULE3 128 -#define APCI3200_AI_MODULE4 192 -#define TRUE 1 -#define FALSE 0 -#define APCI3200_AI_EOSIRQ 16 -#define APCI3200_AI_EOS 20 -#define APCI3200_AI_CHAN_ID 24 -#define APCI3200_AI_CHAN_VAL 28 -#define ANALOG_INPUT 0 -#define TEMPERATURE 1 -#define RESISTANCE 2 - -#define ENABLE_EXT_TRIG 1 -#define ENABLE_EXT_GATE 2 -#define ENABLE_EXT_TRIG_GATE 3 - -#define APCI3200_MAXVOLT 2.5 -#define ADDIDATA_GREATER_THAN_TEST 0 -#define ADDIDATA_LESS_THAN_TEST 1 - -#define ADDIDATA_UNIPOLAR 1 -#define ADDIDATA_BIPOLAR 2 - -#define MAX_MODULE 4 - -/* ANALOG INPUT RANGE */ -static const struct comedi_lrange range_apci3200_ai = { - 8, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2), - BIP_RANGE(1), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2), - UNI_RANGE(1) - } -}; - -static const struct comedi_lrange range_apci3300_ai = { - 4, { - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2), - UNI_RANGE(1) - } -}; - -int MODULE_NO; -struct { - int i_Gain; - int i_Polarity; - int i_OffsetRange; - int i_Coupling; - int i_SingleDiff; - int i_AutoCalibration; - unsigned int ui_ReloadValue; - unsigned int ui_TimeUnitReloadVal; - int i_Interrupt; - int i_ModuleSelection; -} Config_Parameters_Module1, Config_Parameters_Module2, - Config_Parameters_Module3, Config_Parameters_Module4; - - -struct str_ADDIDATA_RTDStruct { - unsigned int ul_NumberOfValue; - unsigned int *pul_ResistanceValue; - unsigned int *pul_TemperatureValue; -}; - -struct str_Module { - unsigned long ul_CurrentSourceCJC; - unsigned long ul_CurrentSource[5]; - unsigned long ul_GainFactor[8]; /* Gain Factor */ - unsigned int w_GainValue[10]; -}; - -struct str_BoardInfos { - - int i_CJCAvailable; - int i_CJCPolarity; - int i_CJCGain; - int i_InterruptFlag; - int i_ADDIDATAPolarity; - int i_ADDIDATAGain; - int i_AutoCalibration; - int i_ADDIDATAConversionTime; - int i_ADDIDATAConversionTimeUnit; - int i_ADDIDATAType; - int i_ChannelNo; - int i_ChannelCount; - int i_ScanType; - int i_FirstChannel; - int i_LastChannel; - int i_Sum; - int i_Offset; - unsigned int ui_Channel_num; - int i_Count; - int i_Initialised; - unsigned int ui_InterruptChannelValue[144]; /* Buffer */ - unsigned char b_StructInitialized; - /* 7 is the maximal number of channels */ - unsigned int ui_ScanValueArray[7 + 12]; - - int i_ConnectionType; - int i_NbrOfModule; - struct str_Module s_Module[MAX_MODULE]; -}; - -/* BEGIN JK 06.07.04: Management of sevrals boards */ -/* - int i_CJCAvailable=1; - int i_CJCPolarity=0; - int i_CJCGain=2;/* changed from 0 to 2 */ - int i_InterruptFlag=0; - int i_ADDIDATAPolarity; - int i_ADDIDATAGain; - int i_AutoCalibration=0; /* : auto calibration */ - int i_ADDIDATAConversionTime; - int i_ADDIDATAConversionTimeUnit; - int i_ADDIDATAType; - int i_ChannelNo; - int i_ChannelCount=0; - int i_ScanType; - int i_FirstChannel; - int i_LastChannel; - int i_Sum=0; - int i_Offset; - unsigned int ui_Channel_num=0; - static int i_Count=0; - int i_Initialised=0; - unsigned int ui_InterruptChannelValue[96]; /* Buffer */ -*/ -struct str_BoardInfos s_BoardInfos[100]; /* 100 will be the max number of boards to be used */ -/* END JK 06.07.04: Management of sevrals boards */ - -#define AMCC_OP_REG_MCSR 0x3c -#define EEPROM_BUSY 0x80000000 -#define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */ -#define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */ -#define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */ -#define NVCMD_BEGIN_WRITE (0x6 << 5) /* EEPROM begin write command */ - -static int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead, - unsigned int dw_PCIBoardEepromAddress, - unsigned short w_EepromStartAddress, - unsigned short *pw_DataRead) -{ - unsigned int dw_eeprom_busy = 0; - int i_Counter = 0; - int i_WordCounter; - int i; - unsigned char pb_ReadByte[1]; - unsigned char b_ReadLowByte = 0; - unsigned char b_ReadHighByte = 0; - unsigned char b_SelectedAddressLow = 0; - unsigned char b_SelectedAddressHigh = 0; - unsigned short w_ReadWord = 0; - - for (i_WordCounter = 0; i_WordCounter < i_NbOfWordsToRead; - i_WordCounter++) { - do { - dw_eeprom_busy = - inl(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR); - dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY; - } while (dw_eeprom_busy == EEPROM_BUSY); - - for (i_Counter = 0; i_Counter < 2; i_Counter++) { - b_SelectedAddressLow = (w_EepromStartAddress + i_Counter) % 256; /* Read the low 8 bit part */ - b_SelectedAddressHigh = (w_EepromStartAddress + i_Counter) / 256; /* Read the high 8 bit part */ - - /* Select the load low address mode */ - outb(NVCMD_LOAD_LOW, - dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR + - 3); - - /* Wait on busy */ - do { - dw_eeprom_busy = - inl(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR); - dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY; - } while (dw_eeprom_busy == EEPROM_BUSY); - - /* Load the low address */ - outb(b_SelectedAddressLow, - dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR + - 2); - - /* Wait on busy */ - do { - dw_eeprom_busy = - inl(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR); - dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY; - } while (dw_eeprom_busy == EEPROM_BUSY); - - /* Select the load high address mode */ - outb(NVCMD_LOAD_HIGH, - dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR + - 3); - - /* Wait on busy */ - do { - dw_eeprom_busy = - inl(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR); - dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY; - } while (dw_eeprom_busy == EEPROM_BUSY); - - /* Load the high address */ - outb(b_SelectedAddressHigh, - dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR + - 2); - - /* Wait on busy */ - do { - dw_eeprom_busy = - inl(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR); - dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY; - } while (dw_eeprom_busy == EEPROM_BUSY); - - /* Select the READ mode */ - outb(NVCMD_BEGIN_READ, - dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR + - 3); - - /* Wait on busy */ - do { - dw_eeprom_busy = - inl(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR); - dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY; - } while (dw_eeprom_busy == EEPROM_BUSY); - - /* Read data into the EEPROM */ - *pb_ReadByte = - inb(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR + 2); - - /* Wait on busy */ - do { - dw_eeprom_busy = - inl(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR); - dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY; - } while (dw_eeprom_busy == EEPROM_BUSY); - - /* Select the upper address part */ - if (i_Counter == 0) - b_ReadLowByte = pb_ReadByte[0]; - else - b_ReadHighByte = pb_ReadByte[0]; - - - /* Sleep */ - msleep(1); - - } - w_ReadWord = - (b_ReadLowByte | (((unsigned short)b_ReadHighByte) * - 256)); - - pw_DataRead[i_WordCounter] = w_ReadWord; - - w_EepromStartAddress += 2; /* to read the next word */ - - } /* for (...) i_NbOfWordsToRead */ - return 0; -} - -static void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAddress, - struct str_BoardInfos *BoardInformations) -{ - unsigned short w_AnalogInputMainHeaderAddress; - unsigned short w_AnalogInputComponentAddress; - unsigned short w_NumberOfModuls = 0; - unsigned short w_CurrentSources[2]; - unsigned short w_ModulCounter = 0; - unsigned short w_FirstHeaderSize = 0; - unsigned short w_NumberOfInputs = 0; - unsigned short w_CJCFlag = 0; - unsigned short w_NumberOfGainValue = 0; - unsigned short w_SingleHeaderAddress = 0; - unsigned short w_SingleHeaderSize = 0; - unsigned short w_Input = 0; - unsigned short w_GainFactorAddress = 0; - unsigned short w_GainFactorValue[2]; - unsigned short w_GainIndex = 0; - unsigned short w_GainValue = 0; - - /*****************************************/ - /** Get the Analog input header address **/ - /*****************************************/ - i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, 0x116, /* w_EepromStartAddress: Analog input header address */ - &w_AnalogInputMainHeaderAddress); - - /*******************************************/ - /** Compute the real analog input address **/ - /*******************************************/ - w_AnalogInputMainHeaderAddress = w_AnalogInputMainHeaderAddress + 0x100; - - /******************************/ - /** Get the number of moduls **/ - /******************************/ - i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, w_AnalogInputMainHeaderAddress + 0x02, /* w_EepromStartAddress: Number of conponment */ - &w_NumberOfModuls); - - for (w_ModulCounter = 0; w_ModulCounter < w_NumberOfModuls; - w_ModulCounter++) { - /***********************************/ - /** Compute the component address **/ - /***********************************/ - w_AnalogInputComponentAddress = - w_AnalogInputMainHeaderAddress + - (w_FirstHeaderSize * w_ModulCounter) + 0x04; - - /****************************/ - /** Read first header size **/ - /****************************/ - i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress, /* Address of the first header */ - &w_FirstHeaderSize); - - w_FirstHeaderSize = w_FirstHeaderSize >> 4; - - /***************************/ - /** Read number of inputs **/ - /***************************/ - i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x06, /* Number of inputs for the first modul */ - &w_NumberOfInputs); - - w_NumberOfInputs = w_NumberOfInputs >> 4; - - /***********************/ - /** Read the CJC flag **/ - /***********************/ - i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x08, /* CJC flag */ - &w_CJCFlag); - - w_CJCFlag = (w_CJCFlag >> 3) & 0x1; /* Get only the CJC flag */ - - /*******************************/ - /** Read number of gain value **/ - /*******************************/ - i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x44, /* Number of gain value */ - &w_NumberOfGainValue); - - w_NumberOfGainValue = w_NumberOfGainValue & 0xFF; - - /***********************************/ - /** Compute single header address **/ - /***********************************/ - w_SingleHeaderAddress = - w_AnalogInputComponentAddress + 0x46 + - (((w_NumberOfGainValue / 16) + 1) * 2) + - (6 * w_NumberOfGainValue) + - (4 * (((w_NumberOfGainValue / 16) + 1) * 2)); - - /********************************************/ - /** Read current sources value for input 1 **/ - /********************************************/ - i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, w_SingleHeaderAddress, /* w_EepromStartAddress: Single header address */ - &w_SingleHeaderSize); - - w_SingleHeaderSize = w_SingleHeaderSize >> 4; - - /*************************************/ - /** Read gain factor for the module **/ - /*************************************/ - w_GainFactorAddress = w_AnalogInputComponentAddress; - - for (w_GainIndex = 0; w_GainIndex < w_NumberOfGainValue; - w_GainIndex++) { - /************************************/ - /** Read gain value for the module **/ - /************************************/ - i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 70 + (2 * (1 + (w_NumberOfGainValue / 16))) + (0x02 * w_GainIndex), /* Gain value */ - &w_GainValue); - - BoardInformations->s_Module[w_ModulCounter]. - w_GainValue[w_GainIndex] = w_GainValue; - - /*************************************/ - /** Read gain factor for the module **/ - /*************************************/ - i_AddiHeaderRW_ReadEeprom(2, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 70 + ((2 * w_NumberOfGainValue) + (2 * (1 + (w_NumberOfGainValue / 16)))) + (0x04 * w_GainIndex), /* Gain factor */ - w_GainFactorValue); - - BoardInformations->s_Module[w_ModulCounter]. - ul_GainFactor[w_GainIndex] = - (w_GainFactorValue[1] << 16) + - w_GainFactorValue[0]; - } - - /***************************************************************/ - /** Read current source value for each channels of the module **/ - /***************************************************************/ - for (w_Input = 0; w_Input < w_NumberOfInputs; w_Input++) { - /********************************************/ - /** Read current sources value for input 1 **/ - /********************************************/ - i_AddiHeaderRW_ReadEeprom(2, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, - (w_Input * w_SingleHeaderSize) + - w_SingleHeaderAddress + 0x0C, w_CurrentSources); - - /************************************/ - /** Save the current sources value **/ - /************************************/ - BoardInformations->s_Module[w_ModulCounter]. - ul_CurrentSource[w_Input] = - (w_CurrentSources[0] + - ((w_CurrentSources[1] & 0xFFF) << 16)); - } - - /***************************************/ - /** Read the CJC current source value **/ - /***************************************/ - i_AddiHeaderRW_ReadEeprom(2, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, - (w_Input * w_SingleHeaderSize) + w_SingleHeaderAddress + - 0x0C, w_CurrentSources); - - /************************************/ - /** Save the current sources value **/ - /************************************/ - BoardInformations->s_Module[w_ModulCounter]. - ul_CurrentSourceCJC = - (w_CurrentSources[0] + - ((w_CurrentSources[1] & 0xFFF) << 16)); - } -} - -static int i_APCI3200_GetChannelCalibrationValue(struct comedi_device *dev, - unsigned int ui_Channel_num, - unsigned int *CJCCurrentSource, - unsigned int *ChannelCurrentSource, - unsigned int *ChannelGainFactor) -{ - int i_DiffChannel = 0; - int i_Module = 0; - - /* Test if single or differential mode */ - if (s_BoardInfos[dev->minor].i_ConnectionType == 1) { - /* if diff */ - - if (ui_Channel_num <= 1) - i_DiffChannel = ui_Channel_num, i_Module = 0; - else if ((ui_Channel_num >= 2) && (ui_Channel_num <= 3)) - i_DiffChannel = ui_Channel_num - 2, i_Module = 1; - else if ((ui_Channel_num >= 4) && (ui_Channel_num <= 5)) - i_DiffChannel = ui_Channel_num - 4, i_Module = 2; - else if ((ui_Channel_num >= 6) && (ui_Channel_num <= 7)) - i_DiffChannel = ui_Channel_num - 6, i_Module = 3; - - } else { - /* if single */ - if ((ui_Channel_num == 0) || (ui_Channel_num == 1)) - i_DiffChannel = 0, i_Module = 0; - else if ((ui_Channel_num == 2) || (ui_Channel_num == 3)) - i_DiffChannel = 1, i_Module = 0; - else if ((ui_Channel_num == 4) || (ui_Channel_num == 5)) - i_DiffChannel = 0, i_Module = 1; - else if ((ui_Channel_num == 6) || (ui_Channel_num == 7)) - i_DiffChannel = 1, i_Module = 1; - else if ((ui_Channel_num == 8) || (ui_Channel_num == 9)) - i_DiffChannel = 0, i_Module = 2; - else if ((ui_Channel_num == 10) || (ui_Channel_num == 11)) - i_DiffChannel = 1, i_Module = 2; - else if ((ui_Channel_num == 12) || (ui_Channel_num == 13)) - i_DiffChannel = 0, i_Module = 3; - else if ((ui_Channel_num == 14) || (ui_Channel_num == 15)) - i_DiffChannel = 1, i_Module = 3; - } - - /* Test if thermocouple or RTD mode */ - *CJCCurrentSource = - s_BoardInfos[dev->minor].s_Module[i_Module].ul_CurrentSourceCJC; - - *ChannelCurrentSource = - s_BoardInfos[dev->minor].s_Module[i_Module]. - ul_CurrentSource[i_DiffChannel]; - /* } */ - /* } */ - - /* Channle gain factor */ - *ChannelGainFactor = - s_BoardInfos[dev->minor].s_Module[i_Module]. - ul_GainFactor[s_BoardInfos[dev->minor].i_ADDIDATAGain]; - /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - - return 0; -} - -static int apci3200_di_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - - data[1] = inl(devpriv->i_IobaseReserved) & 0xf; - - return insn->n; -} - -static int apci3200_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - - s->state = inl(devpriv->i_IobaseAddon) & 0xf; - - if (comedi_dio_update_state(s, data)) - outl(s->state, devpriv->i_IobaseAddon); - - data[1] = s->state; - - return insn->n; -} - -static int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_EOC = 0; - unsigned int ui_ChannelNo = 0; - unsigned int ui_CommandRegister = 0; - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_ChannelNo=i_ChannelNo; */ - ui_ChannelNo = s_BoardInfos[dev->minor].i_ChannelNo; - - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /*********************************/ - /* Write the channel to configure */ - /*********************************/ - /* Begin JK 20.10.2004: Bad channel value is used when using differential mode */ - /* outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4); */ - /* outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4); */ - outl(0 | s_BoardInfos[dev->minor].i_ChannelNo, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4); - /* End JK 20.10.2004: Bad channel value is used when using differential mode */ - - /*******************************/ - /* Set the convert timing unit */ - /*******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - - /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36); - - /**************************/ - /* Set the convert timing */ - /**************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - - /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); - - /**************************************************************************/ - /* Set the start end stop index to the selected channel and set the start */ - /**************************************************************************/ - - ui_CommandRegister = ui_ChannelNo | (ui_ChannelNo << 8) | 0x80000; - - /*Test if the interrupt is enable */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) { - /* Enable the interrupt */ - ui_CommandRegister = ui_CommandRegister | 0x00100000; - } - - /******************************/ - /* Write the command register */ - /******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - - /* outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8); */ - outl(ui_CommandRegister, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - - /*Test if interrupt is enable */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) { - do { - /*************************/ - /*Read the EOC Status bit */ - /*************************/ - - /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */ - ui_EOC = inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 20) & 1; - - } while (ui_EOC != 1); - - /***************************************/ - /* Read the digital value of the input */ - /***************************************/ - - /* data[0] = inl (devpriv->iobase+i_Offset + 28); */ - data[0] = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - /* END JK 06.07.04: Management of sevrals boards */ - - } - return 0; -} - -static int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_Temp = 0, ui_EOC = 0; - unsigned int ui_CommandRegister = 0; - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /*********************************/ - /* Write the channel to configure */ - /*********************************/ - /* Begin JK 20.10.2004: This seems not necessary ! */ - /* outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4); */ - /* outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4); */ - /* End JK 20.10.2004: This seems not necessary ! */ - - /*******************************/ - /* Set the convert timing unit */ - /*******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36); - /**************************/ - /* Set the convert timing */ - /**************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); - /*****************************/ - /*Read the calibration offset */ - /*****************************/ - /* ui_Temp = inl(devpriv->iobase+i_Offset + 12); */ - ui_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - - /*********************************/ - /*Configure the Offset Conversion */ - /*********************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl((ui_Temp | 0x00020000), devpriv->iobase+i_Offset + 12); */ - outl((ui_Temp | 0x00020000), - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - /*******************************/ - /*Initialise ui_CommandRegister */ - /*******************************/ - - ui_CommandRegister = 0; - - /*Test if the interrupt is enable */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) { - /*Enable the interrupt */ - ui_CommandRegister = ui_CommandRegister | 0x00100000; - } - - /**********************/ - /*Start the conversion */ - /**********************/ - ui_CommandRegister = ui_CommandRegister | 0x00080000; - - /***************************/ - /*Write the command regiter */ - /***************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8); */ - outl(ui_CommandRegister, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - - /*Test if interrupt is enable */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) { - do { - /*******************/ - /*Read the EOC flag */ - /*******************/ - - /* ui_EOC = inl (devpriv->iobase+i_Offset + 20) & 1; */ - ui_EOC = inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 20) & 1; - - } while (ui_EOC != 1); - - /**************************************************/ - /*Read the digital value of the calibration Offset */ - /**************************************************/ - - /* data[0] = inl(devpriv->iobase+i_Offset+ 28); */ - data[0] = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - } - return 0; -} - -static int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_EOC = 0; - int ui_CommandRegister = 0; - - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /*********************************/ - /* Write the channel to configure */ - /*********************************/ - /* Begin JK 20.10.2004: This seems not necessary ! */ - /* outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4); */ - /* outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4); */ - /* End JK 20.10.2004: This seems not necessary ! */ - - /***************************/ - /*Read the calibration gain */ - /***************************/ - /*******************************/ - /* Set the convert timing unit */ - /*******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36); - /**************************/ - /* Set the convert timing */ - /**************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); - /*******************************/ - /*Configure the Gain Conversion */ - /*******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(0x00040000 , devpriv->iobase+i_Offset + 12); */ - outl(0x00040000, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - - /*******************************/ - /*Initialise ui_CommandRegister */ - /*******************************/ - - ui_CommandRegister = 0; - - /*Test if the interrupt is enable */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) { - /*Enable the interrupt */ - ui_CommandRegister = ui_CommandRegister | 0x00100000; - } - - /**********************/ - /*Start the conversion */ - /**********************/ - - ui_CommandRegister = ui_CommandRegister | 0x00080000; - /***************************/ - /*Write the command regiter */ - /***************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8); */ - outl(ui_CommandRegister, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - - /*Test if interrupt is enable */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) { - do { - - /*******************/ - /*Read the EOC flag */ - /*******************/ - - /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */ - ui_EOC = inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 20) & 1; - - } while (ui_EOC != 1); - - /************************************************/ - /*Read the digital value of the calibration Gain */ - /************************************************/ - - /* data[0] = inl(devpriv->iobase+i_Offset + 28); */ - data[0] = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - - } - return 0; -} - -static int i_APCI3200_ReadCJCValue(struct comedi_device *dev, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_EOC = 0; - int ui_CommandRegister = 0; - - /******************************/ - /*Set the converting time unit */ - /******************************/ - - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - - /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36); - /**************************/ - /* Set the convert timing */ - /**************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - - /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); - - /******************************/ - /*Configure the CJC Conversion */ - /******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - - /* outl( 0x00000400 , devpriv->iobase+i_Offset + 4); */ - outl(0x00000400, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4); - /*******************************/ - /*Initialise dw_CommandRegister */ - /*******************************/ - ui_CommandRegister = 0; - /*Test if the interrupt is enable */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) { - /*Enable the interrupt */ - ui_CommandRegister = ui_CommandRegister | 0x00100000; - } - - /**********************/ - /*Start the conversion */ - /**********************/ - - ui_CommandRegister = ui_CommandRegister | 0x00080000; - - /***************************/ - /*Write the command regiter */ - /***************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8); */ - outl(ui_CommandRegister, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - - /*Test if interrupt is enable */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) { - do { - - /*******************/ - /*Read the EOC flag */ - /*******************/ - - /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */ - ui_EOC = inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 20) & 1; - - } while (ui_EOC != 1); - - /***********************************/ - /*Read the digital value of the CJC */ - /***********************************/ - - /* data[0] = inl(devpriv->iobase+i_Offset + 28); */ - data[0] = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - } - return 0; -} - -static int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_EOC = 0; - int ui_CommandRegister = 0; - - /*******************************************/ - /*Read calibration offset value for the CJC */ - /*******************************************/ - /*******************************/ - /* Set the convert timing unit */ - /*******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36); - /**************************/ - /* Set the convert timing */ - /**************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); - /******************************/ - /*Configure the CJC Conversion */ - /******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(0x00000400 , devpriv->iobase+i_Offset + 4); */ - outl(0x00000400, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4); - /*********************************/ - /*Configure the Offset Conversion */ - /*********************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(0x00020000, devpriv->iobase+i_Offset + 12); */ - outl(0x00020000, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - /*******************************/ - /*Initialise ui_CommandRegister */ - /*******************************/ - ui_CommandRegister = 0; - /*Test if the interrupt is enable */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) { - /*Enable the interrupt */ - ui_CommandRegister = ui_CommandRegister | 0x00100000; - } - - /**********************/ - /*Start the conversion */ - /**********************/ - ui_CommandRegister = ui_CommandRegister | 0x00080000; - /***************************/ - /*Write the command regiter */ - /***************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(ui_CommandRegister,devpriv->iobase+i_Offset + 8); */ - outl(ui_CommandRegister, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) { - do { - /*******************/ - /*Read the EOC flag */ - /*******************/ - /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */ - ui_EOC = inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 20) & 1; - } while (ui_EOC != 1); - - /**************************************************/ - /*Read the digital value of the calibration Offset */ - /**************************************************/ - /* data[0] = inl(devpriv->iobase+i_Offset + 28); */ - data[0] = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - } - return 0; -} - -static int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_EOC = 0; - int ui_CommandRegister = 0; - - /*******************************/ - /* Set the convert timing unit */ - /*******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36); - /**************************/ - /* Set the convert timing */ - /**************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); - /******************************/ - /*Configure the CJC Conversion */ - /******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(0x00000400,devpriv->iobase+i_Offset + 4); */ - outl(0x00000400, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4); - /*******************************/ - /*Configure the Gain Conversion */ - /*******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(0x00040000,devpriv->iobase+i_Offset + 12); */ - outl(0x00040000, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - - /*******************************/ - /*Initialise dw_CommandRegister */ - /*******************************/ - ui_CommandRegister = 0; - /*Test if the interrupt is enable */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) { - /*Enable the interrupt */ - ui_CommandRegister = ui_CommandRegister | 0x00100000; - } - /**********************/ - /*Start the conversion */ - /**********************/ - ui_CommandRegister = ui_CommandRegister | 0x00080000; - /***************************/ - /*Write the command regiter */ - /***************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(ui_CommandRegister ,devpriv->iobase+i_Offset + 8); */ - outl(ui_CommandRegister, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) { - do { - /*******************/ - /*Read the EOC flag */ - /*******************/ - /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */ - ui_EOC = inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 20) & 1; - } while (ui_EOC != 1); - /************************************************/ - /*Read the digital value of the calibration Gain */ - /************************************************/ - /* data[0] = inl (devpriv->iobase+i_Offset + 28); */ - data[0] = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - } - return 0; -} - -static int apci3200_reset(struct comedi_device *dev) -{ - struct addi_private *devpriv = dev->private; - int i_Temp; - unsigned int dw_Dummy; - - /* i_InterruptFlag=0; */ - /* i_Initialised==0; */ - /* i_Count=0; */ - /* i_Sum=0; */ - - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - s_BoardInfos[dev->minor].i_Initialised = 0; - s_BoardInfos[dev->minor].i_Count = 0; - s_BoardInfos[dev->minor].i_Sum = 0; - s_BoardInfos[dev->minor].b_StructInitialized = 0; - - outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); - - /* Enable the interrupt for the controller */ - dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); - outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); - outl(0, devpriv->i_IobaseAddon); /* Resets the output */ - /***************/ - /*Empty the buffer */ - /**************/ - for (i_Temp = 0; i_Temp <= 95; i_Temp++) { - /* ui_InterruptChannelValue[i_Temp]=0; */ - s_BoardInfos[dev->minor].ui_InterruptChannelValue[i_Temp] = 0; - } /* for(i_Temp=0;i_Temp<=95;i_Temp++) */ - /*****************************/ - /*Reset the START and IRQ bit */ - /*****************************/ - for (i_Temp = 0; i_Temp <= 192;) { - while (((inl(devpriv->iobase + i_Temp + 12) >> 19) & 1) != 1) ; - outl(0, devpriv->iobase + i_Temp + 8); - i_Temp = i_Temp + 64; - } /* for(i_Temp=0;i_Temp<=192;i_Temp+64) */ - return 0; -} - -/* - * Read value of the selected channel - * - * data[0] : Digital Value Of Input - * data[1] : Calibration Offset Value - * data[2] : Calibration Gain Value - * data[3] : CJC value - * data[4] : CJC offset value - * data[5] : CJC gain value - * data[6] : CJC current source from eeprom - * data[7] : Channel current source from eeprom - * data[8] : Channle gain factor from eeprom - */ -static int apci3200_ai_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - unsigned int ui_DummyValue = 0; - int i_ConvertCJCCalibration; - int i = 0; - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if(i_Initialised==0) */ - if (s_BoardInfos[dev->minor].i_Initialised == 0) - /* END JK 06.07.04: Management of sevrals boards */ - { - apci3200_reset(dev); - return -EINVAL; - } /* if(i_Initialised==0); */ - - switch (insn->unused[0]) { - case 0: - - i_APCI3200_Read1AnalogInputChannel(dev, s, insn, - &ui_DummyValue); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count+0]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev->minor]. - i_Count + 0] = ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - - /* Begin JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - i_APCI3200_GetChannelCalibrationValue(dev, - s_BoardInfos[dev->minor].ui_Channel_num, - &s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev->minor]. - i_Count + 6], - &s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev->minor]. - i_Count + 7], - &s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev->minor]. - i_Count + 8]); - /* End JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1)) */ - if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2) - && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE) - && (s_BoardInfos[dev->minor].i_CJCAvailable == 1)) - /* END JK 06.07.04: Management of sevrals boards */ - { - i_APCI3200_ReadCJCValue(dev, &ui_DummyValue); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count + 3]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev-> - minor].i_Count + 3] = ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)) */ - else { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count + 3]=0; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev-> - minor].i_Count + 3] = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* elseif((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1)) */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE)) */ - if ((s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) - && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)) - /* END JK 06.07.04: Management of sevrals boards */ - { - i_APCI3200_ReadCalibrationOffsetValue(dev, - &ui_DummyValue); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count + 1]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev-> - minor].i_Count + 1] = ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - i_APCI3200_ReadCalibrationGainValue(dev, - &ui_DummyValue); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count + 2]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev-> - minor].i_Count + 2] = ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE)) */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)&& (i_CJCAvailable==1)) */ - if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2) - && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE) - && (s_BoardInfos[dev->minor].i_CJCAvailable == 1)) - /* END JK 06.07.04: Management of sevrals boards */ - { - /**********************************************************/ - /*Test if the Calibration channel must be read for the CJC */ - /**********************************************************/ - /**********************************/ - /*Test if the polarity is the same */ - /**********************************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */ - if (s_BoardInfos[dev->minor].i_CJCPolarity != - s_BoardInfos[dev->minor].i_ADDIDATAPolarity) - /* END JK 06.07.04: Management of sevrals boards */ - { - i_ConvertCJCCalibration = 1; - } /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */ - else { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if(i_CJCGain==i_ADDIDATAGain) */ - if (s_BoardInfos[dev->minor].i_CJCGain == - s_BoardInfos[dev->minor].i_ADDIDATAGain) - /* END JK 06.07.04: Management of sevrals boards */ - { - i_ConvertCJCCalibration = 0; - } /* if(i_CJCGain==i_ADDIDATAGain) */ - else { - i_ConvertCJCCalibration = 1; - } /* elseif(i_CJCGain==i_ADDIDATAGain) */ - } /* elseif(i_CJCPolarity!=i_ADDIDATAPolarity) */ - if (i_ConvertCJCCalibration == 1) { - i_APCI3200_ReadCJCCalOffset(dev, - &ui_DummyValue); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count+4]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos - [dev->minor].i_Count + 4] = - ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - - i_APCI3200_ReadCJCCalGain(dev, &ui_DummyValue); - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count+5]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos - [dev->minor].i_Count + 5] = - ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(i_ConvertCJCCalibration==1) */ - else { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count+4]=0; */ - /* ui_InterruptChannelValue[i_Count+5]=0; */ - - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos - [dev->minor].i_Count + 4] = 0; - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos - [dev->minor].i_Count + 5] = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* elseif(i_ConvertCJCCalibration==1) */ - } /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)) */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if(i_ScanType!=1) */ - if (s_BoardInfos[dev->minor].i_ScanType != 1) { - /* i_Count=0; */ - s_BoardInfos[dev->minor].i_Count = 0; - } /* if(i_ScanType!=1) */ - else { - /* i_Count=i_Count +6; */ - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count +6; */ - s_BoardInfos[dev->minor].i_Count = - s_BoardInfos[dev->minor].i_Count + 9; - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - } /* else if(i_ScanType!=1) */ - - /* if((i_ScanType==1) &&(i_InterruptFlag==1)) */ - if ((s_BoardInfos[dev->minor].i_ScanType == 1) - && (s_BoardInfos[dev->minor].i_InterruptFlag == 1)) { - /* i_Count=i_Count-6; */ - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count-6; */ - s_BoardInfos[dev->minor].i_Count = - s_BoardInfos[dev->minor].i_Count - 9; - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - } - /* if(i_ScanType==0) */ - if (s_BoardInfos[dev->minor].i_ScanType == 0) { - /* - data[0]= ui_InterruptChannelValue[0]; - data[1]= ui_InterruptChannelValue[1]; - data[2]= ui_InterruptChannelValue[2]; - data[3]= ui_InterruptChannelValue[3]; - data[4]= ui_InterruptChannelValue[4]; - data[5]= ui_InterruptChannelValue[5]; - */ - data[0] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[0]; - data[1] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[1]; - data[2] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[2]; - data[3] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[3]; - data[4] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[4]; - data[5] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[5]; - - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - i_APCI3200_GetChannelCalibrationValue(dev, - s_BoardInfos[dev->minor].ui_Channel_num, - &data[6], &data[7], &data[8]); - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - } - break; - case 1: - - for (i = 0; i < insn->n; i++) { - /* data[i]=ui_InterruptChannelValue[i]; */ - data[i] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[i]; - } - - /* i_Count=0; */ - /* i_Sum=0; */ - /* if(i_ScanType==1) */ - s_BoardInfos[dev->minor].i_Count = 0; - s_BoardInfos[dev->minor].i_Sum = 0; - if (s_BoardInfos[dev->minor].i_ScanType == 1) { - /* i_Initialised=0; */ - /* i_InterruptFlag=0; */ - s_BoardInfos[dev->minor].i_Initialised = 0; - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } - break; - default: - printk("\nThe parameters passed are in error\n"); - apci3200_reset(dev); - return -EINVAL; - } /* switch(insn->unused[0]) */ - - return insn->n; -} - -/* - * Configures The Analog Input Subdevice - * - * data[0] = 0 Normal AI - * = 1 RTD - * = 2 THERMOCOUPLE - * data[1] = Gain To Use - * data[2] = 0 Bipolar - * = 1 Unipolar - * data[3] = Offset Range - * data[4] = 0 DC Coupling - * = 1 AC Coupling - * data[5] = 0 Single - * = 1 Differential - * data[6] = TimerReloadValue - * data[7] = ConvertingTimeUnit - * data[8] = 0 Analog voltage measurement - * = 1 Resistance measurement - * = 2 Temperature measurement - * data[9] = 0 Interrupt Disable - * = 1 INterrupt Enable - * data[10] = Type of Thermocouple - * data[11] = single channel Module Number - * data[12] = 0 Single Read - * = 1 Read more channel - * = 2 Single scan - * = 3 Continuous Scan - * data[13] = Number of channels to read - * data[14] = 0 RTD not used - * = 1 RTD 2 wire connection - * = 2 RTD 3 wire connection - * = 3 RTD 4 wire connection - */ -static int apci3200_ai_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ul_Config = 0, ul_Temp = 0; - unsigned int ui_ChannelNo = 0; - unsigned int ui_Dummy = 0; - int i_err = 0; - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* Initialize the structure */ - if (s_BoardInfos[dev->minor].b_StructInitialized != 1) { - s_BoardInfos[dev->minor].i_CJCAvailable = 1; - s_BoardInfos[dev->minor].i_CJCPolarity = 0; - s_BoardInfos[dev->minor].i_CJCGain = 2; /* changed from 0 to 2 */ - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - s_BoardInfos[dev->minor].i_AutoCalibration = 0; /* : auto calibration */ - s_BoardInfos[dev->minor].i_ChannelCount = 0; - s_BoardInfos[dev->minor].i_Sum = 0; - s_BoardInfos[dev->minor].ui_Channel_num = 0; - s_BoardInfos[dev->minor].i_Count = 0; - s_BoardInfos[dev->minor].i_Initialised = 0; - s_BoardInfos[dev->minor].b_StructInitialized = 1; - - /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - s_BoardInfos[dev->minor].i_ConnectionType = 0; - /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - - /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - memset(s_BoardInfos[dev->minor].s_Module, 0, - sizeof(s_BoardInfos[dev->minor].s_Module[MAX_MODULE])); - - v_GetAPCI3200EepromCalibrationValue(devpriv->i_IobaseAmcc, - &s_BoardInfos[dev->minor]); - /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - } - - if (data[0] != 0 && data[0] != 1 && data[0] != 2) { - printk("\nThe selection of acquisition type is in error\n"); - i_err++; - } /* if(data[0]!=0 && data[0]!=1 && data[0]!=2) */ - if (data[0] == 1) { - if (data[14] != 0 && data[14] != 1 && data[14] != 2 - && data[14] != 4) { - printk("\n Error in selection of RTD connection type\n"); - i_err++; - } /* if(data[14]!=0 && data[14]!=1 && data[14]!=2 && data[14]!=4) */ - } /* if(data[0]==1 ) */ - if (data[1] < 0 || data[1] > 7) { - printk("\nThe selection of gain is in error\n"); - i_err++; - } /* if(data[1]<0 || data[1]>7) */ - if (data[2] != 0 && data[2] != 1) { - printk("\nThe selection of polarity is in error\n"); - i_err++; - } /* if(data[2]!=0 && data[2]!=1) */ - if (data[3] != 0) { - printk("\nThe selection of offset range is in error\n"); - i_err++; - } /* if(data[3]!=0) */ - if (data[4] != 0 && data[4] != 1) { - printk("\nThe selection of coupling is in error\n"); - i_err++; - } /* if(data[4]!=0 && data[4]!=1) */ - if (data[5] != 0 && data[5] != 1) { - printk("\nThe selection of single/differential mode is in error\n"); - i_err++; - } /* if(data[5]!=0 && data[5]!=1) */ - if (data[8] != 0 && data[8] != 1 && data[2] != 2) { - printk("\nError in selection of functionality\n"); - } /* if(data[8]!=0 && data[8]!=1 && data[2]!=2) */ - if (data[12] == 0 || data[12] == 1) { - if (data[6] != 20 && data[6] != 40 && data[6] != 80 - && data[6] != 160) { - printk("\nThe selection of conversion time reload value is in error\n"); - i_err++; - } /* if (data[6]!=20 && data[6]!=40 && data[6]!=80 && data[6]!=160 ) */ - if (data[7] != 2) { - printk("\nThe selection of conversion time unit is in error\n"); - i_err++; - } /* if(data[7]!=2) */ - } - if (data[9] != 0 && data[9] != 1) { - printk("\nThe selection of interrupt enable is in error\n"); - i_err++; - } /* if(data[9]!=0 && data[9]!=1) */ - if (data[11] < 0 || data[11] > 4) { - printk("\nThe selection of module is in error\n"); - i_err++; - } /* if(data[11] <0 || data[11]>1) */ - if (data[12] < 0 || data[12] > 3) { - printk("\nThe selection of singlechannel/scan selection is in error\n"); - i_err++; - } /* if(data[12] < 0 || data[12]> 3) */ - if (data[13] < 0 || data[13] > 16) { - printk("\nThe selection of number of channels is in error\n"); - i_err++; - } /* if(data[13] <0 ||data[13] >15) */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* - i_ChannelCount=data[13]; - i_ScanType=data[12]; - i_ADDIDATAPolarity = data[2]; - i_ADDIDATAGain=data[1]; - i_ADDIDATAConversionTime=data[6]; - i_ADDIDATAConversionTimeUnit=data[7]; - i_ADDIDATAType=data[0]; - */ - - /* Save acquisition configuration for the actual board */ - s_BoardInfos[dev->minor].i_ChannelCount = data[13]; - s_BoardInfos[dev->minor].i_ScanType = data[12]; - s_BoardInfos[dev->minor].i_ADDIDATAPolarity = data[2]; - s_BoardInfos[dev->minor].i_ADDIDATAGain = data[1]; - s_BoardInfos[dev->minor].i_ADDIDATAConversionTime = data[6]; - s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit = data[7]; - s_BoardInfos[dev->minor].i_ADDIDATAType = data[0]; - /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - s_BoardInfos[dev->minor].i_ConnectionType = data[5]; - /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* END JK 06.07.04: Management of sevrals boards */ - - /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - memset(s_BoardInfos[dev->minor].ui_ScanValueArray, 0, (7 + 12) * sizeof(unsigned int)); /* 7 is the maximal number of channels */ - /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - - /* BEGIN JK 02.07.04 : This while can't be do, it block the process when using severals boards */ - /* while(i_InterruptFlag==1) */ - while (s_BoardInfos[dev->minor].i_InterruptFlag == 1) { -#ifndef MSXBOX - udelay(1); -#else - /* In the case where the driver is compiled for the MSX-Box */ - /* we used a printk to have a little delay because udelay */ - /* seems to be broken under the MSX-Box. */ - /* This solution hat to be studied. */ - printk(""); -#endif - } - /* END JK 02.07.04 : This while can't be do, it block the process when using severals boards */ - - ui_ChannelNo = CR_CHAN(insn->chanspec); /* get the channel */ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_ChannelNo=ui_ChannelNo; */ - /* ui_Channel_num =ui_ChannelNo; */ - - s_BoardInfos[dev->minor].i_ChannelNo = ui_ChannelNo; - s_BoardInfos[dev->minor].ui_Channel_num = ui_ChannelNo; - - /* END JK 06.07.04: Management of sevrals boards */ - - if (data[5] == 0) { - if (ui_ChannelNo > 15) { - printk("\nThe Selection of the channel is in error\n"); - i_err++; - } /* if(ui_ChannelNo>15) */ - } /* if(data[5]==0) */ - else { - if (data[14] == 2) { - if (ui_ChannelNo > 3) { - printk("\nThe Selection of the channel is in error\n"); - i_err++; - } /* if(ui_ChannelNo>3) */ - } /* if(data[14]==2) */ - else { - if (ui_ChannelNo > 7) { - printk("\nThe Selection of the channel is in error\n"); - i_err++; - } /* if(ui_ChannelNo>7) */ - } /* elseif(data[14]==2) */ - } /* elseif(data[5]==0) */ - if (data[12] == 0 || data[12] == 1) { - switch (data[5]) { - case 0: - if (ui_ChannelNo <= 3) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=0; */ - s_BoardInfos[dev->minor].i_Offset = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo <=3) */ - if (ui_ChannelNo >= 4 && ui_ChannelNo <= 7) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=64; */ - s_BoardInfos[dev->minor].i_Offset = 64; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo >=4 && ui_ChannelNo <=7) */ - if (ui_ChannelNo >= 8 && ui_ChannelNo <= 11) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=128; */ - s_BoardInfos[dev->minor].i_Offset = 128; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo >=8 && ui_ChannelNo <=11) */ - if (ui_ChannelNo >= 12 && ui_ChannelNo <= 15) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=192; */ - s_BoardInfos[dev->minor].i_Offset = 192; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo >=12 && ui_ChannelNo <=15) */ - break; - case 1: - if (data[14] == 2) { - if (ui_ChannelNo == 0) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=0; */ - s_BoardInfos[dev->minor].i_Offset = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo ==0 ) */ - if (ui_ChannelNo == 1) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=0; */ - s_BoardInfos[dev->minor].i_Offset = 64; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo ==1) */ - if (ui_ChannelNo == 2) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=128; */ - s_BoardInfos[dev->minor].i_Offset = 128; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo ==2 ) */ - if (ui_ChannelNo == 3) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=192; */ - s_BoardInfos[dev->minor].i_Offset = 192; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo ==3) */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_ChannelNo=0; */ - s_BoardInfos[dev->minor].i_ChannelNo = 0; - /* END JK 06.07.04: Management of sevrals boards */ - ui_ChannelNo = 0; - break; - } /* if(data[14]==2) */ - if (ui_ChannelNo <= 1) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=0; */ - s_BoardInfos[dev->minor].i_Offset = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo <=1) */ - if (ui_ChannelNo >= 2 && ui_ChannelNo <= 3) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_ChannelNo=i_ChannelNo-2; */ - /* i_Offset=64; */ - s_BoardInfos[dev->minor].i_ChannelNo = - s_BoardInfos[dev->minor].i_ChannelNo - - 2; - s_BoardInfos[dev->minor].i_Offset = 64; - /* END JK 06.07.04: Management of sevrals boards */ - ui_ChannelNo = ui_ChannelNo - 2; - } /* if(ui_ChannelNo >=2 && ui_ChannelNo <=3) */ - if (ui_ChannelNo >= 4 && ui_ChannelNo <= 5) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_ChannelNo=i_ChannelNo-4; */ - /* i_Offset=128; */ - s_BoardInfos[dev->minor].i_ChannelNo = - s_BoardInfos[dev->minor].i_ChannelNo - - 4; - s_BoardInfos[dev->minor].i_Offset = 128; - /* END JK 06.07.04: Management of sevrals boards */ - ui_ChannelNo = ui_ChannelNo - 4; - } /* if(ui_ChannelNo >=4 && ui_ChannelNo <=5) */ - if (ui_ChannelNo >= 6 && ui_ChannelNo <= 7) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_ChannelNo=i_ChannelNo-6; */ - /* i_Offset=192; */ - s_BoardInfos[dev->minor].i_ChannelNo = - s_BoardInfos[dev->minor].i_ChannelNo - - 6; - s_BoardInfos[dev->minor].i_Offset = 192; - /* END JK 06.07.04: Management of sevrals boards */ - ui_ChannelNo = ui_ChannelNo - 6; - } /* if(ui_ChannelNo >=6 && ui_ChannelNo <=7) */ - break; - - default: - printk("\n This selection of polarity does not exist\n"); - i_err++; - } /* switch(data[2]) */ - } /* if(data[12]==0 || data[12]==1) */ - else { - switch (data[11]) { - case 1: - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=0; */ - s_BoardInfos[dev->minor].i_Offset = 0; - /* END JK 06.07.04: Management of sevrals boards */ - break; - case 2: - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=64; */ - s_BoardInfos[dev->minor].i_Offset = 64; - /* END JK 06.07.04: Management of sevrals boards */ - break; - case 3: - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=128; */ - s_BoardInfos[dev->minor].i_Offset = 128; - /* END JK 06.07.04: Management of sevrals boards */ - break; - case 4: - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=192; */ - s_BoardInfos[dev->minor].i_Offset = 192; - /* END JK 06.07.04: Management of sevrals boards */ - break; - default: - printk("\nError in module selection\n"); - i_err++; - } /* switch(data[11]) */ - } /* elseif(data[12]==0 || data[12]==1) */ - if (i_err) { - apci3200_reset(dev); - return -EINVAL; - } - /* if(i_ScanType!=1) */ - if (s_BoardInfos[dev->minor].i_ScanType != 1) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Count=0; */ - /* i_Sum=0; */ - s_BoardInfos[dev->minor].i_Count = 0; - s_BoardInfos[dev->minor].i_Sum = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(i_ScanType!=1) */ - - ul_Config = - data[1] | (data[2] << 6) | (data[5] << 7) | (data[3] << 8) | - (data[4] << 9); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* END JK 06.07.04: Management of sevrals boards */ - /*********************************/ - /* Write the channel to configure */ - /*********************************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* outl(0 | ui_ChannelNo , devpriv->iobase+i_Offset + 0x4); */ - outl(0 | ui_ChannelNo, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4); - /* END JK 06.07.04: Management of sevrals boards */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* END JK 06.07.04: Management of sevrals boards */ - /**************************/ - /* Reset the configuration */ - /**************************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* outl(0 , devpriv->iobase+i_Offset + 0x0); */ - outl(0, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0); - /* END JK 06.07.04: Management of sevrals boards */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* END JK 06.07.04: Management of sevrals boards */ - - /***************************/ - /* Write the configuration */ - /***************************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* outl(ul_Config , devpriv->iobase+i_Offset + 0x0); */ - outl(ul_Config, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0); - /* END JK 06.07.04: Management of sevrals boards */ - - /***************************/ - /*Reset the calibration bit */ - /***************************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ul_Temp = inl(devpriv->iobase+i_Offset + 12); */ - ul_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - /* END JK 06.07.04: Management of sevrals boards */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* END JK 06.07.04: Management of sevrals boards */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* outl((ul_Temp & 0xFFF9FFFF) , devpriv->iobase+.i_Offset + 12); */ - outl((ul_Temp & 0xFFF9FFFF), - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - /* END JK 06.07.04: Management of sevrals boards */ - - if (data[9] == 1) { - devpriv->tsk_Current = current; - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_InterruptFlag=1; */ - s_BoardInfos[dev->minor].i_InterruptFlag = 1; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(data[9]==1) */ - else { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_InterruptFlag=0; */ - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* else if(data[9]==1) */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Initialised=1; */ - s_BoardInfos[dev->minor].i_Initialised = 1; - /* END JK 06.07.04: Management of sevrals boards */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if(i_ScanType==1) */ - if (s_BoardInfos[dev->minor].i_ScanType == 1) - /* END JK 06.07.04: Management of sevrals boards */ - { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Sum=i_Sum+1; */ - s_BoardInfos[dev->minor].i_Sum = - s_BoardInfos[dev->minor].i_Sum + 1; - /* END JK 06.07.04: Management of sevrals boards */ - - insn->unused[0] = 0; - apci3200_ai_read(dev, s, insn, &ui_Dummy); - } - - return insn->n; -} - -/* - * Tests the Selected Anlog Input Channel - * - * data[0] = 0 TestAnalogInputShortCircuit - * = 1 TestAnalogInputConnection - * - * data[0] : Digital value obtained - * data[1] : calibration offset - * data[2] : calibration gain - */ -static int apci3200_ai_bits_test(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_Configuration = 0; - int i_Temp; /* ,i_TimeUnit; */ - - /* if(i_Initialised==0) */ - - if (s_BoardInfos[dev->minor].i_Initialised == 0) { - apci3200_reset(dev); - return -EINVAL; - } /* if(i_Initialised==0); */ - if (data[0] != 0 && data[0] != 1) { - printk("\nError in selection of functionality\n"); - apci3200_reset(dev); - return -EINVAL; - } /* if(data[0]!=0 && data[0]!=1) */ - - if (data[0] == 1) /* Perform Short Circuit TEST */ - { - /**************************/ - /*Set the short-cicuit bit */ - /**************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor]. - i_Offset + 12) >> 19) & 1) != - 1) ; - /* outl((0x00001000 |i_ChannelNo) , devpriv->iobase+i_Offset + 4); */ - outl((0x00001000 | s_BoardInfos[dev->minor].i_ChannelNo), - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 4); - /*************************/ - /*Set the time unit to ns */ - /*************************/ - /* i_TimeUnit= i_ADDIDATAConversionTimeUnit; - i_ADDIDATAConversionTimeUnit= 1; */ - /* i_Temp= i_InterruptFlag ; */ - i_Temp = s_BoardInfos[dev->minor].i_InterruptFlag; - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - i_APCI3200_Read1AnalogInputChannel(dev, s, insn, data); - /* if(i_AutoCalibration == FALSE) */ - if (s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) { - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor]. - i_Offset + - 12) >> 19) & 1) != 1) ; - - /* outl((0x00001000 |i_ChannelNo) , devpriv->iobase+i_Offset + 4); */ - outl((0x00001000 | s_BoardInfos[dev->minor]. - i_ChannelNo), - devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 4); - data++; - i_APCI3200_ReadCalibrationOffsetValue(dev, data); - data++; - i_APCI3200_ReadCalibrationGainValue(dev, data); - } - } else { - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor]. - i_Offset + 12) >> 19) & 1) != - 1) ; - /* outl((0x00000800|i_ChannelNo) , devpriv->iobase+i_Offset + 4); */ - outl((0x00000800 | s_BoardInfos[dev->minor].i_ChannelNo), - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 4); - /* ui_Configuration = inl(devpriv->iobase+i_Offset + 0); */ - ui_Configuration = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 0); - /*************************/ - /*Set the time unit to ns */ - /*************************/ - /* i_TimeUnit= i_ADDIDATAConversionTimeUnit; - i_ADDIDATAConversionTimeUnit= 1; */ - /* i_Temp= i_InterruptFlag ; */ - i_Temp = s_BoardInfos[dev->minor].i_InterruptFlag; - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - i_APCI3200_Read1AnalogInputChannel(dev, s, insn, data); - /* if(i_AutoCalibration == FALSE) */ - if (s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) { - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor]. - i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl((0x00000800|i_ChannelNo) , devpriv->iobase+i_Offset + 4); */ - outl((0x00000800 | s_BoardInfos[dev->minor]. - i_ChannelNo), - devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 4); - data++; - i_APCI3200_ReadCalibrationOffsetValue(dev, data); - data++; - i_APCI3200_ReadCalibrationGainValue(dev, data); - } - } - /* i_InterruptFlag=i_Temp ; */ - s_BoardInfos[dev->minor].i_InterruptFlag = i_Temp; - return insn->n; -} - -static int apci3200_ai_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - apci3200_reset(dev); - return insn->n; -} - -static int apci3200_ai_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd) -{ - - int err = 0; - unsigned int ui_ConvertTime = 0; - unsigned int ui_ConvertTimeBase = 0; - unsigned int ui_DelayTime = 0; - unsigned int ui_DelayTimeBase = 0; - int i_NbrOfChannel = 0; - int i_Cpt = 0; - double d_ConversionTimeForAllChannels = 0.0; - double d_SCANTimeNewUnit = 0.0; - unsigned int arg; - - /* Step 1 : check if triggers are trivially valid */ - - err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); - err |= cfc_check_trigger_src(&cmd->scan_begin_src, - TRIG_TIMER | TRIG_FOLLOW); - err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER); - err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); - err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); - - if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) - err |= -EINVAL; - - if (err) { - apci3200_reset(dev); - return 1; - } - - /* Step 2a : make sure trigger sources are unique */ - - err |= cfc_check_trigger_is_unique(&cmd->start_src); - err |= cfc_check_trigger_is_unique(&cmd->scan_begin_src); - err |= cfc_check_trigger_is_unique(&cmd->stop_src); - - /* Step 2b : and mutually compatible */ - - if (err) { - apci3200_reset(dev); - return 2; - } - - /* Step 3: check if arguments are trivially valid */ - - switch (cmd->start_src) { - case TRIG_NOW: - err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - break; - case TRIG_EXT: - /* validate the trigger edge selection */ - arg = cmd->start_arg & 0xffff; - if (arg < 1 || arg > 3) { - cmd->start_arg &= ~0xffff; - cmd->start_arg |= 1; - err |= -EINVAL; - } - /* validate the trigger mode selection */ - arg = cmd->start_arg >> 16; - if (arg != 2) { - cmd->start_arg &= ~(0xffff << 16); - cmd->start_arg |= (2 << 16); - err |= -EINVAL; - } - break; - } - - err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); - - /* i_FirstChannel=cmd->chanlist[0]; */ - s_BoardInfos[dev->minor].i_FirstChannel = cmd->chanlist[0]; - /* i_LastChannel=cmd->chanlist[1]; */ - s_BoardInfos[dev->minor].i_LastChannel = cmd->chanlist[1]; - - if (cmd->convert_src == TRIG_TIMER) { - ui_ConvertTime = cmd->convert_arg & 0xFFFF; - ui_ConvertTimeBase = cmd->convert_arg >> 16; - if (ui_ConvertTime != 20 && ui_ConvertTime != 40 - && ui_ConvertTime != 80 && ui_ConvertTime != 160) - { - printk("\nThe selection of conversion time reload value is in error\n"); - err++; - } /* if (ui_ConvertTime!=20 && ui_ConvertTime!=40 && ui_ConvertTime!=80 && ui_ConvertTime!=160 ) */ - if (ui_ConvertTimeBase != 2) { - printk("\nThe selection of conversion time unit is in error\n"); - err++; - } /* if(ui_ConvertTimeBase!=2) */ - } else { - ui_ConvertTime = 0; - ui_ConvertTimeBase = 0; - } - if (cmd->scan_begin_src == TRIG_FOLLOW) { - ui_DelayTime = 0; - ui_DelayTimeBase = 0; - } /* if(cmd->scan_begin_src==TRIG_FOLLOW) */ - else { - ui_DelayTime = cmd->scan_begin_arg & 0xFFFF; - ui_DelayTimeBase = cmd->scan_begin_arg >> 16; - if (ui_DelayTimeBase != 2 && ui_DelayTimeBase != 3) { - err++; - printk("\nThe Delay time base selection is in error\n"); - } - if (ui_DelayTime < 1 || ui_DelayTime > 1023) { - err++; - printk("\nThe Delay time value is in error\n"); - } - if (err) { - apci3200_reset(dev); - return 3; - } - fpu_begin(); - d_SCANTimeNewUnit = (double)ui_DelayTime; - /* i_NbrOfChannel= i_LastChannel-i_FirstChannel + 4; */ - i_NbrOfChannel = - s_BoardInfos[dev->minor].i_LastChannel - - s_BoardInfos[dev->minor].i_FirstChannel + 4; - /**********************************************************/ - /*calculate the total conversion time for all the channels */ - /**********************************************************/ - d_ConversionTimeForAllChannels = - (double)((double)ui_ConvertTime / - (double)i_NbrOfChannel); - - /*******************************/ - /*Convert the frequence in time */ - /*******************************/ - d_ConversionTimeForAllChannels = - (double)1.0 / d_ConversionTimeForAllChannels; - ui_ConvertTimeBase = 3; - /***********************************/ - /*Test if the time unit is the same */ - /***********************************/ - - if (ui_DelayTimeBase <= ui_ConvertTimeBase) { - - for (i_Cpt = 0; - i_Cpt < (ui_ConvertTimeBase - ui_DelayTimeBase); - i_Cpt++) { - - d_ConversionTimeForAllChannels = - d_ConversionTimeForAllChannels * 1000; - d_ConversionTimeForAllChannels = - d_ConversionTimeForAllChannels + 1; - } - } else { - for (i_Cpt = 0; - i_Cpt < (ui_DelayTimeBase - ui_ConvertTimeBase); - i_Cpt++) { - d_SCANTimeNewUnit = d_SCANTimeNewUnit * 1000; - - } - } - - if (d_ConversionTimeForAllChannels >= d_SCANTimeNewUnit) { - - printk("\nSCAN Delay value cannot be used\n"); - /*********************************/ - /*SCAN Delay value cannot be used */ - /*********************************/ - err++; - } - fpu_end(); - } /* else if(cmd->scan_begin_src==TRIG_FOLLOW) */ - - if (err) { - apci3200_reset(dev); - return 4; - } - - return 0; -} - -static int apci3200_cancel(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_Configuration = 0; - - /* i_InterruptFlag=0; */ - /* i_Initialised=0; */ - /* i_Count=0; */ - /* i_Sum=0; */ - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - s_BoardInfos[dev->minor].i_Initialised = 0; - s_BoardInfos[dev->minor].i_Count = 0; - s_BoardInfos[dev->minor].i_Sum = 0; - - /*******************/ - /*Read the register */ - /*******************/ - /* ui_Configuration = inl(devpriv->iobase+i_Offset + 8); */ - ui_Configuration = - inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - /*****************************/ - /*Reset the START and IRQ bit */ - /*****************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl((ui_Configuration & 0xFFE7FFFF),devpriv->iobase+i_Offset + 8); */ - outl((ui_Configuration & 0xFFE7FFFF), - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - return 0; -} - -/* - * Does asynchronous acquisition - * Determines the mode 1 or 2. - */ -static int apci3200_ai_cmd(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - struct addi_private *devpriv = dev->private; - struct comedi_cmd *cmd = &s->async->cmd; - unsigned int ui_Configuration = 0; - /* INT i_CurrentSource = 0; */ - unsigned int ui_Trigger = 0; - unsigned int ui_TriggerEdge = 0; - unsigned int ui_Triggermode = 0; - unsigned int ui_ScanMode = 0; - unsigned int ui_ConvertTime = 0; - unsigned int ui_ConvertTimeBase = 0; - unsigned int ui_DelayTime = 0; - unsigned int ui_DelayTimeBase = 0; - unsigned int ui_DelayMode = 0; - - /* i_FirstChannel=cmd->chanlist[0]; */ - /* i_LastChannel=cmd->chanlist[1]; */ - s_BoardInfos[dev->minor].i_FirstChannel = cmd->chanlist[0]; - s_BoardInfos[dev->minor].i_LastChannel = cmd->chanlist[1]; - if (cmd->start_src == TRIG_EXT) { - ui_Trigger = 1; - ui_TriggerEdge = cmd->start_arg & 0xFFFF; - ui_Triggermode = cmd->start_arg >> 16; - } /* if(cmd->start_src==TRIG_EXT) */ - else { - ui_Trigger = 0; - } /* elseif(cmd->start_src==TRIG_EXT) */ - - if (cmd->stop_src == TRIG_COUNT) { - ui_ScanMode = 0; - } /* if (cmd->stop_src==TRIG_COUNT) */ - else { - ui_ScanMode = 2; - } /* else if (cmd->stop_src==TRIG_COUNT) */ - - if (cmd->scan_begin_src == TRIG_FOLLOW) { - ui_DelayTime = 0; - ui_DelayTimeBase = 0; - ui_DelayMode = 0; - } /* if(cmd->scan_begin_src==TRIG_FOLLOW) */ - else { - ui_DelayTime = cmd->scan_begin_arg & 0xFFFF; - ui_DelayTimeBase = cmd->scan_begin_arg >> 16; - ui_DelayMode = 1; - } /* else if(cmd->scan_begin_src==TRIG_FOLLOW) */ - if (cmd->convert_src == TRIG_TIMER) { - ui_ConvertTime = cmd->convert_arg & 0xFFFF; - ui_ConvertTimeBase = cmd->convert_arg >> 16; - } else { - ui_ConvertTime = 0; - ui_ConvertTimeBase = 0; - } - - /* if(i_ADDIDATAType ==1 || ((i_ADDIDATAType==2))) */ - /* { */ - /**************************************************/ - /*Read the old configuration of the current source */ - /**************************************************/ - /* ui_Configuration = inl(devpriv->iobase+i_Offset + 12); */ - ui_Configuration = - inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - /***********************************************/ - /*Write the configuration of the current source */ - /***********************************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl((ui_Configuration & 0xFFC00000 ), devpriv->iobase+i_Offset +12); */ - outl((ui_Configuration & 0xFFC00000), - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - /* } */ - ui_Configuration = 0; - - /* ui_Configuration = i_FirstChannel |(i_LastChannel << 8)| 0x00100000 | */ - ui_Configuration = - s_BoardInfos[dev->minor].i_FirstChannel | (s_BoardInfos[dev-> - minor]. - i_LastChannel << 8) | 0x00100000 | (ui_Trigger << 24) | - (ui_TriggerEdge << 25) | (ui_Triggermode << 27) | (ui_DelayMode - << 18) | (ui_ScanMode << 16); - - /*************************/ - /*Write the Configuration */ - /*************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl( ui_Configuration, devpriv->iobase+i_Offset + 0x8); */ - outl(ui_Configuration, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x8); - /***********************/ - /*Write the Delay Value */ - /***********************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(ui_DelayTime,devpriv->iobase+i_Offset + 40); */ - outl(ui_DelayTime, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 40); - /***************************/ - /*Write the Delay time base */ - /***************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(ui_DelayTimeBase,devpriv->iobase+i_Offset + 44); */ - outl(ui_DelayTimeBase, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 44); - /*********************************/ - /*Write the conversion time value */ - /*********************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(ui_ConvertTime,devpriv->iobase+i_Offset + 32); */ - outl(ui_ConvertTime, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); - - /********************************/ - /*Write the conversion time base */ - /********************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(ui_ConvertTimeBase,devpriv->iobase+i_Offset + 36); */ - outl(ui_ConvertTimeBase, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36); - /*******************/ - /*Read the register */ - /*******************/ - /* ui_Configuration = inl(devpriv->iobase+i_Offset + 4); */ - ui_Configuration = - inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4); - /******************/ - /*Set the SCAN bit */ - /******************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - - /* outl(((ui_Configuration & 0x1E0FF) | 0x00002000),devpriv->iobase+i_Offset + 4); */ - outl(((ui_Configuration & 0x1E0FF) | 0x00002000), - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4); - /*******************/ - /*Read the register */ - /*******************/ - ui_Configuration = 0; - /* ui_Configuration = inl(devpriv->iobase+i_Offset + 8); */ - ui_Configuration = - inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - - /*******************/ - /*Set the START bit */ - /*******************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl((ui_Configuration | 0x00080000),devpriv->iobase+i_Offset + 8); */ - outl((ui_Configuration | 0x00080000), - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - return 0; -} - -/* - * This function copies the acquired data(from FIFO) to Comedi buffer. - */ -static int i_APCI3200_InterruptHandleEos(struct comedi_device *dev) -{ - struct addi_private *devpriv = dev->private; - struct comedi_subdevice *s = dev->read_subdev; - unsigned int ui_StatusRegister = 0; - - /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* comedi_async *async = s->async; */ - /* UINT *data; */ - /* data=async->data+async->buf_int_ptr;//new samples added from here onwards */ - int n = 0, i = 0; - /* END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - - /************************************/ - /*Read the interrupt status register */ - /************************************/ - /* ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16); */ - ui_StatusRegister = - inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 16); - - /*************************/ - /*Test if interrupt occur */ - /*************************/ - - if ((ui_StatusRegister & 0x2) == 0x2) { - /*************************/ - /*Read the channel number */ - /*************************/ - /* ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24); */ - /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* This value is not used */ - /* ui_ChannelNumber = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 24); */ - /* END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - - /*************************************/ - /*Read the digital Analog Input value */ - /*************************************/ - - /* data[i_Count] = inl(devpriv->iobase+i_Offset + 28); */ - /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* data[s_BoardInfos [dev->minor].i_Count] = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 28); */ - s_BoardInfos[dev->minor].ui_ScanValueArray[s_BoardInfos[dev-> - minor].i_Count] = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - - /* if((i_Count == (i_LastChannel-i_FirstChannel+3))) */ - if ((s_BoardInfos[dev->minor].i_Count == - (s_BoardInfos[dev->minor].i_LastChannel - - s_BoardInfos[dev->minor]. - i_FirstChannel + 3))) { - - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - s_BoardInfos[dev->minor].i_Count++; - - for (i = s_BoardInfos[dev->minor].i_FirstChannel; - i <= s_BoardInfos[dev->minor].i_LastChannel; - i++) { - i_APCI3200_GetChannelCalibrationValue(dev, i, - &s_BoardInfos[dev->minor]. - ui_ScanValueArray[s_BoardInfos[dev-> - minor].i_Count + ((i - - s_BoardInfos - [dev->minor]. - i_FirstChannel) - * 3)], - &s_BoardInfos[dev->minor]. - ui_ScanValueArray[s_BoardInfos[dev-> - minor].i_Count + ((i - - s_BoardInfos - [dev->minor]. - i_FirstChannel) - * 3) + 1], - &s_BoardInfos[dev->minor]. - ui_ScanValueArray[s_BoardInfos[dev-> - minor].i_Count + ((i - - s_BoardInfos - [dev->minor]. - i_FirstChannel) - * 3) + 2]); - } - - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - - /* i_Count=-1; */ - - s_BoardInfos[dev->minor].i_Count = -1; - - /* async->buf_int_count+=(i_LastChannel-i_FirstChannel+4)*sizeof(unsigned int); */ - /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* async->buf_int_count+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(unsigned int); */ - /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* async->buf_int_ptr+=(i_LastChannel-i_FirstChannel+4)*sizeof(unsigned int); */ - /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* async->buf_int_ptr+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(unsigned int); */ - /* comedi_eos(dev,s); */ - - /* Set the event type (Comedi Buffer End Of Scan) */ - s->async->events |= COMEDI_CB_EOS; - - /* Test if enougth memory is available and allocate it for 7 values */ - n = comedi_buf_write_alloc(s, - (7 + 12) * sizeof(unsigned int)); - - /* If not enough memory available, event is set to Comedi Buffer Error */ - if (n > ((7 + 12) * sizeof(unsigned int))) { - printk("\ncomedi_buf_write_alloc n = %i", n); - s->async->events |= COMEDI_CB_ERROR; - } - /* Write all 7 scan values in the comedi buffer */ - comedi_buf_memcpy_to(s, 0, - (unsigned int *) s_BoardInfos[dev->minor]. - ui_ScanValueArray, (7 + 12) * sizeof(unsigned int)); - - /* Update comedi buffer pinters indexes */ - comedi_buf_write_free(s, - (7 + 12) * sizeof(unsigned int)); - - /* Send events */ - comedi_event(dev, s); - /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - - /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* */ - /* if (s->async->buf_int_ptr>=s->async->data_len) // for buffer rool over */ - /* { */ - /* /* buffer rollover */ */ - /* s->async->buf_int_ptr=0; */ - /* comedi_eobuf(dev,s); */ - /* } */ - /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - } - /* i_Count++; */ - s_BoardInfos[dev->minor].i_Count++; - } - /* i_InterruptFlag=0; */ - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - return 0; -} - -static void apci3200_interrupt(int irq, void *d) -{ - struct comedi_device *dev = d; - struct addi_private *devpriv = dev->private; - unsigned int ui_StatusRegister = 0; - unsigned int ui_ChannelNumber = 0; - int i_CalibrationFlag = 0; - int i_CJCFlag = 0; - unsigned int ui_DummyValue = 0; - unsigned int ui_DigitalTemperature = 0; - unsigned int ui_DigitalInput = 0; - int i_ConvertCJCCalibration; - /* BEGIN JK TEST */ - int i_ReturnValue = 0; - /* END JK TEST */ - - /* switch(i_ScanType) */ - switch (s_BoardInfos[dev->minor].i_ScanType) { - case 0: - case 1: - /* switch(i_ADDIDATAType) */ - switch (s_BoardInfos[dev->minor].i_ADDIDATAType) { - case 0: - case 1: - - /************************************/ - /*Read the interrupt status register */ - /************************************/ - /* ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16); */ - ui_StatusRegister = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 16); - if ((ui_StatusRegister & 0x2) == 0x2) { - /* i_CalibrationFlag = ((inl(devpriv->iobase+i_Offset + 12) & 0x00060000) >> 17); */ - i_CalibrationFlag = - ((inl(devpriv->iobase + - s_BoardInfos[dev-> - minor]. - i_Offset + - 12) & 0x00060000) >> - 17); - /*************************/ - /*Read the channel number */ - /*************************/ - /* ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24); */ - - /*************************************/ - /*Read the digital analog input value */ - /*************************************/ - /* ui_DigitalInput = inl(devpriv->iobase+i_Offset + 28); */ - ui_DigitalInput = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - - /***********************************************/ - /* Test if the value read is the channel value */ - /***********************************************/ - if (i_CalibrationFlag == 0) { - /* ui_InterruptChannelValue[i_Count + 0] = ui_DigitalInput; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev->minor]. - i_Count + 0] = ui_DigitalInput; - - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - /* - i_APCI3200_GetChannelCalibrationValue (dev, s_BoardInfos [dev->minor].ui_Channel_num, - &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 6], - &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 7], - &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 8]); - */ - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - - /******************************************************/ - /*Start the conversion of the calibration offset value */ - /******************************************************/ - i_APCI3200_ReadCalibrationOffsetValue - (dev, &ui_DummyValue); - } /* if (i_CalibrationFlag == 0) */ - /**********************************************************/ - /* Test if the value read is the calibration offset value */ - /**********************************************************/ - - if (i_CalibrationFlag == 1) { - - /******************/ - /* Save the value */ - /******************/ - - /* ui_InterruptChannelValue[i_Count + 1] = ui_DigitalInput; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev->minor]. - i_Count + 1] = ui_DigitalInput; - - /******************************************************/ - /* Start the conversion of the calibration gain value */ - /******************************************************/ - i_APCI3200_ReadCalibrationGainValue(dev, - &ui_DummyValue); - } /* if (i_CalibrationFlag == 1) */ - /******************************************************/ - /*Test if the value read is the calibration gain value */ - /******************************************************/ - - if (i_CalibrationFlag == 2) { - - /****************/ - /*Save the value */ - /****************/ - /* ui_InterruptChannelValue[i_Count + 2] = ui_DigitalInput; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev->minor]. - i_Count + 2] = ui_DigitalInput; - /* if(i_ScanType==1) */ - if (s_BoardInfos[dev->minor]. - i_ScanType == 1) { - - /* i_InterruptFlag=0; */ - s_BoardInfos[dev->minor]. - i_InterruptFlag = 0; - /* i_Count=i_Count + 6; */ - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count + 6; */ - s_BoardInfos[dev->minor]. - i_Count = - s_BoardInfos[dev-> - minor].i_Count + 9; - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - } /* if(i_ScanType==1) */ - else { - /* i_Count=0; */ - s_BoardInfos[dev->minor]. - i_Count = 0; - } /* elseif(i_ScanType==1) */ - /* if(i_ScanType!=1) */ - if (s_BoardInfos[dev->minor]. - i_ScanType != 1) { - i_ReturnValue = send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ - } /* if(i_ScanType!=1) */ - else { - /* if(i_ChannelCount==i_Sum) */ - if (s_BoardInfos[dev->minor]. - i_ChannelCount == - s_BoardInfos[dev-> - minor].i_Sum) { - send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ - } - } /* if(i_ScanType!=1) */ - } /* if (i_CalibrationFlag == 2) */ - } /* if ((ui_StatusRegister & 0x2) == 0x2) */ - - break; - - case 2: - /************************************/ - /*Read the interrupt status register */ - /************************************/ - - /* ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16); */ - ui_StatusRegister = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 16); - /*************************/ - /*Test if interrupt occur */ - /*************************/ - - if ((ui_StatusRegister & 0x2) == 0x2) { - - /* i_CJCFlag = ((inl(devpriv->iobase+i_Offset + 4) & 0x00000400) >> 10); */ - i_CJCFlag = - ((inl(devpriv->iobase + - s_BoardInfos[dev-> - minor]. - i_Offset + - 4) & 0x00000400) >> 10); - - /* i_CalibrationFlag = ((inl(devpriv->iobase+i_Offset + 12) & 0x00060000) >> 17); */ - i_CalibrationFlag = - ((inl(devpriv->iobase + - s_BoardInfos[dev-> - minor]. - i_Offset + - 12) & 0x00060000) >> - 17); - - /*************************/ - /*Read the channel number */ - /*************************/ - - /* ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24); */ - ui_ChannelNumber = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 24); - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - s_BoardInfos[dev->minor].ui_Channel_num = - ui_ChannelNumber; - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - - /************************************/ - /*Read the digital temperature value */ - /************************************/ - /* ui_DigitalTemperature = inl(devpriv->iobase+i_Offset + 28); */ - ui_DigitalTemperature = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - - /*********************************************/ - /*Test if the value read is the channel value */ - /*********************************************/ - - if ((i_CalibrationFlag == 0) - && (i_CJCFlag == 0)) { - /* ui_InterruptChannelValue[i_Count + 0]=ui_DigitalTemperature; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev->minor]. - i_Count + 0] = - ui_DigitalTemperature; - - /*********************************/ - /*Start the conversion of the CJC */ - /*********************************/ - i_APCI3200_ReadCJCValue(dev, - &ui_DummyValue); - - } /* if ((i_CalibrationFlag == 0) && (i_CJCFlag == 0)) */ - - /*****************************************/ - /*Test if the value read is the CJC value */ - /*****************************************/ - - if ((i_CJCFlag == 1) - && (i_CalibrationFlag == 0)) { - /* ui_InterruptChannelValue[i_Count + 3]=ui_DigitalTemperature; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev->minor]. - i_Count + 3] = - ui_DigitalTemperature; - - /******************************************************/ - /*Start the conversion of the calibration offset value */ - /******************************************************/ - i_APCI3200_ReadCalibrationOffsetValue - (dev, &ui_DummyValue); - } /* if ((i_CJCFlag == 1) && (i_CalibrationFlag == 0)) */ - - /********************************************************/ - /*Test if the value read is the calibration offset value */ - /********************************************************/ - - if ((i_CalibrationFlag == 1) - && (i_CJCFlag == 0)) { - /* ui_InterruptChannelValue[i_Count + 1]=ui_DigitalTemperature; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev->minor]. - i_Count + 1] = - ui_DigitalTemperature; - - /****************************************************/ - /*Start the conversion of the calibration gain value */ - /****************************************************/ - i_APCI3200_ReadCalibrationGainValue(dev, - &ui_DummyValue); - - } /* if ((i_CalibrationFlag == 1) && (i_CJCFlag == 0)) */ - - /******************************************************/ - /*Test if the value read is the calibration gain value */ - /******************************************************/ - - if ((i_CalibrationFlag == 2) - && (i_CJCFlag == 0)) { - /* ui_InterruptChannelValue[i_Count + 2]=ui_DigitalTemperature; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev->minor]. - i_Count + 2] = - ui_DigitalTemperature; - - /**********************************************************/ - /*Test if the Calibration channel must be read for the CJC */ - /**********************************************************/ - - /*Test if the polarity is the same */ - /**********************************/ - /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */ - if (s_BoardInfos[dev->minor]. - i_CJCPolarity != - s_BoardInfos[dev->minor]. - i_ADDIDATAPolarity) { - i_ConvertCJCCalibration = 1; - } /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */ - else { - /* if(i_CJCGain==i_ADDIDATAGain) */ - if (s_BoardInfos[dev->minor]. - i_CJCGain == - s_BoardInfos[dev-> - minor]. - i_ADDIDATAGain) { - i_ConvertCJCCalibration - = 0; - } /* if(i_CJCGain==i_ADDIDATAGain) */ - else { - i_ConvertCJCCalibration - = 1; - } /* elseif(i_CJCGain==i_ADDIDATAGain) */ - } /* elseif(i_CJCPolarity!=i_ADDIDATAPolarity) */ - if (i_ConvertCJCCalibration == 1) { - /****************************************************************/ - /*Start the conversion of the calibration gain value for the CJC */ - /****************************************************************/ - i_APCI3200_ReadCJCCalOffset(dev, - &ui_DummyValue); - - } /* if(i_ConvertCJCCalibration==1) */ - else { - /* ui_InterruptChannelValue[i_Count + 4]=0; */ - /* ui_InterruptChannelValue[i_Count + 5]=0; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev-> - minor].i_Count + - 4] = 0; - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev-> - minor].i_Count + - 5] = 0; - } /* elseif(i_ConvertCJCCalibration==1) */ - } /* else if ((i_CalibrationFlag == 2) && (i_CJCFlag == 0)) */ - - /********************************************************************/ - /*Test if the value read is the calibration offset value for the CJC */ - /********************************************************************/ - - if ((i_CalibrationFlag == 1) - && (i_CJCFlag == 1)) { - /* ui_InterruptChannelValue[i_Count + 4]=ui_DigitalTemperature; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev->minor]. - i_Count + 4] = - ui_DigitalTemperature; - - /****************************************************************/ - /*Start the conversion of the calibration gain value for the CJC */ - /****************************************************************/ - i_APCI3200_ReadCJCCalGain(dev, - &ui_DummyValue); - - } /* if ((i_CalibrationFlag == 1) && (i_CJCFlag == 1)) */ - - /******************************************************************/ - /*Test if the value read is the calibration gain value for the CJC */ - /******************************************************************/ - - if ((i_CalibrationFlag == 2) - && (i_CJCFlag == 1)) { - /* ui_InterruptChannelValue[i_Count + 5]=ui_DigitalTemperature; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev->minor]. - i_Count + 5] = - ui_DigitalTemperature; - - /* if(i_ScanType==1) */ - if (s_BoardInfos[dev->minor]. - i_ScanType == 1) { - - /* i_InterruptFlag=0; */ - s_BoardInfos[dev->minor]. - i_InterruptFlag = 0; - /* i_Count=i_Count + 6; */ - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count + 6; */ - s_BoardInfos[dev->minor]. - i_Count = - s_BoardInfos[dev-> - minor].i_Count + 9; - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - } /* if(i_ScanType==1) */ - else { - /* i_Count=0; */ - s_BoardInfos[dev->minor]. - i_Count = 0; - } /* elseif(i_ScanType==1) */ - - /* if(i_ScanType!=1) */ - if (s_BoardInfos[dev->minor]. - i_ScanType != 1) { - send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ - } /* if(i_ScanType!=1) */ - else { - /* if(i_ChannelCount==i_Sum) */ - if (s_BoardInfos[dev->minor]. - i_ChannelCount == - s_BoardInfos[dev-> - minor].i_Sum) { - send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ - - } /* if(i_ChannelCount==i_Sum) */ - } /* else if(i_ScanType!=1) */ - } /* if ((i_CalibrationFlag == 2) && (i_CJCFlag == 1)) */ - - } /* else if ((ui_StatusRegister & 0x2) == 0x2) */ - break; - } /* switch(i_ADDIDATAType) */ - break; - case 2: - case 3: - i_APCI3200_InterruptHandleEos(dev); - break; - } /* switch(i_ScanType) */ - return; -} diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c deleted file mode 100644 index af70c8401880..000000000000 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ /dev/null @@ -1,77 +0,0 @@ -#include <linux/module.h> -#include <linux/pci.h> - -#include "../comedidev.h" -#include "comedi_fc.h" -#include "amcc_s5933.h" - -#include "addi-data/addi_common.h" - -#define ADDIDATA_WATCHDOG 2 /* Or shold it be something else */ - -#include "addi-data/addi_eeprom.c" -#include "addi-data/hwdrv_apci035.c" -#include "addi-data/addi_common.c" - -static const struct addi_board apci035_boardtypes[] = { - { - .pc_DriverName = "apci035", - .i_IorangeBase1 = APCI035_ADDRESS_RANGE, - .i_PCIEeprom = 1, - .pc_EepromChip = "S5920", - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_AiMaxdata = 0xff, - .pr_AiRangelist = &range_apci035_ai, - .i_Timer = 1, - .ui_MinAcquisitiontimeNs = 10000, - .ui_MinDelaytimeNs = 100000, - .interrupt = apci035_interrupt, - .reset = apci035_reset, - .ai_config = apci035_ai_config, - .ai_read = apci035_ai_read, - .timer_config = apci035_timer_config, - .timer_write = apci035_timer_write, - .timer_read = apci035_timer_read, - }, -}; - -static int apci035_auto_attach(struct comedi_device *dev, - unsigned long context) -{ - dev->board_ptr = &apci035_boardtypes[0]; - - return addi_auto_attach(dev, context); -} - -static struct comedi_driver apci035_driver = { - .driver_name = "addi_apci_035", - .module = THIS_MODULE, - .auto_attach = apci035_auto_attach, - .detach = i_ADDI_Detach, -}; - -static int apci035_pci_probe(struct pci_dev *dev, - const struct pci_device_id *id) -{ - return comedi_pci_auto_config(dev, &apci035_driver, id->driver_data); -} - -static const struct pci_device_id apci035_pci_table[] = { - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x0300) }, - { 0 } -}; -MODULE_DEVICE_TABLE(pci, apci035_pci_table); - -static struct pci_driver apci035_pci_driver = { - .name = "addi_apci_035", - .id_table = apci035_pci_table, - .probe = apci035_pci_probe, - .remove = comedi_pci_auto_unconfig, -}; -module_comedi_pci_driver(apci035_driver, apci035_pci_driver); - -MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 840cb289507a..bf14165297b7 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -258,9 +258,8 @@ static irqreturn_t apci1032_interrupt(int irq, void *d) outl(ctrl & ~APCI1032_CTRL_INT_ENA, dev->iobase + APCI1032_CTRL_REG); s->state = inl(dev->iobase + APCI1032_STATUS_REG) & 0xffff; - comedi_buf_put(s, s->state); - s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; - comedi_event(dev, s); + comedi_buf_write_samples(s, &s->state, 1); + comedi_handle_events(dev, s); /* enable the interrupt */ outl(ctrl, dev->iobase + APCI1032_CTRL_REG); diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index b7a284ac6649..30b132c3d092 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -1,54 +1,109 @@ #include <linux/module.h> #include <linux/pci.h> +#include <linux/sched.h> +#include <linux/interrupt.h> #include "../comedidev.h" #include "comedi_fc.h" #include "amcc_s5933.h" -#include "addi-data/addi_common.h" +struct apci1500_private { + int iobase; + int i_IobaseAmcc; + int i_IobaseAddon; + int i_IobaseReserved; + unsigned char b_OutputMemoryStatus; + struct task_struct *tsk_Current; +}; -#include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1500.c" -#include "addi-data/addi_common.c" - -static const struct addi_board apci1500_boardtypes[] = { - { - .pc_DriverName = "apci1500", - .i_IorangeBase1 = APCI1500_ADDRESS_RANGE, - .i_PCIEeprom = 0, - .i_NbrDiChannel = 16, - .i_NbrDoChannel = 16, - .i_DoMaxdata = 0xffff, - .i_Timer = 1, - .interrupt = apci1500_interrupt, - .reset = apci1500_reset, - .di_config = apci1500_di_config, - .di_read = apci1500_di_read, - .di_write = apci1500_di_write, - .di_bits = apci1500_di_insn_bits, - .do_config = apci1500_do_config, - .do_write = apci1500_do_write, - .do_bits = apci1500_do_bits, - .timer_config = apci1500_timer_config, - .timer_write = apci1500_timer_write, - .timer_read = apci1500_timer_read, - .timer_bits = apci1500_timer_bits, - }, -}; static int apci1500_auto_attach(struct comedi_device *dev, unsigned long context) { - dev->board_ptr = &apci1500_boardtypes[0]; + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct apci1500_private *devpriv; + struct comedi_subdevice *s; + int ret; + + devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); + if (!devpriv) + return -ENOMEM; + + ret = comedi_pci_enable(dev); + if (ret) + return ret; + + dev->iobase = pci_resource_start(pcidev, 1); + devpriv->iobase = dev->iobase; + devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); + devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); + devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); + + if (pcidev->irq > 0) { + ret = request_irq(pcidev->irq, apci1500_interrupt, IRQF_SHARED, + dev->board_name, dev); + if (ret == 0) + dev->irq = pcidev->irq; + } + + ret = comedi_alloc_subdevices(dev, 3); + if (ret) + return ret; - return addi_auto_attach(dev, context); + /* Allocate and Initialise DI Subdevice Structures */ + s = &dev->subdevices[0]; + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = 16; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_config = apci1500_di_config; + s->insn_read = apci1500_di_read; + s->insn_write = apci1500_di_write; + s->insn_bits = apci1500_di_insn_bits; + + /* Allocate and Initialise DO Subdevice Structures */ + s = &dev->subdevices[1]; + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 16; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_config = apci1500_do_config; + s->insn_write = apci1500_do_write; + s->insn_bits = apci1500_do_bits; + + /* Allocate and Initialise Timer Subdevice Structures */ + s = &dev->subdevices[2]; + s->type = COMEDI_SUBD_TIMER; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = 1; + s->maxdata = 0; + s->len_chanlist = 1; + s->range_table = &range_digital; + s->insn_write = apci1500_timer_write; + s->insn_read = apci1500_timer_read; + s->insn_config = apci1500_timer_config; + s->insn_bits = apci1500_timer_bits; + + apci1500_reset(dev); + + return 0; +} + +static void apci1500_detach(struct comedi_device *dev) +{ + if (dev->iobase) + apci1500_reset(dev); + comedi_pci_detach(dev); } static struct comedi_driver apci1500_driver = { .driver_name = "addi_apci_1500", .module = THIS_MODULE, .auto_attach = apci1500_auto_attach, - .detach = i_ADDI_Detach, + .detach = apci1500_detach, }; static int apci1500_pci_probe(struct pci_dev *dev, diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 55d00fd94c91..d8410415cc90 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -163,7 +163,7 @@ static int apci1516_auto_attach(struct comedi_device *dev, s = &dev->subdevices[1]; if (this_board->do_nchan) { s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = this_board->do_nchan; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index 688b015a834e..6872b69da5db 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -28,16 +28,91 @@ #include "../comedidev.h" #include "comedi_fc.h" -#include "amcc_s5933.h" +#include "addi_tcw.h" #include "addi_watchdog.h" +/* + * PCI BAR 0 + * + * PLD Revision 1.0 I/O Mapping + * 0x00 93C76 EEPROM + * 0x04 - 0x18 Timer 12-Bit + * + * PLD Revision 2.x I/O Mapping + * 0x00 93C76 EEPROM + * 0x04 - 0x14 Digital Input + * 0x18 - 0x25 Digital Output + * 0x28 - 0x44 Watchdog 8-Bit + * 0x48 - 0x64 Timer 12-Bit + */ +#define APCI1564_EEPROM_REG 0x00 +#define APCI1564_EEPROM_VCC_STATUS (1 << 8) +#define APCI1564_EEPROM_TO_REV(x) (((x) >> 4) & 0xf) +#define APCI1564_EEPROM_DI (1 << 3) +#define APCI1564_EEPROM_DO (1 << 2) +#define APCI1564_EEPROM_CS (1 << 1) +#define APCI1564_EEPROM_CLK (1 << 0) +#define APCI1564_REV1_TIMER_IOBASE 0x04 +#define APCI1564_REV2_MAIN_IOBASE 0x04 +#define APCI1564_REV2_TIMER_IOBASE 0x48 + +/* + * PCI BAR 1 + * + * PLD Revision 1.0 I/O Mapping + * 0x00 - 0x10 Digital Input + * 0x14 - 0x20 Digital Output + * 0x24 - 0x3c Watchdog 8-Bit + * + * PLD Revision 2.x I/O Mapping + * 0x00 Counter_0 + * 0x20 Counter_1 + * 0x30 Counter_3 + */ +#define APCI1564_REV1_MAIN_IOBASE 0x00 + +/* + * dev->iobase Register Map + * PLD Revision 1.0 - PCI BAR 1 + 0x00 + * PLD Revision 2.x - PCI BAR 0 + 0x04 + */ +#define APCI1564_DI_REG 0x00 +#define APCI1564_DI_INT_MODE1_REG 0x04 +#define APCI1564_DI_INT_MODE2_REG 0x08 +#define APCI1564_DI_INT_STATUS_REG 0x0c +#define APCI1564_DI_IRQ_REG 0x10 +#define APCI1564_DO_REG 0x14 +#define APCI1564_DO_INT_CTRL_REG 0x18 +#define APCI1564_DO_INT_STATUS_REG 0x1c +#define APCI1564_DO_IRQ_REG 0x20 +#define APCI1564_WDOG_REG 0x24 +#define APCI1564_WDOG_RELOAD_REG 0x28 +#define APCI1564_WDOG_TIMEBASE_REG 0x2c +#define APCI1564_WDOG_CTRL_REG 0x30 +#define APCI1564_WDOG_STATUS_REG 0x34 +#define APCI1564_WDOG_IRQ_REG 0x38 +#define APCI1564_WDOG_WARN_TIMEVAL_REG 0x3c +#define APCI1564_WDOG_WARN_TIMEBASE_REG 0x40 + +/* + * devpriv->timer Register Map (see addi_tcw.h for register/bit defines) + * PLD Revision 1.0 - PCI BAR 0 + 0x04 + * PLD Revision 2.x - PCI BAR 0 + 0x48 + */ + +/* + * devpriv->counters Register Map (see addi_tcw.h for register/bit defines) + * PLD Revision 2.x - PCI BAR 1 + 0x00 + */ +#define APCI1564_COUNTER(x) ((x) * 0x20) + struct apci1564_private { - unsigned int amcc_iobase; /* base of AMCC I/O registers */ + unsigned long eeprom; /* base address of EEPROM register */ + unsigned long timer; /* base address of 12-bit timer */ + unsigned long counters; /* base address of 32-bit counters */ unsigned int mode1; /* riding-edge/high level channels */ unsigned int mode2; /* falling-edge/low level channels */ unsigned int ctrl; /* interrupt mode OR (edge) . AND (level) */ - unsigned char timer_select_mode; - unsigned char mode_select_register; struct task_struct *tsk_current; }; @@ -48,27 +123,30 @@ static int apci1564_reset(struct comedi_device *dev) struct apci1564_private *devpriv = dev->private; /* Disable the input interrupts and reset status register */ - outl(0x0, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG); - inl(devpriv->amcc_iobase + APCI1564_DI_INT_STATUS_REG); - outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE1_REG); - outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE2_REG); + outl(0x0, dev->iobase + APCI1564_DI_IRQ_REG); + inl(dev->iobase + APCI1564_DI_INT_STATUS_REG); + outl(0x0, dev->iobase + APCI1564_DI_INT_MODE1_REG); + outl(0x0, dev->iobase + APCI1564_DI_INT_MODE2_REG); /* Reset the output channels and disable interrupts */ - outl(0x0, devpriv->amcc_iobase + APCI1564_DO_REG); - outl(0x0, devpriv->amcc_iobase + APCI1564_DO_INT_CTRL_REG); + outl(0x0, dev->iobase + APCI1564_DO_REG); + outl(0x0, dev->iobase + APCI1564_DO_INT_CTRL_REG); /* Reset the watchdog registers */ - addi_watchdog_reset(devpriv->amcc_iobase + APCI1564_WDOG_REG); + addi_watchdog_reset(dev->iobase + APCI1564_WDOG_REG); /* Reset the timer registers */ - outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); - outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_RELOAD_REG); + outl(0x0, devpriv->timer + ADDI_TCW_CTRL_REG); + outl(0x0, devpriv->timer + ADDI_TCW_RELOAD_REG); + + if (devpriv->counters) { + unsigned long iobase = devpriv->counters + ADDI_TCW_CTRL_REG; - /* Reset the counter registers */ - outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(APCI1564_COUNTER1)); - outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(APCI1564_COUNTER2)); - outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(APCI1564_COUNTER3)); - outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(APCI1564_COUNTER4)); + /* Reset the counter registers */ + outl(0x0, iobase + APCI1564_COUNTER(0)); + outl(0x0, iobase + APCI1564_COUNTER(1)); + outl(0x0, iobase + APCI1564_COUNTER(2)); + } return 0; } @@ -82,55 +160,52 @@ static irqreturn_t apci1564_interrupt(int irq, void *d) unsigned int ctrl; unsigned int chan; - /* check interrupt is from this device */ - if ((inl(devpriv->amcc_iobase + AMCC_OP_REG_INTCSR) & - INTCSR_INTR_ASSERTED) == 0) - return IRQ_NONE; - - status = inl(devpriv->amcc_iobase + APCI1564_DI_IRQ_REG); + status = inl(dev->iobase + APCI1564_DI_IRQ_REG); if (status & APCI1564_DI_INT_ENABLE) { /* disable the interrupt */ outl(status & APCI1564_DI_INT_DISABLE, - devpriv->amcc_iobase + APCI1564_DI_IRQ_REG); + dev->iobase + APCI1564_DI_IRQ_REG); - s->state = inl(dev->iobase + APCI1564_DI_INT_STATUS_REG) - & 0xffff; - comedi_buf_put(s, s->state); - s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; - comedi_event(dev, s); + s->state = inl(dev->iobase + APCI1564_DI_INT_STATUS_REG) & + 0xffff; + comedi_buf_write_samples(s, &s->state, 1); + comedi_handle_events(dev, s); /* enable the interrupt */ - outl(status, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG); + outl(status, dev->iobase + APCI1564_DI_IRQ_REG); } - status = inl(devpriv->amcc_iobase + APCI1564_TIMER_IRQ_REG); + status = inl(devpriv->timer + ADDI_TCW_IRQ_REG); if (status & 0x01) { /* Disable Timer Interrupt */ - ctrl = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); - outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); + ctrl = inl(devpriv->timer + ADDI_TCW_CTRL_REG); + outl(0x0, devpriv->timer + ADDI_TCW_CTRL_REG); /* Send a signal to from kernel to user space */ send_sig(SIGIO, devpriv->tsk_current, 0); /* Enable Timer Interrupt */ - outl(ctrl, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); + outl(ctrl, devpriv->timer + ADDI_TCW_CTRL_REG); } - for (chan = 0; chan < 4; chan++) { - status = inl(dev->iobase + APCI1564_COUNTER_IRQ_REG(chan)); - if (status & 0x01) { - /* Disable Counter Interrupt */ - ctrl = inl(dev->iobase + - APCI1564_COUNTER_CTRL_REG(chan)); - outl(0x0, dev->iobase + - APCI1564_COUNTER_CTRL_REG(chan)); - - /* Send a signal to from kernel to user space */ - send_sig(SIGIO, devpriv->tsk_current, 0); - - /* Enable Counter Interrupt */ - outl(ctrl, dev->iobase + - APCI1564_COUNTER_CTRL_REG(chan)); + if (devpriv->counters) { + for (chan = 0; chan < 4; chan++) { + unsigned long iobase; + + iobase = devpriv->counters + APCI1564_COUNTER(chan); + + status = inl(iobase + ADDI_TCW_IRQ_REG); + if (status & 0x01) { + /* Disable Counter Interrupt */ + ctrl = inl(iobase + ADDI_TCW_CTRL_REG); + outl(0x0, iobase + ADDI_TCW_CTRL_REG); + + /* Send a signal to from kernel to user space */ + send_sig(SIGIO, devpriv->tsk_current, 0); + + /* Enable Counter Interrupt */ + outl(ctrl, iobase + ADDI_TCW_CTRL_REG); + } } } @@ -142,9 +217,7 @@ static int apci1564_di_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct apci1564_private *devpriv = dev->private; - - data[1] = inl(devpriv->amcc_iobase + APCI1564_DI_REG); + data[1] = inl(dev->iobase + APCI1564_DI_REG); return insn->n; } @@ -154,12 +227,10 @@ static int apci1564_do_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct apci1564_private *devpriv = dev->private; - - s->state = inl(devpriv->amcc_iobase + APCI1564_DO_REG); + s->state = inl(dev->iobase + APCI1564_DO_REG); if (comedi_dio_update_state(s, data)) - outl(s->state, devpriv->amcc_iobase + APCI1564_DO_REG); + outl(s->state, dev->iobase + APCI1564_DO_REG); data[1] = s->state; @@ -171,9 +242,7 @@ static int apci1564_diag_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct apci1564_private *devpriv = dev->private; - - data[1] = inl(devpriv->amcc_iobase + APCI1564_DO_INT_STATUS_REG) & 3; + data[1] = inl(dev->iobase + APCI1564_DO_INT_STATUS_REG) & 3; return insn->n; } @@ -227,10 +296,10 @@ static int apci1564_cos_insn_config(struct comedi_device *dev, devpriv->ctrl = 0; devpriv->mode1 = 0; devpriv->mode2 = 0; - outl(0x0, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG); - inl(devpriv->amcc_iobase + APCI1564_DI_INT_STATUS_REG); - outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE1_REG); - outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE2_REG); + outl(0x0, dev->iobase + APCI1564_DI_IRQ_REG); + inl(dev->iobase + APCI1564_DI_INT_STATUS_REG); + outl(0x0, dev->iobase + APCI1564_DI_INT_MODE1_REG); + outl(0x0, dev->iobase + APCI1564_DI_INT_MODE2_REG); break; case COMEDI_DIGITAL_TRIG_ENABLE_EDGES: if (devpriv->ctrl != (APCI1564_DI_INT_ENABLE | @@ -342,9 +411,9 @@ static int apci1564_cos_cmd(struct comedi_device *dev, return -EINVAL; } - outl(devpriv->mode1, devpriv->amcc_iobase + APCI1564_DI_INT_MODE1_REG); - outl(devpriv->mode2, devpriv->amcc_iobase + APCI1564_DI_INT_MODE2_REG); - outl(devpriv->ctrl, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG); + outl(devpriv->mode1, dev->iobase + APCI1564_DI_INT_MODE1_REG); + outl(devpriv->mode2, dev->iobase + APCI1564_DI_INT_MODE2_REG); + outl(devpriv->ctrl, dev->iobase + APCI1564_DI_IRQ_REG); return 0; } @@ -352,12 +421,10 @@ static int apci1564_cos_cmd(struct comedi_device *dev, static int apci1564_cos_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { - struct apci1564_private *devpriv = dev->private; - - outl(0x0, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG); - inl(devpriv->amcc_iobase + APCI1564_DI_INT_STATUS_REG); - outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE1_REG); - outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE2_REG); + outl(0x0, dev->iobase + APCI1564_DI_IRQ_REG); + inl(dev->iobase + APCI1564_DI_INT_STATUS_REG); + outl(0x0, dev->iobase + APCI1564_DI_INT_MODE1_REG); + outl(0x0, dev->iobase + APCI1564_DI_INT_MODE2_REG); return 0; } @@ -368,6 +435,7 @@ static int apci1564_auto_attach(struct comedi_device *dev, struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct apci1564_private *devpriv; struct comedi_subdevice *s; + unsigned int val; int ret; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); @@ -378,8 +446,20 @@ static int apci1564_auto_attach(struct comedi_device *dev, if (ret) return ret; - dev->iobase = pci_resource_start(pcidev, 1); - devpriv->amcc_iobase = pci_resource_start(pcidev, 0); + /* read the EEPROM register and check the I/O map revision */ + devpriv->eeprom = pci_resource_start(pcidev, 0); + val = inl(devpriv->eeprom + APCI1564_EEPROM_REG); + if (APCI1564_EEPROM_TO_REV(val) == 0) { + /* PLD Revision 1.0 I/O Mapping */ + dev->iobase = pci_resource_start(pcidev, 1) + + APCI1564_REV1_MAIN_IOBASE; + devpriv->timer = devpriv->eeprom + APCI1564_REV1_TIMER_IOBASE; + } else { + /* PLD Revision 2.x I/O Mapping */ + dev->iobase = devpriv->eeprom + APCI1564_REV2_MAIN_IOBASE; + devpriv->timer = devpriv->eeprom + APCI1564_REV2_TIMER_IOBASE; + devpriv->counters = pci_resource_start(pcidev, 1); + } apci1564_reset(dev); @@ -390,7 +470,7 @@ static int apci1564_auto_attach(struct comedi_device *dev, dev->irq = pcidev->irq; } - ret = comedi_alloc_subdevices(dev, 6); + ret = comedi_alloc_subdevices(dev, 7); if (ret) return ret; @@ -406,7 +486,7 @@ static int apci1564_auto_attach(struct comedi_device *dev, /* Allocate and Initialise DO Subdevice Structures */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 32; s->maxdata = 1; s->range_table = &range_digital; @@ -431,26 +511,40 @@ static int apci1564_auto_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } - /* Allocate and Initialise Timer Subdevice Structures */ + /* Timer subdevice */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; s->n_chan = 1; - s->maxdata = 0; - s->len_chanlist = 1; + s->maxdata = 0x0fff; s->range_table = &range_digital; - s->insn_write = apci1564_timer_write; - s->insn_read = apci1564_timer_read; - s->insn_config = apci1564_timer_config; + s->insn_config = apci1564_timer_insn_config; + s->insn_write = apci1564_timer_insn_write; + s->insn_read = apci1564_timer_insn_read; - /* Initialize the watchdog subdevice */ + /* Counter subdevice */ s = &dev->subdevices[4]; - ret = addi_watchdog_init(s, devpriv->amcc_iobase + APCI1564_WDOG_REG); + if (devpriv->counters) { + s->type = COMEDI_SUBD_COUNTER; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE | SDF_LSAMPL; + s->n_chan = 3; + s->maxdata = 0xffffffff; + s->range_table = &range_digital; + s->insn_config = apci1564_counter_insn_config; + s->insn_write = apci1564_counter_insn_write; + s->insn_read = apci1564_counter_insn_read; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* Initialize the watchdog subdevice */ + s = &dev->subdevices[5]; + ret = addi_watchdog_init(s, dev->iobase + APCI1564_WDOG_REG); if (ret) return ret; /* Initialize the diagnostic status subdevice */ - s = &dev->subdevices[5]; + s = &dev->subdevices[6]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 2; diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index 4162e2dc2860..a1248dab369f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -140,7 +140,7 @@ static int apci16xx_auto_attach(struct comedi_device *dev, for (i = 0; i < n_subdevs; i++) { s = &dev->subdevices[i]; s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_WRITEABLE | SDF_READABLE; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; s->n_chan = ((i * 32) < board->n_chan) ? 32 : last; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index aea3da325359..eebf4f151b39 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -47,7 +47,6 @@ struct apci2032_int_private { spinlock_t spinlock; - unsigned int stop_count; bool active; unsigned char enabled_isns; }; @@ -148,7 +147,6 @@ static int apci2032_int_cmd(struct comedi_device *dev, spin_lock_irqsave(&subpriv->spinlock, flags); subpriv->enabled_isns = enabled_isns; - subpriv->stop_count = cmd->stop_arg; subpriv->active = true; outl(enabled_isns, dev->iobase + APCI2032_INT_CTRL_REG); @@ -178,7 +176,6 @@ static irqreturn_t apci2032_interrupt(int irq, void *d) struct comedi_cmd *cmd = &s->async->cmd; struct apci2032_int_private *subpriv; unsigned int val; - bool do_event = false; if (!dev->attached) return IRQ_NONE; @@ -212,27 +209,16 @@ static irqreturn_t apci2032_interrupt(int irq, void *d) bits |= (1 << i); } - if (comedi_buf_put(s, bits)) { - s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; - if (cmd->stop_src == TRIG_COUNT && - subpriv->stop_count > 0) { - subpriv->stop_count--; - if (subpriv->stop_count == 0) { - /* end of acquisition */ - s->async->events |= COMEDI_CB_EOA; - apci2032_int_stop(dev, s); - } - } - } else { - apci2032_int_stop(dev, s); - s->async->events |= COMEDI_CB_OVERFLOW; - } - do_event = true; + comedi_buf_write_samples(s, &bits, 1); + + if (cmd->stop_src == TRIG_COUNT && + s->async->scans_done >= cmd->stop_arg) + s->async->events |= COMEDI_CB_EOA; } spin_unlock(&subpriv->spinlock); - if (do_event) - comedi_event(dev, s); + + comedi_handle_events(dev, s); return IRQ_HANDLED; } @@ -274,7 +260,7 @@ static int apci2032_auto_attach(struct comedi_device *dev, /* Initialize the digital output subdevice */ s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 32; s->maxdata = 1; s->range_table = &range_digital; @@ -303,7 +289,7 @@ static int apci2032_auto_attach(struct comedi_device *dev, return -ENOMEM; spin_lock_init(&subpriv->spinlock); s->private = subpriv; - s->subdev_flags = SDF_READABLE | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_CMD_READ | SDF_PACKED; s->len_chanlist = 2; s->do_cmdtest = apci2032_int_cmdtest; s->do_cmd = apci2032_int_cmd; diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index 51ab1f937bae..1f9d13661ac9 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -98,7 +98,7 @@ static int apci2200_auto_attach(struct comedi_device *dev, /* Initialize the digital output subdevice */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index ba71e24a56fd..c65f9407fd06 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -1,70 +1,993 @@ +/* + * addi_apci_3120.c + * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. + * + * ADDI-DATA GmbH + * Dieselstrasse 3 + * D-77833 Ottersweier + * Tel: +19(0)7223/9493-0 + * Fax: +49(0)7223/9493-92 + * http://www.addi-data.com + * info@addi-data.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + #include <linux/module.h> #include <linux/pci.h> +#include <linux/interrupt.h> #include "../comedidev.h" #include "comedi_fc.h" #include "amcc_s5933.h" -#include "addi-data/addi_common.h" +/* + * PCI BAR 0 register map (devpriv->amcc) + * see amcc_s5933.h for register and bit defines + */ +#define APCI3120_FIFO_ADVANCE_ON_BYTE_2 (1 << 29) + +/* + * PCI BAR 1 register map (dev->iobase) + */ +#define APCI3120_AI_FIFO_REG 0x00 +#define APCI3120_CTRL_REG 0x00 +#define APCI3120_CTRL_EXT_TRIG (1 << 15) +#define APCI3120_CTRL_GATE(x) (1 << (12 + (x))) +#define APCI3120_CTRL_PR(x) (((x) & 0xf) << 8) +#define APCI3120_CTRL_PA(x) (((x) & 0xf) << 0) +#define APCI3120_AI_SOFTTRIG_REG 0x02 +#define APCI3120_STATUS_REG 0x02 +#define APCI3120_STATUS_EOC_INT (1 << 15) +#define APCI3120_STATUS_AMCC_INT (1 << 14) +#define APCI3120_STATUS_EOS_INT (1 << 13) +#define APCI3120_STATUS_TIMER2_INT (1 << 12) +#define APCI3120_STATUS_INT_MASK (0xf << 12) +#define APCI3120_STATUS_TO_DI_BITS(x) (((x) >> 8) & 0xf) +#define APCI3120_STATUS_TO_VERSION(x) (((x) >> 4) & 0xf) +#define APCI3120_STATUS_FIFO_FULL (1 << 2) +#define APCI3120_STATUS_FIFO_EMPTY (1 << 1) +#define APCI3120_STATUS_DA_READY (1 << 0) +#define APCI3120_TIMER_REG 0x04 +#define APCI3120_CHANLIST_REG 0x06 +#define APCI3120_CHANLIST_INDEX(x) (((x) & 0xf) << 8) +#define APCI3120_CHANLIST_UNIPOLAR (1 << 7) +#define APCI3120_CHANLIST_GAIN(x) (((x) & 0x3) << 4) +#define APCI3120_CHANLIST_MUX(x) (((x) & 0xf) << 0) +#define APCI3120_AO_REG(x) (0x08 + (((x) / 4) * 2)) +#define APCI3120_AO_MUX(x) (((x) & 0x3) << 14) +#define APCI3120_AO_DATA(x) ((x) << 0) +#define APCI3120_TIMER_MODE_REG 0x0c +#define APCI3120_TIMER_MODE(_t, _m) ((_m) << ((_t) * 2)) +#define APCI3120_TIMER_MODE0 0 /* I8254_MODE0 */ +#define APCI3120_TIMER_MODE2 1 /* I8254_MODE2 */ +#define APCI3120_TIMER_MODE4 2 /* I8254_MODE4 */ +#define APCI3120_TIMER_MODE5 3 /* I8254_MODE5 */ +#define APCI3120_TIMER_MODE_MASK(_t) (3 << ((_t) * 2)) +#define APCI3120_CTR0_REG 0x0d +#define APCI3120_CTR0_DO_BITS(x) ((x) << 4) +#define APCI3120_CTR0_TIMER_SEL(x) ((x) << 0) +#define APCI3120_MODE_REG 0x0e +#define APCI3120_MODE_TIMER2_CLK_OSC (0 << 6) +#define APCI3120_MODE_TIMER2_CLK_OUT1 (1 << 6) +#define APCI3120_MODE_TIMER2_CLK_EOC (2 << 6) +#define APCI3120_MODE_TIMER2_CLK_EOS (3 << 6) +#define APCI3120_MODE_TIMER2_CLK_MASK (3 << 6) +#define APCI3120_MODE_TIMER2_AS_TIMER (0 << 4) +#define APCI3120_MODE_TIMER2_AS_COUNTER (1 << 4) +#define APCI3120_MODE_TIMER2_AS_WDOG (2 << 4) +#define APCI3120_MODE_TIMER2_AS_MASK (3 << 4) /* sets AS_TIMER */ +#define APCI3120_MODE_SCAN_ENA (1 << 3) +#define APCI3120_MODE_TIMER2_IRQ_ENA (1 << 2) +#define APCI3120_MODE_EOS_IRQ_ENA (1 << 1) +#define APCI3120_MODE_EOC_IRQ_ENA (1 << 0) + +/* + * PCI BAR 2 register map (devpriv->addon) + */ +#define APCI3120_ADDON_ADDR_REG 0x00 +#define APCI3120_ADDON_DATA_REG 0x02 +#define APCI3120_ADDON_CTRL_REG 0x04 +#define APCI3120_ADDON_CTRL_AMWEN_ENA (1 << 1) +#define APCI3120_ADDON_CTRL_A2P_FIFO_ENA (1 << 0) -#include "addi-data/hwdrv_apci3120.c" +/* + * Board revisions + */ +#define APCI3120_REVA 0xa +#define APCI3120_REVB 0xb +#define APCI3120_REVA_OSC_BASE 70 /* 70ns = 14.29MHz */ +#define APCI3120_REVB_OSC_BASE 50 /* 50ns = 20MHz */ + +static const struct comedi_lrange apci3120_ai_range = { + 8, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2), + BIP_RANGE(1), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2), + UNI_RANGE(1) + } +}; enum apci3120_boardid { BOARD_APCI3120, BOARD_APCI3001, }; -static const struct addi_board apci3120_boardtypes[] = { +struct apci3120_board { + const char *name; + unsigned int ai_is_16bit:1; + unsigned int has_ao:1; +}; + +static const struct apci3120_board apci3120_boardtypes[] = { [BOARD_APCI3120] = { - .pc_DriverName = "apci3120", - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_NbrAoChannel = 8, - .i_AiMaxdata = 0xffff, - .i_AoMaxdata = 0x3fff, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 0x0f, - .interrupt = apci3120_interrupt, + .name = "apci3120", + .ai_is_16bit = 1, + .has_ao = 1, }, [BOARD_APCI3001] = { - .pc_DriverName = "apci3001", - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_AiMaxdata = 0xfff, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 0x0f, - .interrupt = apci3120_interrupt, + .name = "apci3001", }, }; -static irqreturn_t v_ADDI_Interrupt(int irq, void *d) +struct apci3120_dmabuf { + unsigned short *virt; + dma_addr_t hw; + unsigned int size; + unsigned int use_size; +}; + +struct apci3120_private { + unsigned long amcc; + unsigned long addon; + unsigned int osc_base; + unsigned int use_dma:1; + unsigned int use_double_buffer:1; + unsigned int cur_dmabuf:1; + struct apci3120_dmabuf dmabuf[2]; + unsigned char do_bits; + unsigned char timer_mode; + unsigned char mode; + unsigned short ctrl; +}; + +static void apci3120_addon_write(struct comedi_device *dev, + unsigned int val, unsigned int reg) +{ + struct apci3120_private *devpriv = dev->private; + + /* 16-bit interface for AMCC add-on registers */ + + outw(reg, devpriv->addon + APCI3120_ADDON_ADDR_REG); + outw(val & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG); + + outw(reg + 2, devpriv->addon + APCI3120_ADDON_ADDR_REG); + outw((val >> 16) & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG); +} + +static void apci3120_init_dma(struct comedi_device *dev, + struct apci3120_dmabuf *dmabuf) +{ + struct apci3120_private *devpriv = dev->private; + + /* AMCC - enable transfer count and reset A2P FIFO */ + outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, + devpriv->amcc + AMCC_OP_REG_AGCSTS); + + /* Add-On - enable transfer count and reset A2P FIFO */ + apci3120_addon_write(dev, AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, + AMCC_OP_REG_AGCSTS); + + /* AMCC - enable transfers and reset A2P flags */ + outl(RESET_A2P_FLAGS | EN_A2P_TRANSFERS, + devpriv->amcc + AMCC_OP_REG_MCSR); + + /* Add-On - DMA start address */ + apci3120_addon_write(dev, dmabuf->hw, AMCC_OP_REG_AMWAR); + + /* Add-On - Number of acquisitions */ + apci3120_addon_write(dev, dmabuf->use_size, AMCC_OP_REG_AMWTC); + + /* AMCC - enable write complete (DMA) and set FIFO advance */ + outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | AINT_WRITE_COMPL, + devpriv->amcc + AMCC_OP_REG_INTCSR); + + /* Add-On - enable DMA */ + outw(APCI3120_ADDON_CTRL_AMWEN_ENA | APCI3120_ADDON_CTRL_A2P_FIFO_ENA, + devpriv->addon + APCI3120_ADDON_CTRL_REG); +} + +static void apci3120_setup_dma(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct apci3120_private *devpriv = dev->private; + struct comedi_cmd *cmd = &s->async->cmd; + struct apci3120_dmabuf *dmabuf0 = &devpriv->dmabuf[0]; + struct apci3120_dmabuf *dmabuf1 = &devpriv->dmabuf[1]; + unsigned int dmalen0 = dmabuf0->size; + unsigned int dmalen1 = dmabuf1->size; + unsigned int scan_bytes; + + scan_bytes = comedi_samples_to_bytes(s, cmd->scan_end_arg); + + if (cmd->stop_src == TRIG_COUNT) { + /* + * Must we fill full first buffer? And must we fill + * full second buffer when first is once filled? + */ + if (dmalen0 > (cmd->stop_arg * scan_bytes)) + dmalen0 = cmd->stop_arg * scan_bytes; + else if (dmalen1 > (cmd->stop_arg * scan_bytes - dmalen0)) + dmalen1 = cmd->stop_arg * scan_bytes - dmalen0; + } + + if (cmd->flags & CMDF_WAKE_EOS) { + /* don't we want wake up every scan? */ + if (dmalen0 > scan_bytes) { + dmalen0 = scan_bytes; + if (cmd->scan_end_arg & 1) + dmalen0 += 2; + } + if (dmalen1 > scan_bytes) { + dmalen1 = scan_bytes; + if (cmd->scan_end_arg & 1) + dmalen1 -= 2; + if (dmalen1 < 4) + dmalen1 = 4; + } + } else { + /* isn't output buff smaller that our DMA buff? */ + if (dmalen0 > s->async->prealloc_bufsz) + dmalen0 = s->async->prealloc_bufsz; + if (dmalen1 > s->async->prealloc_bufsz) + dmalen1 = s->async->prealloc_bufsz; + } + dmabuf0->use_size = dmalen0; + dmabuf1->use_size = dmalen1; + + apci3120_init_dma(dev, dmabuf0); +} + +/* + * There are three timers on the board. They all use the same base + * clock with a fixed prescaler for each timer. The base clock used + * depends on the board version and type. + * + * APCI-3120 Rev A boards OSC = 14.29MHz base clock (~70ns) + * APCI-3120 Rev B boards OSC = 20MHz base clock (50ns) + * APCI-3001 boards OSC = 20MHz base clock (50ns) + * + * The prescalers for each timer are: + * Timer 0 CLK = OSC/10 + * Timer 1 CLK = OSC/1000 + * Timer 2 CLK = OSC/1000 + */ +static unsigned int apci3120_ns_to_timer(struct comedi_device *dev, + unsigned int timer, + unsigned int ns, + unsigned int flags) +{ + struct apci3120_private *devpriv = dev->private; + unsigned int prescale = (timer == 0) ? 10 : 1000; + unsigned int timer_base = devpriv->osc_base * prescale; + unsigned int divisor; + + switch (flags & CMDF_ROUND_MASK) { + case CMDF_ROUND_UP: + divisor = DIV_ROUND_UP(ns, timer_base); + break; + case CMDF_ROUND_DOWN: + divisor = ns / timer_base; + break; + case CMDF_ROUND_NEAREST: + default: + divisor = DIV_ROUND_CLOSEST(ns, timer_base); + break; + } + + if (timer == 2) { + /* timer 2 is 24-bits */ + if (divisor > 0x00ffffff) + divisor = 0x00ffffff; + } else { + /* timers 0 and 1 are 16-bits */ + if (divisor > 0xffff) + divisor = 0xffff; + } + /* the timers require a minimum divisor of 2 */ + if (divisor < 2) + divisor = 2; + + return divisor; +} + +static void apci3120_clr_timer2_interrupt(struct comedi_device *dev) +{ + /* a dummy read of APCI3120_CTR0_REG clears the timer 2 interrupt */ + inb(dev->iobase + APCI3120_CTR0_REG); +} + +static void apci3120_timer_write(struct comedi_device *dev, + unsigned int timer, unsigned int val) +{ + struct apci3120_private *devpriv = dev->private; + + /* write 16-bit value to timer (lower 16-bits of timer 2) */ + outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) | + APCI3120_CTR0_TIMER_SEL(timer), + dev->iobase + APCI3120_CTR0_REG); + outw(val & 0xffff, dev->iobase + APCI3120_TIMER_REG); + + if (timer == 2) { + /* write upper 16-bits to timer 2 */ + outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) | + APCI3120_CTR0_TIMER_SEL(timer + 1), + dev->iobase + APCI3120_CTR0_REG); + outw((val >> 16) & 0xffff, dev->iobase + APCI3120_TIMER_REG); + } +} + +static unsigned int apci3120_timer_read(struct comedi_device *dev, + unsigned int timer) +{ + struct apci3120_private *devpriv = dev->private; + unsigned int val; + + /* read 16-bit value from timer (lower 16-bits of timer 2) */ + outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) | + APCI3120_CTR0_TIMER_SEL(timer), + dev->iobase + APCI3120_CTR0_REG); + val = inw(dev->iobase + APCI3120_TIMER_REG); + + if (timer == 2) { + /* read upper 16-bits from timer 2 */ + outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) | + APCI3120_CTR0_TIMER_SEL(timer + 1), + dev->iobase + APCI3120_CTR0_REG); + val |= (inw(dev->iobase + APCI3120_TIMER_REG) << 16); + } + + return val; +} + +static void apci3120_timer_set_mode(struct comedi_device *dev, + unsigned int timer, unsigned int mode) +{ + struct apci3120_private *devpriv = dev->private; + + devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(timer); + devpriv->timer_mode |= APCI3120_TIMER_MODE(timer, mode); + outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_MODE_REG); +} + +static void apci3120_timer_enable(struct comedi_device *dev, + unsigned int timer, bool enable) +{ + struct apci3120_private *devpriv = dev->private; + + if (enable) + devpriv->ctrl |= APCI3120_CTRL_GATE(timer); + else + devpriv->ctrl &= ~APCI3120_CTRL_GATE(timer); + outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); +} + +static void apci3120_exttrig_enable(struct comedi_device *dev, bool enable) +{ + struct apci3120_private *devpriv = dev->private; + + if (enable) + devpriv->ctrl |= APCI3120_CTRL_EXT_TRIG; + else + devpriv->ctrl &= ~APCI3120_CTRL_EXT_TRIG; + outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); +} + +static void apci3120_set_chanlist(struct comedi_device *dev, + struct comedi_subdevice *s, + int n_chan, unsigned int *chanlist) +{ + struct apci3120_private *devpriv = dev->private; + int i; + + /* set chanlist for scan */ + for (i = 0; i < n_chan; i++) { + unsigned int chan = CR_CHAN(chanlist[i]); + unsigned int range = CR_RANGE(chanlist[i]); + unsigned int val; + + val = APCI3120_CHANLIST_MUX(chan) | + APCI3120_CHANLIST_GAIN(range) | + APCI3120_CHANLIST_INDEX(i); + + if (comedi_range_is_unipolar(s, range)) + val |= APCI3120_CHANLIST_UNIPOLAR; + + outw(val, dev->iobase + APCI3120_CHANLIST_REG); + } + + /* a dummy read of APCI3120_TIMER_MODE_REG resets the ai FIFO */ + inw(dev->iobase + APCI3120_TIMER_MODE_REG); + + /* set scan length (PR) and scan start (PA) */ + devpriv->ctrl = APCI3120_CTRL_PR(n_chan - 1) | APCI3120_CTRL_PA(0); + outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); + + /* enable chanlist scanning if necessary */ + if (n_chan > 1) + devpriv->mode |= APCI3120_MODE_SCAN_ENA; +} + +static void apci3120_interrupt_dma(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct apci3120_private *devpriv = dev->private; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; + struct apci3120_dmabuf *dmabuf; + unsigned int nbytes; + unsigned int nsamples; + + dmabuf = &devpriv->dmabuf[devpriv->cur_dmabuf]; + + nbytes = dmabuf->use_size - inl(devpriv->amcc + AMCC_OP_REG_MWTC); + + if (nbytes < dmabuf->use_size) + dev_err(dev->class_dev, "Interrupted DMA transfer!\n"); + if (nbytes & 1) { + dev_err(dev->class_dev, "Odd count of bytes in DMA ring!\n"); + async->events |= COMEDI_CB_ERROR; + return; + } + + nsamples = comedi_bytes_to_samples(s, nbytes); + if (nsamples) { + comedi_buf_write_samples(s, dmabuf->virt, nsamples); + + if (!(cmd->flags & CMDF_WAKE_EOS)) + async->events |= COMEDI_CB_EOS; + } + + if ((async->events & COMEDI_CB_CANCEL_MASK) || + (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)) + return; + + if (devpriv->use_double_buffer) { + /* switch DMA buffers for next interrupt */ + devpriv->cur_dmabuf = !devpriv->cur_dmabuf; + dmabuf = &devpriv->dmabuf[devpriv->cur_dmabuf]; + apci3120_init_dma(dev, dmabuf); + } else { + /* restart DMA if not using double buffering */ + apci3120_init_dma(dev, dmabuf); + } +} + +static irqreturn_t apci3120_interrupt(int irq, void *d) { struct comedi_device *dev = d; - const struct addi_board *this_board = dev->board_ptr; + struct apci3120_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->read_subdev; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; + unsigned int status; + unsigned int int_amcc; + + status = inw(dev->iobase + APCI3120_STATUS_REG); + int_amcc = inl(devpriv->amcc + AMCC_OP_REG_INTCSR); + + if (!(status & APCI3120_STATUS_INT_MASK) && + !(int_amcc & ANY_S593X_INT)) { + dev_err(dev->class_dev, "IRQ from unknown source\n"); + return IRQ_NONE; + } + + outl(int_amcc | AINT_INT_MASK, devpriv->amcc + AMCC_OP_REG_INTCSR); - this_board->interrupt(irq, d); - return IRQ_RETVAL(1); + if (devpriv->ctrl & APCI3120_CTRL_EXT_TRIG) + apci3120_exttrig_enable(dev, false); + + if (int_amcc & MASTER_ABORT_INT) + dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n"); + if (int_amcc & TARGET_ABORT_INT) + dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n"); + + if ((status & APCI3120_STATUS_EOC_INT) == 0 && + (devpriv->mode & APCI3120_MODE_EOC_IRQ_ENA)) { + /* nothing to do... EOC mode is not currently used */ + } + + if ((status & APCI3120_STATUS_EOS_INT) && + (devpriv->mode & APCI3120_MODE_EOS_IRQ_ENA)) { + unsigned short val; + int i; + + for (i = 0; i < cmd->chanlist_len; i++) { + val = inw(dev->iobase + APCI3120_AI_FIFO_REG); + comedi_buf_write_samples(s, &val, 1); + } + + devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); + } + + if (status & APCI3120_STATUS_TIMER2_INT) { + /* + * for safety... + * timer2 interrupts are not enabled in the driver + */ + apci3120_clr_timer2_interrupt(dev); + } + + if (status & APCI3120_STATUS_AMCC_INT) { + /* AMCC- Clear write complete interrupt (DMA) */ + outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR); + + /* do some data transfer */ + apci3120_interrupt_dma(dev, s); + } + + if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg) + async->events |= COMEDI_CB_EOA; + + comedi_handle_events(dev, s); + + return IRQ_HANDLED; +} + +static int apci3120_ai_cmd(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct apci3120_private *devpriv = dev->private; + struct comedi_cmd *cmd = &s->async->cmd; + unsigned int divisor; + + /* set default mode bits */ + devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC | + APCI3120_MODE_TIMER2_AS_TIMER; + + /* AMCC- Clear write complete interrupt (DMA) */ + outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR); + + devpriv->cur_dmabuf = 0; + + /* load chanlist for command scan */ + apci3120_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist); + + if (cmd->start_src == TRIG_EXT) + apci3120_exttrig_enable(dev, true); + + if (cmd->scan_begin_src == TRIG_TIMER) { + /* + * Timer 1 is used in MODE2 (rate generator) to set the + * start time for each scan. + */ + divisor = apci3120_ns_to_timer(dev, 1, cmd->scan_begin_arg, + cmd->flags); + apci3120_timer_set_mode(dev, 1, APCI3120_TIMER_MODE2); + apci3120_timer_write(dev, 1, divisor); + } + + /* + * Timer 0 is used in MODE2 (rate generator) to set the conversion + * time for each acquisition. + */ + divisor = apci3120_ns_to_timer(dev, 0, cmd->convert_arg, cmd->flags); + apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2); + apci3120_timer_write(dev, 0, divisor); + + if (devpriv->use_dma) + apci3120_setup_dma(dev, s); + else + devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; + + /* set mode to enable acquisition */ + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); + + if (cmd->scan_begin_src == TRIG_TIMER) + apci3120_timer_enable(dev, 1, true); + apci3120_timer_enable(dev, 0, true); + + return 0; +} + +static int apci3120_ai_cmdtest(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_cmd *cmd) +{ + unsigned int arg; + int err = 0; + + /* Step 1 : check if triggers are trivially valid */ + + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_TIMER | TRIG_FOLLOW); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); + + if (err) + return 1; + + /* Step 2a : make sure trigger sources are unique */ + + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ + + if (err) + return 2; + + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + + if (cmd->scan_begin_src == TRIG_TIMER) /* Test Delay timing */ + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 100000); + + /* minimum conversion time per sample is 10us */ + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 10000); + + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); + + if (err) + return 3; + + /* Step 4: fix up any arguments */ + + if (cmd->scan_begin_src == TRIG_TIMER) { + /* scan begin must be larger than the scan time */ + arg = cmd->convert_arg * cmd->scan_end_arg; + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, arg); + } + + if (err) + return 4; + + /* Step 5: check channel list if it exists */ + + return 0; +} + +static int apci3120_cancel(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct apci3120_private *devpriv = dev->private; + + /* Add-On - disable DMA */ + outw(0, devpriv->addon + 4); + + /* Add-On - disable bus master */ + apci3120_addon_write(dev, 0, AMCC_OP_REG_AGCSTS); + + /* AMCC - disable bus master */ + outl(0, devpriv->amcc + AMCC_OP_REG_MCSR); + + /* disable all counters, ext trigger, and reset scan */ + devpriv->ctrl = 0; + outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); + + /* DISABLE_ALL_INTERRUPT */ + devpriv->mode = 0; + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); + + inw(dev->iobase + APCI3120_STATUS_REG); + devpriv->cur_dmabuf = 0; + + return 0; +} + +static int apci3120_ai_eoc(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned long context) +{ + unsigned int status; + + status = inw(dev->iobase + APCI3120_STATUS_REG); + if ((status & APCI3120_STATUS_EOC_INT) == 0) + return 0; + return -EBUSY; +} + +static int apci3120_ai_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct apci3120_private *devpriv = dev->private; + unsigned int divisor; + int ret; + int i; + + /* set mode for A/D conversions by software trigger with timer 0 */ + devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC | + APCI3120_MODE_TIMER2_AS_TIMER; + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); + + /* load chanlist for single channel scan */ + apci3120_set_chanlist(dev, s, 1, &insn->chanspec); + + /* + * Timer 0 is used in MODE4 (software triggered strobe) to set the + * conversion time for each acquisition. Each conversion is triggered + * when the divisor is written to the timer, The conversion is done + * when the EOC bit in the status register is '0'. + */ + apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE4); + apci3120_timer_enable(dev, 0, true); + + /* fixed conversion time of 10 us */ + divisor = apci3120_ns_to_timer(dev, 0, 10000, CMDF_ROUND_NEAREST); + + for (i = 0; i < insn->n; i++) { + /* trigger conversion */ + apci3120_timer_write(dev, 0, divisor); + + ret = comedi_timeout(dev, s, insn, apci3120_ai_eoc, 0); + if (ret) + return ret; + + data[i] = inw(dev->iobase + APCI3120_AI_FIFO_REG); + } + + return insn->n; +} + +static int apci3120_ao_ready(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned long context) +{ + unsigned int status; + + status = inw(dev->iobase + APCI3120_STATUS_REG); + if (status & APCI3120_STATUS_DA_READY) + return 0; + return -EBUSY; +} + +static int apci3120_ao_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned int chan = CR_CHAN(insn->chanspec); + int i; + + for (i = 0; i < insn->n; i++) { + unsigned int val = data[i]; + int ret; + + ret = comedi_timeout(dev, s, insn, apci3120_ao_ready, 0); + if (ret) + return ret; + + outw(APCI3120_AO_MUX(chan) | APCI3120_AO_DATA(val), + dev->iobase + APCI3120_AO_REG(chan)); + + s->readback[chan] = val; + } + + return insn->n; +} + +static int apci3120_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned int status; + + status = inw(dev->iobase + APCI3120_STATUS_REG); + data[1] = APCI3120_STATUS_TO_DI_BITS(status); + + return insn->n; +} + +static int apci3120_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct apci3120_private *devpriv = dev->private; + + if (comedi_dio_update_state(s, data)) { + devpriv->do_bits = s->state; + outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits), + dev->iobase + APCI3120_CTR0_REG); + } + + data[1] = s->state; + + return insn->n; +} + +static int apci3120_timer_insn_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct apci3120_private *devpriv = dev->private; + unsigned int divisor; + unsigned int status; + unsigned int mode; + unsigned int timer_mode; + + switch (data[0]) { + case INSN_CONFIG_ARM: + apci3120_clr_timer2_interrupt(dev); + divisor = apci3120_ns_to_timer(dev, 2, data[1], + CMDF_ROUND_DOWN); + apci3120_timer_write(dev, 2, divisor); + apci3120_timer_enable(dev, 2, true); + break; + + case INSN_CONFIG_DISARM: + apci3120_timer_enable(dev, 2, false); + apci3120_clr_timer2_interrupt(dev); + break; + + case INSN_CONFIG_GET_COUNTER_STATUS: + data[1] = 0; + data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING | + COMEDI_COUNTER_TERMINAL_COUNT; + + if (devpriv->ctrl & APCI3120_CTRL_GATE(2)) { + data[1] |= COMEDI_COUNTER_ARMED; + data[1] |= COMEDI_COUNTER_COUNTING; + } + status = inw(dev->iobase + APCI3120_STATUS_REG); + if (status & APCI3120_STATUS_TIMER2_INT) { + data[1] &= ~COMEDI_COUNTER_COUNTING; + data[1] |= COMEDI_COUNTER_TERMINAL_COUNT; + } + break; + + case INSN_CONFIG_SET_COUNTER_MODE: + switch (data[1]) { + case I8254_MODE0: + mode = APCI3120_MODE_TIMER2_AS_COUNTER; + timer_mode = APCI3120_TIMER_MODE0; + break; + case I8254_MODE2: + mode = APCI3120_MODE_TIMER2_AS_TIMER; + timer_mode = APCI3120_TIMER_MODE2; + break; + case I8254_MODE4: + mode = APCI3120_MODE_TIMER2_AS_TIMER; + timer_mode = APCI3120_TIMER_MODE4; + break; + case I8254_MODE5: + mode = APCI3120_MODE_TIMER2_AS_WDOG; + timer_mode = APCI3120_TIMER_MODE5; + break; + default: + return -EINVAL; + } + apci3120_timer_enable(dev, 2, false); + apci3120_clr_timer2_interrupt(dev); + apci3120_timer_set_mode(dev, 2, timer_mode); + devpriv->mode &= ~APCI3120_MODE_TIMER2_AS_MASK; + devpriv->mode |= mode; + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); + break; + + default: + return -EINVAL; + } + + return insn->n; +} + +static int apci3120_timer_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + int i; + + for (i = 0; i < insn->n; i++) + data[i] = apci3120_timer_read(dev, 2); + + return insn->n; +} + +static void apci3120_dma_alloc(struct comedi_device *dev) +{ + struct apci3120_private *devpriv = dev->private; + struct apci3120_dmabuf *dmabuf; + int order; + int i; + + for (i = 0; i < 2; i++) { + dmabuf = &devpriv->dmabuf[i]; + for (order = 2; order >= 0; order--) { + dmabuf->virt = dma_alloc_coherent(dev->hw_dev, + PAGE_SIZE << order, + &dmabuf->hw, + GFP_KERNEL); + if (dmabuf->virt) + break; + } + if (!dmabuf->virt) + break; + dmabuf->size = PAGE_SIZE << order; + + if (i == 0) + devpriv->use_dma = 1; + if (i == 1) + devpriv->use_double_buffer = 1; + } +} + +static void apci3120_dma_free(struct comedi_device *dev) +{ + struct apci3120_private *devpriv = dev->private; + struct apci3120_dmabuf *dmabuf; + int i; + + if (!devpriv) + return; + + for (i = 0; i < 2; i++) { + dmabuf = &devpriv->dmabuf[i]; + if (dmabuf->virt) { + dma_free_coherent(dev->hw_dev, dmabuf->size, + dmabuf->virt, dmabuf->hw); + } + } +} + +static void apci3120_reset(struct comedi_device *dev) +{ + /* disable all interrupt sources */ + outb(0, dev->iobase + APCI3120_MODE_REG); + + /* disable all counters, ext trigger, and reset scan */ + outw(0, dev->iobase + APCI3120_CTRL_REG); + + /* clear interrupt status */ + inw(dev->iobase + APCI3120_STATUS_REG); } static int apci3120_auto_attach(struct comedi_device *dev, unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct addi_board *this_board = NULL; - struct addi_private *devpriv; + const struct apci3120_board *this_board = NULL; + struct apci3120_private *devpriv; struct comedi_subdevice *s; - int ret, order, i; + unsigned int status; + int ret; if (context < ARRAY_SIZE(apci3120_boardtypes)) this_board = &apci3120_boardtypes[context]; if (!this_board) return -ENODEV; dev->board_ptr = this_board; - dev->board_name = this_board->pc_DriverName; + dev->board_name = this_board->name; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) @@ -76,136 +999,100 @@ static int apci3120_auto_attach(struct comedi_device *dev, pci_set_master(pcidev); dev->iobase = pci_resource_start(pcidev, 1); - devpriv->iobase = dev->iobase; - devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); - devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); - devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); + devpriv->amcc = pci_resource_start(pcidev, 0); + devpriv->addon = pci_resource_start(pcidev, 2); + + apci3120_reset(dev); if (pcidev->irq > 0) { - ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, + ret = request_irq(pcidev->irq, apci3120_interrupt, IRQF_SHARED, dev->board_name, dev); - if (ret == 0) + if (ret == 0) { dev->irq = pcidev->irq; - } - /* Allocate DMA buffers */ - for (i = 0; i < 2; i++) { - for (order = 2; order >= 0; order--) { - devpriv->ul_DmaBufferVirtual[i] = - dma_alloc_coherent(dev->hw_dev, PAGE_SIZE << order, - &devpriv->ul_DmaBufferHw[i], - GFP_KERNEL); - - if (devpriv->ul_DmaBufferVirtual[i]) - break; + apci3120_dma_alloc(dev); } - if (!devpriv->ul_DmaBufferVirtual[i]) - break; - devpriv->ui_DmaBufferSize[i] = PAGE_SIZE << order; } - if (devpriv->ul_DmaBufferVirtual[0]) - devpriv->us_UseDma = 1; - if (devpriv->ul_DmaBufferVirtual[1]) - devpriv->b_DmaDoubleBuffer = 1; + status = inw(dev->iobase + APCI3120_STATUS_REG); + if (APCI3120_STATUS_TO_VERSION(status) == APCI3120_REVB || + context == BOARD_APCI3001) + devpriv->osc_base = APCI3120_REVB_OSC_BASE; + else + devpriv->osc_base = APCI3120_REVA_OSC_BASE; ret = comedi_alloc_subdevices(dev, 5); if (ret) return ret; - /* Allocate and Initialise AI Subdevice Structures */ + /* Analog Input subdevice */ s = &dev->subdevices[0]; - dev->read_subdev = s; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = - SDF_READABLE | SDF_COMMON | SDF_GROUND - | SDF_DIFF; - if (this_board->i_NbrAiChannel) - s->n_chan = this_board->i_NbrAiChannel; - else - s->n_chan = this_board->i_NbrAiChannelDiff; - s->maxdata = this_board->i_AiMaxdata; - s->len_chanlist = this_board->i_AiChannelList; - s->range_table = &range_apci3120_ai; - - s->insn_config = apci3120_ai_insn_config; - s->insn_read = apci3120_ai_insn_read; - s->do_cmdtest = apci3120_ai_cmdtest; - s->do_cmd = apci3120_ai_cmd; - s->cancel = apci3120_cancel; - - /* Allocate and Initialise AO Subdevice Structures */ + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; + s->n_chan = 16; + s->maxdata = this_board->ai_is_16bit ? 0xffff : 0x0fff; + s->range_table = &apci3120_ai_range; + s->insn_read = apci3120_ai_insn_read; + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = s->n_chan; + s->do_cmdtest = apci3120_ai_cmdtest; + s->do_cmd = apci3120_ai_cmd; + s->cancel = apci3120_cancel; + } + + /* Analog Output subdevice */ s = &dev->subdevices[1]; - if (this_board->i_NbrAoChannel) { - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = this_board->i_NbrAoChannel; - s->maxdata = this_board->i_AoMaxdata; - s->len_chanlist = this_board->i_NbrAoChannel; - s->range_table = &range_apci3120_ao; - s->insn_write = apci3120_ao_insn_write; + if (this_board->has_ao) { + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 8; + s->maxdata = 0x3fff; + s->range_table = &range_bipolar10; + s->insn_write = apci3120_ao_insn_write; + + ret = comedi_alloc_subdev_readback(s); + if (ret) + return ret; } else { - s->type = COMEDI_SUBD_UNUSED; + s->type = COMEDI_SUBD_UNUSED; } - /* Allocate and Initialise DI Subdevice Structures */ + /* Digital Input subdevice */ s = &dev->subdevices[2]; - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = this_board->i_NbrDiChannel; - s->maxdata = 1; - s->len_chanlist = this_board->i_NbrDiChannel; - s->range_table = &range_digital; - s->insn_bits = apci3120_di_insn_bits; - - /* Allocate and Initialise DO Subdevice Structures */ + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = 4; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = apci3120_di_insn_bits; + + /* Digital Output subdevice */ s = &dev->subdevices[3]; - s->type = COMEDI_SUBD_DO; - s->subdev_flags = - SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = this_board->i_NbrDoChannel; - s->maxdata = this_board->i_DoMaxdata; - s->len_chanlist = this_board->i_NbrDoChannel; - s->range_table = &range_digital; - s->insn_bits = apci3120_do_insn_bits; - - /* Allocate and Initialise Timer Subdevice Structures */ - s = &dev->subdevices[4]; - s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = 1; - s->maxdata = 0; - s->len_chanlist = 1; - s->range_table = &range_digital; + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = apci3120_do_insn_bits; - s->insn_write = apci3120_write_insn_timer; - s->insn_read = apci3120_read_insn_timer; - s->insn_config = apci3120_config_insn_timer; + /* Timer subdevice */ + s = &dev->subdevices[4]; + s->type = COMEDI_SUBD_TIMER; + s->subdev_flags = SDF_READABLE; + s->n_chan = 1; + s->maxdata = 0x00ffffff; + s->insn_config = apci3120_timer_insn_config; + s->insn_read = apci3120_timer_insn_read; - apci3120_reset(dev); return 0; } static void apci3120_detach(struct comedi_device *dev) { - struct addi_private *devpriv = dev->private; - - if (dev->iobase) - apci3120_reset(dev); comedi_pci_detach(dev); - if (devpriv) { - unsigned int i; - - for (i = 0; i < 2; i++) { - if (devpriv->ul_DmaBufferVirtual[i]) { - dma_free_coherent(dev->hw_dev, - devpriv->ui_DmaBufferSize[i], - devpriv-> - ul_DmaBufferVirtual[i], - devpriv->ul_DmaBufferHw[i]); - } - } - } + apci3120_dma_free(dev); } static struct comedi_driver apci3120_driver = { diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c deleted file mode 100644 index fe6897eff3db..000000000000 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ /dev/null @@ -1,125 +0,0 @@ -#include <linux/module.h> -#include <linux/pci.h> - -#include <asm/i387.h> - -#include "../comedidev.h" -#include "comedi_fc.h" -#include "amcc_s5933.h" - -#include "addi-data/addi_common.h" - -static void fpu_begin(void) -{ - kernel_fpu_begin(); -} - -static void fpu_end(void) -{ - kernel_fpu_end(); -} - -#include "addi-data/addi_eeprom.c" -#include "addi-data/hwdrv_apci3200.c" -#include "addi-data/addi_common.c" - -enum apci3200_boardid { - BOARD_APCI3200, - BOARD_APCI3300, -}; - -static const struct addi_board apci3200_boardtypes[] = { - [BOARD_APCI3200] = { - .pc_DriverName = "apci3200", - .i_IorangeBase1 = 256, - .i_PCIEeprom = 1, - .pc_EepromChip = "S5920", - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_AiMaxdata = 0x3ffff, - .pr_AiRangelist = &range_apci3200_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .ui_MinAcquisitiontimeNs = 10000, - .ui_MinDelaytimeNs = 100000, - .interrupt = apci3200_interrupt, - .reset = apci3200_reset, - .ai_config = apci3200_ai_config, - .ai_read = apci3200_ai_read, - .ai_write = apci3200_ai_write, - .ai_bits = apci3200_ai_bits_test, - .ai_cmdtest = apci3200_ai_cmdtest, - .ai_cmd = apci3200_ai_cmd, - .ai_cancel = apci3200_cancel, - .di_bits = apci3200_di_insn_bits, - .do_bits = apci3200_do_insn_bits, - }, - [BOARD_APCI3300] = { - .pc_DriverName = "apci3300", - .i_IorangeBase1 = 256, - .i_PCIEeprom = 1, - .pc_EepromChip = "S5920", - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 8, - .i_AiMaxdata = 0x3ffff, - .pr_AiRangelist = &range_apci3300_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .ui_MinAcquisitiontimeNs = 10000, - .ui_MinDelaytimeNs = 100000, - .interrupt = apci3200_interrupt, - .reset = apci3200_reset, - .ai_config = apci3200_ai_config, - .ai_read = apci3200_ai_read, - .ai_write = apci3200_ai_write, - .ai_bits = apci3200_ai_bits_test, - .ai_cmdtest = apci3200_ai_cmdtest, - .ai_cmd = apci3200_ai_cmd, - .ai_cancel = apci3200_cancel, - .di_bits = apci3200_di_insn_bits, - .do_bits = apci3200_do_insn_bits, - }, -}; - -static int apci3200_auto_attach(struct comedi_device *dev, - unsigned long context) -{ - const struct addi_board *board = NULL; - - if (context < ARRAY_SIZE(apci3200_boardtypes)) - board = &apci3200_boardtypes[context]; - if (!board) - return -ENODEV; - dev->board_ptr = board; - - return addi_auto_attach(dev, context); -} - -static struct comedi_driver apci3200_driver = { - .driver_name = "addi_apci_3200", - .module = THIS_MODULE, - .auto_attach = apci3200_auto_attach, - .detach = i_ADDI_Detach, -}; - -static int apci3200_pci_probe(struct pci_dev *dev, - const struct pci_device_id *id) -{ - return comedi_pci_auto_config(dev, &apci3200_driver, id->driver_data); -} - -static const struct pci_device_id apci3200_pci_table[] = { - { PCI_VDEVICE(ADDIDATA, 0x3000), BOARD_APCI3200 }, - { PCI_VDEVICE(ADDIDATA, 0x3007), BOARD_APCI3300 }, - { 0 } -}; -MODULE_DEVICE_TABLE(pci, apci3200_pci_table); - -static struct pci_driver apci3200_pci_driver = { - .name = "addi_apci_3200", - .id_table = apci3200_pci_table, - .probe = apci3200_pci_probe, - .remove = comedi_pci_auto_unconfig, -}; -module_comedi_pci_driver(apci3200_driver, apci3200_pci_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index 010efa3fed6c..a726efcea6a5 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -357,12 +357,11 @@ static int apci3501_auto_attach(struct comedi_device *dev, s = &dev->subdevices[0]; if (ao_n_chan) { s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; s->n_chan = ao_n_chan; s->maxdata = 0x3fff; s->range_table = &apci3501_ao_range; s->insn_write = apci3501_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) @@ -383,7 +382,7 @@ static int apci3501_auto_attach(struct comedi_device *dev, /* Initialize the digital output subdevice */ s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 2; s->maxdata = 1; s->range_table = &range_digital; @@ -392,7 +391,7 @@ static int apci3501_auto_attach(struct comedi_device *dev, /* Initialize the timer/watchdog subdevice */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 1; s->maxdata = 0; s->len_chanlist = 1; diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index a296bd5b2c0c..c173810a3b5b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -371,10 +371,10 @@ static irqreturn_t apci3xxx_irq_handler(int irq, void *d) writel(status, dev->mmio + 16); val = readl(dev->mmio + 28); - comedi_buf_put(s, val); + comedi_buf_write_samples(s, &val, 1); s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } @@ -849,12 +849,11 @@ static int apci3xxx_auto_attach(struct comedi_device *dev, if (board->has_ao) { s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 4; s->maxdata = 0x0fff; s->range_table = &apci3xxx_ao_range; s->insn_write = apci3xxx_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) @@ -880,7 +879,7 @@ static int apci3xxx_auto_attach(struct comedi_device *dev, if (board->has_dig_out) { s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 4; s->maxdata = 1; s->range_table = &range_digital; @@ -893,7 +892,7 @@ static int apci3xxx_auto_attach(struct comedi_device *dev, if (board->has_ttl_io) { s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITEABLE; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 24; s->maxdata = 1; s->io_bits = 0xff; /* channels 0-7 are always outputs */ diff --git a/drivers/staging/comedi/drivers/addi_tcw.h b/drivers/staging/comedi/drivers/addi_tcw.h new file mode 100644 index 000000000000..8794d4cbbfb0 --- /dev/null +++ b/drivers/staging/comedi/drivers/addi_tcw.h @@ -0,0 +1,56 @@ +#ifndef _ADDI_TCW_H +#define _ADDI_TCW_H + +/* + * Following are the generic definitions for the ADDI-DATA timer/counter/ + * watchdog (TCW) registers and bits. Some of the registers are not used + * depending on the use of the TCW. + */ + +#define ADDI_TCW_VAL_REG 0x00 + +#define ADDI_TCW_SYNC_REG 0x00 +#define ADDI_TCW_SYNC_CTR_TRIG (1 << 8) +#define ADDI_TCW_SYNC_CTR_DIS (1 << 7) +#define ADDI_TCW_SYNC_CTR_ENA (1 << 6) +#define ADDI_TCW_SYNC_TIMER_TRIG (1 << 5) +#define ADDI_TCW_SYNC_TIMER_DIS (1 << 4) +#define ADDI_TCW_SYNC_TIMER_ENA (1 << 3) +#define ADDI_TCW_SYNC_WDOG_TRIG (1 << 2) +#define ADDI_TCW_SYNC_WDOG_DIS (1 << 1) +#define ADDI_TCW_SYNC_WDOG_ENA (1 << 0) + +#define ADDI_TCW_RELOAD_REG 0x04 + +#define ADDI_TCW_TIMEBASE_REG 0x08 + +#define ADDI_TCW_CTRL_REG 0x0c +#define ADDI_TCW_CTRL_EXT_CLK_STATUS (1 << 21) +#define ADDI_TCW_CTRL_CASCADE (1 << 20) +#define ADDI_TCW_CTRL_CNTR_ENA (1 << 19) +#define ADDI_TCW_CTRL_CNT_UP (1 << 18) +#define ADDI_TCW_CTRL_EXT_CLK(x) ((x) << 16) +#define ADDI_TCW_CTRL_OUT(x) ((x) << 11) +#define ADDI_TCW_CTRL_GATE (1 << 10) +#define ADDI_TCW_CTRL_TRIG (1 << 9) +#define ADDI_TCW_CTRL_EXT_GATE(x) ((x) << 7) +#define ADDI_TCW_CTRL_EXT_TRIG(x) ((x) << 5) +#define ADDI_TCW_CTRL_TIMER_ENA (1 << 4) +#define ADDI_TCW_CTRL_RESET_ENA (1 << 3) +#define ADDI_TCW_CTRL_WARN_ENA (1 << 2) +#define ADDI_TCW_CTRL_IRQ_ENA (1 << 1) +#define ADDI_TCW_CTRL_ENA (1 << 0) + +#define ADDI_TCW_STATUS_REG 0x10 +#define ADDI_TCW_STATUS_SOFT_CLR (1 << 3) +#define ADDI_TCW_STATUS_SOFT_TRIG (1 << 1) +#define ADDI_TCW_STATUS_OVERFLOW (1 << 0) + +#define ADDI_TCW_IRQ_REG 0x14 +#define ADDI_TCW_IRQ (1 << 0) + +#define ADDI_TCW_WARN_TIMEVAL_REG 0x18 + +#define ADDI_TCW_WARN_TIMEBASE_REG 0x1c + +#endif diff --git a/drivers/staging/comedi/drivers/addi_watchdog.c b/drivers/staging/comedi/drivers/addi_watchdog.c index 23031feaa095..c5b082d4e51e 100644 --- a/drivers/staging/comedi/drivers/addi_watchdog.c +++ b/drivers/staging/comedi/drivers/addi_watchdog.c @@ -20,21 +20,9 @@ #include <linux/module.h> #include "../comedidev.h" +#include "addi_tcw.h" #include "addi_watchdog.h" -/* - * Register offsets/defines for the addi-data watchdog - */ -#define ADDI_WDOG_REG 0x00 -#define ADDI_WDOG_RELOAD_REG 0x04 -#define ADDI_WDOG_TIMEBASE 0x08 -#define ADDI_WDOG_CTRL_REG 0x0c -#define ADDI_WDOG_CTRL_ENABLE (1 << 0) -#define ADDI_WDOG_CTRL_SW_TRIG (1 << 9) -#define ADDI_WDOG_STATUS_REG 0x10 -#define ADDI_WDOG_STATUS_ENABLED (1 << 0) -#define ADDI_WDOG_STATUS_SW_TRIG (1 << 1) - struct addi_watchdog_private { unsigned long iobase; unsigned int wdog_ctrl; @@ -60,9 +48,9 @@ static int addi_watchdog_insn_config(struct comedi_device *dev, switch (data[0]) { case INSN_CONFIG_ARM: - spriv->wdog_ctrl = ADDI_WDOG_CTRL_ENABLE; + spriv->wdog_ctrl = ADDI_TCW_CTRL_ENA; reload = data[1] & s->maxdata; - outl(reload, spriv->iobase + ADDI_WDOG_RELOAD_REG); + outl(reload, spriv->iobase + ADDI_TCW_RELOAD_REG); /* Time base is 20ms, let the user know the timeout */ dev_info(dev->class_dev, "watchdog enabled, timeout:%dms\n", @@ -75,7 +63,7 @@ static int addi_watchdog_insn_config(struct comedi_device *dev, return -EINVAL; } - outl(spriv->wdog_ctrl, spriv->iobase + ADDI_WDOG_CTRL_REG); + outl(spriv->wdog_ctrl, spriv->iobase + ADDI_TCW_CTRL_REG); return insn->n; } @@ -89,7 +77,7 @@ static int addi_watchdog_insn_read(struct comedi_device *dev, int i; for (i = 0; i < insn->n; i++) - data[i] = inl(spriv->iobase + ADDI_WDOG_STATUS_REG); + data[i] = inl(spriv->iobase + ADDI_TCW_STATUS_REG); return insn->n; } @@ -109,8 +97,8 @@ static int addi_watchdog_insn_write(struct comedi_device *dev, /* "ping" the watchdog */ for (i = 0; i < insn->n; i++) { - outl(spriv->wdog_ctrl | ADDI_WDOG_CTRL_SW_TRIG, - spriv->iobase + ADDI_WDOG_CTRL_REG); + outl(spriv->wdog_ctrl | ADDI_TCW_CTRL_TRIG, + spriv->iobase + ADDI_TCW_CTRL_REG); } return insn->n; @@ -118,8 +106,8 @@ static int addi_watchdog_insn_write(struct comedi_device *dev, void addi_watchdog_reset(unsigned long iobase) { - outl(0x0, iobase + ADDI_WDOG_CTRL_REG); - outl(0x0, iobase + ADDI_WDOG_RELOAD_REG); + outl(0x0, iobase + ADDI_TCW_CTRL_REG); + outl(0x0, iobase + ADDI_TCW_RELOAD_REG); } EXPORT_SYMBOL_GPL(addi_watchdog_reset); @@ -134,7 +122,7 @@ int addi_watchdog_init(struct comedi_subdevice *s, unsigned long iobase) spriv->iobase = iobase; s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 1; s->maxdata = 0xff; s->insn_config = addi_watchdog_insn_config; diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 0ad46fe492c9..528f15c25dae 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -169,7 +169,6 @@ static int pci6208_auto_attach(struct comedi_device *dev, s->maxdata = 0xffff; s->range_table = &range_bipolar10; s->insn_write = pci6208_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index d18d8f21af23..47f6c0e9f014 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -133,8 +133,6 @@ static const struct comedi_lrange pci9111_ai_range = { struct pci9111_private_data { unsigned long lcr_io_base; - int stop_counter; - unsigned int scan_delay; unsigned int chunk_counter; unsigned int chunk_num_samples; @@ -404,12 +402,6 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, outb(CR_RANGE(cmd->chanlist[0]) & PCI9111_AI_RANGE_MASK, dev->iobase + PCI9111_AI_RANGE_STAT_REG); - /* Set counter */ - if (cmd->stop_src == TRIG_COUNT) - dev_private->stop_counter = cmd->stop_arg * cmd->chanlist_len; - else /* TRIG_NONE */ - dev_private->stop_counter = 0; - /* Set timer pacer */ dev_private->scan_delay = 0; if (cmd->convert_src == TRIG_TIMER) { @@ -435,7 +427,6 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, } outb(trig, dev->iobase + PCI9111_AI_TRIG_CTRL_REG); - dev_private->stop_counter *= (1 + dev_private->scan_delay); dev_private->chunk_counter = 0; dev_private->chunk_num_samples = cmd->chanlist_len * (1 + dev_private->scan_delay); @@ -452,7 +443,7 @@ static void pci9111_ai_munge(struct comedi_device *dev, unsigned int maxdata = s->maxdata; unsigned int invert = (maxdata + 1) >> 1; unsigned int shift = (maxdata == 0xffff) ? 0 : 4; - unsigned int num_samples = num_bytes / sizeof(short); + unsigned int num_samples = comedi_bytes_to_samples(s, num_bytes); unsigned int i; for (i = 0; i < num_samples; i++) @@ -464,22 +455,14 @@ static void pci9111_handle_fifo_half_full(struct comedi_device *dev, { struct pci9111_private_data *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - unsigned int total = 0; unsigned int samples; - if (cmd->stop_src == TRIG_COUNT && - PCI9111_FIFO_HALF_SIZE > devpriv->stop_counter) - samples = devpriv->stop_counter; - else - samples = PCI9111_FIFO_HALF_SIZE; - + samples = comedi_nsamples_left(s, PCI9111_FIFO_HALF_SIZE); insw(dev->iobase + PCI9111_AI_FIFO_REG, devpriv->ai_bounce_buffer, samples); if (devpriv->scan_delay < 1) { - total = cfc_write_array_to_buffer(s, - devpriv->ai_bounce_buffer, - samples * sizeof(short)); + comedi_buf_write_samples(s, devpriv->ai_bounce_buffer, samples); } else { unsigned int pos = 0; unsigned int to_read; @@ -492,17 +475,15 @@ static void pci9111_handle_fifo_half_full(struct comedi_device *dev, if (to_read > samples - pos) to_read = samples - pos; - total += cfc_write_array_to_buffer(s, + comedi_buf_write_samples(s, devpriv->ai_bounce_buffer + pos, - to_read * sizeof(short)); + to_read); } else { to_read = devpriv->chunk_num_samples - devpriv->chunk_counter; if (to_read > samples - pos) to_read = samples - pos; - - total += to_read * sizeof(short); } pos += to_read; @@ -513,8 +494,6 @@ static void pci9111_handle_fifo_half_full(struct comedi_device *dev, devpriv->chunk_counter = 0; } } - - devpriv->stop_counter -= total / sizeof(short); } static irqreturn_t pci9111_interrupt(int irq, void *p_device) @@ -561,7 +540,7 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) dev_dbg(dev->class_dev, "fifo overflow\n"); outb(0, dev->iobase + PCI9111_INT_CLR_REG); async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } @@ -571,14 +550,14 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) pci9111_handle_fifo_half_full(dev, s); } - if (cmd->stop_src == TRIG_COUNT && dev_private->stop_counter == 0) + if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg) async->events |= COMEDI_CB_EOA; outb(0, dev->iobase + PCI9111_INT_CLR_REG); spin_unlock_irqrestore(&dev->spinlock, irq_flags); - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } @@ -752,7 +731,6 @@ static int pci9111_auto_attach(struct comedi_device *dev, s->len_chanlist = 1; s->range_table = &range_bipolar10; s->insn_write = pci9111_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) @@ -768,7 +746,7 @@ static int pci9111_auto_attach(struct comedi_device *dev, s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index e18fd9569a2b..26603582e71a 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -221,7 +221,6 @@ struct pci9118_private { unsigned char int_ctrl; unsigned char ai_cfg; unsigned int ai_do; /* what do AI? 0=nothing, 1 to 4 mode */ - unsigned int ai_act_scan; /* how many scans we finished */ unsigned int ai_n_realscanlen; /* * what we must transfer for one * outgoing scan include front/back adds @@ -447,51 +446,112 @@ static void interrupt_pci9118_ai_mode4_switch(struct comedi_device *dev, outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG); } -static unsigned int defragment_dma_buffer(struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned short *dma_buffer, - unsigned int num_samples) +static unsigned int valid_samples_in_act_dma_buf(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int n_raw_samples) { struct pci9118_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - unsigned int i = 0, j = 0; - unsigned int start_pos = devpriv->ai_add_front, - stop_pos = devpriv->ai_add_front + cmd->chanlist_len; - unsigned int raw_scanlen = devpriv->ai_add_front + cmd->chanlist_len + - devpriv->ai_add_back; + unsigned int start_pos = devpriv->ai_add_front; + unsigned int stop_pos = start_pos + cmd->chanlist_len; + unsigned int span_len = stop_pos + devpriv->ai_add_back; + unsigned int dma_pos = devpriv->ai_act_dmapos; + unsigned int whole_spans, n_samples, x; - for (i = 0; i < num_samples; i++) { - if (devpriv->ai_act_dmapos >= start_pos && - devpriv->ai_act_dmapos < stop_pos) { - dma_buffer[j++] = dma_buffer[i]; + if (span_len == cmd->chanlist_len) + return n_raw_samples; /* use all samples */ + + /* + * Not all samples are to be used. Buffer contents consist of a + * possibly non-whole number of spans and a region of each span + * is to be used. + * + * Account for samples in whole number of spans. + */ + whole_spans = n_raw_samples / span_len; + n_samples = whole_spans * cmd->chanlist_len; + n_raw_samples -= whole_spans * span_len; + + /* + * Deal with remaining samples which could overlap up to two spans. + */ + while (n_raw_samples) { + if (dma_pos < start_pos) { + /* Skip samples before start position. */ + x = start_pos - dma_pos; + if (x > n_raw_samples) + x = n_raw_samples; + dma_pos += x; + n_raw_samples -= x; + if (!n_raw_samples) + break; } - devpriv->ai_act_dmapos++; - devpriv->ai_act_dmapos %= raw_scanlen; + if (dma_pos < stop_pos) { + /* Include samples before stop position. */ + x = stop_pos - dma_pos; + if (x > n_raw_samples) + x = n_raw_samples; + n_samples += x; + dma_pos += x; + n_raw_samples -= x; + } + /* Advance to next span. */ + start_pos += span_len; + stop_pos += span_len; } - - return j; + return n_samples; } -static int move_block_from_dma(struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned short *dma_buffer, - unsigned int num_samples) +static void move_block_from_dma(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned short *dma_buffer, + unsigned int n_raw_samples) { struct pci9118_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - unsigned int num_bytes; - - num_samples = defragment_dma_buffer(dev, s, dma_buffer, num_samples); - devpriv->ai_act_scan += - (s->async->cur_chan + num_samples) / cmd->scan_end_arg; - s->async->cur_chan += num_samples; - s->async->cur_chan %= cmd->scan_end_arg; - num_bytes = - cfc_write_array_to_buffer(s, dma_buffer, - num_samples * sizeof(short)); - if (num_bytes < num_samples * sizeof(short)) - return -1; - return 0; + unsigned int start_pos = devpriv->ai_add_front; + unsigned int stop_pos = start_pos + cmd->chanlist_len; + unsigned int span_len = stop_pos + devpriv->ai_add_back; + unsigned int dma_pos = devpriv->ai_act_dmapos; + unsigned int x; + + if (span_len == cmd->chanlist_len) { + /* All samples are to be copied. */ + comedi_buf_write_samples(s, dma_buffer, n_raw_samples); + dma_pos += n_raw_samples; + } else { + /* + * Not all samples are to be copied. Buffer contents consist + * of a possibly non-whole number of spans and a region of + * each span is to be copied. + */ + while (n_raw_samples) { + if (dma_pos < start_pos) { + /* Skip samples before start position. */ + x = start_pos - dma_pos; + if (x > n_raw_samples) + x = n_raw_samples; + dma_pos += x; + n_raw_samples -= x; + if (!n_raw_samples) + break; + } + if (dma_pos < stop_pos) { + /* Copy samples before stop position. */ + x = stop_pos - dma_pos; + if (x > n_raw_samples) + x = n_raw_samples; + comedi_buf_write_samples(s, dma_buffer, x); + dma_pos += x; + n_raw_samples -= x; + } + /* Advance to next span. */ + start_pos += span_len; + stop_pos += span_len; + } + } + /* Update position in span for next time. */ + devpriv->ai_act_dmapos = dma_pos % span_len; } static void pci9118_exttrg_enable(struct comedi_device *dev, bool enable) @@ -578,9 +638,7 @@ static int pci9118_ai_cancel(struct comedi_device *dev, devpriv->ai_do = 0; devpriv->usedma = 0; - devpriv->ai_act_scan = 0; devpriv->ai_act_dmapos = 0; - s->async->cur_chan = 0; s->async->inttrig = NULL; devpriv->ai_neverending = 0; devpriv->dma_actbuf = 0; @@ -594,8 +652,9 @@ static void pci9118_ai_munge(struct comedi_device *dev, unsigned int start_chan_index) { struct pci9118_private *devpriv = dev->private; - unsigned int i, num_samples = num_bytes / sizeof(short); unsigned short *array = data; + unsigned int num_samples = comedi_bytes_to_samples(s, num_bytes); + unsigned int i; for (i = 0; i < num_samples; i++) { if (devpriv->usedma) @@ -617,17 +676,11 @@ static void interrupt_pci9118_ai_onesample(struct comedi_device *dev, sampl = inl(dev->iobase + PCI9118_AI_FIFO_REG); - cfc_write_to_buffer(s, sampl); - s->async->cur_chan++; - if (s->async->cur_chan >= cmd->scan_end_arg) { - /* one scan done */ - s->async->cur_chan %= cmd->scan_end_arg; - devpriv->ai_act_scan++; - if (!devpriv->ai_neverending) { - /* all data sampled? */ - if (devpriv->ai_act_scan >= cmd->stop_arg) - s->async->events |= COMEDI_CB_EOA; - } + comedi_buf_write_samples(s, &sampl, 1); + + if (!devpriv->ai_neverending) { + if (s->async->scans_done >= cmd->stop_arg) + s->async->events |= COMEDI_CB_EOA; } } @@ -637,39 +690,37 @@ static void interrupt_pci9118_ai_dma(struct comedi_device *dev, struct pci9118_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; struct pci9118_dmabuf *dmabuf = &devpriv->dmabuf[devpriv->dma_actbuf]; - unsigned int next_dma_buf, samplesinbuf, sampls, m; + unsigned int n_all = comedi_bytes_to_samples(s, dmabuf->use_size); + unsigned int n_valid; + bool more_dma; - samplesinbuf = dmabuf->use_size >> 1; /* number of received samples */ + /* determine whether more DMA buffers to do after this one */ + n_valid = valid_samples_in_act_dma_buf(dev, s, n_all); + more_dma = n_valid < comedi_nsamples_left(s, n_valid + 1); - if (devpriv->dma_doublebuf) { /* - * switch DMA buffers if is used - * double buffering - */ - next_dma_buf = 1 - devpriv->dma_actbuf; - pci9118_amcc_setup_dma(dev, next_dma_buf); - if (devpriv->ai_do == 4) - interrupt_pci9118_ai_mode4_switch(dev, next_dma_buf); + /* switch DMA buffers and restart DMA if double buffering */ + if (more_dma && devpriv->dma_doublebuf) { + devpriv->dma_actbuf = 1 - devpriv->dma_actbuf; + pci9118_amcc_setup_dma(dev, devpriv->dma_actbuf); + if (devpriv->ai_do == 4) { + interrupt_pci9118_ai_mode4_switch(dev, + devpriv->dma_actbuf); + } } - if (samplesinbuf) { - /* how many samples is to end of buffer */ - m = s->async->prealloc_bufsz >> 1; - sampls = m; - move_block_from_dma(dev, s, dmabuf->virt, samplesinbuf); - m = m - sampls; /* m=how many samples was transferred */ - } + if (n_all) + move_block_from_dma(dev, s, dmabuf->virt, n_all); if (!devpriv->ai_neverending) { - /* all data sampled? */ - if (devpriv->ai_act_scan >= cmd->stop_arg) + if (s->async->scans_done >= cmd->stop_arg) s->async->events |= COMEDI_CB_EOA; } - if (devpriv->dma_doublebuf) { - /* switch dma buffers */ - devpriv->dma_actbuf = 1 - devpriv->dma_actbuf; - } else { - /* restart DMA if is not used double buffering */ + if (s->async->events & COMEDI_CB_CANCEL_MASK) + more_dma = false; + + /* restart DMA if not double buffering */ + if (more_dma && !devpriv->dma_doublebuf) { pci9118_amcc_setup_dma(dev, 0); if (devpriv->ai_do == 4) interrupt_pci9118_ai_mode4_switch(dev, 0); @@ -766,7 +817,7 @@ static irqreturn_t pci9118_interrupt(int irq, void *d) interrupt_pci9118_ai_onesample(dev, s); interrupt_exit: - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } @@ -1123,9 +1174,7 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) inl(dev->iobase + PCI9118_AI_STATUS_REG); inl(dev->iobase + PCI9118_INT_CTRL_REG); - devpriv->ai_act_scan = 0; devpriv->ai_act_dmapos = 0; - s->async->cur_chan = 0; if (devpriv->usedma) { Compute_and_setup_dma(dev, s); @@ -1624,7 +1673,6 @@ static int pci9118_common_attach(struct comedi_device *dev, s->maxdata = 0x0fff; s->range_table = &range_bipolar10; s->insn_write = pci9118_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 5539bd294862..d02df7d0c629 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -298,7 +298,6 @@ static const struct boardtype boardtypes[] = { struct pci1710_private { unsigned int CntrlReg; /* Control register */ - unsigned int ai_act_scan; /* how many scans we finished */ unsigned char ai_et; unsigned int ai_et_CntrlReg; unsigned int ai_et_MuxVal; @@ -730,16 +729,12 @@ static int pci171x_ai_cancel(struct comedi_device *dev, break; } - devpriv->ai_act_scan = 0; - s->async->cur_chan = 0; - return 0; } static void pci1710_handle_every_sample(struct comedi_device *dev, struct comedi_subdevice *s) { - struct pci1710_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; unsigned int status; unsigned int val; @@ -749,14 +744,14 @@ static void pci1710_handle_every_sample(struct comedi_device *dev, if (status & Status_FE) { dev_dbg(dev->class_dev, "A/D FIFO empty (%4x)\n", status); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return; } if (status & Status_FF) { dev_dbg(dev->class_dev, "A/D FIFO Full status (Fatal Error!) (%4x)\n", status); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return; } @@ -770,27 +765,19 @@ static void pci1710_handle_every_sample(struct comedi_device *dev, break; } - comedi_buf_put(s, val & s->maxdata); - - s->async->cur_chan++; - if (s->async->cur_chan >= cmd->chanlist_len) - s->async->cur_chan = 0; + val &= s->maxdata; + comedi_buf_write_samples(s, &val, 1); - - if (s->async->cur_chan == 0) { /* one scan done */ - devpriv->ai_act_scan++; - if (cmd->stop_src == TRIG_COUNT && - devpriv->ai_act_scan >= cmd->stop_arg) { - /* all data sampled */ - s->async->events |= COMEDI_CB_EOA; - break; - } + if (cmd->stop_src == TRIG_COUNT && + s->async->scans_done >= cmd->stop_arg) { + s->async->events |= COMEDI_CB_EOA; + break; } } outb(0, dev->iobase + PCI171x_CLRINT); /* clear our INT request */ - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } /* @@ -799,8 +786,6 @@ static void pci1710_handle_every_sample(struct comedi_device *dev, static int move_block_from_fifo(struct comedi_device *dev, struct comedi_subdevice *s, int n, int turn) { - struct pci1710_private *devpriv = dev->private; - struct comedi_cmd *cmd = &s->async->cmd; unsigned int val; int ret; int i; @@ -814,13 +799,8 @@ static int move_block_from_fifo(struct comedi_device *dev, return ret; } - comedi_buf_put(s, val & s->maxdata); - - s->async->cur_chan++; - if (s->async->cur_chan >= cmd->chanlist_len) { - s->async->cur_chan = 0; - devpriv->ai_act_scan++; - } + val &= s->maxdata; + comedi_buf_write_samples(s, &val, 1); } return 0; } @@ -829,48 +809,47 @@ static void pci1710_handle_fifo(struct comedi_device *dev, struct comedi_subdevice *s) { const struct boardtype *this_board = dev->board_ptr; - struct pci1710_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - int m, samplesinbuf; + unsigned int nsamples; + unsigned int m; m = inw(dev->iobase + PCI171x_STATUS); if (!(m & Status_FH)) { dev_dbg(dev->class_dev, "A/D FIFO not half full! (%4x)\n", m); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return; } if (m & Status_FF) { dev_dbg(dev->class_dev, "A/D FIFO Full status (Fatal Error!) (%4x)\n", m); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return; } - samplesinbuf = this_board->fifo_half_size; - if (samplesinbuf * sizeof(short) >= s->async->prealloc_bufsz) { - m = s->async->prealloc_bufsz / sizeof(short); + nsamples = this_board->fifo_half_size; + if (comedi_samples_to_bytes(s, nsamples) >= s->async->prealloc_bufsz) { + m = comedi_bytes_to_samples(s, s->async->prealloc_bufsz); if (move_block_from_fifo(dev, s, m, 0)) return; - samplesinbuf -= m; + nsamples -= m; } - if (samplesinbuf) { - if (move_block_from_fifo(dev, s, samplesinbuf, 1)) + if (nsamples) { + if (move_block_from_fifo(dev, s, nsamples, 1)) return; } if (cmd->stop_src == TRIG_COUNT && - devpriv->ai_act_scan >= cmd->stop_arg) { - /* all data sampled */ + s->async->scans_done >= cmd->stop_arg) { s->async->events |= COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return; } outb(0, dev->iobase + PCI171x_CLRINT); /* clear our INT request */ - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } /* @@ -928,9 +907,6 @@ static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) outb(0, dev->iobase + PCI171x_CLRFIFO); outb(0, dev->iobase + PCI171x_CLRINT); - devpriv->ai_act_scan = 0; - s->async->cur_chan = 0; - devpriv->CntrlReg &= Control_CNT0; if ((cmd->flags & CMDF_WAKE_EOS) == 0) devpriv->CntrlReg |= Control_ONEFH; @@ -1208,7 +1184,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, if (this_board->n_dichan) { s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_READABLE; s->n_chan = this_board->n_dichan; s->maxdata = 1; s->len_chanlist = this_board->n_dichan; @@ -1220,7 +1196,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, if (this_board->n_dochan) { s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE; s->n_chan = this_board->n_dochan; s->maxdata = 1; s->len_chanlist = this_board->n_dochan; diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 1610e2b406f3..65f854e1eb66 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -1,205 +1,124 @@ /* - comedi/drivers/pci1723.c - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 2000 David A. Schleef <ds@schleef.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + * adv_pci1723.c + * Comedi driver for the Advantech PCI-1723 card. + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 2000 David A. Schleef <ds@schleef.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ /* -Driver: adv_pci1723 -Description: Advantech PCI-1723 -Author: yonggang <rsmgnu@gmail.com>, Ian Abbott <abbotti@mev.co.uk> -Devices: [Advantech] PCI-1723 (adv_pci1723) -Updated: Mon, 14 Apr 2008 15:12:56 +0100 -Status: works - -Configuration Options: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - - If bus/slot is not specified, the first supported - PCI device found will be used. - -Subdevice 0 is 8-channel AO, 16-bit, range +/- 10 V. - -Subdevice 1 is 16-channel DIO. The channels are configurable as input or -output in 2 groups (0 to 7, 8 to 15). Configuring any channel implicitly -configures all channels in the same group. - -TODO: - -1. Add the two milliamp ranges to the AO subdevice (0 to 20 mA, 4 to 20 mA). -2. Read the initial ranges and values of the AO subdevice at start-up instead - of reinitializing them. -3. Implement calibration. -*/ + * Driver: adv_pci1723 + * Description: Advantech PCI-1723 + * Author: yonggang <rsmgnu@gmail.com>, Ian Abbott <abbotti@mev.co.uk> + * Devices: (Advantech) PCI-1723 [adv_pci1723] + * Updated: Mon, 14 Apr 2008 15:12:56 +0100 + * Status: works + * + * Configuration Options: not applicable, uses comedi PCI auto config + * + * Subdevice 0 is 8-channel AO, 16-bit, range +/- 10 V. + * + * Subdevice 1 is 16-channel DIO. The channels are configurable as + * input or output in 2 groups (0 to 7, 8 to 15). Configuring any + * channel implicitly configures all channels in the same group. + * + * TODO: + * 1. Add the two milliamp ranges to the AO subdevice (0 to 20 mA, + * 4 to 20 mA). + * 2. Read the initial ranges and values of the AO subdevice at + * start-up instead of reinitializing them. + * 3. Implement calibration. + */ #include <linux/module.h> #include <linux/pci.h> #include "../comedidev.h" -/* all the registers for the pci1723 board */ -#define PCI1723_DA(N) ((N)<<1) /* W: D/A register N (0 to 7) */ - -#define PCI1723_SYN_SET 0x12 /* synchronized set register */ -#define PCI1723_ALL_CHNNELE_SYN_STROBE 0x12 - /* synchronized status register */ - -#define PCI1723_RANGE_CALIBRATION_MODE 0x14 - /* range and calibration mode */ -#define PCI1723_RANGE_CALIBRATION_STATUS 0x14 - /* range and calibration status */ - -#define PCI1723_CONTROL_CMD_CALIBRATION_FUN 0x16 - /* - * SADC control command for - * calibration function - */ -#define PCI1723_STATUS_CMD_CALIBRATION_FUN 0x16 - /* - * SADC control status for - * calibration function - */ - -#define PCI1723_CALIBRATION_PARA_STROBE 0x18 - /* Calibration parameter strobe */ - -#define PCI1723_DIGITAL_IO_PORT_SET 0x1A /* Digital I/O port setting */ -#define PCI1723_DIGITAL_IO_PORT_MODE 0x1A /* Digital I/O port mode */ - -#define PCI1723_WRITE_DIGITAL_OUTPUT_CMD 0x1C - /* Write digital output command */ -#define PCI1723_READ_DIGITAL_INPUT_DATA 0x1C /* Read digital input data */ - -#define PCI1723_WRITE_CAL_CMD 0x1E /* Write calibration command */ -#define PCI1723_READ_CAL_STATUS 0x1E /* Read calibration status */ - -#define PCI1723_SYN_STROBE 0x20 /* Synchronized strobe */ - -#define PCI1723_RESET_ALL_CHN_STROBE 0x22 - /* Reset all D/A channels strobe */ - -#define PCI1723_RESET_CAL_CONTROL_STROBE 0x24 - /* - * Reset the calibration - * controller strobe - */ - -#define PCI1723_CHANGE_CHA_OUTPUT_TYPE_STROBE 0x26 - /* - * Change D/A channels output - * type strobe - */ - -#define PCI1723_SELECT_CALIBRATION 0x28 /* Select the calibration Ref_V */ - -struct pci1723_private { - unsigned char da_range[8]; /* D/A output range for each channel */ - unsigned short ao_data[8]; /* data output buffer */ -}; - /* - * The pci1723 card reset; + * PCI Bar 2 I/O Register map (dev->iobase) */ -static int pci1723_reset(struct comedi_device *dev) +#define PCI1723_AO_REG(x) (0x00 + ((x) * 2)) +#define PCI1723_BOARD_ID_REG 0x10 +#define PCI1723_BOARD_ID_MASK (0xf << 0) +#define PCI1723_SYNC_CTRL_REG 0x12 +#define PCI1723_SYNC_CTRL_ASYNC (0 << 0) +#define PCI1723_SYNC_CTRL_SYNC (1 << 0) +#define PCI1723_CTRL_REG 0x14 +#define PCI1723_CTRL_BUSY (1 << 15) +#define PCI1723_CTRL_INIT (1 << 14) +#define PCI1723_CTRL_SELF (1 << 8) +#define PCI1723_CTRL_IDX(x) (((x) & 0x3) << 6) +#define PCI1723_CTRL_RANGE(x) (((x) & 0x3) << 4) +#define PCI1723_CTRL_GAIN (0 << 3) +#define PCI1723_CTRL_OFFSET (1 << 3) +#define PCI1723_CTRL_CHAN(x) (((x) & 0x7) << 0) +#define PCI1723_CALIB_CTRL_REG 0x16 +#define PCI1723_CALIB_CTRL_CS (1 << 2) +#define PCI1723_CALIB_CTRL_DAT (1 << 1) +#define PCI1723_CALIB_CTRL_CLK (1 << 0) +#define PCI1723_CALIB_STROBE_REG 0x18 +#define PCI1723_DIO_CTRL_REG 0x1a +#define PCI1723_DIO_CTRL_HDIO (1 << 1) +#define PCI1723_DIO_CTRL_LDIO (1 << 0) +#define PCI1723_DIO_DATA_REG 0x1c +#define PCI1723_CALIB_DATA_REG 0x1e +#define PCI1723_SYNC_STROBE_REG 0x20 +#define PCI1723_RESET_AO_STROBE_REG 0x22 +#define PCI1723_RESET_CALIB_STROBE_REG 0x24 +#define PCI1723_RANGE_STROBE_REG 0x26 +#define PCI1723_VREF_REG 0x28 +#define PCI1723_VREF_NEG10V (0 << 0) +#define PCI1723_VREF_0V (1 << 0) +#define PCI1723_VREF_POS10V (3 << 0) + +static int pci1723_ao_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - struct pci1723_private *devpriv = dev->private; + unsigned int chan = CR_CHAN(insn->chanspec); int i; - outw(0x01, dev->iobase + PCI1723_SYN_SET); - /* set synchronous output mode */ - - for (i = 0; i < 8; i++) { - /* set all outputs to 0V */ - devpriv->ao_data[i] = 0x8000; - outw(devpriv->ao_data[i], dev->iobase + PCI1723_DA(i)); - /* set all ranges to +/- 10V */ - devpriv->da_range[i] = 0; - outw(((devpriv->da_range[i] << 4) | i), - PCI1723_RANGE_CALIBRATION_MODE); - } - - outw(0, dev->iobase + PCI1723_CHANGE_CHA_OUTPUT_TYPE_STROBE); - /* update ranges */ - outw(0, dev->iobase + PCI1723_SYN_STROBE); /* update outputs */ - - /* set asynchronous output mode */ - outw(0, dev->iobase + PCI1723_SYN_SET); - - return 0; -} - -static int pci1723_insn_read_ao(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - struct pci1723_private *devpriv = dev->private; - int n, chan; - - chan = CR_CHAN(insn->chanspec); - for (n = 0; n < insn->n; n++) - data[n] = devpriv->ao_data[chan]; + for (i = 0; i < insn->n; i++) { + unsigned int val = data[i]; - return n; -} - -/* - analog data output; -*/ -static int pci1723_ao_write_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - struct pci1723_private *devpriv = dev->private; - unsigned int chan = CR_CHAN(insn->chanspec); - int n; - - for (n = 0; n < insn->n; n++) { - devpriv->ao_data[chan] = data[n]; - outw(data[n], dev->iobase + PCI1723_DA(chan)); + outw(val, dev->iobase + PCI1723_AO_REG(chan)); + s->readback[chan] = val; } - return n; + return insn->n; } -/* - digital i/o config/query -*/ static int pci1723_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { unsigned int chan = CR_CHAN(insn->chanspec); - unsigned int mask; - unsigned short mode; + unsigned int mask = (chan < 8) ? 0x00ff : 0xff00; + unsigned short mode = 0x0000; /* assume output */ int ret; - if (chan < 8) - mask = 0x00ff; - else - mask = 0xff00; - ret = comedi_dio_insn_config(dev, s, insn, data, mask); if (ret) return ret; - /* update hardware DIO mode */ - mode = 0x0000; /* assume output */ if (!(s->io_bits & 0x00ff)) - mode |= 0x0001; /* low byte input */ + mode |= PCI1723_DIO_CTRL_LDIO; /* low byte input */ if (!(s->io_bits & 0xff00)) - mode |= 0x0002; /* high byte input */ - outw(mode, dev->iobase + PCI1723_DIGITAL_IO_PORT_SET); + mode |= PCI1723_DIO_CTRL_HDIO; /* high byte input */ + outw(mode, dev->iobase + PCI1723_DIO_CTRL_REG); return insn->n; } @@ -210,24 +129,21 @@ static int pci1723_dio_insn_bits(struct comedi_device *dev, unsigned int *data) { if (comedi_dio_update_state(s, data)) - outw(s->state, dev->iobase + PCI1723_WRITE_DIGITAL_OUTPUT_CMD); + outw(s->state, dev->iobase + PCI1723_DIO_DATA_REG); - data[1] = inw(dev->iobase + PCI1723_READ_DIGITAL_INPUT_DATA); + data[1] = inw(dev->iobase + PCI1723_DIO_DATA_REG); return insn->n; } static int pci1723_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - struct pci1723_private *devpriv; struct comedi_subdevice *s; + unsigned int val; int ret; - - devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); - if (!devpriv) - return -ENOMEM; + int i; ret = comedi_pci_enable(dev); if (ret) @@ -239,61 +155,57 @@ static int pci1723_auto_attach(struct comedi_device *dev, return ret; s = &dev->subdevices[0]; - dev->write_subdev = s; s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 8; s->maxdata = 0xffff; - s->len_chanlist = 8; s->range_table = &range_bipolar10; - s->insn_write = pci1723_ao_write_winsn; - s->insn_read = pci1723_insn_read_ao; + s->insn_write = pci1723_ao_insn_write; + + ret = comedi_alloc_subdev_readback(s); + if (ret) + return ret; + + /* synchronously reset all analog outputs to 0V, +/-10V range */ + outw(PCI1723_SYNC_CTRL_SYNC, dev->iobase + PCI1723_SYNC_CTRL_REG); + for (i = 0; i < s->n_chan; i++) { + outw(PCI1723_CTRL_RANGE(0) | PCI1723_CTRL_CHAN(i), + PCI1723_CTRL_REG); + outw(0, dev->iobase + PCI1723_RANGE_STROBE_REG); + + outw(0x8000, dev->iobase + PCI1723_AO_REG(i)); + s->readback[i] = 0x8000; + } + outw(0, dev->iobase + PCI1723_SYNC_STROBE_REG); + + /* disable syncronous control */ + outw(PCI1723_SYNC_CTRL_ASYNC, dev->iobase + PCI1723_SYNC_CTRL_REG); s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 16; s->maxdata = 1; - s->len_chanlist = 16; s->range_table = &range_digital; s->insn_config = pci1723_dio_insn_config; s->insn_bits = pci1723_dio_insn_bits; - /* read DIO config */ - switch (inw(dev->iobase + PCI1723_DIGITAL_IO_PORT_MODE) & 0x03) { - case 0x00: /* low byte output, high byte output */ - s->io_bits = 0xFFFF; - break; - case 0x01: /* low byte input, high byte output */ - s->io_bits = 0xFF00; - break; - case 0x02: /* low byte output, high byte input */ - s->io_bits = 0x00FF; - break; - case 0x03: /* low byte input, high byte input */ - s->io_bits = 0x0000; - break; - } - /* read DIO port state */ - s->state = inw(dev->iobase + PCI1723_READ_DIGITAL_INPUT_DATA); - - pci1723_reset(dev); + /* get initial DIO direction and state */ + val = inw(dev->iobase + PCI1723_DIO_CTRL_REG); + if (!(val & PCI1723_DIO_CTRL_LDIO)) + s->io_bits |= 0x00ff; /* low byte output */ + if (!(val & PCI1723_DIO_CTRL_HDIO)) + s->io_bits |= 0xff00; /* high byte output */ + s->state = inw(dev->iobase + PCI1723_DIO_DATA_REG); return 0; } -static void pci1723_detach(struct comedi_device *dev) -{ - if (dev->iobase) - pci1723_reset(dev); - comedi_pci_detach(dev); -} - static struct comedi_driver adv_pci1723_driver = { .driver_name = "adv_pci1723", .module = THIS_MODULE, .auto_attach = pci1723_auto_attach, - .detach = pci1723_detach, + .detach = comedi_pci_detach, }; static int adv_pci1723_pci_probe(struct pci_dev *dev, @@ -318,5 +230,5 @@ static struct pci_driver adv_pci1723_pci_driver = { module_comedi_pci_driver(adv_pci1723_driver, adv_pci1723_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); +MODULE_DESCRIPTION("Advantech PCI-1723 Comedi driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/adv_pci1724.c b/drivers/staging/comedi/drivers/adv_pci1724.c index 2697758b1ed9..a8d28403262e 100644 --- a/drivers/staging/comedi/drivers/adv_pci1724.c +++ b/drivers/staging/comedi/drivers/adv_pci1724.c @@ -1,122 +1,76 @@ /* - comedi/drivers/adv_pci1724.c - This is a driver for the Advantech PCI-1724U card. - - Author: Frank Mori Hess <fmh6jj@gmail.com> - Copyright (C) 2013 GnuBIO Inc - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 1997-8 David A. Schleef <ds@schleef.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ + * adv_pci1724.c + * Comedi driver for the Advantech PCI-1724U card. + * + * Author: Frank Mori Hess <fmh6jj@gmail.com> + * Copyright (C) 2013 GnuBIO Inc + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ /* - -Driver: adv_1724 -Description: Advantech PCI-1724U -Author: Frank Mori Hess <fmh6jj@gmail.com> -Status: works -Updated: 2013-02-09 -Devices: [Advantech] PCI-1724U (adv_pci1724) - -Subdevice 0 is the analog output. -Subdevice 1 is the offset calibration for the analog output. -Subdevice 2 is the gain calibration for the analog output. - -The calibration offset and gains have quite a large effect -on the analog output, so it is possible to adjust the analog output to -have an output range significantly different from the board's -nominal output ranges. For a calibrated +/- 10V range, the analog -output's offset will be set somewhere near mid-range (0x2000) and its -gain will be near maximum (0x3fff). - -There is really no difference between the board's documented 0-20mA -versus 4-20mA output ranges. To pick one or the other is simply a matter -of adjusting the offset and gain calibration until the board outputs in -the desired range. - -Configuration options: - None - -Manual configuration of comedi devices is not supported by this driver; -supported PCI devices are configured as comedi devices automatically. - -*/ + * Driver: adv_pci1724 + * Description: Advantech PCI-1724U + * Devices: (Advantech) PCI-1724U [adv_pci1724] + * Author: Frank Mori Hess <fmh6jj@gmail.com> + * Updated: 2013-02-09 + * Status: works + * + * Configuration Options: not applicable, uses comedi PCI auto config + * + * Subdevice 0 is the analog output. + * Subdevice 1 is the offset calibration for the analog output. + * Subdevice 2 is the gain calibration for the analog output. + * + * The calibration offset and gains have quite a large effect on the + * analog output, so it is possible to adjust the analog output to + * have an output range significantly different from the board's + * nominal output ranges. For a calibrated +/-10V range, the analog + * output's offset will be set somewhere near mid-range (0x2000) and + * its gain will be near maximum (0x3fff). + * + * There is really no difference between the board's documented 0-20mA + * versus 4-20mA output ranges. To pick one or the other is simply a + * matter of adjusting the offset and gain calibration until the board + * outputs in the desired range. + */ #include <linux/module.h> -#include <linux/delay.h> #include <linux/pci.h> #include "../comedidev.h" -#define PCI_VENDOR_ID_ADVANTECH 0x13fe - -#define NUM_AO_CHANNELS 32 - -/* register offsets */ -enum board_registers { - DAC_CONTROL_REG = 0x0, - SYNC_OUTPUT_REG = 0x4, - EEPROM_CONTROL_REG = 0x8, - SYNC_OUTPUT_TRIGGER_REG = 0xc, - BOARD_ID_REG = 0x10 -}; - -/* bit definitions for registers */ -enum dac_control_contents { - DAC_DATA_MASK = 0x3fff, - DAC_DESTINATION_MASK = 0xc000, - DAC_NORMAL_MODE = 0xc000, - DAC_OFFSET_MODE = 0x8000, - DAC_GAIN_MODE = 0x4000, - DAC_CHANNEL_SELECT_MASK = 0xf0000, - DAC_GROUP_SELECT_MASK = 0xf00000 -}; - -static uint32_t dac_data_bits(uint16_t dac_data) -{ - return dac_data & DAC_DATA_MASK; -} - -static uint32_t dac_channel_select_bits(unsigned channel) -{ - return (channel << 16) & DAC_CHANNEL_SELECT_MASK; -} - -static uint32_t dac_group_select_bits(unsigned group) -{ - return (1 << (20 + group)) & DAC_GROUP_SELECT_MASK; -} - -static uint32_t dac_channel_and_group_select_bits(unsigned comedi_channel) -{ - return dac_channel_select_bits(comedi_channel % 8) | - dac_group_select_bits(comedi_channel / 8); -} - -enum sync_output_contents { - SYNC_MODE = 0x1, - DAC_BUSY = 0x2, /* dac state machine is not ready */ -}; - -enum sync_output_trigger_contents { - SYNC_TRIGGER_BITS = 0x0 /* any value works */ -}; - -enum board_id_contents { - BOARD_ID_MASK = 0xf -}; - -static const struct comedi_lrange ao_ranges_1724 = { +/* + * PCI bar 2 Register I/O map (dev->iobase) + */ +#define PCI1724_DAC_CTRL_REG 0x00 +#define PCI1724_DAC_CTRL_GX(x) (1 << (20 + ((x) / 8))) +#define PCI1724_DAC_CTRL_CX(x) (((x) % 8) << 16) +#define PCI1724_DAC_CTRL_MODE_GAIN (1 << 14) +#define PCI1724_DAC_CTRL_MODE_OFFSET (2 << 14) +#define PCI1724_DAC_CTRL_MODE_NORMAL (3 << 14) +#define PCI1724_DAC_CTRL_MODE_MASK (3 << 14) +#define PCI1724_DAC_CTRL_DATA(x) (((x) & 0x3fff) << 0) +#define PCI1724_SYNC_CTRL_REG 0x04 +#define PCI1724_SYNC_CTRL_DACSTAT (1 << 1) +#define PCI1724_SYNC_CTRL_SYN (1 << 0) +#define PCI1724_EEPROM_CTRL_REG 0x08 +#define PCI1724_SYNC_TRIG_REG 0x0c /* any value works */ +#define PCI1724_BOARD_ID_REG 0x10 +#define PCI1724_BOARD_ID_MASK (0xf << 0) + +static const struct comedi_lrange adv_pci1724_ao_ranges = { 4, { BIP_RANGE(10), RANGE_mA(0, 20), @@ -125,254 +79,120 @@ static const struct comedi_lrange ao_ranges_1724 = { } }; -/* this structure is for data unique to this hardware driver. */ -struct adv_pci1724_private { - int ao_value[NUM_AO_CHANNELS]; - int offset_value[NUM_AO_CHANNELS]; - int gain_value[NUM_AO_CHANNELS]; -}; - -static int wait_for_dac_idle(struct comedi_device *dev) -{ - static const int timeout = 10000; - int i; - - for (i = 0; i < timeout; ++i) { - if ((inl(dev->iobase + SYNC_OUTPUT_REG) & DAC_BUSY) == 0) - break; - udelay(1); - } - if (i == timeout) { - dev_err(dev->class_dev, - "Timed out waiting for dac to become idle\n"); - return -EIO; - } - return 0; -} - -static int set_dac(struct comedi_device *dev, unsigned mode, unsigned channel, - unsigned data) -{ - int retval; - unsigned control_bits; - - retval = wait_for_dac_idle(dev); - if (retval < 0) - return retval; - - control_bits = mode; - control_bits |= dac_channel_and_group_select_bits(channel); - control_bits |= dac_data_bits(data); - outl(control_bits, dev->iobase + DAC_CONTROL_REG); - return 0; -} - -static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int adv_pci1724_dac_idle(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned long context) { - struct adv_pci1724_private *devpriv = dev->private; - int channel = CR_CHAN(insn->chanspec); - int retval; - int i; + unsigned int status; - /* turn off synchronous mode */ - outl(0, dev->iobase + SYNC_OUTPUT_REG); - - for (i = 0; i < insn->n; ++i) { - retval = set_dac(dev, DAC_NORMAL_MODE, channel, data[i]); - if (retval < 0) - return retval; - devpriv->ao_value[channel] = data[i]; - } - return insn->n; + status = inl(dev->iobase + PCI1724_SYNC_CTRL_REG); + if ((status & PCI1724_SYNC_CTRL_DACSTAT) == 0) + return 0; + return -EBUSY; } -static int ao_readback_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int adv_pci1724_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - struct adv_pci1724_private *devpriv = dev->private; - int channel = CR_CHAN(insn->chanspec); - int i; - - if (devpriv->ao_value[channel] < 0) { - dev_err(dev->class_dev, - "Cannot read back channels which have not yet been written to\n"); - return -EIO; - } - for (i = 0; i < insn->n; i++) - data[i] = devpriv->ao_value[channel]; - - return insn->n; -} - -static int offset_write_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - struct adv_pci1724_private *devpriv = dev->private; - int channel = CR_CHAN(insn->chanspec); - int retval; - int i; - - /* turn off synchronous mode */ - outl(0, dev->iobase + SYNC_OUTPUT_REG); - - for (i = 0; i < insn->n; ++i) { - retval = set_dac(dev, DAC_OFFSET_MODE, channel, data[i]); - if (retval < 0) - return retval; - devpriv->offset_value[channel] = data[i]; - } - - return insn->n; -} - -static int offset_read_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - struct adv_pci1724_private *devpriv = dev->private; - unsigned int channel = CR_CHAN(insn->chanspec); + unsigned long mode = (unsigned long)s->private; + unsigned int chan = CR_CHAN(insn->chanspec); + unsigned int ctrl; + int ret; int i; - if (devpriv->offset_value[channel] < 0) { - dev_err(dev->class_dev, - "Cannot read back channels which have not yet been written to\n"); - return -EIO; - } - for (i = 0; i < insn->n; i++) - data[i] = devpriv->offset_value[channel]; - - return insn->n; -} - -static int gain_write_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - struct adv_pci1724_private *devpriv = dev->private; - int channel = CR_CHAN(insn->chanspec); - int retval; - int i; + ctrl = PCI1724_DAC_CTRL_GX(chan) | PCI1724_DAC_CTRL_CX(chan) | mode; /* turn off synchronous mode */ - outl(0, dev->iobase + SYNC_OUTPUT_REG); + outl(0, dev->iobase + PCI1724_SYNC_CTRL_REG); for (i = 0; i < insn->n; ++i) { - retval = set_dac(dev, DAC_GAIN_MODE, channel, data[i]); - if (retval < 0) - return retval; - devpriv->gain_value[channel] = data[i]; - } + unsigned int val = data[i]; - return insn->n; -} + ret = comedi_timeout(dev, s, insn, adv_pci1724_dac_idle, 0); + if (ret) + return ret; -static int gain_read_insn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data) -{ - struct adv_pci1724_private *devpriv = dev->private; - unsigned int channel = CR_CHAN(insn->chanspec); - int i; + outl(ctrl | PCI1724_DAC_CTRL_DATA(val), + dev->iobase + PCI1724_DAC_CTRL_REG); - if (devpriv->gain_value[channel] < 0) { - dev_err(dev->class_dev, - "Cannot read back channels which have not yet been written to\n"); - return -EIO; + s->readback[chan] = val; } - for (i = 0; i < insn->n; i++) - data[i] = devpriv->gain_value[channel]; return insn->n; } -/* Allocate and initialize the subdevice structures. - */ -static int setup_subdevices(struct comedi_device *dev) +static int adv_pci1724_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct comedi_subdevice *s; + unsigned int board_id; int ret; + ret = comedi_pci_enable(dev); + if (ret) + return ret; + + dev->iobase = pci_resource_start(pcidev, 2); + board_id = inl(dev->iobase + PCI1724_BOARD_ID_REG); + dev_info(dev->class_dev, "board id: %d\n", + board_id & PCI1724_BOARD_ID_MASK); + ret = comedi_alloc_subdevices(dev, 3); if (ret) return ret; - /* analog output subdevice */ + /* Analog Output subdevice */ s = &dev->subdevices[0]; - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND; - s->n_chan = NUM_AO_CHANNELS; - s->maxdata = 0x3fff; - s->range_table = &ao_ranges_1724; - s->insn_read = ao_readback_insn; - s->insn_write = ao_winsn; + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND; + s->n_chan = 32; + s->maxdata = 0x3fff; + s->range_table = &adv_pci1724_ao_ranges; + s->insn_write = adv_pci1724_insn_write; + s->private = (void *)PCI1724_DAC_CTRL_MODE_NORMAL; + + ret = comedi_alloc_subdev_readback(s); + if (ret) + return ret; - /* offset calibration */ + /* Offset Calibration subdevice */ s = &dev->subdevices[1]; - s->type = COMEDI_SUBD_CALIB; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; - s->n_chan = NUM_AO_CHANNELS; - s->insn_read = offset_read_insn; - s->insn_write = offset_write_insn; - s->maxdata = 0x3fff; + s->type = COMEDI_SUBD_CALIB; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; + s->n_chan = 32; + s->maxdata = 0x3fff; + s->insn_write = adv_pci1724_insn_write; + s->private = (void *)PCI1724_DAC_CTRL_MODE_OFFSET; + + ret = comedi_alloc_subdev_readback(s); + if (ret) + return ret; - /* gain calibration */ + /* Gain Calibration subdevice */ s = &dev->subdevices[2]; - s->type = COMEDI_SUBD_CALIB; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; - s->n_chan = NUM_AO_CHANNELS; - s->insn_read = gain_read_insn; - s->insn_write = gain_write_insn; - s->maxdata = 0x3fff; - - return 0; -} - -static int adv_pci1724_auto_attach(struct comedi_device *dev, - unsigned long context_unused) -{ - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - struct adv_pci1724_private *devpriv; - int i; - int retval; - unsigned int board_id; - - devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); - if (!devpriv) - return -ENOMEM; - - /* init software copies of output values to indicate we don't know - * what the output value is since it has never been written. */ - for (i = 0; i < NUM_AO_CHANNELS; ++i) { - devpriv->ao_value[i] = -1; - devpriv->offset_value[i] = -1; - devpriv->gain_value[i] = -1; - } - - retval = comedi_pci_enable(dev); - if (retval) - return retval; - - dev->iobase = pci_resource_start(pcidev, 2); - board_id = inl(dev->iobase + BOARD_ID_REG) & BOARD_ID_MASK; - dev_info(dev->class_dev, "board id: %d\n", board_id); - - retval = setup_subdevices(dev); - if (retval < 0) - return retval; + s->type = COMEDI_SUBD_CALIB; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; + s->n_chan = 32; + s->maxdata = 0x3fff; + s->insn_write = adv_pci1724_insn_write; + s->private = (void *)PCI1724_DAC_CTRL_MODE_GAIN; + + ret = comedi_alloc_subdev_readback(s); + if (ret) + return ret; - dev_info(dev->class_dev, "%s (pci %s) attached, board id: %u\n", - dev->board_name, pci_name(pcidev), board_id); return 0; } static struct comedi_driver adv_pci1724_driver = { - .driver_name = "adv_pci1724", - .module = THIS_MODULE, - .auto_attach = adv_pci1724_auto_attach, - .detach = comedi_pci_detach, + .driver_name = "adv_pci1724", + .module = THIS_MODULE, + .auto_attach = adv_pci1724_auto_attach, + .detach = comedi_pci_detach, }; static int adv_pci1724_pci_probe(struct pci_dev *dev, @@ -389,12 +209,11 @@ static const struct pci_device_id adv_pci1724_pci_table[] = { MODULE_DEVICE_TABLE(pci, adv_pci1724_pci_table); static struct pci_driver adv_pci1724_pci_driver = { - .name = "adv_pci1724", - .id_table = adv_pci1724_pci_table, - .probe = adv_pci1724_pci_probe, - .remove = comedi_pci_auto_unconfig, + .name = "adv_pci1724", + .id_table = adv_pci1724_pci_table, + .probe = adv_pci1724_pci_probe, + .remove = comedi_pci_auto_unconfig, }; - module_comedi_pci_driver(adv_pci1724_driver, adv_pci1724_pci_driver); MODULE_AUTHOR("Frank Mori Hess <fmh6jj@gmail.com>"); diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index f2e2d7e163bf..09609d6d02da 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -930,7 +930,7 @@ static int pci1760_attach(struct comedi_device *dev) s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_READABLE; s->n_chan = 8; s->maxdata = 1; s->len_chanlist = 8; @@ -939,7 +939,7 @@ static int pci1760_attach(struct comedi_device *dev) s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 8; s->maxdata = 1; s->len_chanlist = 8; @@ -978,7 +978,7 @@ static int pci_dio_add_di(struct comedi_device *dev, const struct dio_boardtype *this_board = dev->board_ptr; s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | d->specflags; + s->subdev_flags = SDF_READABLE | d->specflags; if (d->chans > 16) s->subdev_flags |= SDF_LSAMPL; s->n_chan = d->chans; @@ -1008,7 +1008,7 @@ static int pci_dio_add_do(struct comedi_device *dev, const struct dio_boardtype *this_board = dev->board_ptr; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE; if (d->chans > 16) s->subdev_flags |= SDF_LSAMPL; s->n_chan = d->chans; diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c index 538277a691b2..fbc3e5aa94cb 100644 --- a/drivers/staging/comedi/drivers/aio_aio12_8.c +++ b/drivers/staging/comedi/drivers/aio_aio12_8.c @@ -212,7 +212,6 @@ static int aio_aio12_8_attach(struct comedi_device *dev, s->maxdata = 0x0fff; s->range_table = &range_aio_aio12_8; s->insn_write = aio_aio12_8_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/amcc_s5933.h b/drivers/staging/comedi/drivers/amcc_s5933.h index cf6a497b092c..d4b8c0195bd3 100644 --- a/drivers/staging/comedi/drivers/amcc_s5933.h +++ b/drivers/staging/comedi/drivers/amcc_s5933.h @@ -110,6 +110,8 @@ #define AGCSTS_TCZERO_MASK 0x000000c0 #define AGCSTS_FIFO_ST_MASK 0x0000003f +#define AGCSTS_TC_ENABLE 0x10000000 + #define AGCSTS_RESET_MBFLAGS 0x08000000 #define AGCSTS_RESET_P2A_FIFO 0x04000000 #define AGCSTS_RESET_A2P_FIFO 0x02000000 diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c index 2c1bfb09601d..26aad705aad3 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_common.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c @@ -120,7 +120,6 @@ struct dio200_subdev_intr { unsigned int ofs; unsigned int valid_isns; unsigned int enabled_isns; - unsigned int stopcount; bool active:1; }; @@ -256,7 +255,6 @@ static void dio200_read_scan_intr(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int triggered) { - struct dio200_subdev_intr *subpriv = s->private; struct comedi_cmd *cmd = &s->async->cmd; unsigned short val; unsigned int n, ch; @@ -267,26 +265,12 @@ static void dio200_read_scan_intr(struct comedi_device *dev, if (triggered & (1U << ch)) val |= (1U << n); } - /* Write the scan to the buffer. */ - if (comedi_buf_put(s, val)) { - s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS); - } else { - /* Error! Stop acquisition. */ - dio200_stop_intr(dev, s); - s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW; - dev_err(dev->class_dev, "buffer overflow\n"); - } - /* Check for end of acquisition. */ - if (cmd->stop_src == TRIG_COUNT) { - if (subpriv->stopcount > 0) { - subpriv->stopcount--; - if (subpriv->stopcount == 0) { - s->async->events |= COMEDI_CB_EOA; - dio200_stop_intr(dev, s); - } - } - } + comedi_buf_write_samples(s, &val, 1); + + if (cmd->stop_src == TRIG_COUNT && + s->async->scans_done >= cmd->stop_arg) + s->async->events |= COMEDI_CB_EOA; } static int dio200_handle_read_intr(struct comedi_device *dev, @@ -297,13 +281,11 @@ static int dio200_handle_read_intr(struct comedi_device *dev, unsigned triggered; unsigned intstat; unsigned cur_enabled; - unsigned int oldevents; unsigned long flags; triggered = 0; spin_lock_irqsave(&subpriv->spinlock, flags); - oldevents = s->async->events; if (board->has_int_sce) { /* * Collect interrupt sources that have triggered and disable @@ -356,8 +338,7 @@ static int dio200_handle_read_intr(struct comedi_device *dev, } spin_unlock_irqrestore(&subpriv->spinlock, flags); - if (oldevents != s->async->events) - comedi_event(dev, s); + comedi_handle_events(dev, s); return (triggered != 0); } @@ -436,7 +417,6 @@ static int dio200_subdev_intr_cmd(struct comedi_device *dev, spin_lock_irqsave(&subpriv->spinlock, flags); subpriv->active = true; - subpriv->stopcount = cmd->stop_arg; if (cmd->start_src == TRIG_INT) s->async->inttrig = dio200_inttrig_start_intr; @@ -469,7 +449,7 @@ static int dio200_subdev_intr_init(struct comedi_device *dev, dio200_write8(dev, subpriv->ofs, 0); s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_CMD_READ | SDF_PACKED; if (board->has_int_sce) { s->n_chan = DIO200_MAX_ISNS; s->len_chanlist = DIO200_MAX_ISNS; diff --git a/drivers/staging/comedi/drivers/amplc_pc236_common.c b/drivers/staging/comedi/drivers/amplc_pc236_common.c index 963c5d868b81..be87172d1f3f 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236_common.c +++ b/drivers/staging/comedi/drivers/amplc_pc236_common.c @@ -135,9 +135,8 @@ static irqreturn_t pc236_interrupt(int irq, void *d) handled = pc236_intr_check(dev); if (dev->attached && handled) { - comedi_buf_put(s, 0); - s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; - comedi_event(dev, s); + comedi_buf_write_samples(s, &s->state, 1); + comedi_handle_events(dev, s); } return IRQ_RETVAL(handled); } diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index f8e551d8fd9e..b1946ce6ecc1 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -83,7 +83,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) s = &dev->subdevices[0]; /* digital output subdevice */ s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 3bbbb57f19d6..924c8298c7a0 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -381,7 +381,6 @@ struct pci224_private { unsigned short daccon; unsigned int cached_div1; unsigned int cached_div2; - unsigned int ao_stop_count; unsigned short ao_enab; /* max 16 channels so 'short' will do */ unsigned char intsce; }; @@ -514,30 +513,21 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, { struct pci224_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - unsigned int bytes_per_scan = cfc_bytes_per_scan(s); - unsigned int num_scans; + unsigned int num_scans = comedi_nscans_left(s, 0); unsigned int room; unsigned short dacstat; unsigned int i, n; - /* Determine number of scans available in buffer. */ - num_scans = comedi_buf_read_n_available(s) / bytes_per_scan; - if (cmd->stop_src == TRIG_COUNT) { - /* Fixed number of scans. */ - if (num_scans > devpriv->ao_stop_count) - num_scans = devpriv->ao_stop_count; - } - /* Determine how much room is in the FIFO (in samples). */ dacstat = inw(dev->iobase + PCI224_DACCON); switch (dacstat & PCI224_DACCON_FIFOFL_MASK) { case PCI224_DACCON_FIFOFL_EMPTY: room = PCI224_FIFO_ROOM_EMPTY; if (cmd->stop_src == TRIG_COUNT && - devpriv->ao_stop_count == 0) { + s->async->scans_done >= cmd->stop_arg) { /* FIFO empty at end of counted acquisition. */ s->async->events |= COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return; } break; @@ -568,25 +558,23 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, /* Process scans. */ for (n = 0; n < num_scans; n++) { - cfc_read_array_from_buffer(s, &devpriv->ao_scan_vals[0], - bytes_per_scan); + comedi_buf_read_samples(s, &devpriv->ao_scan_vals[0], + cmd->chanlist_len); for (i = 0; i < cmd->chanlist_len; i++) { outw(devpriv->ao_scan_vals[devpriv->ao_scan_order[i]], dev->iobase + PCI224_DACDATA); } } - if (cmd->stop_src == TRIG_COUNT) { - devpriv->ao_stop_count -= num_scans; - if (devpriv->ao_stop_count == 0) { - /* - * Change FIFO interrupt trigger level to wait - * until FIFO is empty. - */ - devpriv->daccon = COMBINE(devpriv->daccon, - PCI224_DACCON_FIFOINTR_EMPTY, - PCI224_DACCON_FIFOINTR_MASK); - outw(devpriv->daccon, dev->iobase + PCI224_DACCON); - } + if (cmd->stop_src == TRIG_COUNT && + s->async->scans_done >= cmd->stop_arg) { + /* + * Change FIFO interrupt trigger level to wait + * until FIFO is empty. + */ + devpriv->daccon = COMBINE(devpriv->daccon, + PCI224_DACCON_FIFOINTR_EMPTY, + PCI224_DACCON_FIFOINTR_MASK); + outw(devpriv->daccon, dev->iobase + PCI224_DACCON); } if ((devpriv->daccon & PCI224_DACCON_TRIG_MASK) == PCI224_DACCON_TRIG_NONE) { @@ -618,7 +606,7 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, outw(devpriv->daccon, dev->iobase + PCI224_DACCON); } - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static int pci224_ao_inttrig_start(struct comedi_device *dev, @@ -908,14 +896,6 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (cmd->scan_begin_src == TRIG_TIMER) pci224_ao_start_pacer(dev, s); - /* - * Sort out end of acquisition. - */ - if (cmd->stop_src == TRIG_COUNT) - devpriv->ao_stop_count = cmd->stop_arg; - else /* TRIG_EXT | TRIG_NONE */ - devpriv->ao_stop_count = 0; - spin_lock_irqsave(&devpriv->ao_spinlock, flags); if (cmd->start_src == TRIG_INT) { s->async->inttrig = pci224_ao_inttrig_start; @@ -1095,7 +1075,6 @@ pci224_auto_attach(struct comedi_device *dev, unsigned long context_model) s->maxdata = (1 << thisboard->ao_bits) - 1; s->range_table = thisboard->ao_range; s->insn_write = pci224_ao_insn_write; - s->insn_read = comedi_readback_insn_read; s->len_chanlist = s->n_chan; dev->write_subdev = s; s->do_cmd = pci224_ao_cmd; diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 01796cd28e5b..49806a5e514c 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -35,7 +35,7 @@ * automatically. * * The PCI230+ and PCI260+ have the same PCI device IDs as the PCI230 and - * PCI260, but can be distinguished by the the size of the PCI regions. A + * PCI260, but can be distinguished by the size of the PCI regions. A * card will be configured as a "+" model if detected as such. * * Subdevices: @@ -490,9 +490,6 @@ struct pci230_private { spinlock_t ai_stop_spinlock; /* Spin lock for stopping AI command */ spinlock_t ao_stop_spinlock; /* Spin lock for stopping AO command */ unsigned long daqio; /* PCI230's DAQ I/O space */ - unsigned int ai_scan_count; /* Number of AI scans remaining */ - unsigned int ai_scan_pos; /* Current position within AI scan */ - unsigned int ao_scan_count; /* Number of AO scans remaining. */ int intr_cpuid; /* ID of CPU running ISR */ unsigned short hwver; /* Hardware version (for '+' models) */ unsigned short adccon; /* ADCCON register value */ @@ -1074,37 +1071,27 @@ static void pci230_ao_stop(struct comedi_device *dev, static void pci230_handle_ao_nofifo(struct comedi_device *dev, struct comedi_subdevice *s) { - struct pci230_private *devpriv = dev->private; - unsigned short data; - int i, ret; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; + unsigned short data; + int i; - if (cmd->stop_src == TRIG_COUNT && devpriv->ao_scan_count == 0) + if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg) return; + for (i = 0; i < cmd->chanlist_len; i++) { unsigned int chan = CR_CHAN(cmd->chanlist[i]); - /* Read sample from Comedi's circular buffer. */ - ret = comedi_buf_get(s, &data); - if (ret == 0) { - s->async->events |= COMEDI_CB_OVERFLOW; - pci230_ao_stop(dev, s); - dev_err(dev->class_dev, "AO buffer underrun\n"); + if (!comedi_buf_read_samples(s, &data, 1)) { + async->events |= COMEDI_CB_OVERFLOW; return; } pci230_ao_write_nofifo(dev, data, chan); s->readback[chan] = data; } - async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; - if (cmd->stop_src == TRIG_COUNT) { - devpriv->ao_scan_count--; - if (devpriv->ao_scan_count == 0) { - /* End of acquisition. */ - async->events |= COMEDI_CB_EOA; - pci230_ao_stop(dev, s); - } - } + + if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg) + async->events |= COMEDI_CB_EOA; } /* @@ -1117,26 +1104,18 @@ static bool pci230_handle_ao_fifo(struct comedi_device *dev, struct pci230_private *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; - unsigned int num_scans; + unsigned int num_scans = comedi_nscans_left(s, 0); unsigned int room; unsigned short dacstat; unsigned int i, n; unsigned int events = 0; - bool running; /* Get DAC FIFO status. */ dacstat = inw(devpriv->daqio + PCI230_DACCON); - /* Determine number of scans available in buffer. */ - num_scans = comedi_buf_read_n_available(s) / cfc_bytes_per_scan(s); - if (cmd->stop_src == TRIG_COUNT) { - /* Fixed number of scans. */ - if (num_scans > devpriv->ao_scan_count) - num_scans = devpriv->ao_scan_count; - if (devpriv->ao_scan_count == 0) { - /* End of acquisition. */ - events |= COMEDI_CB_EOA; - } - } + + if (cmd->stop_src == TRIG_COUNT && num_scans == 0) + events |= COMEDI_CB_EOA; + if (events == 0) { /* Check for FIFO underrun. */ if (dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) { @@ -1175,27 +1154,22 @@ static bool pci230_handle_ao_fifo(struct comedi_device *dev, unsigned int chan = CR_CHAN(cmd->chanlist[i]); unsigned short datum; - comedi_buf_get(s, &datum); + comedi_buf_read_samples(s, &datum, 1); pci230_ao_write_fifo(dev, datum, chan); s->readback[chan] = datum; } } - events |= COMEDI_CB_EOS | COMEDI_CB_BLOCK; - if (cmd->stop_src == TRIG_COUNT) { - devpriv->ao_scan_count -= num_scans; - if (devpriv->ao_scan_count == 0) { - /* - * All data for the command has been written - * to FIFO. Set FIFO interrupt trigger level - * to 'empty'. - */ - devpriv->daccon = - (devpriv->daccon & - ~PCI230P2_DAC_INT_FIFO_MASK) | - PCI230P2_DAC_INT_FIFO_EMPTY; - outw(devpriv->daccon, - devpriv->daqio + PCI230_DACCON); - } + + if (cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) { + /* + * All data for the command has been written + * to FIFO. Set FIFO interrupt trigger level + * to 'empty'. + */ + devpriv->daccon &= ~PCI230P2_DAC_INT_FIFO_MASK; + devpriv->daccon |= PCI230P2_DAC_INT_FIFO_EMPTY; + outw(devpriv->daccon, devpriv->daqio + PCI230_DACCON); } /* Check if FIFO underrun occurred while writing to FIFO. */ dacstat = inw(devpriv->daqio + PCI230_DACCON); @@ -1204,15 +1178,8 @@ static bool pci230_handle_ao_fifo(struct comedi_device *dev, events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; } } - if (events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) { - /* Stopping AO due to completion or error. */ - pci230_ao_stop(dev, s); - running = false; - } else { - running = true; - } async->events |= events; - return running; + return !(async->events & COMEDI_CB_CANCEL_MASK); } static int pci230_ao_inttrig_scan_begin(struct comedi_device *dev, @@ -1235,7 +1202,7 @@ static int pci230_ao_inttrig_scan_begin(struct comedi_device *dev, /* Not using DAC FIFO. */ spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags); pci230_handle_ao_nofifo(dev, s); - comedi_event(dev, s); + comedi_handle_events(dev, s); } else { /* Using DAC FIFO. */ /* Read DACSWTRIG register to trigger conversion. */ @@ -1265,7 +1232,7 @@ static void pci230_ao_start(struct comedi_device *dev, /* Preload FIFO data. */ run = pci230_handle_ao_fifo(dev, s); - comedi_event(dev, s); + comedi_handle_events(dev, s); if (!run) { /* Stopped. */ return; @@ -1354,8 +1321,6 @@ static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return -EBUSY; } - devpriv->ao_scan_count = cmd->stop_arg; - /* * Set range - see analogue output range table; 0 => unipolar 10V, * 1 => bipolar +/-10V range scale @@ -1754,19 +1719,15 @@ static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev, { struct pci230_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - unsigned int scanlen = cmd->scan_end_arg; unsigned int wake; unsigned short triglev; unsigned short adccon; if (cmd->flags & CMDF_WAKE_EOS) - wake = scanlen - devpriv->ai_scan_pos; - else if (cmd->stop_src != TRIG_COUNT || - devpriv->ai_scan_count >= PCI230_ADC_FIFOLEVEL_HALFFULL || - scanlen >= PCI230_ADC_FIFOLEVEL_HALFFULL) - wake = PCI230_ADC_FIFOLEVEL_HALFFULL; + wake = cmd->scan_end_arg - s->async->cur_chan; else - wake = devpriv->ai_scan_count * scanlen - devpriv->ai_scan_pos; + wake = comedi_nsamples_left(s, PCI230_ADC_FIFOLEVEL_HALFFULL); + if (wake >= PCI230_ADC_FIFOLEVEL_HALFFULL) { triglev = PCI230_ADC_INT_FIFO_HALF; } else if (wake > 1 && devpriv->hwver > 0) { @@ -2059,28 +2020,17 @@ static void pci230_handle_ai(struct comedi_device *dev, struct pci230_private *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; - unsigned int scanlen = cmd->scan_end_arg; - unsigned int events = 0; unsigned int status_fifo; unsigned int i; unsigned int todo; unsigned int fifoamount; + unsigned short val; /* Determine number of samples to read. */ - if (cmd->stop_src != TRIG_COUNT) { - todo = PCI230_ADC_FIFOLEVEL_HALFFULL; - } else if (devpriv->ai_scan_count == 0) { - todo = 0; - } else if (devpriv->ai_scan_count > PCI230_ADC_FIFOLEVEL_HALFFULL || - scanlen > PCI230_ADC_FIFOLEVEL_HALFFULL) { - todo = PCI230_ADC_FIFOLEVEL_HALFFULL; - } else { - todo = devpriv->ai_scan_count * scanlen - devpriv->ai_scan_pos; - if (todo > PCI230_ADC_FIFOLEVEL_HALFFULL) - todo = PCI230_ADC_FIFOLEVEL_HALFFULL; - } + todo = comedi_nsamples_left(s, PCI230_ADC_FIFOLEVEL_HALFFULL); if (todo == 0) return; + fifoamount = 0; for (i = 0; i < todo; i++) { if (fifoamount == 0) { @@ -2092,7 +2042,7 @@ static void pci230_handle_ai(struct comedi_device *dev, * unnoticed by the caller. */ dev_err(dev->class_dev, "AI FIFO overrun\n"); - events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; + async->events |= COMEDI_CB_ERROR; break; } else if (status_fifo & PCI230_ADC_FIFO_EMPTY) { /* FIFO empty. */ @@ -2111,37 +2061,23 @@ static void pci230_handle_ai(struct comedi_device *dev, fifoamount = 1; } } - /* Read sample and store in Comedi's circular buffer. */ - if (comedi_buf_put(s, pci230_ai_read(dev)) == 0) { - events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW; - dev_err(dev->class_dev, "AI buffer overflow\n"); + + val = pci230_ai_read(dev); + if (!comedi_buf_write_samples(s, &val, 1)) break; - } + fifoamount--; - devpriv->ai_scan_pos++; - if (devpriv->ai_scan_pos == scanlen) { - /* End of scan. */ - devpriv->ai_scan_pos = 0; - devpriv->ai_scan_count--; - async->events |= COMEDI_CB_EOS; + + if (cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) { + async->events |= COMEDI_CB_EOA; + break; } } - if (cmd->stop_src == TRIG_COUNT && devpriv->ai_scan_count == 0) { - /* End of acquisition. */ - events |= COMEDI_CB_EOA; - } else { - /* More samples required, tell Comedi to block. */ - events |= COMEDI_CB_BLOCK; - } - async->events |= events; - if (async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | - COMEDI_CB_OVERFLOW)) { - /* disable hardware conversions */ - pci230_ai_stop(dev, s); - } else { - /* update FIFO interrupt trigger level */ + + /* update FIFO interrupt trigger level if still running */ + if (!(async->events & COMEDI_CB_CANCEL_MASK)) pci230_ai_update_fifo_trigger_level(dev, s); - } } static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) @@ -2177,9 +2113,6 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (!pci230_claim_shared(dev, res_mask, OWNER_AICMD)) return -EBUSY; - devpriv->ai_scan_count = cmd->stop_arg; - devpriv->ai_scan_pos = 0; /* Position within scan. */ - /* * Steps: * - Set channel scan list. @@ -2355,7 +2288,8 @@ static irqreturn_t pci230_interrupt(int irq, void *d) unsigned char status_int, valid_status_int, temp_ier; struct comedi_device *dev = (struct comedi_device *)d; struct pci230_private *devpriv = dev->private; - struct comedi_subdevice *s; + struct comedi_subdevice *s_ao = dev->write_subdev; + struct comedi_subdevice *s_ai = dev->read_subdev; unsigned long irqflags; /* Read interrupt status/enable register. */ @@ -2385,23 +2319,14 @@ static irqreturn_t pci230_interrupt(int irq, void *d) * two. */ - if (valid_status_int & PCI230_INT_ZCLK_CT1) { - s = dev->write_subdev; - pci230_handle_ao_nofifo(dev, s); - comedi_event(dev, s); - } + if (valid_status_int & PCI230_INT_ZCLK_CT1) + pci230_handle_ao_nofifo(dev, s_ao); - if (valid_status_int & PCI230P2_INT_DAC) { - s = dev->write_subdev; - pci230_handle_ao_fifo(dev, s); - comedi_event(dev, s); - } + if (valid_status_int & PCI230P2_INT_DAC) + pci230_handle_ao_fifo(dev, s_ao); - if (valid_status_int & PCI230_INT_ADC) { - s = dev->read_subdev; - pci230_handle_ai(dev, s); - comedi_event(dev, s); - } + if (valid_status_int & PCI230_INT_ADC) + pci230_handle_ai(dev, s_ai); /* Reenable interrupts. */ spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); @@ -2410,6 +2335,9 @@ static irqreturn_t pci230_interrupt(int irq, void *d) devpriv->intr_running = false; spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); + comedi_handle_events(dev, s_ao); + comedi_handle_events(dev, s_ai); + return IRQ_HANDLED; } @@ -2583,7 +2511,6 @@ static int pci230_auto_attach(struct comedi_device *dev, s->maxdata = (1 << thisboard->ao_bits) - 1; s->range_table = &pci230_ao_range; s->insn_write = pci230_ao_insn_write; - s->insn_read = comedi_readback_insn_read; s->len_chanlist = 2; if (dev->irq) { dev->write_subdev = s; diff --git a/drivers/staging/comedi/drivers/amplc_pci263.c b/drivers/staging/comedi/drivers/amplc_pci263.c index 2259bee98d48..0d2224b832ac 100644 --- a/drivers/staging/comedi/drivers/amplc_pci263.c +++ b/drivers/staging/comedi/drivers/amplc_pci263.c @@ -71,7 +71,7 @@ static int pci263_auto_attach(struct comedi_device *dev, s = &dev->subdevices[0]; /* digital output subdevice */ s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c index e03dd6e71415..e7cb7032a910 100644 --- a/drivers/staging/comedi/drivers/c6xdigio.c +++ b/drivers/staging/comedi/drivers/c6xdigio.c @@ -265,7 +265,7 @@ static int c6xdigio_attach(struct comedi_device *dev, s = &dev->subdevices[0]; /* pwm output subdevice */ s->type = COMEDI_SUBD_PWM; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 2; s->maxdata = 500; s->range_table = &range_unknown; diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index f88880aea6da..0a48d2a961d5 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -305,7 +305,6 @@ static int das16cs_auto_attach(struct comedi_device *dev, s->maxdata = 0xffff; s->range_table = &range_bipolar10; s->insn_write = &das16cs_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 1ec363b7505c..669b1703eb99 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -346,8 +346,6 @@ struct cb_pcidas_private { /* divisors of master clock for analog input pacing */ unsigned int divisor1; unsigned int divisor2; - /* number of analog input samples remaining */ - unsigned int count; /* bits to write to registers */ unsigned int adc_fifo_bits; unsigned int s5933_intcsr_bits; @@ -358,11 +356,6 @@ struct cb_pcidas_private { /* divisors of master clock for analog output pacing */ unsigned int ao_divisor1; unsigned int ao_divisor2; - /* number of analog output samples remaining */ - unsigned int ao_count; - unsigned int caldac_value[NUM_CHANNELS_8800]; - unsigned int trimpot_value[NUM_CHANNELS_8402]; - unsigned int dac08_value; unsigned int calibration_source; }; @@ -596,25 +589,14 @@ static void write_calibration_bitstream(struct comedi_device *dev, } } -static int caldac_8800_write(struct comedi_device *dev, unsigned int address, - uint8_t value) +static void caldac_8800_write(struct comedi_device *dev, + unsigned int chan, uint8_t val) { struct cb_pcidas_private *devpriv = dev->private; - static const int num_caldac_channels = 8; static const int bitstream_length = 11; - unsigned int bitstream = ((address & 0x7) << 8) | value; + unsigned int bitstream = ((chan & 0x7) << 8) | val; static const int caldac_8800_udelay = 1; - if (address >= num_caldac_channels) { - dev_err(dev->class_dev, "illegal caldac channel\n"); - return -1; - } - - if (value == devpriv->caldac_value[address]) - return 1; - - devpriv->caldac_value[address] = value; - write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream, bitstream_length); @@ -623,75 +605,62 @@ static int caldac_8800_write(struct comedi_device *dev, unsigned int address, devpriv->control_status + CALIBRATION_REG); udelay(caldac_8800_udelay); outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG); - - return 1; } -static int caldac_write_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int cb_pcidas_caldac_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - const unsigned int channel = CR_CHAN(insn->chanspec); + unsigned int chan = CR_CHAN(insn->chanspec); - return caldac_8800_write(dev, channel, data[0]); -} + if (insn->n) { + unsigned int val = data[insn->n - 1]; -static int caldac_read_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - struct cb_pcidas_private *devpriv = dev->private; - - data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)]; + if (s->readback[chan] != val) { + caldac_8800_write(dev, chan, val); + s->readback[chan] = val; + } + } - return 1; + return insn->n; } /* 1602/16 pregain offset */ static void dac08_write(struct comedi_device *dev, unsigned int value) { struct cb_pcidas_private *devpriv = dev->private; - unsigned long cal_reg; - - if (devpriv->dac08_value != value) { - devpriv->dac08_value = value; - - cal_reg = devpriv->control_status + CALIBRATION_REG; - value &= 0xff; - value |= cal_enable_bits(dev); + value &= 0xff; + value |= cal_enable_bits(dev); - /* latch the new value into the caldac */ - outw(value, cal_reg); - udelay(1); - outw(value | SELECT_DAC08_BIT, cal_reg); - udelay(1); - outw(value, cal_reg); - udelay(1); - } + /* latch the new value into the caldac */ + outw(value, devpriv->control_status + CALIBRATION_REG); + udelay(1); + outw(value | SELECT_DAC08_BIT, + devpriv->control_status + CALIBRATION_REG); + udelay(1); + outw(value, devpriv->control_status + CALIBRATION_REG); + udelay(1); } -static int dac08_write_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int cb_pcidas_dac08_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - int i; - - for (i = 0; i < insn->n; i++) - dac08_write(dev, data[i]); - - return insn->n; -} + unsigned int chan = CR_CHAN(insn->chanspec); -static int dac08_read_insn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data) -{ - struct cb_pcidas_private *devpriv = dev->private; + if (insn->n) { + unsigned int val = data[insn->n - 1]; - data[0] = devpriv->dac08_value; + if (s->readback[chan] != val) { + dac08_write(dev, val); + s->readback[chan] = val; + } + } - return 1; + return insn->n; } static int trimpot_7376_write(struct comedi_device *dev, uint8_t value) @@ -740,50 +709,41 @@ static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel, return 0; } -static int cb_pcidas_trimpot_write(struct comedi_device *dev, - unsigned int channel, unsigned int value) +static void cb_pcidas_trimpot_write(struct comedi_device *dev, + unsigned int chan, unsigned int val) { const struct cb_pcidas_board *thisboard = dev->board_ptr; - struct cb_pcidas_private *devpriv = dev->private; - - if (devpriv->trimpot_value[channel] == value) - return 1; - devpriv->trimpot_value[channel] = value; switch (thisboard->trimpot) { case AD7376: - trimpot_7376_write(dev, value); + trimpot_7376_write(dev, val); break; case AD8402: - trimpot_8402_write(dev, channel, value); + trimpot_8402_write(dev, chan, val); break; default: dev_err(dev->class_dev, "driver bug?\n"); - return -1; + break; } - - return 1; } -static int trimpot_write_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int cb_pcidas_trimpot_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - unsigned int channel = CR_CHAN(insn->chanspec); + unsigned int chan = CR_CHAN(insn->chanspec); - return cb_pcidas_trimpot_write(dev, channel, data[0]); -} + if (insn->n) { + unsigned int val = data[insn->n - 1]; -static int trimpot_read_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - struct cb_pcidas_private *devpriv = dev->private; - unsigned int channel = CR_CHAN(insn->chanspec); - - data[0] = devpriv->trimpot_value[channel]; + if (s->readback[chan] != val) { + cb_pcidas_trimpot_write(dev, chan, val); + s->readback[chan] = val; + } + } - return 1; + return insn->n; } static int cb_pcidas_ai_check_chanlist(struct comedi_device *dev, @@ -976,9 +936,6 @@ static int cb_pcidas_ai_cmd(struct comedi_device *dev, if (cmd->scan_begin_src == TRIG_TIMER || cmd->convert_src == TRIG_TIMER) cb_pcidas_ai_load_counters(dev); - /* set number of conversions */ - if (cmd->stop_src == TRIG_COUNT) - devpriv->count = cmd->chanlist_len * cmd->stop_arg; /* enable interrupts */ spin_lock_irqsave(&dev->spinlock, flags); devpriv->adc_fifo_bits |= INTE; @@ -1134,32 +1091,34 @@ static int cb_pcidas_cancel(struct comedi_device *dev, return 0; } +static void cb_pcidas_ao_load_fifo(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int nsamples) +{ + struct cb_pcidas_private *devpriv = dev->private; + unsigned int nbytes; + + nsamples = comedi_nsamples_left(s, nsamples); + nbytes = comedi_buf_read_samples(s, devpriv->ao_buffer, nsamples); + + nsamples = comedi_bytes_to_samples(s, nbytes); + outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, nsamples); +} + static int cb_pcidas_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trig_num) { const struct cb_pcidas_board *thisboard = dev->board_ptr; struct cb_pcidas_private *devpriv = dev->private; - unsigned int num_bytes, num_points = thisboard->fifo_size; struct comedi_async *async = s->async; - struct comedi_cmd *cmd = &s->async->cmd; + struct comedi_cmd *cmd = &async->cmd; unsigned long flags; if (trig_num != cmd->start_arg) return -EINVAL; - /* load up fifo */ - if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points) - num_points = devpriv->ao_count; - - num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer, - num_points * sizeof(short)); - num_points = num_bytes / sizeof(short); - - if (cmd->stop_src == TRIG_COUNT) - devpriv->ao_count -= num_points; - /* write data to board's fifo */ - outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes); + cb_pcidas_ao_load_fifo(dev, s, thisboard->fifo_size); /* enable dac half-full and empty interrupts */ spin_lock_irqsave(&dev->spinlock, flags); @@ -1224,9 +1183,6 @@ static int cb_pcidas_ao_cmd(struct comedi_device *dev, if (cmd->scan_begin_src == TRIG_TIMER) cb_pcidas_ao_load_counters(dev); - /* set number of conversions */ - if (cmd->stop_src == TRIG_COUNT) - devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg; /* set pacer source */ spin_lock_irqsave(&dev->spinlock, flags); switch (cmd->scan_begin_src) { @@ -1275,8 +1231,6 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status) struct comedi_subdevice *s = dev->write_subdev; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; - unsigned int half_fifo = thisboard->fifo_size / 2; - unsigned int num_points; unsigned long flags; if (status & DAEMI) { @@ -1286,32 +1240,17 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status) devpriv->control_status + INT_ADCFIFO); spin_unlock_irqrestore(&dev->spinlock, flags); if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) { - if (cmd->stop_src == TRIG_NONE || - (cmd->stop_src == TRIG_COUNT - && devpriv->ao_count)) { + if (cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) { + async->events |= COMEDI_CB_EOA; + } else { dev_err(dev->class_dev, "dac fifo underflow\n"); async->events |= COMEDI_CB_ERROR; } - async->events |= COMEDI_CB_EOA; } } else if (status & DAHFI) { - unsigned int num_bytes; + cb_pcidas_ao_load_fifo(dev, s, thisboard->fifo_size / 2); - /* figure out how many points we are writing to fifo */ - num_points = half_fifo; - if (cmd->stop_src == TRIG_COUNT && - devpriv->ao_count < num_points) - num_points = devpriv->ao_count; - num_bytes = - cfc_read_array_from_buffer(s, devpriv->ao_buffer, - num_points * sizeof(short)); - num_points = num_bytes / sizeof(short); - - if (cmd->stop_src == TRIG_COUNT) - devpriv->ao_count -= num_points; - /* write data to board's fifo */ - outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, - num_points); /* clear half-full interrupt latch */ spin_lock_irqsave(&dev->spinlock, flags); outw(devpriv->adc_fifo_bits | DAHFI, @@ -1319,7 +1258,7 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status) spin_unlock_irqrestore(&dev->spinlock, flags); } - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static irqreturn_t cb_pcidas_interrupt(int irq, void *d) @@ -1362,18 +1301,15 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d) /* if fifo half-full */ if (status & ADHFI) { /* read data */ - num_samples = half_fifo; - if (cmd->stop_src == TRIG_COUNT && - num_samples > devpriv->count) { - num_samples = devpriv->count; - } + num_samples = comedi_nsamples_left(s, half_fifo); insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer, num_samples); - cfc_write_array_to_buffer(s, devpriv->ai_buffer, - num_samples * sizeof(short)); - devpriv->count -= num_samples; - if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) + comedi_buf_write_samples(s, devpriv->ai_buffer, num_samples); + + if (cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) async->events |= COMEDI_CB_EOA; + /* clear half-full interrupt latch */ spin_lock_irqsave(&dev->spinlock, flags); outw(devpriv->adc_fifo_bits | INT, @@ -1382,14 +1318,17 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d) /* else if fifo not empty */ } else if (status & (ADNEI | EOBI)) { for (i = 0; i < timeout; i++) { + unsigned short val; + /* break if fifo is empty */ if ((ADNE & inw(devpriv->control_status + INT_ADCFIFO)) == 0) break; - cfc_write_to_buffer(s, inw(devpriv->adc_fifo)); + val = inw(devpriv->adc_fifo); + comedi_buf_write_samples(s, &val, 1); + if (cmd->stop_src == TRIG_COUNT && - --devpriv->count == 0) { - /* end of acquisition */ + async->scans_done >= cmd->stop_arg) { async->events |= COMEDI_CB_EOA; break; } @@ -1419,7 +1358,7 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d) async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; } - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } @@ -1503,7 +1442,6 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev, s->range_table = &cb_pcidas_ao_ranges; /* default to no fifo (*insn_write) */ s->insn_write = cb_pcidas_ao_nofifo_winsn; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) @@ -1542,10 +1480,16 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev, s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; s->n_chan = NUM_CHANNELS_8800; s->maxdata = 0xff; - s->insn_read = caldac_read_insn; - s->insn_write = caldac_write_insn; - for (i = 0; i < s->n_chan; i++) + s->insn_write = cb_pcidas_caldac_insn_write; + + ret = comedi_alloc_subdev_readback(s); + if (ret) + return ret; + + for (i = 0; i < s->n_chan; i++) { caldac_8800_write(dev, i, s->maxdata / 2); + s->readback[i] = s->maxdata / 2; + } /* trim potentiometer */ s = &dev->subdevices[5]; @@ -1558,10 +1502,16 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev, s->n_chan = NUM_CHANNELS_8402; s->maxdata = 0xff; } - s->insn_read = trimpot_read_insn; - s->insn_write = trimpot_write_insn; - for (i = 0; i < s->n_chan; i++) + s->insn_write = cb_pcidas_trimpot_insn_write; + + ret = comedi_alloc_subdev_readback(s); + if (ret) + return ret; + + for (i = 0; i < s->n_chan; i++) { cb_pcidas_trimpot_write(dev, i, s->maxdata / 2); + s->readback[i] = s->maxdata / 2; + } /* dac08 caldac */ s = &dev->subdevices[6]; @@ -1569,10 +1519,17 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_CALIB; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; s->n_chan = NUM_CHANNELS_DAC08; - s->insn_read = dac08_read_insn; - s->insn_write = dac08_write_insn; s->maxdata = 0xff; - dac08_write(dev, s->maxdata / 2); + s->insn_write = cb_pcidas_dac08_insn_write; + + ret = comedi_alloc_subdev_readback(s); + if (ret) + return ret; + + for (i = 0; i < s->n_chan; i++) { + dac08_write(dev, s->maxdata / 2); + s->readback[i] = s->maxdata / 2; + } } else s->type = COMEDI_SUBD_UNUSED; diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 3b6bffc66918..eddb7ace43df 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1065,8 +1065,6 @@ struct pcidas64_private { /* local address (used by dma controller) */ uint32_t local0_iobase; uint32_t local1_iobase; - /* number of analog input samples remaining */ - unsigned int ai_count; /* dma buffers for analog input */ uint16_t *ai_buffer[MAX_AI_DMA_RING_COUNT]; /* physical addresses of ai dma buffers */ @@ -1087,8 +1085,6 @@ struct pcidas64_private { dma_addr_t ao_dma_desc_bus_addr; /* keeps track of buffer where the next ao sample should go */ unsigned int ao_dma_index; - /* number of analog output samples remaining */ - unsigned long ao_count; unsigned int hw_revision; /* stc chip hardware revision number */ /* last bits sent to INTR_ENABLE_REG register */ unsigned int intr_enable_bits; @@ -1109,9 +1105,6 @@ struct pcidas64_private { uint8_t i2c_cal_range_bits; /* configure digital triggers to trigger on falling edge */ unsigned int ext_trig_falling; - /* states of various devices stored to enable read-back */ - unsigned int ad8402_state[2]; - unsigned int caldac_state[8]; short ai_cmd_running; unsigned int ai_fifo_segment_length; struct ext_clock_info ext_clock; @@ -2199,10 +2192,6 @@ static void setup_sample_counters(struct comedi_device *dev, { struct pcidas64_private *devpriv = dev->private; - if (cmd->stop_src == TRIG_COUNT) { - /* set software count */ - devpriv->ai_count = cmd->stop_arg * cmd->chanlist_len; - } /* load hardware conversion counter */ if (use_hw_sample_counter(cmd)) { writew(cmd->stop_arg & 0xffff, @@ -2642,8 +2631,6 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) { struct pcidas64_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; - struct comedi_async *async = s->async; - struct comedi_cmd *cmd = &async->cmd; unsigned int i; uint16_t prepost_bits; int read_segment, read_index, write_segment, write_index; @@ -2672,26 +2659,21 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) devpriv->ai_fifo_segment_length - read_index; else num_samples = write_index - read_index; - - if (cmd->stop_src == TRIG_COUNT) { - if (devpriv->ai_count == 0) - break; - if (num_samples > devpriv->ai_count) - num_samples = devpriv->ai_count; - - devpriv->ai_count -= num_samples; - } - if (num_samples < 0) { dev_err(dev->class_dev, "cb_pcidas64: bug! num_samples < 0\n"); break; } + num_samples = comedi_nsamples_left(s, num_samples); + if (num_samples == 0) + break; + for (i = 0; i < num_samples; i++) { - cfc_write_to_buffer(s, - readw(devpriv->main_iobase + - ADC_FIFO_REG)); + unsigned short val; + + val = readw(devpriv->main_iobase + ADC_FIFO_REG); + comedi_buf_write_samples(s, &val, 1); } } while (read_segment != write_segment); @@ -2706,33 +2688,30 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev) { struct pcidas64_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; - struct comedi_async *async = s->async; - struct comedi_cmd *cmd = &async->cmd; + unsigned int nsamples; unsigned int i; - unsigned int max_transfer = 100000; uint32_t fifo_data; int write_code = readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff; int read_code = readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; - if (cmd->stop_src == TRIG_COUNT) { - if (max_transfer > devpriv->ai_count) - max_transfer = devpriv->ai_count; + nsamples = comedi_nsamples_left(s, 100000); + for (i = 0; read_code != write_code && i < nsamples;) { + unsigned short val; - } - for (i = 0; read_code != write_code && i < max_transfer;) { fifo_data = readl(dev->mmio + ADC_FIFO_REG); - cfc_write_to_buffer(s, fifo_data & 0xffff); + val = fifo_data & 0xffff; + comedi_buf_write_samples(s, &val, 1); i++; - if (i < max_transfer) { - cfc_write_to_buffer(s, (fifo_data >> 16) & 0xffff); + if (i < nsamples) { + val = (fifo_data >> 16) & 0xffff; + comedi_buf_write_samples(s, &val, 1); i++; } read_code = readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; } - devpriv->ai_count -= i; } /* empty fifo */ @@ -2750,8 +2729,7 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) { const struct pcidas64_board *thisboard = dev->board_ptr; struct pcidas64_private *devpriv = dev->private; - struct comedi_async *async = dev->read_subdev->async; - struct comedi_cmd *cmd = &async->cmd; + struct comedi_subdevice *s = dev->read_subdev; uint32_t next_transfer_addr; int j; int num_samples = 0; @@ -2772,16 +2750,10 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] + DMA_BUFFER_SIZE) && j < ai_dma_ring_count(thisboard); j++) { /* transfer data from dma buffer to comedi buffer */ - num_samples = dma_transfer_size(dev); - if (cmd->stop_src == TRIG_COUNT) { - if (num_samples > devpriv->ai_count) - num_samples = devpriv->ai_count; - devpriv->ai_count -= num_samples; - } - cfc_write_array_to_buffer(dev->read_subdev, - devpriv->ai_buffer[devpriv-> - ai_dma_index], - num_samples * sizeof(uint16_t)); + num_samples = comedi_nsamples_left(s, dma_transfer_size(dev)); + comedi_buf_write_samples(s, + devpriv->ai_buffer[devpriv->ai_dma_index], + num_samples); devpriv->ai_dma_index = (devpriv->ai_dma_index + 1) % ai_dma_ring_count(thisboard); } @@ -2831,12 +2803,12 @@ static void handle_ai_interrupt(struct comedi_device *dev, spin_unlock_irqrestore(&dev->spinlock, flags); } /* if we are have all the data, then quit */ - if ((cmd->stop_src == TRIG_COUNT && (int)devpriv->ai_count <= 0) || - (cmd->stop_src == TRIG_EXT && (status & ADC_STOP_BIT))) { + if ((cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) || + (cmd->stop_src == TRIG_EXT && (status & ADC_STOP_BIT))) async->events |= COMEDI_CB_EOA; - } - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static inline unsigned int prev_ao_dma_index(struct comedi_device *dev) @@ -2871,22 +2843,6 @@ static int last_ao_dma_load_completed(struct comedi_device *dev) return 1; } -static int ao_stopped_by_error(struct comedi_device *dev, - const struct comedi_cmd *cmd) -{ - struct pcidas64_private *devpriv = dev->private; - - if (cmd->stop_src == TRIG_NONE) - return 1; - if (cmd->stop_src == TRIG_COUNT) { - if (devpriv->ao_count) - return 1; - if (last_ao_dma_load_completed(dev) == 0) - return 1; - } - return 0; -} - static inline int ao_dma_needs_restart(struct comedi_device *dev, unsigned short dma_status) { @@ -2912,32 +2868,39 @@ static void restart_ao_dma(struct comedi_device *dev) dma_start_sync(dev, 0); } +static unsigned int cb_pcidas64_ao_fill_buffer(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned short *dest, + unsigned int max_bytes) +{ + unsigned int nsamples = comedi_bytes_to_samples(s, max_bytes); + unsigned int actual_bytes; + + nsamples = comedi_nsamples_left(s, nsamples); + actual_bytes = comedi_buf_read_samples(s, dest, nsamples); + + return comedi_bytes_to_samples(s, actual_bytes); +} + static unsigned int load_ao_dma_buffer(struct comedi_device *dev, const struct comedi_cmd *cmd) { struct pcidas64_private *devpriv = dev->private; - unsigned int num_bytes, buffer_index, prev_buffer_index; + struct comedi_subdevice *s = dev->write_subdev; + unsigned int buffer_index = devpriv->ao_dma_index; + unsigned int prev_buffer_index = prev_ao_dma_index(dev); + unsigned int nsamples; + unsigned int nbytes; unsigned int next_bits; - buffer_index = devpriv->ao_dma_index; - prev_buffer_index = prev_ao_dma_index(dev); - - num_bytes = comedi_buf_read_n_available(dev->write_subdev); - if (num_bytes > DMA_BUFFER_SIZE) - num_bytes = DMA_BUFFER_SIZE; - if (cmd->stop_src == TRIG_COUNT && num_bytes > devpriv->ao_count) - num_bytes = devpriv->ao_count; - num_bytes -= num_bytes % bytes_in_sample; - - if (num_bytes == 0) + nsamples = cb_pcidas64_ao_fill_buffer(dev, s, + devpriv->ao_buffer[buffer_index], + DMA_BUFFER_SIZE); + if (nsamples == 0) return 0; - num_bytes = cfc_read_array_from_buffer(dev->write_subdev, - devpriv-> - ao_buffer[buffer_index], - num_bytes); - devpriv->ao_dma_desc[buffer_index].transfer_size = - cpu_to_le32(num_bytes); + nbytes = comedi_samples_to_bytes(s, nsamples); + devpriv->ao_dma_desc[buffer_index].transfer_size = cpu_to_le32(nbytes); /* set end of chain bit so we catch underruns */ next_bits = le32_to_cpu(devpriv->ao_dma_desc[buffer_index].next); next_bits |= PLX_END_OF_CHAIN_BIT; @@ -2949,9 +2912,8 @@ static unsigned int load_ao_dma_buffer(struct comedi_device *dev, devpriv->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits); devpriv->ao_dma_index = (buffer_index + 1) % AO_DMA_RING_COUNT; - devpriv->ao_count -= num_bytes; - return num_bytes; + return nbytes; } static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) @@ -3016,11 +2978,14 @@ static void handle_ao_interrupt(struct comedi_device *dev, } if ((status & DAC_DONE_BIT)) { - async->events |= COMEDI_CB_EOA; - if (ao_stopped_by_error(dev, cmd)) + if ((cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) || + last_ao_dma_load_completed(dev)) + async->events |= COMEDI_CB_EOA; + else async->events |= COMEDI_CB_ERROR; } - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static irqreturn_t handle_interrupt(int irq, void *d) @@ -3191,7 +3156,9 @@ static void set_dac_interval_regs(struct comedi_device *dev, static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) { struct pcidas64_private *devpriv = dev->private; - unsigned int num_bytes; + struct comedi_subdevice *s = dev->write_subdev; + unsigned int nsamples; + unsigned int nbytes; int i; /* clear queue pointer too, since external queue has @@ -3199,22 +3166,23 @@ static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG); writew(0, devpriv->main_iobase + DAC_BUFFER_CLEAR_REG); - num_bytes = (DAC_FIFO_SIZE / 2) * bytes_in_sample; - if (cmd->stop_src == TRIG_COUNT && - num_bytes / bytes_in_sample > devpriv->ao_count) - num_bytes = devpriv->ao_count * bytes_in_sample; - num_bytes = cfc_read_array_from_buffer(dev->write_subdev, - devpriv->ao_bounce_buffer, - num_bytes); - for (i = 0; i < num_bytes / bytes_in_sample; i++) { + nsamples = cb_pcidas64_ao_fill_buffer(dev, s, + devpriv->ao_bounce_buffer, + DAC_FIFO_SIZE); + if (nsamples == 0) + return -1; + + for (i = 0; i < nsamples; i++) { writew(devpriv->ao_bounce_buffer[i], devpriv->main_iobase + DAC_FIFO_REG); } - devpriv->ao_count -= num_bytes / bytes_in_sample; - if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count == 0) + + if (cmd->stop_src == TRIG_COUNT && + s->async->scans_done >= cmd->stop_arg) return 0; - num_bytes = load_ao_dma_buffer(dev, cmd); - if (num_bytes == 0) + + nbytes = load_ao_dma_buffer(dev, cmd); + if (nbytes == 0) return -1; load_ao_dma(dev, cmd); @@ -3275,7 +3243,6 @@ static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) writew(0x0, devpriv->main_iobase + DAC_CONTROL0_REG); devpriv->ao_dma_index = 0; - devpriv->ao_count = cmd->stop_arg * cmd->chanlist_len; set_dac_select_reg(dev, cmd); set_dac_interval_regs(dev, cmd); @@ -3580,9 +3547,6 @@ static void caldac_write(struct comedi_device *dev, unsigned int channel, unsigned int value) { const struct pcidas64_board *thisboard = dev->board_ptr; - struct pcidas64_private *devpriv = dev->private; - - devpriv->caldac_state[channel] = value; switch (thisboard->layout) { case LAYOUT_60XX: @@ -3597,33 +3561,27 @@ static void caldac_write(struct comedi_device *dev, unsigned int channel, } } -static int calib_write_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int cb_pcidas64_calib_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - struct pcidas64_private *devpriv = dev->private; - int channel = CR_CHAN(insn->chanspec); - - /* return immediately if setting hasn't changed, since - * programming these things is slow */ - if (devpriv->caldac_state[channel] == data[0]) - return 1; - - caldac_write(dev, channel, data[0]); - - return 1; -} + unsigned int chan = CR_CHAN(insn->chanspec); -static int calib_read_insn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data) -{ - struct pcidas64_private *devpriv = dev->private; - unsigned int channel = CR_CHAN(insn->chanspec); + /* + * Programming the calib device is slow. Only write the + * last data value if the value has changed. + */ + if (insn->n) { + unsigned int val = data[insn->n - 1]; - data[0] = devpriv->caldac_state[channel]; + if (s->readback[chan] != val) { + caldac_write(dev, chan, val); + s->readback[chan] = val; + } + } - return 1; + return insn->n; } static void ad8402_write(struct comedi_device *dev, unsigned int channel, @@ -3635,8 +3593,6 @@ static void ad8402_write(struct comedi_device *dev, unsigned int channel, unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff); static const int ad8402_udelay = 1; - devpriv->ad8402_state[channel] = value; - register_bits = SELECT_8402_64XX_BIT; udelay(ad8402_udelay); writew(register_bits, devpriv->main_iobase + CALIBRATION_REG); @@ -3658,35 +3614,27 @@ static void ad8402_write(struct comedi_device *dev, unsigned int channel, } /* for pci-das6402/16, channel 0 is analog input gain and channel 1 is offset */ -static int ad8402_write_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int cb_pcidas64_ad8402_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - struct pcidas64_private *devpriv = dev->private; - int channel = CR_CHAN(insn->chanspec); - - /* return immediately if setting hasn't changed, since - * programming these things is slow */ - if (devpriv->ad8402_state[channel] == data[0]) - return 1; - - devpriv->ad8402_state[channel] = data[0]; - - ad8402_write(dev, channel, data[0]); - - return 1; -} + unsigned int chan = CR_CHAN(insn->chanspec); -static int ad8402_read_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - struct pcidas64_private *devpriv = dev->private; - unsigned int channel = CR_CHAN(insn->chanspec); + /* + * Programming the calib device is slow. Only write the + * last data value if the value has changed. + */ + if (insn->n) { + unsigned int val = data[insn->n - 1]; - data[0] = devpriv->ad8402_state[channel]; + if (s->readback[chan] != val) { + ad8402_write(dev, chan, val); + s->readback[chan] = val; + } + } - return 1; + return insn->n; } static uint16_t read_eeprom(struct comedi_device *dev, uint8_t address) @@ -3816,7 +3764,6 @@ static int setup_subdevices(struct comedi_device *dev) s->maxdata = (1 << thisboard->ao_bits) - 1; s->range_table = thisboard->ao_range_table; s->insn_write = ao_winsn; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) @@ -3849,7 +3796,7 @@ static int setup_subdevices(struct comedi_device *dev) if (thisboard->layout == LAYOUT_64XX) { s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 4; s->maxdata = 1; s->range_table = &range_digital; @@ -3895,10 +3842,16 @@ static int setup_subdevices(struct comedi_device *dev) s->maxdata = 0xfff; else s->maxdata = 0xff; - s->insn_read = calib_read_insn; - s->insn_write = calib_write_insn; - for (i = 0; i < s->n_chan; i++) + s->insn_write = cb_pcidas64_calib_insn_write; + + ret = comedi_alloc_subdev_readback(s); + if (ret) + return ret; + + for (i = 0; i < s->n_chan; i++) { caldac_write(dev, i, s->maxdata / 2); + s->readback[i] = s->maxdata / 2; + } /* 2 channel ad8402 potentiometer */ s = &dev->subdevices[7]; @@ -3906,11 +3859,17 @@ static int setup_subdevices(struct comedi_device *dev) s->type = COMEDI_SUBD_CALIB; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; s->n_chan = 2; - s->insn_read = ad8402_read_insn; - s->insn_write = ad8402_write_insn; s->maxdata = 0xff; - for (i = 0; i < s->n_chan; i++) + s->insn_write = cb_pcidas64_ad8402_insn_write; + + ret = comedi_alloc_subdev_readback(s); + if (ret) + return ret; + + for (i = 0; i < s->n_chan; i++) { ad8402_write(dev, i, s->maxdata / 2); + s->readback[i] = s->maxdata / 2; + } } else s->type = COMEDI_SUBD_UNUSED; diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index fe4d2544f3dc..70dd2c9eecdb 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -1,40 +1,45 @@ /* - comedi/drivers/cb_pcimdas.c - Comedi driver for Computer Boards PCIM-DAS1602/16 - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 2000 David A. Schleef <ds@schleef.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ + * comedi/drivers/cb_pcimdas.c + * Comedi driver for Computer Boards PCIM-DAS1602/16 and PCIe-DAS1602/16 + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 2000 David A. Schleef <ds@schleef.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + /* -Driver: cb_pcimdas -Description: Measurement Computing PCI Migration series boards -Devices: [ComputerBoards] PCIM-DAS1602/16 (cb_pcimdas) -Author: Richard Bytheway -Updated: Wed, 13 Nov 2002 12:34:56 +0000 -Status: experimental - -Written to support the PCIM-DAS1602/16 on a 2.4 series kernel. - -Configuration Options: - [0] - PCI bus number - [1] - PCI slot number - -Developed from cb_pcidas and skel by Richard Bytheway (mocelet@sucs.org). -Only supports DIO, AO and simple AI in it's present form. -No interrupts, multi channel or FIFO AI, -although the card looks like it could support this. -See http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf for more details. -*/ + * Driver: cb_pcimdas + * Description: Measurement Computing PCI Migration series boards + * Devices: [ComputerBoards] PCIM-DAS1602/16 (cb_pcimdas), PCIe-DAS1602/16 + * Author: Richard Bytheway + * Updated: Mon, 13 Oct 2014 11:57:39 +0000 + * Status: experimental + * + * Written to support the PCIM-DAS1602/16 and PCIe-DAS1602/16. + * + * Configuration Options: + * none + * + * Manual configuration of PCI(e) cards is not supported; they are configured + * automatically. + * + * Developed from cb_pcidas and skel by Richard Bytheway (mocelet@sucs.org). + * Only supports DIO, AO and simple AI in it's present form. + * No interrupts, multi channel or FIFO AI, + * although the card looks like it could support this. + * + * http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf + * http://www.mccdaq.com/PDFs/Manuals/pcie-das1602-16.pdf + */ #include <linux/module.h> #include <linux/pci.h> @@ -45,7 +50,7 @@ See http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf for more details. #include "plx9052.h" #include "8255.h" -/* Registers for the PCIM-DAS1602/16 */ +/* Registers for the PCIM-DAS1602/16 and PCIe-DAS1602/16 */ /* DAC Offsets */ #define ADC_TRIG 0 @@ -221,7 +226,6 @@ static int cb_pcimdas_auto_attach(struct comedi_device *dev, /* ranges are hardware settable, but not software readable. */ s->range_table = &range_unknown; s->insn_write = cb_pcimdas_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) @@ -251,7 +255,8 @@ static int cb_pcimdas_pci_probe(struct pci_dev *dev, } static const struct pci_device_id cb_pcimdas_pci_table[] = { - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0056) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0056) }, /* PCIM-DAS1602/16 */ + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0115) }, /* PCIe-DAS1602/16 */ { 0 } }; MODULE_DEVICE_TABLE(pci, cb_pcimdas_pci_table); @@ -265,5 +270,5 @@ static struct pci_driver cb_pcimdas_pci_driver = { module_comedi_pci_driver(cb_pcimdas_driver, cb_pcimdas_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); +MODULE_DESCRIPTION("Comedi driver for PCIM-DAS1602/16 and PCIe-DAS1602/16"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index 8450c99af8b0..85b2f4ab1ba4 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -61,8 +61,7 @@ struct bonded_device { }; struct comedi_bond_private { -# define MAX_BOARD_NAME 256 - char name[MAX_BOARD_NAME]; + char name[256]; struct bonded_device **devs; unsigned ndevs; unsigned nchans; @@ -262,12 +261,10 @@ static int do_dev_config(struct comedi_device *dev, struct comedi_devconfig *it) { /* Append dev:subdev to devpriv->name */ char buf[20]; - int left = - MAX_BOARD_NAME - strlen(devpriv->name) - 1; snprintf(buf, sizeof(buf), "%u:%u ", bdev->minor, bdev->subdev); - buf[sizeof(buf) - 1] = 0; - strncat(devpriv->name, buf, left); + strlcat(devpriv->name, buf, + sizeof(devpriv->name)); } } diff --git a/drivers/staging/comedi/drivers/comedi_fc.h b/drivers/staging/comedi/drivers/comedi_fc.h index ce2835972507..756be931c1a4 100644 --- a/drivers/staging/comedi/drivers/comedi_fc.h +++ b/drivers/staging/comedi/drivers/comedi_fc.h @@ -23,49 +23,6 @@ #include "../comedidev.h" -static inline unsigned int cfc_bytes_per_scan(struct comedi_subdevice *s) -{ - return comedi_bytes_per_scan(s); -} - -static inline void cfc_inc_scan_progress(struct comedi_subdevice *s, - unsigned int num_bytes) -{ - comedi_inc_scan_progress(s, num_bytes); -} - -static inline unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *s, - const void *data, - unsigned int num_bytes) -{ - return comedi_write_array_to_buffer(s, data, num_bytes); -} - -static inline unsigned int cfc_write_to_buffer(struct comedi_subdevice *s, - unsigned short data) -{ - return comedi_write_array_to_buffer(s, &data, sizeof(data)); -}; - -static inline unsigned int cfc_write_long_to_buffer(struct comedi_subdevice *s, - unsigned int data) -{ - return comedi_write_array_to_buffer(s, &data, sizeof(data)); -}; - -static inline unsigned int -cfc_read_array_from_buffer(struct comedi_subdevice *s, void *data, - unsigned int num_bytes) -{ - return comedi_read_array_from_buffer(s, data, num_bytes); -} - -static inline unsigned int cfc_handle_events(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - return comedi_handle_events(dev, s); -} - /** * cfc_check_trigger_src() - trivially validate a comedi_cmd trigger source * @src: pointer to the trigger source to validate diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c index bf002988192d..3bac903c8627 100644 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ b/drivers/staging/comedi/drivers/comedi_parport.c @@ -225,10 +225,9 @@ static irqreturn_t parport_interrupt(int irq, void *d) if (!(ctrl & PARPORT_CTRL_IRQ_ENA)) return IRQ_NONE; - comedi_buf_put(s, 0); - s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; + comedi_buf_write_samples(s, &s->state, 1); + comedi_handle_events(dev, s); - comedi_event(dev, s); return IRQ_HANDLED; } diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 00c03df72523..e56525a1c8f3 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -52,18 +52,23 @@ zero volts). #include "comedi_fc.h" #include <linux/timer.h> +#include <linux/ktime.h> #define N_CHANS 8 +enum waveform_state_bits { + WAVEFORM_AI_RUNNING = 0 +}; + /* Data unique to this driver */ struct waveform_private { struct timer_list timer; - struct timeval last; /* time last timer interrupt occurred */ + ktime_t last; /* time last timer interrupt occurred */ unsigned int uvolt_amplitude; /* waveform amplitude in microvolts */ unsigned long usec_period; /* waveform period in microseconds */ unsigned long usec_current; /* current time (mod waveform period) */ unsigned long usec_remainder; /* usec since last scan */ - unsigned long ai_count; /* number of conversions remaining */ + unsigned long state_bits; unsigned int scan_period; /* scan period in usec */ unsigned int convert_period; /* conversion period in usec */ unsigned int ao_loopbacks[N_CHANS]; @@ -164,36 +169,29 @@ static void waveform_ai_interrupt(unsigned long arg) { struct comedi_device *dev = (struct comedi_device *)arg; struct waveform_private *devpriv = dev->private; - struct comedi_async *async = dev->read_subdev->async; + struct comedi_subdevice *s = dev->read_subdev; + struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; unsigned int i, j; /* all times in microsec */ unsigned long elapsed_time; unsigned int num_scans; - struct timeval now; - bool stopping = false; + ktime_t now; + + /* check command is still active */ + if (!test_bit(WAVEFORM_AI_RUNNING, &devpriv->state_bits)) + return; - do_gettimeofday(&now); + now = ktime_get(); - elapsed_time = - 1000000 * (now.tv_sec - devpriv->last.tv_sec) + now.tv_usec - - devpriv->last.tv_usec; + elapsed_time = ktime_to_us(ktime_sub(now, devpriv->last)); devpriv->last = now; num_scans = (devpriv->usec_remainder + elapsed_time) / devpriv->scan_period; devpriv->usec_remainder = (devpriv->usec_remainder + elapsed_time) % devpriv->scan_period; - if (cmd->stop_src == TRIG_COUNT) { - unsigned int remaining = cmd->stop_arg - devpriv->ai_count; - - if (num_scans >= remaining) { - /* about to finish */ - num_scans = remaining; - stopping = true; - } - } - + num_scans = comedi_nscans_left(s, num_scans); for (i = 0; i < num_scans; i++) { for (j = 0; j < cmd->chanlist_len; j++) { unsigned short sample; @@ -203,20 +201,19 @@ static void waveform_ai_interrupt(unsigned long arg) devpriv->usec_current + i * devpriv->scan_period + j * devpriv->convert_period); - cfc_write_to_buffer(dev->read_subdev, sample); + comedi_buf_write_samples(s, &sample, 1); } } - devpriv->ai_count += i; devpriv->usec_current += elapsed_time; devpriv->usec_current %= devpriv->usec_period; - if (stopping) + if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg) async->events |= COMEDI_CB_EOA; else mod_timer(&devpriv->timer, jiffies + 1); - comedi_event(dev, dev->read_subdev); + comedi_handle_events(dev, s); } static int waveform_ai_cmdtest(struct comedi_device *dev, @@ -308,7 +305,6 @@ static int waveform_ai_cmd(struct comedi_device *dev, return -1; } - devpriv->ai_count = 0; devpriv->scan_period = cmd->scan_begin_arg / nano_per_micro; if (cmd->convert_src == TRIG_NOW) @@ -316,11 +312,16 @@ static int waveform_ai_cmd(struct comedi_device *dev, else /* TRIG_TIMER */ devpriv->convert_period = cmd->convert_arg / nano_per_micro; - do_gettimeofday(&devpriv->last); - devpriv->usec_current = devpriv->last.tv_usec % devpriv->usec_period; + devpriv->last = ktime_get(); + devpriv->usec_current = + ((u32)ktime_to_us(devpriv->last)) % devpriv->usec_period; devpriv->usec_remainder = 0; devpriv->timer.expires = jiffies + 1; + /* mark command as active */ + smp_mb__before_atomic(); + set_bit(WAVEFORM_AI_RUNNING, &devpriv->state_bits); + smp_mb__after_atomic(); add_timer(&devpriv->timer); return 0; } @@ -330,7 +331,11 @@ static int waveform_ai_cancel(struct comedi_device *dev, { struct waveform_private *devpriv = dev->private; - del_timer_sync(&devpriv->timer); + /* mark command as no longer active */ + clear_bit(WAVEFORM_AI_RUNNING, &devpriv->state_bits); + smp_mb__after_atomic(); + /* cannot call del_timer_sync() as may be called from timer routine */ + del_timer(&devpriv->timer); return 0; } @@ -405,7 +410,7 @@ static int waveform_attach(struct comedi_device *dev, dev->write_subdev = s; /* analog output subdevice (loopback) */ s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND; s->n_chan = N_CHANS; s->maxdata = 0xffff; s->range_table = &waveform_ai_ranges; @@ -432,7 +437,7 @@ static void waveform_detach(struct comedi_device *dev) struct waveform_private *devpriv = dev->private; if (devpriv) - waveform_ai_cancel(dev, dev->read_subdev); + del_timer_sync(&devpriv->timer); } static struct comedi_driver waveform_driver = { diff --git a/drivers/staging/comedi/drivers/dac02.c b/drivers/staging/comedi/drivers/dac02.c index 34cbe83f0ce7..beb36c8dd00a 100644 --- a/drivers/staging/comedi/drivers/dac02.c +++ b/drivers/staging/comedi/drivers/dac02.c @@ -129,7 +129,6 @@ static int dac02_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->maxdata = 0x0fff; s->range_table = &das02_ao_ranges; s->insn_write = dac02_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index e5b5a8133b34..96697fbb5239 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -707,7 +707,6 @@ static int daqboard2000_auto_attach(struct comedi_device *dev, s->n_chan = 2; s->maxdata = 0xffff; s->insn_write = daqboard2000_ao_insn_write; - s->insn_read = comedi_readback_insn_read; s->range_table = &range_bipolar10; result = comedi_alloc_subdev_readback(s); diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index bdb671a66e22..20a9f0eb72b5 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -474,7 +474,6 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) s->maxdata = (1 << thisboard->ao_nbits) - 1; s->range_table = &range_bipolar5; s->insn_write = das08_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) @@ -507,7 +506,7 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) /* do */ if (thisboard->do_nchan) { s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = thisboard->do_nchan; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 2d8e86cec47a..2436057304a3 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -541,6 +541,7 @@ static void das16_interrupt(struct comedi_device *dev) struct comedi_cmd *cmd = &async->cmd; unsigned long spin_flags; unsigned long dma_flags; + unsigned int nsamples; int num_bytes, residue; int buffer_index; @@ -583,21 +584,25 @@ static void das16_interrupt(struct comedi_device *dev) spin_unlock_irqrestore(&dev->spinlock, spin_flags); - cfc_write_array_to_buffer(s, - devpriv->dma_buffer[buffer_index], num_bytes); + nsamples = comedi_bytes_to_samples(s, num_bytes); + comedi_buf_write_samples(s, devpriv->dma_buffer[buffer_index], + nsamples); - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static void das16_timer_interrupt(unsigned long arg) { struct comedi_device *dev = (struct comedi_device *)arg; struct das16_private_struct *devpriv = dev->private; + unsigned long flags; das16_interrupt(dev); + spin_lock_irqsave(&dev->spinlock, flags); if (devpriv->timer_running) mod_timer(&devpriv->timer, jiffies + timer_period()); + spin_unlock_irqrestore(&dev->spinlock, flags); } static int das16_ai_check_chanlist(struct comedi_device *dev, @@ -764,7 +769,7 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) return -1; } - devpriv->adc_byte_count = cmd->stop_arg * cfc_bytes_per_scan(s); + devpriv->adc_byte_count = cmd->stop_arg * comedi_bytes_per_scan(s); if (devpriv->can_burst) outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV_REG); @@ -814,7 +819,8 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) enable_dma(devpriv->dma_chan); release_dma_lock(flags); - /* set up interrupt */ + /* set up timer */ + spin_lock_irqsave(&dev->spinlock, flags); devpriv->timer_running = 1; devpriv->timer.expires = jiffies + timer_period(); add_timer(&devpriv->timer); @@ -823,6 +829,7 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) if (devpriv->can_burst) outb(0, dev->iobase + DAS1600_CONV_REG); + spin_unlock_irqrestore(&dev->spinlock, flags); return 0; } @@ -856,8 +863,9 @@ static void das16_ai_munge(struct comedi_device *dev, unsigned int num_bytes, unsigned int start_chan_index) { - unsigned int i, num_samples = num_bytes / sizeof(short); unsigned short *data = array; + unsigned int num_samples = comedi_bytes_to_samples(s, num_bytes); + unsigned int i; for (i = 0; i < num_samples; i++) { data[i] = le16_to_cpu(data[i]); @@ -1167,7 +1175,6 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->maxdata = 0x0fff; s->range_table = devpriv->user_ao_range_table; s->insn_write = das16_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) @@ -1226,6 +1233,8 @@ static void das16_detach(struct comedi_device *dev) int i; if (devpriv) { + if (devpriv->timer.data) + del_timer_sync(&devpriv->timer); if (dev->iobase) das16_reset(dev); diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index 24b63c452f51..80f41b7e8273 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -442,8 +442,7 @@ static void das16m1_handler(struct comedi_device *dev, unsigned int status) num_samples = FIFO_SIZE; insw(dev->iobase, devpriv->ai_buffer, num_samples); munge_sample_array(devpriv->ai_buffer, num_samples); - cfc_write_array_to_buffer(s, devpriv->ai_buffer, - num_samples * sizeof(short)); + comedi_buf_write_samples(s, devpriv->ai_buffer, num_samples); devpriv->adc_count += num_samples; if (cmd->stop_src == TRIG_COUNT) { @@ -460,7 +459,7 @@ static void das16m1_handler(struct comedi_device *dev, unsigned int status) dev_err(dev->class_dev, "fifo overflow\n"); } - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static int das16m1_poll(struct comedi_device *dev, struct comedi_subdevice *s) @@ -598,7 +597,7 @@ static int das16m1_attach(struct comedi_device *dev, s = &dev->subdevices[2]; /* do */ s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 4; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index a53d87ce9b14..be825d21a185 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -421,7 +421,6 @@ static const struct das1800_board das1800_boards[] = { }; struct das1800_private { - unsigned int count; /* number of data points left to be taken */ unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */ unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */ int irq_dma_bits; /* bits for control register b */ @@ -479,42 +478,33 @@ static void das1800_handle_fifo_half_full(struct comedi_device *dev, struct comedi_subdevice *s) { struct das1800_private *devpriv = dev->private; - int numPoints = 0; /* number of points to read */ - struct comedi_cmd *cmd = &s->async->cmd; + unsigned int nsamples = comedi_nsamples_left(s, FIFO_SIZE / 2); - numPoints = FIFO_SIZE / 2; - /* if we only need some of the points */ - if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints) - numPoints = devpriv->count; - insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints); - munge_data(dev, devpriv->ai_buf0, numPoints); - cfc_write_array_to_buffer(s, devpriv->ai_buf0, - numPoints * sizeof(devpriv->ai_buf0[0])); - if (cmd->stop_src == TRIG_COUNT) - devpriv->count -= numPoints; + insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, nsamples); + munge_data(dev, devpriv->ai_buf0, nsamples); + comedi_buf_write_samples(s, devpriv->ai_buf0, nsamples); } static void das1800_handle_fifo_not_empty(struct comedi_device *dev, struct comedi_subdevice *s) { - struct das1800_private *devpriv = dev->private; + struct comedi_cmd *cmd = &s->async->cmd; unsigned short dpnt; int unipolar; - struct comedi_cmd *cmd = &s->async->cmd; unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB; while (inb(dev->iobase + DAS1800_STATUS) & FNE) { - if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) - break; dpnt = inw(dev->iobase + DAS1800_FIFO); /* convert to unsigned type if we are in a bipolar mode */ if (!unipolar) ; dpnt = munge_bipolar_sample(dev, dpnt); - cfc_write_to_buffer(s, dpnt); - if (cmd->stop_src == TRIG_COUNT) - devpriv->count--; + comedi_buf_write_samples(s, &dpnt, 1); + + if (cmd->stop_src == TRIG_COUNT && + s->async->scans_done >= cmd->stop_arg) + break; } } @@ -525,8 +515,8 @@ static void das1800_flush_dma_channel(struct comedi_device *dev, unsigned int channel, uint16_t *buffer) { struct das1800_private *devpriv = dev->private; - unsigned int num_bytes, num_samples; - struct comedi_cmd *cmd = &s->async->cmd; + unsigned int nbytes; + unsigned int nsamples; disable_dma(channel); @@ -535,17 +525,12 @@ static void das1800_flush_dma_channel(struct comedi_device *dev, clear_dma_ff(channel); /* figure out how many points to read */ - num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel); - num_samples = num_bytes / sizeof(short); - - /* if we only need some of the points */ - if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples) - num_samples = devpriv->count; + nbytes = devpriv->dma_transfer_size - get_dma_residue(channel); + nsamples = comedi_bytes_to_samples(s, nbytes); + nsamples = comedi_nsamples_left(s, nsamples); - munge_data(dev, buffer, num_samples); - cfc_write_array_to_buffer(s, buffer, num_bytes); - if (cmd->stop_src == TRIG_COUNT) - devpriv->count -= num_samples; + munge_data(dev, buffer, nsamples); + comedi_buf_write_samples(s, buffer, nsamples); } /* flushes remaining data from board when external trigger has stopped acquisition @@ -649,14 +634,13 @@ static void das1800_ai_handler(struct comedi_device *dev) das1800_handle_fifo_not_empty(dev, s); } - async->events |= COMEDI_CB_BLOCK; /* if the card's fifo has overflowed */ if (status & OVF) { /* clear OVF interrupt bit */ outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS); dev_err(dev->class_dev, "FIFO overflow\n"); async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return; } /* stop taking data if appropriate */ @@ -670,11 +654,12 @@ static void das1800_ai_handler(struct comedi_device *dev) else das1800_handle_fifo_not_empty(dev, s); async->events |= COMEDI_CB_EOA; - } else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) { /* stop_src TRIG_COUNT */ + } else if (cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) { async->events |= COMEDI_CB_EOA; } - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static int das1800_ai_poll(struct comedi_device *dev, @@ -1102,9 +1087,6 @@ static int das1800_ai_do_cmd(struct comedi_device *dev, /* interrupt fifo half full */ devpriv->irq_dma_bits |= FIMD; } - /* determine how many conversions we need */ - if (cmd->stop_src == TRIG_COUNT) - devpriv->count = cmd->stop_arg * cmd->chanlist_len; das1800_cancel(dev, s); @@ -1515,7 +1497,7 @@ static int das1800_attach(struct comedi_device *dev, /* do */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = thisboard->do_n_chan; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index ab6e40608885..780f4f646ea0 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c @@ -35,6 +35,7 @@ #include <linux/interrupt.h> #include "../comedidev.h" +#include "comedi_fc.h" #include "8253.h" /* @@ -192,26 +193,197 @@ static void das6402_enable_counter(struct comedi_device *dev, bool load) } } +static unsigned int das6402_ai_read_sample(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + unsigned int val; + + val = inw(dev->iobase + DAS6402_AI_DATA_REG); + if (s->maxdata == 0x0fff) + val >>= 4; + return val; +} + static irqreturn_t das6402_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct comedi_subdevice *s = dev->read_subdev; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; + unsigned int status; + + status = inb(dev->iobase + DAS6402_STATUS_REG); + if ((status & DAS6402_STATUS_INT) == 0) + return IRQ_NONE; + + if (status & DAS6402_STATUS_FFULL) { + async->events |= COMEDI_CB_OVERFLOW; + } else if (status & DAS6402_STATUS_FFNE) { + unsigned int val; + + val = das6402_ai_read_sample(dev, s); + comedi_buf_write_samples(s, &val, 1); + + if (cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) + async->events |= COMEDI_CB_EOA; + } das6402_clear_all_interrupts(dev); + comedi_handle_events(dev, s); + return IRQ_HANDLED; } +static void das6402_ai_set_mode(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int chanspec, + unsigned int mode) +{ + unsigned int range = CR_RANGE(chanspec); + unsigned int aref = CR_AREF(chanspec); + + mode |= DAS6402_MODE_RANGE(range); + if (aref == AREF_GROUND) + mode |= DAS6402_MODE_SE; + if (comedi_range_is_unipolar(s, range)) + mode |= DAS6402_MODE_UNI; + + das6402_set_mode(dev, mode); +} + static int das6402_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { - return -EINVAL; + struct das6402_private *devpriv = dev->private; + struct comedi_cmd *cmd = &s->async->cmd; + unsigned int chan_lo = CR_CHAN(cmd->chanlist[0]); + unsigned int chan_hi = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]); + + das6402_ai_set_mode(dev, s, cmd->chanlist[0], DAS6402_MODE_FIFONEPTY); + + /* load the mux for chanlist conversion */ + outw(DAS6402_AI_MUX_HI(chan_hi) | DAS6402_AI_MUX_LO(chan_lo), + dev->iobase + DAS6402_AI_MUX_REG); + + das6402_enable_counter(dev, true); + + /* enable interrupt and pacer trigger */ + outb(DAS6402_CTRL_INTE | + DAS6402_CTRL_IRQ(devpriv->irq) | + DAS6402_CTRL_PACER_TRIG, dev->iobase + DAS6402_CTRL_REG); + + return 0; +} + +static int das6402_ai_check_chanlist(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_cmd *cmd) +{ + unsigned int chan0 = CR_CHAN(cmd->chanlist[0]); + unsigned int range0 = CR_RANGE(cmd->chanlist[0]); + unsigned int aref0 = CR_AREF(cmd->chanlist[0]); + int i; + + for (i = 1; i < cmd->chanlist_len; i++) { + unsigned int chan = CR_CHAN(cmd->chanlist[i]); + unsigned int range = CR_RANGE(cmd->chanlist[i]); + unsigned int aref = CR_AREF(cmd->chanlist[i]); + + if (chan != chan0 + i) { + dev_dbg(dev->class_dev, + "chanlist must be consecutive\n"); + return -EINVAL; + } + + if (range != range0) { + dev_dbg(dev->class_dev, + "chanlist must have the same range\n"); + return -EINVAL; + } + + if (aref != aref0) { + dev_dbg(dev->class_dev, + "chanlist must have the same reference\n"); + return -EINVAL; + } + + if (aref0 == AREF_DIFF && chan > (s->n_chan / 2)) { + dev_dbg(dev->class_dev, + "chanlist differential channel to large\n"); + return -EINVAL; + } + } + return 0; } static int das6402_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { - return -EINVAL; + struct das6402_private *devpriv = dev->private; + int err = 0; + unsigned int arg; + + /* Step 1 : check if triggers are trivially valid */ + + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); + + if (err) + return 1; + + /* Step 2a : make sure trigger sources are unique */ + + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ + + if (err) + return 2; + + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 10000); + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); + + if (err) + return 3; + + /* step 4: fix up any arguments */ + + if (cmd->convert_src == TRIG_TIMER) { + arg = cmd->convert_arg; + i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ, + &devpriv->divider1, + &devpriv->divider2, + &arg, cmd->flags); + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg); + } + + if (err) + return 4; + + /* Step 5: check channel list if it exists */ + if (cmd->chanlist && cmd->chanlist_len > 0) + err |= das6402_ai_check_chanlist(dev, s, cmd); + + if (err) + return 5; + + return 0; } static int das6402_ai_cancel(struct comedi_device *dev, @@ -246,26 +418,17 @@ static int das6402_ai_insn_read(struct comedi_device *dev, unsigned int *data) { unsigned int chan = CR_CHAN(insn->chanspec); - unsigned int range = CR_RANGE(insn->chanspec); unsigned int aref = CR_AREF(insn->chanspec); - unsigned int val; int ret; int i; - val = DAS6402_MODE_RANGE(range) | DAS6402_MODE_POLLED; - if (aref == AREF_DIFF) { - if (chan > s->n_chan / 2) - return -EINVAL; - } else { - val |= DAS6402_MODE_SE; - } - if (comedi_range_is_unipolar(s, range)) - val |= DAS6402_MODE_UNI; + if (aref == AREF_DIFF && chan > (s->n_chan / 2)) + return -EINVAL; /* enable software conversion trigger */ outb(DAS6402_CTRL_SOFT_TRIG, dev->iobase + DAS6402_CTRL_REG); - das6402_set_mode(dev, val); + das6402_ai_set_mode(dev, s, insn->chanspec, DAS6402_MODE_POLLED); /* load the mux for single channel conversion */ outw(DAS6402_AI_MUX_HI(chan) | DAS6402_AI_MUX_LO(chan), @@ -279,12 +442,7 @@ static int das6402_ai_insn_read(struct comedi_device *dev, if (ret) break; - val = inw(dev->iobase + DAS6402_AI_DATA_REG); - - if (s->maxdata == 0x0fff) - val >>= 4; - - data[i] = val; + data[i] = das6402_ai_read_sample(dev, s); } das6402_ai_clear_eoc(dev); @@ -497,7 +655,7 @@ static int das6402_attach(struct comedi_device *dev, /* Analog Output subdevice */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 2; s->maxdata = board->maxdata; s->range_table = &das6402_ao_ranges; @@ -520,7 +678,7 @@ static int das6402_attach(struct comedi_device *dev, /* Digital Input subdevice */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 8; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index d75e5528258c..e5bdc2423445 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -219,7 +219,6 @@ static const struct das800_board das800_boards[] = { }; struct das800_private { - unsigned int count; /* number of data points left to be taken */ unsigned int divisor1; /* counter 1 value for timed conversions */ unsigned int divisor2; /* counter 2 value for timed conversions */ unsigned int do_bits; /* digital output bits */ @@ -286,9 +285,6 @@ static void das800_set_frequency(struct comedi_device *dev) static int das800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { - struct das800_private *devpriv = dev->private; - - devpriv->count = 0; das800_disable(dev); return 0; } @@ -399,7 +395,6 @@ static int das800_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { const struct das800_board *thisboard = dev->board_ptr; - struct das800_private *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; unsigned int gain = CR_RANGE(cmd->chanlist[0]); @@ -422,11 +417,6 @@ static int das800_ai_do_cmd(struct comedi_device *dev, gain &= 0xf; outb(gain, dev->iobase + DAS800_GAIN); - if (cmd->stop_src == TRIG_COUNT) - devpriv->count = cmd->stop_arg * cmd->chanlist_len; - else /* TRIG_NONE */ - devpriv->count = 0; - /* enable auto channel scan, send interrupts on end of conversion * and set clock source to internal or external */ @@ -509,25 +499,28 @@ static irqreturn_t das800_interrupt(int irq, void *d) if (s->maxdata == 0x0fff) val >>= 4; /* 12-bit sample */ - /* if there are more data points to collect */ - if (cmd->stop_src == TRIG_NONE || devpriv->count > 0) { - /* write data point to buffer */ - cfc_write_to_buffer(s, val & s->maxdata); - devpriv->count--; + val &= s->maxdata; + comedi_buf_write_samples(s, &val, 1); + + if (cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) { + async->events |= COMEDI_CB_EOA; + break; } } - async->events |= COMEDI_CB_BLOCK; if (fifo_overflow) { spin_unlock_irqrestore(&dev->spinlock, irq_flags); async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } - if (cmd->stop_src == TRIG_NONE || devpriv->count > 0) { - /* Re-enable card's interrupt. - * We already have spinlock, so indirect addressing is safe */ + if (!(async->events & COMEDI_CB_CANCEL_MASK)) { + /* + * Re-enable card's interrupt. + * We already have spinlock, so indirect addressing is safe + */ das800_ind_write(dev, CONTROL1_INTE | devpriv->do_bits, CONTROL1); spin_unlock_irqrestore(&dev->spinlock, irq_flags); @@ -535,9 +528,8 @@ static irqreturn_t das800_interrupt(int irq, void *d) /* otherwise, stop taking data */ spin_unlock_irqrestore(&dev->spinlock, irq_flags); das800_disable(dev); - async->events |= COMEDI_CB_EOA; } - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } @@ -738,7 +730,7 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Digital Output subdevice */ s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 4; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index 7215e09305cf..6df298a99cc6 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -1,125 +1,139 @@ /* - comedi/drivers/dmm32at.c - Diamond Systems mm32at code for a Comedi driver - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 2000 David A. Schleef <ds@schleef.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ + * dmm32at.c + * Diamond Systems Diamond-MM-32-AT Comedi driver + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 2000 David A. Schleef <ds@schleef.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + /* -Driver: dmm32at -Description: Diamond Systems mm32at driver. -Devices: -Author: Perry J. Piplani <perry.j.piplani@nasa.gov> -Updated: Fri Jun 4 09:13:24 CDT 2004 -Status: experimental - -This driver is for the Diamond Systems MM-32-AT board -http://www.diamondsystems.com/products/diamondmm32at It is being used -on serveral projects inside NASA, without problems so far. For analog -input commands, TRIG_EXT is not yet supported at all.. - -Configuration Options: - comedi_config /dev/comedi0 dmm32at baseaddr,irq -*/ + * Driver: dmm32at + * Description: Diamond Systems Diamond-MM-32-AT + * Devices: (Diamond Systems) Diamond-MM-32-AT [dmm32at] + * Author: Perry J. Piplani <perry.j.piplani@nasa.gov> + * Updated: Fri Jun 4 09:13:24 CDT 2004 + * Status: experimental + * + * Configuration Options: + * comedi_config /dev/comedi0 dmm32at baseaddr,irq + * + * This driver is for the Diamond Systems MM-32-AT board + * http://www.diamondsystems.com/products/diamondmm32at + * + * It is being used on serveral projects inside NASA, without + * problems so far. For analog input commands, TRIG_EXT is not + * yet supported. + */ #include <linux/module.h> #include <linux/delay.h> #include <linux/interrupt.h> #include "../comedidev.h" +#include "8255.h" #include "comedi_fc.h" /* Board register addresses */ -#define DMM32AT_CONV 0x00 -#define DMM32AT_AILSB 0x00 -#define DMM32AT_AUXDOUT 0x01 -#define DMM32AT_AIMSB 0x01 -#define DMM32AT_AILOW 0x02 -#define DMM32AT_AIHIGH 0x03 - -#define DMM32AT_DACSTAT 0x04 -#define DMM32AT_DACLSB_REG 0x04 -#define DMM32AT_DACMSB_REG 0x05 -#define DMM32AT_DACMSB_CHAN(x) ((x) << 6) - -#define DMM32AT_FIFOCNTRL 0x07 -#define DMM32AT_FIFOSTAT 0x07 - -#define DMM32AT_CNTRL 0x08 -#define DMM32AT_AISTAT 0x08 - -#define DMM32AT_INTCLOCK 0x09 - -#define DMM32AT_CNTRDIO 0x0a - -#define DMM32AT_AICONF 0x0b -#define DMM32AT_AIRBACK 0x0b +#define DMM32AT_AI_START_CONV_REG 0x00 +#define DMM32AT_AI_LSB_REG 0x00 +#define DMM32AT_AUX_DOUT_REG 0x01 +#define DMM32AT_AUX_DOUT2 (1 << 2) /* J3.42 - OUT2 (OUT2EN) */ +#define DMM32AT_AUX_DOUT1 (1 << 1) /* J3.43 */ +#define DMM32AT_AUX_DOUT0 (1 << 0) /* J3.44 - OUT0 (OUT0EN) */ +#define DMM32AT_AI_MSB_REG 0x01 +#define DMM32AT_AI_LO_CHAN_REG 0x02 +#define DMM32AT_AI_HI_CHAN_REG 0x03 +#define DMM32AT_AUX_DI_REG 0x04 +#define DMM32AT_AUX_DI_DACBUSY (1 << 7) +#define DMM32AT_AUX_DI_CALBUSY (1 << 6) +#define DMM32AT_AUX_DI3 (1 << 3) /* J3.45 - ADCLK (CLKSEL) */ +#define DMM32AT_AUX_DI2 (1 << 2) /* J3.46 - GATE12 (GT12EN) */ +#define DMM32AT_AUX_DI1 (1 << 1) /* J3.47 - GATE0 (GT0EN) */ +#define DMM32AT_AUX_DI0 (1 << 0) /* J3.48 - CLK0 (SRC0) */ +#define DMM32AT_AO_LSB_REG 0x04 +#define DMM32AT_AO_MSB_REG 0x05 +#define DMM32AT_AO_MSB_DACH(x) ((x) << 6) +#define DMM32AT_FIFO_DEPTH_REG 0x06 +#define DMM32AT_FIFO_CTRL_REG 0x07 +#define DMM32AT_FIFO_CTRL_FIFOEN (1 << 3) +#define DMM32AT_FIFO_CTRL_SCANEN (1 << 2) +#define DMM32AT_FIFO_CTRL_FIFORST (1 << 1) +#define DMM32AT_FIFO_STATUS_REG 0x07 +#define DMM32AT_FIFO_STATUS_EF (1 << 7) +#define DMM32AT_FIFO_STATUS_HF (1 << 6) +#define DMM32AT_FIFO_STATUS_FF (1 << 5) +#define DMM32AT_FIFO_STATUS_OVF (1 << 4) +#define DMM32AT_FIFO_STATUS_FIFOEN (1 << 3) +#define DMM32AT_FIFO_STATUS_SCANEN (1 << 2) +#define DMM32AT_FIFO_STATUS_PAGE_MASK (3 << 0) +#define DMM32AT_CTRL_REG 0x08 +#define DMM32AT_CTRL_RESETA (1 << 5) +#define DMM32AT_CTRL_RESETD (1 << 4) +#define DMM32AT_CTRL_INTRST (1 << 3) +#define DMM32AT_CTRL_PAGE_8254 (0 << 0) +#define DMM32AT_CTRL_PAGE_8255 (1 << 0) +#define DMM32AT_CTRL_PAGE_CALIB (3 << 0) +#define DMM32AT_AI_STATUS_REG 0x08 +#define DMM32AT_AI_STATUS_STS (1 << 7) +#define DMM32AT_AI_STATUS_SD1 (1 << 6) +#define DMM32AT_AI_STATUS_SD0 (1 << 5) +#define DMM32AT_AI_STATUS_ADCH_MASK (0x1f << 0) +#define DMM32AT_INTCLK_REG 0x09 +#define DMM32AT_INTCLK_ADINT (1 << 7) +#define DMM32AT_INTCLK_DINT (1 << 6) +#define DMM32AT_INTCLK_TINT (1 << 5) +#define DMM32AT_INTCLK_CLKEN (1 << 1) /* 1=see below 0=software */ +#define DMM32AT_INTCLK_CLKSEL (1 << 0) /* 1=OUT2 0=EXTCLK */ +#define DMM32AT_CTRDIO_CFG_REG 0x0a +#define DMM32AT_CTRDIO_CFG_FREQ12 (1 << 7) /* CLK12 1=100KHz 0=10MHz */ +#define DMM32AT_CTRDIO_CFG_FREQ0 (1 << 6) /* CLK0 1=10KHz 0=10MHz */ +#define DMM32AT_CTRDIO_CFG_OUT2EN (1 << 5) /* J3.42 1=OUT2 is DOUT2 */ +#define DMM32AT_CTRDIO_CFG_OUT0EN (1 << 4) /* J3,44 1=OUT0 is DOUT0 */ +#define DMM32AT_CTRDIO_CFG_GT0EN (1 << 2) /* J3.47 1=DIN1 is GATE0 */ +#define DMM32AT_CTRDIO_CFG_SRC0 (1 << 1) /* CLK0 is 0=FREQ0 1=J3.48 */ +#define DMM32AT_CTRDIO_CFG_GT12EN (1 << 0) /* J3.46 1=DIN2 is GATE12 */ +#define DMM32AT_AI_CFG_REG 0x0b +#define DMM32AT_AI_CFG_SCINT_20US (0 << 4) +#define DMM32AT_AI_CFG_SCINT_15US (1 << 4) +#define DMM32AT_AI_CFG_SCINT_10US (2 << 4) +#define DMM32AT_AI_CFG_SCINT_5US (3 << 4) +#define DMM32AT_AI_CFG_RANGE (1 << 3) /* 0=5V 1=10V */ +#define DMM32AT_AI_CFG_ADBU (1 << 2) /* 0=bipolar 1=unipolar */ +#define DMM32AT_AI_CFG_GAIN(x) ((x) << 0) +#define DMM32AT_AI_READBACK_REG 0x0b +#define DMM32AT_AI_READBACK_WAIT (1 << 7) /* DMM32AT_AI_STATUS_STS */ +#define DMM32AT_AI_READBACK_RANGE (1 << 3) +#define DMM32AT_AI_READBACK_ADBU (1 << 2) +#define DMM32AT_AI_READBACK_GAIN_MASK (3 << 0) #define DMM32AT_CLK1 0x0d #define DMM32AT_CLK2 0x0e #define DMM32AT_CLKCT 0x0f -#define DMM32AT_DIOA 0x0c -#define DMM32AT_DIOB 0x0d -#define DMM32AT_DIOC 0x0e -#define DMM32AT_DIOCONF 0x0f +#define DMM32AT_8255_IOBASE 0x0c /* Page 1 registers */ /* Board register values. */ -/* DMM32AT_DACSTAT 0x04 */ -#define DMM32AT_DACBUSY 0x80 - -/* DMM32AT_FIFOCNTRL 0x07 */ -#define DMM32AT_FIFORESET 0x02 -#define DMM32AT_SCANENABLE 0x04 - -/* DMM32AT_CNTRL 0x08 */ -#define DMM32AT_RESET 0x20 -#define DMM32AT_INTRESET 0x08 -#define DMM32AT_CLKACC 0x00 -#define DMM32AT_DIOACC 0x01 - -/* DMM32AT_AISTAT 0x08 */ -#define DMM32AT_STATUS 0x80 - -/* DMM32AT_INTCLOCK 0x09 */ -#define DMM32AT_ADINT 0x80 -#define DMM32AT_CLKSEL 0x03 - -/* DMM32AT_CNTRDIO 0x0a */ -#define DMM32AT_FREQ12 0x80 - -/* DMM32AT_AICONF 0x0b */ +/* DMM32AT_AI_CFG_REG 0x0b */ #define DMM32AT_RANGE_U10 0x0c #define DMM32AT_RANGE_U5 0x0d #define DMM32AT_RANGE_B10 0x08 #define DMM32AT_RANGE_B5 0x00 -#define DMM32AT_SCINT_20 0x00 -#define DMM32AT_SCINT_15 0x10 -#define DMM32AT_SCINT_10 0x20 -#define DMM32AT_SCINT_5 0x30 /* DMM32AT_CLKCT 0x0f */ #define DMM32AT_CLKCT1 0x56 /* mode3 counter 1 - write low byte only */ #define DMM32AT_CLKCT2 0xb6 /* mode3 counter 2 - write high and low byte */ -/* DMM32AT_DIOCONF 0x0f */ -#define DMM32AT_DIENABLE 0x80 -#define DMM32AT_DIRA 0x10 -#define DMM32AT_DIRB 0x02 -#define DMM32AT_DIRCL 0x01 -#define DMM32AT_DIRCH 0x08 - /* board AI ranges in comedi structure */ static const struct comedi_lrange dmm32at_airanges = { 4, { @@ -150,12 +164,36 @@ static const struct comedi_lrange dmm32at_aoranges = { } }; -struct dmm32at_private { - int data; - int ai_inuse; - unsigned int ai_scans_left; - unsigned char dio_config; -}; +static void dmm32at_ai_set_chanspec(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int chanspec, int nchan) +{ + unsigned int chan = CR_CHAN(chanspec); + unsigned int range = CR_RANGE(chanspec); + unsigned int last_chan = (chan + nchan - 1) % s->n_chan; + + outb(DMM32AT_FIFO_CTRL_FIFORST, dev->iobase + DMM32AT_FIFO_CTRL_REG); + + if (nchan > 1) + outb(DMM32AT_FIFO_CTRL_SCANEN, + dev->iobase + DMM32AT_FIFO_CTRL_REG); + + outb(chan, dev->iobase + DMM32AT_AI_LO_CHAN_REG); + outb(last_chan, dev->iobase + DMM32AT_AI_HI_CHAN_REG); + outb(dmm32at_rangebits[range], dev->iobase + DMM32AT_AI_CFG_REG); +} + +static unsigned int dmm32at_ai_get_sample(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + unsigned int val; + + val = inb(dev->iobase + DMM32AT_AI_LSB_REG); + val |= (inb(dev->iobase + DMM32AT_AI_MSB_REG) << 8); + + /* munge two's complement value to offset binary */ + return comedi_offset_munge(s, val); +} static int dmm32at_ai_status(struct comedi_device *dev, struct comedi_subdevice *s, @@ -165,75 +203,39 @@ static int dmm32at_ai_status(struct comedi_device *dev, unsigned char status; status = inb(dev->iobase + context); - if ((status & DMM32AT_STATUS) == 0) + if ((status & DMM32AT_AI_STATUS_STS) == 0) return 0; return -EBUSY; } -static int dmm32at_ai_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int dmm32at_ai_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - int n; - unsigned int d; - unsigned short msb, lsb; - unsigned char chan; - int range; int ret; + int i; - /* get the channel and range number */ - - chan = CR_CHAN(insn->chanspec) & (s->n_chan - 1); - range = CR_RANGE(insn->chanspec); - - /* zero scan and fifo control and reset fifo */ - outb(DMM32AT_FIFORESET, dev->iobase + DMM32AT_FIFOCNTRL); - - /* write the ai channel range regs */ - outb(chan, dev->iobase + DMM32AT_AILOW); - outb(chan, dev->iobase + DMM32AT_AIHIGH); - /* set the range bits */ - outb(dmm32at_rangebits[range], dev->iobase + DMM32AT_AICONF); + dmm32at_ai_set_chanspec(dev, s, insn->chanspec, 1); /* wait for circuit to settle */ - ret = comedi_timeout(dev, s, insn, dmm32at_ai_status, DMM32AT_AIRBACK); + ret = comedi_timeout(dev, s, insn, dmm32at_ai_status, + DMM32AT_AI_READBACK_REG); if (ret) return ret; - /* convert n samples */ - for (n = 0; n < insn->n; n++) { - /* trigger conversion */ - outb(0xff, dev->iobase + DMM32AT_CONV); + for (i = 0; i < insn->n; i++) { + outb(0xff, dev->iobase + DMM32AT_AI_START_CONV_REG); - /* wait for conversion to end */ ret = comedi_timeout(dev, s, insn, dmm32at_ai_status, - DMM32AT_AISTAT); + DMM32AT_AI_STATUS_REG); if (ret) return ret; - /* read data */ - lsb = inb(dev->iobase + DMM32AT_AILSB); - msb = inb(dev->iobase + DMM32AT_AIMSB); - - /* invert sign bit to make range unsigned, this is an - idiosyncrasy of the diamond board, it return - conversions as a signed value, i.e. -32768 to - 32767, flipping the bit and interpreting it as - signed gives you a range of 0 to 65535 which is - used by comedi */ - d = ((msb ^ 0x0080) << 8) + lsb; - - data[n] = d; + data[i] = dmm32at_ai_get_sample(dev, s); } - /* return the number of samples read/written */ - return n; -} - -static int dmm32at_ns_to_timer(unsigned int *ns, unsigned int flags) -{ - /* trivial timer */ - return *ns; + return insn->n; } static int dmm32at_ai_check_chanlist(struct comedi_device *dev, @@ -273,10 +275,8 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev, /* Step 1 : check if triggers are trivially valid */ err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); - err |= cfc_check_trigger_src(&cmd->scan_begin_src, - TRIG_TIMER /*| TRIG_EXT */); - err |= cfc_check_trigger_src(&cmd->convert_src, - TRIG_TIMER /*| TRIG_EXT */); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER); err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); @@ -285,8 +285,6 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev, /* Step 2a : make sure trigger sources are unique */ - err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); - err |= cfc_check_trigger_is_unique(cmd->convert_src); err |= cfc_check_trigger_is_unique(cmd->stop_src); /* Step 2b : and mutually compatible */ @@ -298,67 +296,32 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev, err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); -#define MAX_SCAN_SPEED 1000000 /* in nanoseconds */ -#define MIN_SCAN_SPEED 1000000000 /* in nanoseconds */ - - if (cmd->scan_begin_src == TRIG_TIMER) { - err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, - MAX_SCAN_SPEED); - err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, - MIN_SCAN_SPEED); - } else { - /* external trigger */ - /* should be level/edge, hi/lo specification here */ - /* should specify multiple external triggers */ - err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 1000000); + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 1000000000); - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg >= 17500) - cmd->convert_arg = 20000; - else if (cmd->convert_arg >= 12500) - cmd->convert_arg = 15000; - else if (cmd->convert_arg >= 7500) - cmd->convert_arg = 10000; - else - cmd->convert_arg = 5000; - } else { - /* external trigger */ - /* see above */ - err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 9); - } + if (cmd->convert_arg >= 17500) + cmd->convert_arg = 20000; + else if (cmd->convert_arg >= 12500) + cmd->convert_arg = 15000; + else if (cmd->convert_arg >= 7500) + cmd->convert_arg = 10000; + else + cmd->convert_arg = 5000; err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); - if (cmd->stop_src == TRIG_COUNT) { - err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0xfffffff0); + if (cmd->stop_src == TRIG_COUNT) err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); - } else { - /* TRIG_NONE */ + else /* TRIG_NONE */ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); - } if (err) return 3; - /* step 4: fix up any arguments */ + /* Step 4: fix up any arguments */ - if (cmd->scan_begin_src == TRIG_TIMER) { - arg = cmd->scan_begin_arg; - dmm32at_ns_to_timer(&arg, cmd->flags); - err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg); - } - if (cmd->convert_src == TRIG_TIMER) { - arg = cmd->convert_arg; - dmm32at_ns_to_timer(&arg, cmd->flags); - err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg); - - if (cmd->scan_begin_src == TRIG_TIMER) { - arg = cmd->convert_arg * cmd->scan_end_arg; - err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, - arg); - } - } + arg = cmd->convert_arg * cmd->scan_end_arg; + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, arg); if (err) return 4; @@ -384,11 +347,11 @@ static void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec) hi2 = (both2 & 0xff00) >> 8; lo2 = both2 & 0x00ff; - /* set the counter frequency to 10mhz */ - outb(0, dev->iobase + DMM32AT_CNTRDIO); + /* set counter clocks to 10MHz, disable all aux dio */ + outb(0, dev->iobase + DMM32AT_CTRDIO_CFG_REG); /* get access to the clock regs */ - outb(DMM32AT_CLKACC, dev->iobase + DMM32AT_CNTRL); + outb(DMM32AT_CTRL_PAGE_8254, dev->iobase + DMM32AT_CTRL_REG); /* write the counter 1 control word and low byte to counter */ outb(DMM32AT_CLKCT1, dev->iobase + DMM32AT_CLKCT); @@ -400,65 +363,37 @@ static void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec) outb(hi2, dev->iobase + DMM32AT_CLK2); /* enable the ai conversion interrupt and the clock to start scans */ - outb(DMM32AT_ADINT | DMM32AT_CLKSEL, dev->iobase + DMM32AT_INTCLOCK); + outb(DMM32AT_INTCLK_ADINT | + DMM32AT_INTCLK_CLKEN | DMM32AT_INTCLK_CLKSEL, + dev->iobase + DMM32AT_INTCLK_REG); } static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { - struct dmm32at_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - int range; - unsigned char chanlo, chanhi; int ret; - if (!cmd->chanlist) - return -EINVAL; - - /* get the channel list and range */ - chanlo = CR_CHAN(cmd->chanlist[0]) & (s->n_chan - 1); - chanhi = chanlo + cmd->chanlist_len - 1; - if (chanhi >= s->n_chan) - return -EINVAL; - range = CR_RANGE(cmd->chanlist[0]); - - /* reset fifo */ - outb(DMM32AT_FIFORESET, dev->iobase + DMM32AT_FIFOCNTRL); - - /* set scan enable */ - outb(DMM32AT_SCANENABLE, dev->iobase + DMM32AT_FIFOCNTRL); - - /* write the ai channel range regs */ - outb(chanlo, dev->iobase + DMM32AT_AILOW); - outb(chanhi, dev->iobase + DMM32AT_AIHIGH); - - /* set the range bits */ - outb(dmm32at_rangebits[range], dev->iobase + DMM32AT_AICONF); + dmm32at_ai_set_chanspec(dev, s, cmd->chanlist[0], cmd->chanlist_len); /* reset the interrupt just in case */ - outb(DMM32AT_INTRESET, dev->iobase + DMM32AT_CNTRL); - - if (cmd->stop_src == TRIG_COUNT) - devpriv->ai_scans_left = cmd->stop_arg; - else { /* TRIG_NONE */ - devpriv->ai_scans_left = 0xffffffff; /* indicates TRIG_NONE to - * isr */ - } + outb(DMM32AT_CTRL_INTRST, dev->iobase + DMM32AT_CTRL_REG); /* * wait for circuit to settle * we don't have the 'insn' here but it's not needed */ - ret = comedi_timeout(dev, s, NULL, dmm32at_ai_status, DMM32AT_AIRBACK); + ret = comedi_timeout(dev, s, NULL, dmm32at_ai_status, + DMM32AT_AI_READBACK_REG); if (ret) return ret; - if (devpriv->ai_scans_left > 1) { + if (cmd->stop_src == TRIG_NONE || cmd->stop_arg > 1) { /* start the clock and enable the interrupts */ dmm32at_setaitimer(dev, cmd->scan_begin_arg); } else { /* start the interrups and initiate a single scan */ - outb(DMM32AT_ADINT, dev->iobase + DMM32AT_INTCLOCK); - outb(0xff, dev->iobase + DMM32AT_CONV); + outb(DMM32AT_INTCLK_ADINT, dev->iobase + DMM32AT_INTCLK_REG); + outb(0xff, dev->iobase + DMM32AT_AI_START_CONV_REG); } return 0; @@ -468,19 +403,16 @@ static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int dmm32at_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { - struct dmm32at_private *devpriv = dev->private; - - devpriv->ai_scans_left = 1; + /* disable further interrupts and clocks */ + outb(0x0, dev->iobase + DMM32AT_INTCLK_REG); return 0; } static irqreturn_t dmm32at_isr(int irq, void *d) { struct comedi_device *dev = d; - struct dmm32at_private *devpriv = dev->private; unsigned char intstat; - unsigned int samp; - unsigned short msb, lsb; + unsigned int val; int i; if (!dev->attached) { @@ -488,38 +420,26 @@ static irqreturn_t dmm32at_isr(int irq, void *d) return IRQ_HANDLED; } - intstat = inb(dev->iobase + DMM32AT_INTCLOCK); + intstat = inb(dev->iobase + DMM32AT_INTCLK_REG); - if (intstat & DMM32AT_ADINT) { + if (intstat & DMM32AT_INTCLK_ADINT) { struct comedi_subdevice *s = dev->read_subdev; struct comedi_cmd *cmd = &s->async->cmd; for (i = 0; i < cmd->chanlist_len; i++) { - /* read data */ - lsb = inb(dev->iobase + DMM32AT_AILSB); - msb = inb(dev->iobase + DMM32AT_AIMSB); - - /* invert sign bit to make range unsigned */ - samp = ((msb ^ 0x0080) << 8) + lsb; - comedi_buf_put(s, samp); + val = dmm32at_ai_get_sample(dev, s); + comedi_buf_write_samples(s, &val, 1); } - if (devpriv->ai_scans_left != 0xffffffff) { /* TRIG_COUNT */ - devpriv->ai_scans_left--; - if (devpriv->ai_scans_left == 0) { - /* disable further interrupts and clocks */ - outb(0x0, dev->iobase + DMM32AT_INTCLOCK); - /* set the buffer to be flushed with an EOF */ - s->async->events |= COMEDI_CB_EOA; - } + if (cmd->stop_src == TRIG_COUNT && + s->async->scans_done >= cmd->stop_arg) + s->async->events |= COMEDI_CB_EOA; - } - /* flush the buffer */ - comedi_event(dev, s); + comedi_handle_events(dev, s); } /* reset the interrupt */ - outb(DMM32AT_INTRESET, dev->iobase + DMM32AT_CNTRL); + outb(DMM32AT_CTRL_INTRST, dev->iobase + DMM32AT_CTRL_REG); return IRQ_HANDLED; } @@ -530,8 +450,8 @@ static int dmm32at_ao_eoc(struct comedi_device *dev, { unsigned char status; - status = inb(dev->iobase + DMM32AT_DACSTAT); - if ((status & DMM32AT_DACBUSY) == 0) + status = inb(dev->iobase + DMM32AT_AUX_DI_REG); + if ((status & DMM32AT_AUX_DI_DACBUSY) == 0) return 0; return -EBUSY; } @@ -549,9 +469,9 @@ static int dmm32at_ao_insn_write(struct comedi_device *dev, int ret; /* write LSB then MSB + chan to load DAC */ - outb(val & 0xff, dev->iobase + DMM32AT_DACLSB_REG); - outb((val >> 8) | DMM32AT_DACMSB_CHAN(chan), - dev->iobase + DMM32AT_DACMSB_REG); + outb(val & 0xff, dev->iobase + DMM32AT_AO_LSB_REG); + outb((val >> 8) | DMM32AT_AO_MSB_DACH(chan), + dev->iobase + DMM32AT_AO_MSB_REG); /* wait for circuit to settle */ ret = comedi_timeout(dev, s, insn, dmm32at_ao_eoc, 0); @@ -559,7 +479,7 @@ static int dmm32at_ao_insn_write(struct comedi_device *dev, return ret; /* dummy read to update DAC */ - inb(dev->iobase + DMM32AT_DACMSB_REG); + inb(dev->iobase + DMM32AT_AO_MSB_REG); s->readback[chan] = val; } @@ -567,136 +487,82 @@ static int dmm32at_ao_insn_write(struct comedi_device *dev, return insn->n; } -static int dmm32at_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct dmm32at_private *devpriv = dev->private; - unsigned int mask; - unsigned int val; - - mask = comedi_dio_update_state(s, data); - if (mask) { - /* get access to the DIO regs */ - outb(DMM32AT_DIOACC, dev->iobase + DMM32AT_CNTRL); - - /* if either part of dio is set for output */ - if (((devpriv->dio_config & DMM32AT_DIRCL) == 0) || - ((devpriv->dio_config & DMM32AT_DIRCH) == 0)) { - val = (s->state & 0x00ff0000) >> 16; - outb(val, dev->iobase + DMM32AT_DIOC); - } - if ((devpriv->dio_config & DMM32AT_DIRB) == 0) { - val = (s->state & 0x0000ff00) >> 8; - outb(val, dev->iobase + DMM32AT_DIOB); - } - if ((devpriv->dio_config & DMM32AT_DIRA) == 0) { - val = (s->state & 0x000000ff); - outb(val, dev->iobase + DMM32AT_DIOA); - } - } - - val = inb(dev->iobase + DMM32AT_DIOA); - val |= inb(dev->iobase + DMM32AT_DIOB) << 8; - val |= inb(dev->iobase + DMM32AT_DIOC) << 16; - s->state = val; - - data[1] = val; - - return insn->n; -} - -static int dmm32at_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int dmm32at_8255_io(struct comedi_device *dev, + int dir, int port, int data, unsigned long regbase) { - struct dmm32at_private *devpriv = dev->private; - unsigned int chan = CR_CHAN(insn->chanspec); - unsigned int mask; - unsigned char chanbit; - int ret; - - if (chan < 8) { - mask = 0x0000ff; - chanbit = DMM32AT_DIRA; - } else if (chan < 16) { - mask = 0x00ff00; - chanbit = DMM32AT_DIRB; - } else if (chan < 20) { - mask = 0x0f0000; - chanbit = DMM32AT_DIRCL; - } else { - mask = 0xf00000; - chanbit = DMM32AT_DIRCH; - } - - ret = comedi_dio_insn_config(dev, s, insn, data, mask); - if (ret) - return ret; - - if (data[0] == INSN_CONFIG_DIO_OUTPUT) - devpriv->dio_config &= ~chanbit; - else - devpriv->dio_config |= chanbit; /* get access to the DIO regs */ - outb(DMM32AT_DIOACC, dev->iobase + DMM32AT_CNTRL); - /* set the DIO's to the new configuration setting */ - outb(devpriv->dio_config, dev->iobase + DMM32AT_DIOCONF); + outb(DMM32AT_CTRL_PAGE_8255, dev->iobase + DMM32AT_CTRL_REG); - return insn->n; + if (dir) { + outb(data, dev->iobase + regbase + port); + return 0; + } + return inb(dev->iobase + regbase + port); } -static int dmm32at_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +/* Make sure the board is there and put it to a known state */ +static int dmm32at_reset(struct comedi_device *dev) { - struct dmm32at_private *devpriv; - int ret; - struct comedi_subdevice *s; unsigned char aihi, ailo, fifostat, aistat, intstat, airback; - ret = comedi_request_region(dev, it->options[0], 0x10); - if (ret) - return ret; - - /* the following just makes sure the board is there and gets - it to a known state */ - /* reset the board */ - outb(DMM32AT_RESET, dev->iobase + DMM32AT_CNTRL); + outb(DMM32AT_CTRL_RESETA, dev->iobase + DMM32AT_CTRL_REG); /* allow a millisecond to reset */ udelay(1000); /* zero scan and fifo control */ - outb(0x0, dev->iobase + DMM32AT_FIFOCNTRL); + outb(0x0, dev->iobase + DMM32AT_FIFO_CTRL_REG); /* zero interrupt and clock control */ - outb(0x0, dev->iobase + DMM32AT_INTCLOCK); + outb(0x0, dev->iobase + DMM32AT_INTCLK_REG); /* write a test channel range, the high 3 bits should drop */ - outb(0x80, dev->iobase + DMM32AT_AILOW); - outb(0xff, dev->iobase + DMM32AT_AIHIGH); + outb(0x80, dev->iobase + DMM32AT_AI_LO_CHAN_REG); + outb(0xff, dev->iobase + DMM32AT_AI_HI_CHAN_REG); /* set the range at 10v unipolar */ - outb(DMM32AT_RANGE_U10, dev->iobase + DMM32AT_AICONF); + outb(DMM32AT_RANGE_U10, dev->iobase + DMM32AT_AI_CFG_REG); /* should take 10 us to settle, here's a hundred */ udelay(100); /* read back the values */ - ailo = inb(dev->iobase + DMM32AT_AILOW); - aihi = inb(dev->iobase + DMM32AT_AIHIGH); - fifostat = inb(dev->iobase + DMM32AT_FIFOSTAT); - aistat = inb(dev->iobase + DMM32AT_AISTAT); - intstat = inb(dev->iobase + DMM32AT_INTCLOCK); - airback = inb(dev->iobase + DMM32AT_AIRBACK); - - if ((ailo != 0x00) || (aihi != 0x1f) || (fifostat != 0x80) || - (aistat != 0x60 || (intstat != 0x00) || airback != 0x0c)) { - dev_err(dev->class_dev, "board detection failed\n"); + ailo = inb(dev->iobase + DMM32AT_AI_LO_CHAN_REG); + aihi = inb(dev->iobase + DMM32AT_AI_HI_CHAN_REG); + fifostat = inb(dev->iobase + DMM32AT_FIFO_STATUS_REG); + aistat = inb(dev->iobase + DMM32AT_AI_STATUS_REG); + intstat = inb(dev->iobase + DMM32AT_INTCLK_REG); + airback = inb(dev->iobase + DMM32AT_AI_READBACK_REG); + + /* + * NOTE: The (DMM32AT_AI_STATUS_SD1 | DMM32AT_AI_STATUS_SD0) + * test makes this driver only work if the board is configured + * with all A/D channels set for single-ended operation. + */ + if (ailo != 0x00 || aihi != 0x1f || + fifostat != DMM32AT_FIFO_STATUS_EF || + aistat != (DMM32AT_AI_STATUS_SD1 | DMM32AT_AI_STATUS_SD0) || + intstat != 0x00 || airback != 0x0c) return -EIO; + + return 0; +} + +static int dmm32at_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + int ret; + + ret = comedi_request_region(dev, it->options[0], 0x10); + if (ret) + return ret; + + ret = dmm32at_reset(dev); + if (ret) { + dev_err(dev->class_dev, "board detection failed\n"); + return ret; } if (it->options[1]) { @@ -706,65 +572,45 @@ static int dmm32at_attach(struct comedi_device *dev, dev->irq = it->options[1]; } - devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); - if (!devpriv) - return -ENOMEM; - ret = comedi_alloc_subdevices(dev, 3); if (ret) return ret; + /* Analog Input subdevice */ s = &dev->subdevices[0]; - /* analog input subdevice */ - s->type = COMEDI_SUBD_AI; - /* we support single-ended (ground) and differential */ - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; - s->n_chan = 32; - s->maxdata = 0xffff; - s->range_table = &dmm32at_airanges; - s->insn_read = dmm32at_ai_rinsn; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; + s->n_chan = 32; + s->maxdata = 0xffff; + s->range_table = &dmm32at_airanges; + s->insn_read = dmm32at_ai_insn_read; if (dev->irq) { dev->read_subdev = s; - s->subdev_flags |= SDF_CMD_READ; - s->len_chanlist = 32; - s->do_cmd = dmm32at_ai_cmd; - s->do_cmdtest = dmm32at_ai_cmdtest; - s->cancel = dmm32at_ai_cancel; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = s->n_chan; + s->do_cmd = dmm32at_ai_cmd; + s->do_cmdtest = dmm32at_ai_cmdtest; + s->cancel = dmm32at_ai_cancel; } + /* Analog Output subdevice */ s = &dev->subdevices[1]; - /* analog output subdevice */ - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE; - s->n_chan = 4; - s->maxdata = 0x0fff; - s->range_table = &dmm32at_aoranges; - s->insn_write = dmm32at_ao_insn_write; - s->insn_read = comedi_readback_insn_read; + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0x0fff; + s->range_table = &dmm32at_aoranges; + s->insn_write = dmm32at_ao_insn_write; ret = comedi_alloc_subdev_readback(s); if (ret) return ret; + /* Digital I/O subdevice */ s = &dev->subdevices[2]; - /* digital i/o subdevice */ - - /* get access to the DIO regs */ - outb(DMM32AT_DIOACC, dev->iobase + DMM32AT_CNTRL); - /* set the DIO's to the defualt input setting */ - devpriv->dio_config = DMM32AT_DIRA | DMM32AT_DIRB | - DMM32AT_DIRCL | DMM32AT_DIRCH | DMM32AT_DIENABLE; - outb(devpriv->dio_config, dev->iobase + DMM32AT_DIOCONF); - - /* set up the subdevice */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 24; - s->maxdata = 1; - s->state = 0; - s->range_table = &range_digital; - s->insn_bits = dmm32at_dio_insn_bits; - s->insn_config = dmm32at_dio_insn_config; + ret = subdev_8255_init(dev, s, dmm32at_8255_io, DMM32AT_8255_IOBASE); + if (ret) + return ret; return 0; } @@ -778,5 +624,5 @@ static struct comedi_driver dmm32at_driver = { module_comedi_driver(dmm32at_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); +MODULE_DESCRIPTION("Comedi: Diamond Systems Diamond-MM-32-AT"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c index e97386343a0e..b96e60ffad73 100644 --- a/drivers/staging/comedi/drivers/dt2801.c +++ b/drivers/staging/comedi/drivers/dt2801.c @@ -597,7 +597,6 @@ havetype: devpriv->dac_range_types[0] = dac_range_lkup(it->options[4]); devpriv->dac_range_types[1] = dac_range_lkup(it->options[5]); s->insn_write = dt2801_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c index 1736e397ad2c..d660f277487e 100644 --- a/drivers/staging/comedi/drivers/dt2811.c +++ b/drivers/staging/comedi/drivers/dt2811.c @@ -418,7 +418,6 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->range_type_list[0] = dac_range_types[devpriv->dac_range[0]]; devpriv->range_type_list[1] = dac_range_types[devpriv->dac_range[1]]; s->insn_write = dt2811_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c index 9216c35c414e..9805be13005a 100644 --- a/drivers/staging/comedi/drivers/dt2814.c +++ b/drivers/staging/comedi/drivers/dt2814.c @@ -230,7 +230,7 @@ static irqreturn_t dt2814_interrupt(int irq, void *d) s->async->events |= COMEDI_CB_EOA; } - comedi_event(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index cc974a5e5cf6..2be98bb9a809 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -449,13 +449,29 @@ static void dt282x_munge(struct comedi_device *dev, } } +static unsigned int dt282x_ao_setup_dma(struct comedi_device *dev, + struct comedi_subdevice *s, + int cur_dma) +{ + struct dt282x_private *devpriv = dev->private; + void *ptr = devpriv->dma[cur_dma].buf; + unsigned int nsamples = comedi_bytes_to_samples(s, devpriv->dma_maxsize); + unsigned int nbytes; + + nbytes = comedi_buf_read_samples(s, ptr, nsamples); + if (nbytes) + dt282x_prep_ao_dma(dev, cur_dma, nbytes); + else + dev_err(dev->class_dev, "AO underrun\n"); + + return nbytes; +} + static void dt282x_ao_dma_interrupt(struct comedi_device *dev, struct comedi_subdevice *s) { struct dt282x_private *devpriv = dev->private; int cur_dma = devpriv->current_dma_index; - void *ptr = devpriv->dma[cur_dma].buf; - int size; outw(devpriv->supcsr | DT2821_SUPCSR_CLRDMADNE, dev->iobase + DT2821_SUPCSR_REG); @@ -464,13 +480,8 @@ static void dt282x_ao_dma_interrupt(struct comedi_device *dev, devpriv->current_dma_index = 1 - cur_dma; - size = cfc_read_array_from_buffer(s, ptr, devpriv->dma_maxsize); - if (size == 0) { - dev_err(dev->class_dev, "AO underrun\n"); + if (!dt282x_ao_setup_dma(dev, s, cur_dma)) s->async->events |= COMEDI_CB_OVERFLOW; - } else { - dt282x_prep_ao_dma(dev, cur_dma, size); - } } static void dt282x_ai_dma_interrupt(struct comedi_device *dev, @@ -480,6 +491,7 @@ static void dt282x_ai_dma_interrupt(struct comedi_device *dev, int cur_dma = devpriv->current_dma_index; void *ptr = devpriv->dma[cur_dma].buf; int size = devpriv->dma[cur_dma].size; + unsigned int nsamples = comedi_bytes_to_samples(s, size); int ret; outw(devpriv->supcsr | DT2821_SUPCSR_CLRDMADNE, @@ -490,13 +502,11 @@ static void dt282x_ai_dma_interrupt(struct comedi_device *dev, devpriv->current_dma_index = 1 - cur_dma; dt282x_munge(dev, s, ptr, size); - ret = cfc_write_array_to_buffer(s, ptr, size); - if (ret != size) { - s->async->events |= COMEDI_CB_OVERFLOW; + ret = comedi_buf_write_samples(s, ptr, nsamples); + if (ret != size) return; - } - devpriv->nread -= size / 2; + devpriv->nread -= nsamples; if (devpriv->nread < 0) { dev_info(dev->class_dev, "nread off by one\n"); devpriv->nread = 0; @@ -555,7 +565,6 @@ static irqreturn_t dt282x_interrupt(int irq, void *d) } #if 0 if (adcsr & DT2821_ADCSR_ADDONE) { - int ret; unsigned short data; data = inw(dev->iobase + DT2821_ADDAT_REG); @@ -563,10 +572,7 @@ static irqreturn_t dt282x_interrupt(int irq, void *d) if (devpriv->ad_2scomp) data = comedi_offset_munge(s, data); - ret = comedi_buf_put(s, data); - - if (ret == 0) - s->async->events |= COMEDI_CB_OVERFLOW; + comedi_buf_write_samples(s, &data, 1); devpriv->nread--; if (!devpriv->nread) { @@ -579,8 +585,8 @@ static irqreturn_t dt282x_interrupt(int irq, void *d) handled = 1; } #endif - cfc_handle_events(dev, s); - cfc_handle_events(dev, s_ao); + comedi_handle_events(dev, s); + comedi_handle_events(dev, s_ao); return IRQ_RETVAL(handled); } @@ -916,26 +922,15 @@ static int dt282x_ao_inttrig(struct comedi_device *dev, { struct dt282x_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - int size; if (trig_num != cmd->start_src) return -EINVAL; - size = cfc_read_array_from_buffer(s, devpriv->dma[0].buf, - devpriv->dma_maxsize); - if (size == 0) { - dev_err(dev->class_dev, "AO underrun\n"); + if (!dt282x_ao_setup_dma(dev, s, 0)) return -EPIPE; - } - dt282x_prep_ao_dma(dev, 0, size); - size = cfc_read_array_from_buffer(s, devpriv->dma[1].buf, - devpriv->dma_maxsize); - if (size == 0) { - dev_err(dev->class_dev, "AO underrun\n"); + if (!dt282x_ao_setup_dma(dev, s, 1)) return -EPIPE; - } - dt282x_prep_ao_dma(dev, 1, size); outw(devpriv->supcsr | DT2821_SUPCSR_STRIG, dev->iobase + DT2821_SUPCSR_REG); @@ -1236,7 +1231,6 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* ranges are per-channel, set by jumpers on the board */ s->range_table = &dt282x_ao_range; s->insn_write = dt282x_ao_insn_write; - s->insn_read = comedi_readback_insn_read; if (dev->irq) { dev->write_subdev = s; s->subdev_flags |= SDF_CMD_WRITE; diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 825561046b6f..1d9a7a63e06f 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -315,7 +315,7 @@ static void dt3k_ai_empty_fifo(struct comedi_device *dev, for (i = 0; i < count; i++) { data = readw(dev->mmio + DPR_ADC_buffer + rear); - comedi_buf_put(s, data); + comedi_buf_write_samples(s, &data, 1); rear++; if (rear >= AI_FIFO_DEPTH) rear = 0; @@ -351,10 +351,8 @@ static irqreturn_t dt3k_interrupt(int irq, void *d) status = readw(dev->mmio + DPR_Intr_Flag); - if (status & DT3000_ADFULL) { + if (status & DT3000_ADFULL) dt3k_ai_empty_fifo(dev, s); - s->async->events |= COMEDI_CB_BLOCK; - } if (status & (DT3000_ADSWERR | DT3000_ADHWERR)) s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; @@ -363,7 +361,7 @@ static irqreturn_t dt3k_interrupt(int irq, void *d) if (debug_n_ints >= 10) s->async->events |= COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } @@ -699,7 +697,6 @@ static int dt3000_auto_attach(struct comedi_device *dev, s->len_chanlist = 1; s->range_table = &range_bipolar10; s->insn_write = dt3k_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index 77bb89fee327..06c601d8fdff 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -804,7 +804,7 @@ static int dt9812_auto_attach(struct comedi_device *dev, /* Digital Output subdevice */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 8; s->maxdata = 1; s->range_table = &range_digital; @@ -822,7 +822,7 @@ static int dt9812_auto_attach(struct comedi_device *dev, /* Analog Output subdevice */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 2; s->maxdata = 0x0fff; s->range_table = is_unipolar ? &range_unipolar2_5 : &range_bipolar10; diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 608aee0c3a15..1b6324c6eb29 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -218,7 +218,7 @@ static int dyna_pci10xx_auto_attach(struct comedi_device *dev, /* digital input */ s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND; + s->subdev_flags = SDF_READABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; @@ -228,7 +228,7 @@ static int dyna_pci10xx_auto_attach(struct comedi_device *dev, /* digital output */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_GROUND; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c index 5a1e3c8fc01c..e1f493241cd6 100644 --- a/drivers/staging/comedi/drivers/fl512.c +++ b/drivers/staging/comedi/drivers/fl512.c @@ -135,7 +135,6 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->maxdata = 0x0fff; s->range_table = &range_fl512; s->insn_write = fl512_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index b8975a4606ea..0979f536ed39 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -196,8 +196,8 @@ static void gsc_hpdi_drain_dma(struct comedi_device *dev, unsigned int channel) size = devpriv->dio_count; devpriv->dio_count -= size; } - cfc_write_array_to_buffer(s, devpriv->desc_dio_buffer[idx], - size * sizeof(uint32_t)); + comedi_buf_write_samples(s, devpriv->desc_dio_buffer[idx], + size); idx++; idx %= devpriv->num_dma_descriptors; start = le32_to_cpu(devpriv->dma_desc[idx].pci_start_addr); @@ -272,7 +272,7 @@ static irqreturn_t gsc_hpdi_interrupt(int irq, void *d) if (devpriv->dio_count == 0) async->events |= COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } @@ -689,7 +689,7 @@ static int gsc_hpdi_auto_attach(struct comedi_device *dev, s = &dev->subdevices[0]; dev->read_subdev = s; s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITEABLE | SDF_LSAMPL | + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_CMD_READ; s->n_chan = 32; s->len_chanlist = 32; diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index f4e1c1cf4178..1ea168620103 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -53,7 +53,7 @@ Configuration options: not applicable, uses PCI auto config #define ICP_MULTI_AI 2 /* R: Analogue input data */ #define ICP_MULTI_DAC_CSR 4 /* R/W: DAC command/status register */ #define ICP_MULTI_AO 6 /* R/W: Analogue output data */ -#define ICP_MULTI_DI 8 /* R/W: Digital inouts */ +#define ICP_MULTI_DI 8 /* R/W: Digital inputs */ #define ICP_MULTI_DO 0x0A /* R/W: Digital outputs */ #define ICP_MULTI_INT_EN 0x0C /* R/W: Interrupt enable register */ #define ICP_MULTI_INT_STAT 0x0E /* R/W: Interrupt status register */ @@ -319,7 +319,7 @@ static int icp_multi_insn_bits_do(struct comedi_device *dev, if (comedi_dio_update_state(s, data)) writew(s->state, dev->mmio + ICP_MULTI_DO); - data[1] = readw(dev->mmio + ICP_MULTI_DI); + data[1] = s->state; return insn->n; } @@ -495,7 +495,6 @@ static int icp_multi_auto_attach(struct comedi_device *dev, s->len_chanlist = 4; s->range_table = &range_analog; s->insn_write = icp_multi_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) @@ -512,7 +511,7 @@ static int icp_multi_auto_attach(struct comedi_device *dev, s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 8; s->maxdata = 1; s->len_chanlist = 8; @@ -521,7 +520,7 @@ static int icp_multi_auto_attach(struct comedi_device *dev, s = &dev->subdevices[4]; s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 4; s->maxdata = 0xffff; s->len_chanlist = 4; diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c index cc5fd75b8bc0..1085d66935fe 100644 --- a/drivers/staging/comedi/drivers/ii_pci20kc.c +++ b/drivers/staging/comedi/drivers/ii_pci20kc.c @@ -392,7 +392,6 @@ static int ii20k_init_module(struct comedi_device *dev, s->maxdata = 0xffff; s->range_table = &ii20k_ao_ranges; s->insn_write = ii20k_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 6561b00bea59..915685c1c85c 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -44,8 +44,6 @@ broken. #include <linux/pci.h> #include <linux/delay.h> #include <linux/interrupt.h> -#include <linux/list.h> -#include <linux/spinlock.h> #include "../comedidev.h" @@ -53,10 +51,7 @@ broken. #include "8253.h" #include "plx9052.h" -#if 0 -/* file removed due to GPL incompatibility */ -#include "me4000_fw.h" -#endif +#define ME4000_FIRMWARE "me4000_firmware.bin" /* * ME4000 Register map and bit defines @@ -333,27 +328,20 @@ static const struct comedi_lrange me4000_ai_range = { } }; -#define FIRMWARE_NOT_AVAILABLE 1 -#if FIRMWARE_NOT_AVAILABLE -extern unsigned char *xilinx_firm; -#endif - -static int xilinx_download(struct comedi_device *dev) +static int me4000_xilinx_download(struct comedi_device *dev, + const u8 *data, size_t size, + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct me4000_info *info = dev->private; unsigned long xilinx_iobase = pci_resource_start(pcidev, 5); - u32 value = 0; - wait_queue_head_t queue; - int idx = 0; - int size = 0; - unsigned int intcsr; + unsigned int file_length; + unsigned int val; + unsigned int i; if (!xilinx_iobase) return -ENODEV; - init_waitqueue_head(&queue); - /* * Set PLX local interrupt 2 polarity to high. * Interrupt is thrown by init pin of xilinx. @@ -361,61 +349,58 @@ static int xilinx_download(struct comedi_device *dev) outl(PLX9052_INTCSR_LI2POL, info->plx_regbase + PLX9052_INTCSR); /* Set /CS and /WRITE of the Xilinx */ - value = inl(info->plx_regbase + PLX9052_CNTRL); - value |= PLX9052_CNTRL_UIO2_DATA; - outl(value, info->plx_regbase + PLX9052_CNTRL); + val = inl(info->plx_regbase + PLX9052_CNTRL); + val |= PLX9052_CNTRL_UIO2_DATA; + outl(val, info->plx_regbase + PLX9052_CNTRL); /* Init Xilinx with CS1 */ inb(xilinx_iobase + 0xC8); /* Wait until /INIT pin is set */ udelay(20); - intcsr = inl(info->plx_regbase + PLX9052_INTCSR); - if (!(intcsr & PLX9052_INTCSR_LI2STAT)) { + val = inl(info->plx_regbase + PLX9052_INTCSR); + if (!(val & PLX9052_INTCSR_LI2STAT)) { dev_err(dev->class_dev, "Can't init Xilinx\n"); return -EIO; } /* Reset /CS and /WRITE of the Xilinx */ - value = inl(info->plx_regbase + PLX9052_CNTRL); - value &= ~PLX9052_CNTRL_UIO2_DATA; - outl(value, info->plx_regbase + PLX9052_CNTRL); - if (FIRMWARE_NOT_AVAILABLE) { - dev_err(dev->class_dev, - "xilinx firmware unavailable due to licensing, aborting"); - return -EIO; - } else { - /* Download Xilinx firmware */ - size = (xilinx_firm[0] << 24) + (xilinx_firm[1] << 16) + - (xilinx_firm[2] << 8) + xilinx_firm[3]; - udelay(10); + val = inl(info->plx_regbase + PLX9052_CNTRL); + val &= ~PLX9052_CNTRL_UIO2_DATA; + outl(val, info->plx_regbase + PLX9052_CNTRL); - for (idx = 0; idx < size; idx++) { - outb(xilinx_firm[16 + idx], xilinx_iobase); - udelay(10); + /* Download Xilinx firmware */ + file_length = (((unsigned int)data[0] & 0xff) << 24) + + (((unsigned int)data[1] & 0xff) << 16) + + (((unsigned int)data[2] & 0xff) << 8) + + ((unsigned int)data[3] & 0xff); + udelay(10); - /* Check if BUSY flag is low */ - if (inl(info->plx_regbase + PLX9052_CNTRL) & PLX9052_CNTRL_UIO1_DATA) { - dev_err(dev->class_dev, - "Xilinx is still busy (idx = %d)\n", - idx); - return -EIO; - } + for (i = 0; i < file_length; i++) { + outb(data[16 + i], xilinx_iobase); + udelay(10); + + /* Check if BUSY flag is low */ + val = inl(info->plx_regbase + PLX9052_CNTRL); + if (val & PLX9052_CNTRL_UIO1_DATA) { + dev_err(dev->class_dev, + "Xilinx is still busy (i = %d)\n", i); + return -EIO; } } /* If done flag is high download was successful */ - if (inl(info->plx_regbase + PLX9052_CNTRL) & PLX9052_CNTRL_UIO0_DATA) { - } else { + val = inl(info->plx_regbase + PLX9052_CNTRL); + if (!(val & PLX9052_CNTRL_UIO0_DATA)) { dev_err(dev->class_dev, "DONE flag is not set\n"); dev_err(dev->class_dev, "Download not successful\n"); return -EIO; } /* Set /CS and /WRITE */ - value = inl(info->plx_regbase + PLX9052_CNTRL); - value |= PLX9052_CNTRL_UIO2_DATA; - outl(value, info->plx_regbase + PLX9052_CNTRL); + val = inl(info->plx_regbase + PLX9052_CNTRL); + val |= PLX9052_CNTRL_UIO2_DATA; + outl(val, info->plx_regbase + PLX9052_CNTRL); return 0; } @@ -431,7 +416,7 @@ static void me4000_reset(struct comedi_device *dev) val |= PLX9052_CNTRL_PCI_RESET; outl(val, info->plx_regbase + PLX9052_CNTRL); val &= ~PLX9052_CNTRL_PCI_RESET; - outl(val , info->plx_regbase + PLX9052_CNTRL); + outl(val, info->plx_regbase + PLX9052_CNTRL); /* 0x8000 to the DACs means an output voltage of 0V */ for (chan = 0; chan < 4; chan++) @@ -848,9 +833,6 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, unsigned int scan_ticks; int err = 0; - /* Only rounding flags are implemented */ - cmd->flags &= CMDF_ROUND_NEAREST | CMDF_ROUND_UP | CMDF_ROUND_DOWN; - /* Round the timer arguments */ ai_round_cmd_args(dev, s, cmd, &init_ticks, &scan_ticks, &chan_ticks); @@ -1092,8 +1074,6 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA) && !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) { - s->async->events |= COMEDI_CB_BLOCK; - c = ME4000_AI_FIFO_COUNT / 2; } else { dev_err(dev->class_dev, @@ -1119,7 +1099,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF; lval ^= 0x8000; - if (!comedi_buf_put(s, lval)) { + if (!comedi_buf_write_samples(s, &lval, 1)) { /* * Buffer overflow, so stop conversion * and disable all interrupts @@ -1128,11 +1108,6 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ); outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); - - s->async->events |= COMEDI_CB_OVERFLOW; - - dev_err(dev->class_dev, "Buffer overflow\n"); - break; } } @@ -1146,7 +1121,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) & ME4000_IRQ_STATUS_BIT_SC) { - s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOA; + s->async->events |= COMEDI_CB_EOA; /* * Acquisition is complete, so stop @@ -1164,11 +1139,8 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF; lval ^= 0x8000; - if (!comedi_buf_put(s, lval)) { - dev_err(dev->class_dev, "Buffer overflow\n"); - s->async->events |= COMEDI_CB_OVERFLOW; + if (!comedi_buf_write_samples(s, &lval, 1)) break; - } } /* Work is done, so reset the interrupt */ @@ -1178,8 +1150,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); } - if (s->async->events) - comedi_event(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } @@ -1397,8 +1368,9 @@ static int me4000_auto_attach(struct comedi_device *dev, if (!info->plx_regbase || !dev->iobase || !info->timer_regbase) return -ENODEV; - result = xilinx_download(dev); - if (result) + result = comedi_load_firmware(dev, &pcidev->dev, ME4000_FIRMWARE, + me4000_xilinx_download, 0); + if (result < 0) return result; me4000_reset(dev); @@ -1449,12 +1421,11 @@ static int me4000_auto_attach(struct comedi_device *dev, if (thisboard->ao_nchan) { s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND; + s->subdev_flags = SDF_WRITABLE | SDF_COMMON | SDF_GROUND; s->n_chan = thisboard->ao_nchan; s->maxdata = 0xFFFF; /* 16 bit DAC */ s->range_table = &range_bipolar10; s->insn_write = me4000_ao_insn_write; - s->insn_read = comedi_readback_insn_read; result = comedi_alloc_subdev_readback(s); if (result) @@ -1561,3 +1532,4 @@ module_comedi_pci_driver(me4000_driver, me4000_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE(ME4000_FIRMWARE); diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 00eaaf8ac148..b5278c11e622 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -511,13 +511,12 @@ static int me_auto_attach(struct comedi_device *dev, s = &dev->subdevices[1]; if (board->has_ao) { s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE | SDF_COMMON; s->n_chan = 4; s->maxdata = 0x0fff; s->len_chanlist = 4; s->range_table = &me_ao_range; s->insn_write = me_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) @@ -528,7 +527,7 @@ static int me_auto_attach(struct comedi_device *dev, s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITEABLE; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 32; s->maxdata = 1; s->len_chanlist = 32; diff --git a/drivers/staging/comedi/drivers/mf6x4.c b/drivers/staging/comedi/drivers/mf6x4.c index c8d3a22c5896..af21bc180c46 100644 --- a/drivers/staging/comedi/drivers/mf6x4.c +++ b/drivers/staging/comedi/drivers/mf6x4.c @@ -259,7 +259,6 @@ static int mf6x4_auto_attach(struct comedi_device *dev, unsigned long context) s->maxdata = 0x3fff; /* 14 bits DAC */ s->range_table = &range_bipolar10; s->insn_write = mf6x4_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c index 4f7829010a99..ffc9e61d6cdd 100644 --- a/drivers/staging/comedi/drivers/mite.c +++ b/drivers/staging/comedi/drivers/mite.c @@ -494,13 +494,10 @@ EXPORT_SYMBOL_GPL(mite_bytes_read_from_memory_ub); unsigned mite_dma_tcr(struct mite_channel *mite_chan) { struct mite_struct *mite = mite_chan->mite; - int tcr; int lkar; lkar = readl(mite->mite_io_addr + MITE_LKAR(mite_chan->channel)); - tcr = readl(mite->mite_io_addr + MITE_TCR(mite_chan->channel)); - - return tcr; + return readl(mite->mite_io_addr + MITE_TCR(mite_chan->channel)); } EXPORT_SYMBOL_GPL(mite_dma_tcr); @@ -542,7 +539,7 @@ int mite_sync_input_dma(struct mite_channel *mite_chan, return 0; comedi_buf_write_free(s, count); - cfc_inc_scan_progress(s, count); + comedi_inc_scan_progress(s, count); async->events |= COMEDI_CB_BLOCK; return 0; } @@ -553,7 +550,7 @@ int mite_sync_output_dma(struct mite_channel *mite_chan, { struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; - u32 stop_count = cmd->stop_arg * cfc_bytes_per_scan(s); + u32 stop_count = cmd->stop_arg * comedi_bytes_per_scan(s); unsigned int old_alloc_count = async->buf_read_alloc_count; u32 nbytes_ub, nbytes_lb; int count; diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c index f710c8e81320..8471219210b6 100644 --- a/drivers/staging/comedi/drivers/multiq3.c +++ b/drivers/staging/comedi/drivers/multiq3.c @@ -238,7 +238,6 @@ static int multiq3_attach(struct comedi_device *dev, s->maxdata = 0xfff; s->range_table = &range_bipolar5; s->insn_write = multiq3_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 45fb601e4080..f99847f3999f 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -208,9 +208,8 @@ static irqreturn_t ni6527_interrupt(int irq, void *d) return IRQ_NONE; if (status & NI6527_STATUS_EDGE) { - comedi_buf_put(s, 0); - s->async->events |= COMEDI_CB_EOS; - comedi_event(dev, s); + comedi_buf_write_samples(s, &s->state, 1); + comedi_handle_events(dev, s); } writeb(NI6527_CLR_IRQS, dev->mmio + NI6527_CLR_REG); @@ -238,9 +237,6 @@ static int ni6527_intr_cmdtest(struct comedi_device *dev, /* Step 2a : make sure trigger sources are unique */ /* Step 2b : and mutually compatible */ - if (err) - return 2; - /* Step 3: check if arguments are trivially valid */ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 3b642861eb36..bcb326e31562 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -508,9 +508,9 @@ static irqreturn_t ni_65xx_interrupt(int irq, void *d) writeb(NI_65XX_CLR_EDGE_INT | NI_65XX_CLR_OVERFLOW_INT, dev->mmio + NI_65XX_CLR_REG); - comedi_buf_put(s, 0); - s->async->events |= COMEDI_CB_EOS; - comedi_event(dev, s); + comedi_buf_write_samples(s, &s->state, 1); + comedi_handle_events(dev, s); + return IRQ_HANDLED; } @@ -534,9 +534,6 @@ static int ni_65xx_intr_cmdtest(struct comedi_device *dev, /* Step 2a : make sure trigger sources are unique */ /* Step 2b : and mutually compatible */ - if (err) - return 2; - /* Step 3: check if arguments are trivially valid */ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 5b6794c8232e..1e4dd82b12ea 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -780,7 +780,7 @@ static void ni_660x_handle_gpct_interrupt(struct comedi_device *dev, struct ni_gpct *counter = s->private; ni_tio_handle_interrupt(counter, s); - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static irqreturn_t ni_660x_interrupt(int irq, void *d) diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index 54721deb80cc..c42a81c0bfa1 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -228,7 +228,6 @@ static int ni_670x_auto_attach(struct comedi_device *dev, s->range_table = &range_bipolar10; } s->insn_write = ni_670x_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index 72ec857d073e..69e543a0bf22 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -168,7 +168,6 @@ static irqreturn_t a2150_interrupt(int irq, void *d) struct comedi_cmd *cmd; unsigned int max_points, num_points, residue, leftover; unsigned short dpnt; - static const int sample_size = sizeof(devpriv->dma_buffer[0]); if (!dev->attached) { dev_err(dev->class_dev, "premature interrupt\n"); @@ -188,14 +187,14 @@ static irqreturn_t a2150_interrupt(int irq, void *d) if (status & OVFL_BIT) { dev_err(dev->class_dev, "fifo overflow\n"); async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } if ((status & DMA_TC_BIT) == 0) { dev_err(dev->class_dev, "caught non-dma interrupt? Aborting.\n"); async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } @@ -206,12 +205,12 @@ static irqreturn_t a2150_interrupt(int irq, void *d) clear_dma_ff(devpriv->dma); /* figure out how many points to read */ - max_points = devpriv->dma_transfer_size / sample_size; + max_points = comedi_bytes_to_samples(s, devpriv->dma_transfer_size); /* residue is the number of points left to be done on the dma * transfer. It should always be zero at this point unless * the stop_src is set to external triggering. */ - residue = get_dma_residue(devpriv->dma) / sample_size; + residue = comedi_bytes_to_samples(s, get_dma_residue(devpriv->dma)); num_points = max_points - residue; if (devpriv->count < num_points && cmd->stop_src == TRIG_COUNT) num_points = devpriv->count; @@ -219,7 +218,8 @@ static irqreturn_t a2150_interrupt(int irq, void *d) /* figure out how many points will be stored next time */ leftover = 0; if (cmd->stop_src == TRIG_NONE) { - leftover = devpriv->dma_transfer_size / sample_size; + leftover = comedi_bytes_to_samples(s, + devpriv->dma_transfer_size); } else if (devpriv->count > max_points) { leftover = devpriv->count - max_points; if (leftover > max_points) @@ -237,7 +237,7 @@ static irqreturn_t a2150_interrupt(int irq, void *d) dpnt = devpriv->dma_buffer[i]; /* convert from 2's complement to unsigned coding */ dpnt ^= 0x8000; - cfc_write_to_buffer(s, dpnt); + comedi_buf_write_samples(s, &dpnt, 1); if (cmd->stop_src == TRIG_COUNT) { if (--devpriv->count == 0) { /* end of acquisition */ async->events |= COMEDI_CB_EOA; @@ -248,14 +248,13 @@ static irqreturn_t a2150_interrupt(int irq, void *d) /* re-enable dma */ if (leftover) { set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer)); - set_dma_count(devpriv->dma, leftover * sample_size); + set_dma_count(devpriv->dma, + comedi_samples_to_bytes(s, leftover)); enable_dma(devpriv->dma); } release_dma_lock(flags); - async->events |= COMEDI_CB_BLOCK; - - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); /* clear interrupt */ outw(0x00, dev->iobase + DMA_TC_CLEAR_REG); diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c index 3e1ce5866147..05370a4a74a5 100644 --- a/drivers/staging/comedi/drivers/ni_at_ao.c +++ b/drivers/staging/comedi/drivers/ni_at_ao.c @@ -244,47 +244,31 @@ static int atao_calib_insn_write(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct atao_private *devpriv = dev->private; unsigned int chan = CR_CHAN(insn->chanspec); - unsigned int bitstring; - unsigned int val; - int bit; - if (insn->n == 0) - return 0; + if (insn->n) { + unsigned int val = data[insn->n - 1]; + unsigned int bitstring = ((chan & 0x7) << 8) | val; + unsigned int bits; + int bit; - devpriv->caldac[chan] = data[insn->n - 1] & s->maxdata; + /* write the channel and last data value to the caldac */ + /* clock the bitstring to the caldac; MSB -> LSB */ + for (bit = 1 << 10; bit; bit >>= 1) { + bits = (bit & bitstring) ? ATAO_CFG2_SDATA : 0; - /* write the channel and last data value to the caldac */ - bitstring = ((chan & 0x7) << 8) | devpriv->caldac[chan]; + outw(bits, dev->iobase + ATAO_CFG2_REG); + outw(bits | ATAO_CFG2_SCLK, + dev->iobase + ATAO_CFG2_REG); + } - /* clock the bitstring to the caldac; MSB -> LSB */ - for (bit = 1 << 10; bit; bit >>= 1) { - val = (bit & bitstring) ? ATAO_CFG2_SDATA : 0; + /* strobe the caldac to load the value */ + outw(ATAO_CFG2_CALLD(chan), dev->iobase + ATAO_CFG2_REG); + outw(ATAO_CFG2_CALLD_NOP, dev->iobase + ATAO_CFG2_REG); - outw(val, dev->iobase + ATAO_CFG2_REG); - outw(val | ATAO_CFG2_SCLK, dev->iobase + ATAO_CFG2_REG); + s->readback[chan] = val; } - /* strobe the caldac to load the value */ - outw(ATAO_CFG2_CALLD(chan), dev->iobase + ATAO_CFG2_REG); - outw(ATAO_CFG2_CALLD_NOP, dev->iobase + ATAO_CFG2_REG); - - return insn->n; -} - -static int atao_calib_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct atao_private *devpriv = dev->private; - unsigned int chan = CR_CHAN(insn->chanspec); - int i; - - for (i = 0; i < insn->n; i++) - data[i] = devpriv->caldac[chan]; - return insn->n; } @@ -344,7 +328,6 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->maxdata = 0x0fff; s->range_table = it->options[3] ? &range_unipolar10 : &range_bipolar10; s->insn_write = atao_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) @@ -366,9 +349,12 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL; s->n_chan = (board->n_ao_chans * 2) + 1; s->maxdata = 0xff; - s->insn_read = atao_calib_insn_read; s->insn_write = atao_calib_insn_write; + ret = comedi_alloc_subdev_readback(s); + if (ret) + return ret; + /* EEPROM subdevice */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_UNUSED; diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index fc3c19de7005..c484c89c94b5 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -217,10 +217,12 @@ static irqreturn_t atmio16d_interrupt(int irq, void *d) { struct comedi_device *dev = d; struct comedi_subdevice *s = dev->read_subdev; + unsigned short val; - comedi_buf_put(s, inw(dev->iobase + AD_FIFO_REG)); + val = inw(dev->iobase + AD_FIFO_REG); + comedi_buf_write_samples(s, &val, 1); + comedi_handle_events(dev, s); - comedi_event(dev, s); return IRQ_HANDLED; } @@ -298,7 +300,6 @@ static int atmio16d_ai_cmd(struct comedi_device *dev, * It is still uber-experimental */ reset_counters(dev); - s->async->cur_chan = 0; /* check if scanning multiple channels */ if (cmd->chanlist_len < 2) { @@ -691,7 +692,6 @@ static int atmio16d_attach(struct comedi_device *dev, break; } s->insn_write = atmio16d_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/ni_labpc.h b/drivers/staging/comedi/drivers/ni_labpc.h index f6e5cd15a409..ac2c01f9dfdc 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.h +++ b/drivers/staging/comedi/drivers/ni_labpc.h @@ -37,8 +37,6 @@ struct labpc_boardinfo { struct labpc_private { /* number of data points left to be taken */ unsigned long long count; - /* software copy of analog output values */ - unsigned int ao_value[NUM_AO_CHAN]; /* software copys of bits written to command registers */ unsigned int cmd1; unsigned int cmd2; @@ -70,10 +68,6 @@ struct labpc_private { unsigned int dma_transfer_size; /* we are using dma/fifo-half-full/etc. */ enum transfer_type current_transfer; - /* stores contents of board's eeprom */ - unsigned int eeprom_data[EEPROM_SIZE]; - /* stores settings of calibration dacs */ - unsigned int caldac[16]; /* * function pointers so we can use inb/outb or readb/writeb as * appropriate diff --git a/drivers/staging/comedi/drivers/ni_labpc_common.c b/drivers/staging/comedi/drivers/ni_labpc_common.c index 35bc2c25ddfb..d89d5852aeea 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_common.c +++ b/drivers/staging/comedi/drivers/ni_labpc_common.c @@ -818,7 +818,7 @@ static int labpc_drain_fifo(struct comedi_device *dev) devpriv->count--; } data = labpc_read_adc_fifo(dev); - cfc_write_to_buffer(dev->read_subdev, data); + comedi_buf_write_samples(dev->read_subdev, &data, 1); devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG); } if (i == timeout) { @@ -876,7 +876,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d) /* clear error interrupt */ devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG); async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); dev_err(dev->class_dev, "overrun\n"); return IRQ_HANDLED; } @@ -896,7 +896,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d) /* clear error interrupt */ devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG); async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); dev_err(dev->class_dev, "overflow\n"); return IRQ_HANDLED; } @@ -914,10 +914,22 @@ static irqreturn_t labpc_interrupt(int irq, void *d) async->events |= COMEDI_CB_EOA; } - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } +static void labpc_ao_write(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int chan, unsigned int val) +{ + struct labpc_private *devpriv = dev->private; + + devpriv->write_byte(dev, val & 0xff, DAC_LSB_REG(chan)); + devpriv->write_byte(dev, (val >> 8) & 0xff, DAC_MSB_REG(chan)); + + s->readback[chan] = val; +} + static int labpc_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -927,7 +939,6 @@ static int labpc_ao_insn_write(struct comedi_device *dev, struct labpc_private *devpriv = dev->private; int channel, range; unsigned long flags; - int lsb, msb; channel = CR_CHAN(insn->chanspec); @@ -950,25 +961,7 @@ static int labpc_ao_insn_write(struct comedi_device *dev, devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG); } /* send data */ - lsb = data[0] & 0xff; - msb = (data[0] >> 8) & 0xff; - devpriv->write_byte(dev, lsb, DAC_LSB_REG(channel)); - devpriv->write_byte(dev, msb, DAC_MSB_REG(channel)); - - /* remember value for readback */ - devpriv->ao_value[channel] = data[0]; - - return 1; -} - -static int labpc_ao_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct labpc_private *devpriv = dev->private; - - data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)]; + labpc_ao_write(dev, s, channel, data[0]); return 1; } @@ -1085,29 +1078,13 @@ static unsigned int labpc_eeprom_read_status(struct comedi_device *dev) return value; } -static int labpc_eeprom_write(struct comedi_device *dev, - unsigned int address, unsigned int value) +static void labpc_eeprom_write(struct comedi_device *dev, + unsigned int address, unsigned int value) { struct labpc_private *devpriv = dev->private; const int write_enable_instruction = 0x6; const int write_instruction = 0x2; const int write_length = 8; /* 8 bit write lengths to eeprom */ - const int write_in_progress_bit = 0x1; - const int timeout = 10000; - int i; - - /* make sure there isn't already a write in progress */ - for (i = 0; i < timeout; i++) { - if ((labpc_eeprom_read_status(dev) & write_in_progress_bit) == - 0) - break; - } - if (i == timeout) { - dev_err(dev->class_dev, "eeprom write timed out\n"); - return -ETIME; - } - /* update software copy of eeprom */ - devpriv->eeprom_data[address] = value; /* enable read/write to eeprom */ devpriv->cmd5 &= ~CMD5_EEPROMCS; @@ -1140,8 +1117,6 @@ static int labpc_eeprom_write(struct comedi_device *dev, devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT); udelay(1); devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG); - - return 0; } /* writes to 8 bit calibration dacs */ @@ -1150,10 +1125,6 @@ static void write_caldac(struct comedi_device *dev, unsigned int channel, { struct labpc_private *devpriv = dev->private; - if (value == devpriv->caldac[channel]) - return; - devpriv->caldac[channel] = value; - /* clear caldac load bit and make sure we don't write to eeprom */ devpriv->cmd5 &= ~(CMD5_CALDACLD | CMD5_EEPROMCS | CMD5_WRTPRT); udelay(1); @@ -1184,25 +1155,30 @@ static int labpc_calib_insn_write(struct comedi_device *dev, * Only write the last data value to the caldac. Preceding * data would be overwritten anyway. */ - if (insn->n > 0) - write_caldac(dev, chan, data[insn->n - 1]); + if (insn->n > 0) { + unsigned int val = data[insn->n - 1]; + + if (s->readback[chan] != val) { + write_caldac(dev, chan, val); + s->readback[chan] = val; + } + } return insn->n; } -static int labpc_calib_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int labpc_eeprom_ready(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned long context) { - struct labpc_private *devpriv = dev->private; - unsigned int chan = CR_CHAN(insn->chanspec); - int i; - - for (i = 0; i < insn->n; i++) - data[i] = devpriv->caldac[chan]; + unsigned int status; - return insn->n; + /* make sure there isn't already a write in progress */ + status = labpc_eeprom_read_status(dev); + if ((status & 0x1) == 0) + return 0; + return -EBUSY; } static int labpc_eeprom_insn_write(struct comedi_device *dev, @@ -1222,25 +1198,15 @@ static int labpc_eeprom_insn_write(struct comedi_device *dev, * data would be overwritten anyway. */ if (insn->n > 0) { - ret = labpc_eeprom_write(dev, chan, data[insn->n - 1]); + unsigned int val = data[insn->n - 1]; + + ret = comedi_timeout(dev, s, insn, labpc_eeprom_ready, 0); if (ret) return ret; - } - - return insn->n; -} - -static int labpc_eeprom_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct labpc_private *devpriv = dev->private; - unsigned int chan = CR_CHAN(insn->chanspec); - int i; - for (i = 0; i < insn->n; i++) - data[i] = devpriv->eeprom_data[chan]; + labpc_eeprom_write(dev, chan, val); + s->readback[chan] = val; + } return insn->n; } @@ -1309,19 +1275,15 @@ int labpc_common_attach(struct comedi_device *dev, s->n_chan = NUM_AO_CHAN; s->maxdata = 0x0fff; s->range_table = &range_labpc_ao; - s->insn_read = labpc_ao_insn_read; s->insn_write = labpc_ao_insn_write; - /* initialize analog outputs to a known value */ - for (i = 0; i < s->n_chan; i++) { - short lsb, msb; + ret = comedi_alloc_subdev_readback(s); + if (ret) + return ret; - devpriv->ao_value[i] = s->maxdata / 2; - lsb = devpriv->ao_value[i] & 0xff; - msb = (devpriv->ao_value[i] >> 8) & 0xff; - devpriv->write_byte(dev, lsb, DAC_LSB_REG(i)); - devpriv->write_byte(dev, msb, DAC_MSB_REG(i)); - } + /* initialize analog outputs to a known value */ + for (i = 0; i < s->n_chan; i++) + labpc_ao_write(dev, s, i, s->maxdata / 2); } else { s->type = COMEDI_SUBD_UNUSED; } @@ -1342,11 +1304,16 @@ int labpc_common_attach(struct comedi_device *dev, s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; s->n_chan = 16; s->maxdata = 0xff; - s->insn_read = labpc_calib_insn_read; s->insn_write = labpc_calib_insn_write; - for (i = 0; i < s->n_chan; i++) + ret = comedi_alloc_subdev_readback(s); + if (ret) + return ret; + + for (i = 0; i < s->n_chan; i++) { write_caldac(dev, i, s->maxdata / 2); + s->readback[i] = s->maxdata / 2; + } } else { s->type = COMEDI_SUBD_UNUSED; } @@ -1358,11 +1325,14 @@ int labpc_common_attach(struct comedi_device *dev, s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; s->n_chan = EEPROM_SIZE; s->maxdata = 0xff; - s->insn_read = labpc_eeprom_insn_read; s->insn_write = labpc_eeprom_insn_write; + ret = comedi_alloc_subdev_readback(s); + if (ret) + return ret; + for (i = 0; i < s->n_chan; i++) - devpriv->eeprom_data[i] = labpc_eeprom_read(dev, i); + s->readback[i] = labpc_eeprom_read(dev, i); } else { s->type = COMEDI_SUBD_UNUSED; } diff --git a/drivers/staging/comedi/drivers/ni_labpc_isadma.c b/drivers/staging/comedi/drivers/ni_labpc_isadma.c index 967202e0635e..6d386050e59d 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_isadma.c +++ b/drivers/staging/comedi/drivers/ni_labpc_isadma.c @@ -91,7 +91,6 @@ void labpc_drain_dma(struct comedi_device *dev) int status; unsigned long flags; unsigned int max_points, num_points, residue, leftover; - int i; status = devpriv->stat1; @@ -122,9 +121,7 @@ void labpc_drain_dma(struct comedi_device *dev) leftover = max_points; } - /* write data to comedi buffer */ - for (i = 0; i < num_points; i++) - cfc_write_to_buffer(s, devpriv->dma_buffer[i]); + comedi_buf_write_samples(s, devpriv->dma_buffer, num_points); if (cmd->stop_src == TRIG_COUNT) devpriv->count -= num_points; @@ -133,8 +130,6 @@ void labpc_drain_dma(struct comedi_device *dev) set_dma_addr(devpriv->dma_chan, devpriv->dma_addr); set_dma_count(devpriv->dma_chan, leftover * sample_size); release_dma_lock(flags); - - async->events |= COMEDI_CB_BLOCK; } EXPORT_SYMBOL_GPL(labpc_drain_dma); diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 320b080149b6..11e70173712d 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -686,13 +686,12 @@ static inline void ni_set_ai_dma_channel(struct comedi_device *dev, int channel) { unsigned bitfield; - if (channel >= 0) { + if (channel >= 0) bitfield = (ni_stc_dma_channel_select_bitfield(channel) << AI_DMA_Select_Shift) & AI_DMA_Select_Mask; - } else { + else bitfield = 0; - } ni_set_bitfield(dev, AI_AO_Select, AI_DMA_Select_Mask, bitfield); } @@ -701,13 +700,12 @@ static inline void ni_set_ao_dma_channel(struct comedi_device *dev, int channel) { unsigned bitfield; - if (channel >= 0) { + if (channel >= 0) bitfield = (ni_stc_dma_channel_select_bitfield(channel) << AO_DMA_Select_Shift) & AO_DMA_Select_Mask; - } else { + else bitfield = 0; - } ni_set_bitfield(dev, AI_AO_Select, AO_DMA_Select_Mask, bitfield); } @@ -1127,31 +1125,18 @@ static void ni_ao_fifo_load(struct comedi_device *dev, struct comedi_subdevice *s, int n) { struct ni_private *devpriv = dev->private; - struct comedi_async *async = s->async; - struct comedi_cmd *cmd = &async->cmd; - int chan; int i; unsigned short d; u32 packed_data; - int range; - int err = 1; - chan = async->cur_chan; for (i = 0; i < n; i++) { - err &= comedi_buf_get(s, &d); - if (err == 0) - break; - - range = CR_RANGE(cmd->chanlist[chan]); + comedi_buf_read_samples(s, &d, 1); if (devpriv->is_6xxx) { packed_data = d & 0xffff; /* 6711 only has 16 bit wide ao fifo */ if (!devpriv->is_6711) { - err &= comedi_buf_get(s, &d); - if (err == 0) - break; - chan++; + comedi_buf_read_samples(s, &d, 1); i++; packed_data |= (d << 16) & 0xffff0000; } @@ -1159,12 +1144,7 @@ static void ni_ao_fifo_load(struct comedi_device *dev, } else { ni_writew(dev, d, DAC_FIFO_Data); } - chan++; - chan %= cmd->chanlist_len; } - async->cur_chan = chan; - if (err == 0) - async->events |= COMEDI_CB_OVERFLOW; } /* @@ -1187,21 +1167,20 @@ static int ni_ao_fifo_half_empty(struct comedi_device *dev, struct comedi_subdevice *s) { const struct ni_board_struct *board = dev->board_ptr; - int n; + unsigned int nbytes; + unsigned int nsamples; - n = comedi_buf_read_n_available(s); - if (n == 0) { + nbytes = comedi_buf_read_n_available(s); + if (nbytes == 0) { s->async->events |= COMEDI_CB_OVERFLOW; return 0; } - n /= sizeof(short); - if (n > board->ao_fifo_depth / 2) - n = board->ao_fifo_depth / 2; - - ni_ao_fifo_load(dev, s, n); + nsamples = comedi_bytes_to_samples(s, nbytes); + if (nsamples > board->ao_fifo_depth / 2) + nsamples = board->ao_fifo_depth / 2; - s->async->events |= COMEDI_CB_BLOCK; + ni_ao_fifo_load(dev, s, nsamples); return 1; } @@ -1211,7 +1190,8 @@ static int ni_ao_prep_fifo(struct comedi_device *dev, { const struct ni_board_struct *board = dev->board_ptr; struct ni_private *devpriv = dev->private; - int n; + unsigned int nbytes; + unsigned int nsamples; /* reset fifo */ ni_stc_writew(dev, 1, DAC_FIFO_Clear); @@ -1219,17 +1199,17 @@ static int ni_ao_prep_fifo(struct comedi_device *dev, ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x); /* load some data */ - n = comedi_buf_read_n_available(s); - if (n == 0) + nbytes = comedi_buf_read_n_available(s); + if (nbytes == 0) return 0; - n /= sizeof(short); - if (n > board->ao_fifo_depth) - n = board->ao_fifo_depth; + nsamples = comedi_bytes_to_samples(s, nbytes); + if (nsamples > board->ao_fifo_depth) + nsamples = board->ao_fifo_depth; - ni_ao_fifo_load(dev, s, n); + ni_ao_fifo_load(dev, s, nsamples); - return n; + return nsamples; } static void ni_ai_fifo_read(struct comedi_device *dev, @@ -1237,44 +1217,42 @@ static void ni_ai_fifo_read(struct comedi_device *dev, { struct ni_private *devpriv = dev->private; struct comedi_async *async = s->async; + u32 dl; + unsigned short data; int i; if (devpriv->is_611x) { - unsigned short data[2]; - u32 dl; - for (i = 0; i < n / 2; i++) { dl = ni_readl(dev, ADC_FIFO_Data_611x); /* This may get the hi/lo data in the wrong order */ - data[0] = (dl >> 16) & 0xffff; - data[1] = dl & 0xffff; - cfc_write_array_to_buffer(s, data, sizeof(data)); + data = (dl >> 16) & 0xffff; + comedi_buf_write_samples(s, &data, 1); + data = dl & 0xffff; + comedi_buf_write_samples(s, &data, 1); } /* Check if there's a single sample stuck in the FIFO */ if (n % 2) { dl = ni_readl(dev, ADC_FIFO_Data_611x); - data[0] = dl & 0xffff; - cfc_write_to_buffer(s, data[0]); + data = dl & 0xffff; + comedi_buf_write_samples(s, &data, 1); } } else if (devpriv->is_6143) { - unsigned short data[2]; - u32 dl; - /* This just reads the FIFO assuming the data is present, no checks on the FIFO status are performed */ for (i = 0; i < n / 2; i++) { dl = ni_readl(dev, AIFIFO_Data_6143); - data[0] = (dl >> 16) & 0xffff; - data[1] = dl & 0xffff; - cfc_write_array_to_buffer(s, data, sizeof(data)); + data = (dl >> 16) & 0xffff; + comedi_buf_write_samples(s, &data, 1); + data = dl & 0xffff; + comedi_buf_write_samples(s, &data, 1); } if (n % 2) { /* Assume there is a single sample stuck in the FIFO */ /* Get stranded sample into FIFO */ ni_writel(dev, 0x01, AIFIFO_Control_6143); dl = ni_readl(dev, AIFIFO_Data_6143); - data[0] = (dl >> 16) & 0xffff; - cfc_write_to_buffer(s, data[0]); + data = (dl >> 16) & 0xffff; + comedi_buf_write_samples(s, &data, 1); } } else { if (n > sizeof(devpriv->ai_fifo_buffer) / @@ -1288,9 +1266,7 @@ static void ni_ai_fifo_read(struct comedi_device *dev, devpriv->ai_fifo_buffer[i] = ni_readw(dev, ADC_FIFO_Data_Register); } - cfc_write_array_to_buffer(s, devpriv->ai_fifo_buffer, - n * - sizeof(devpriv->ai_fifo_buffer[0])); + comedi_buf_write_samples(s, devpriv->ai_fifo_buffer, n); } } @@ -1313,8 +1289,8 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev) { struct ni_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; - unsigned short data[2]; u32 dl; + unsigned short data; unsigned short fifo_empty; int i; @@ -1324,9 +1300,10 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev) dl = ni_readl(dev, ADC_FIFO_Data_611x); /* This may get the hi/lo data in the wrong order */ - data[0] = (dl >> 16); - data[1] = (dl & 0xffff); - cfc_write_array_to_buffer(s, data, sizeof(data)); + data = dl >> 16; + comedi_buf_write_samples(s, &data, 1); + data = dl & 0xffff; + comedi_buf_write_samples(s, &data, 1); } } else if (devpriv->is_6143) { i = 0; @@ -1334,9 +1311,10 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev) dl = ni_readl(dev, AIFIFO_Data_6143); /* This may get the hi/lo data in the wrong order */ - data[0] = (dl >> 16); - data[1] = (dl & 0xffff); - cfc_write_array_to_buffer(s, data, sizeof(data)); + data = dl >> 16; + comedi_buf_write_samples(s, &data, 1); + data = dl & 0xffff; + comedi_buf_write_samples(s, &data, 1); i += 2; } /* Check if stranded sample is present */ @@ -1344,8 +1322,8 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev) /* Get stranded sample into FIFO */ ni_writel(dev, 0x01, AIFIFO_Control_6143); dl = ni_readl(dev, AIFIFO_Data_6143); - data[0] = (dl >> 16) & 0xffff; - cfc_write_to_buffer(s, data[0]); + data = (dl >> 16) & 0xffff; + comedi_buf_write_samples(s, &data, 1); } } else { @@ -1364,10 +1342,7 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev) devpriv->ai_fifo_buffer[i] = ni_readw(dev, ADC_FIFO_Data_Register); } - cfc_write_array_to_buffer(s, devpriv->ai_fifo_buffer, - i * - sizeof(devpriv-> - ai_fifo_buffer[0])); + comedi_buf_write_samples(s, devpriv->ai_fifo_buffer, i); } } } @@ -1386,7 +1361,7 @@ static void get_last_sample_611x(struct comedi_device *dev) if (ni_readb(dev, XXX_Status) & 0x80) { dl = ni_readl(dev, ADC_FIFO_Data_611x); data = (dl & 0xffff); - cfc_write_to_buffer(s, data); + comedi_buf_write_samples(s, &data, 1); } } @@ -1408,7 +1383,7 @@ static void get_last_sample_6143(struct comedi_device *dev) /* This may get the hi/lo data in the wrong order */ data = (dl >> 16) & 0xffff; - cfc_write_to_buffer(s, data); + comedi_buf_write_samples(s, &data, 1); } } @@ -1462,7 +1437,7 @@ static void handle_gpct_interrupt(struct comedi_device *dev, ni_tio_handle_interrupt(&devpriv->counter_dev->counters[counter_index], s); - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); #endif } @@ -1518,7 +1493,7 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, if (comedi_is_subdevice_running(s)) { s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } return; } @@ -1533,7 +1508,7 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, if (status & (AI_Overrun_St | AI_Overflow_St)) s->async->events |= COMEDI_CB_OVERFLOW; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return; } if (status & AI_SC_TC_St) { @@ -1559,7 +1534,7 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, if ((status & AI_STOP_St)) ni_handle_eos(dev, s); - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status) @@ -1635,7 +1610,7 @@ static void handle_b_interrupt(struct comedi_device *dev, } #endif - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s, @@ -1645,12 +1620,12 @@ static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s, struct ni_private *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; - unsigned int length = num_bytes / bytes_per_sample(s); + unsigned int nsamples = comedi_bytes_to_samples(s, num_bytes); unsigned short *array = data; unsigned int *larray = data; unsigned int i; - for (i = 0; i < length; i++) { + for (i = 0; i < nsamples; i++) { #ifdef PCIDMA if (s->subdev_flags & SDF_LSAMPL) larray[i] = le32_to_cpu(larray[i]); @@ -2253,9 +2228,6 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, /* Step 1 : check if triggers are trivially valid */ - if ((cmd->flags & CMDF_WRITE)) - cmd->flags &= ~CMDF_WRITE; - err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT | TRIG_EXT); err |= cfc_check_trigger_src(&cmd->scan_begin_src, @@ -2762,11 +2734,11 @@ static void ni_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int chan_index) { struct comedi_cmd *cmd = &s->async->cmd; - unsigned int length = num_bytes / bytes_per_sample(s); + unsigned int nsamples = comedi_bytes_to_samples(s, num_bytes); unsigned short *array = data; unsigned int i; - for (i = 0; i < length; i++) { + for (i = 0; i < nsamples; i++) { unsigned int range = CR_RANGE(cmd->chanlist[chan_index]); unsigned short val = array[i]; @@ -2981,12 +2953,15 @@ static int ni_ao_insn_config(struct comedi_device *dev, { const struct ni_board_struct *board = dev->board_ptr; struct ni_private *devpriv = dev->private; + unsigned int nbytes; switch (data[0]) { case INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE: switch (data[1]) { case COMEDI_OUTPUT: - data[2] = 1 + board->ao_fifo_depth * sizeof(short); + nbytes = comedi_samples_to_bytes(s, + board->ao_fifo_depth); + data[2] = 1 + nbytes; if (devpriv->mite) data[2] += devpriv->mite->fifo_size; break; @@ -3288,9 +3263,6 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, /* Step 1 : check if triggers are trivially valid */ - if ((cmd->flags & CMDF_WRITE) == 0) - cmd->flags |= CMDF_WRITE; - err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT); err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER | TRIG_EXT); @@ -3515,9 +3487,6 @@ static int ni_cdio_cmdtest(struct comedi_device *dev, /* Step 2a : make sure trigger sources are unique */ /* Step 2b : and mutually compatible */ - if (err) - return 2; - /* Step 3: check if arguments are trivially valid */ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); @@ -3693,7 +3662,7 @@ static void handle_cdio_interrupt(struct comedi_device *dev) M_Offset_CDIO_Command); /* s->async->events |= COMEDI_CB_EOA; */ } - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static int ni_serial_hw_readwrite8(struct comedi_device *dev, @@ -3976,7 +3945,7 @@ static unsigned ni_gpct_to_stc_register(enum ni_gpct_register reg) stc_register = Interrupt_B_Enable_Register; break; default: - printk("%s: unhandled register 0x%x in switch.\n", + pr_err("%s: unhandled register 0x%x in switch.\n", __func__, reg); BUG(); return 0; @@ -5472,7 +5441,6 @@ static int ni_E_init(struct comedi_device *dev, s->range_table = board->ao_range_table; s->insn_config = ni_ao_insn_config; s->insn_write = ni_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 5252cba82e5e..db7e8aac67b5 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -384,11 +384,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d) struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async = s->async; struct mite_struct *mite = devpriv->mite; - - /* int i, j; */ - unsigned int auxdata = 0; - unsigned short data1 = 0; - unsigned short data2 = 0; + unsigned int auxdata; int flags; int status; int work = 0; @@ -451,13 +447,9 @@ static irqreturn_t nidio_interrupt(int irq, void *d) goto out; } auxdata = readl(dev->mmio + Group_1_FIFO); - data1 = auxdata & 0xffff; - data2 = (auxdata & 0xffff0000) >> 16; - comedi_buf_put(s, data1); - comedi_buf_put(s, data2); + comedi_buf_write_samples(s, &auxdata, 1); flags = readb(dev->mmio + Group_1_Flags); } - async->events |= COMEDI_CB_BLOCK; } if (flags & CountExpired) { @@ -485,7 +477,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d) } out: - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); #if 0 if (!tag) writeb(0x03, dev->mmio + Master_DMA_And_Interrupt_Control); diff --git a/drivers/staging/comedi/drivers/ni_stc.h b/drivers/staging/comedi/drivers/ni_stc.h index 29efce30eb7f..bd69c3f0acdc 100644 --- a/drivers/staging/comedi/drivers/ni_stc.h +++ b/drivers/staging/comedi/drivers/ni_stc.h @@ -334,7 +334,7 @@ static inline unsigned RTSI_Output_Bit(unsigned channel, int is_mseries) max_channel = 6; } if (channel > max_channel) { - printk("%s: bug, invalid RTSI_channel=%i\n", __func__, channel); + pr_err("%s: bug, invalid RTSI_channel=%i\n", __func__, channel); return 0; } return 1 << (base_bit_shift + channel); @@ -1090,7 +1090,7 @@ static inline int M_Offset_Static_AI_Control(int i) 0x263, }; if (((unsigned)i) >= ARRAY_SIZE(offset)) { - printk("%s: invalid channel=%i\n", __func__, i); + pr_err("%s: invalid channel=%i\n", __func__, i); return offset[0]; } return offset[i]; @@ -1105,7 +1105,7 @@ static inline int M_Offset_AO_Reference_Attenuation(int channel) 0x267 }; if (((unsigned)channel) >= ARRAY_SIZE(offset)) { - printk("%s: invalid channel=%i\n", __func__, channel); + pr_err("%s: invalid channel=%i\n", __func__, channel); return offset[0]; } return offset[channel]; @@ -1114,7 +1114,7 @@ static inline int M_Offset_AO_Reference_Attenuation(int channel) static inline unsigned M_Offset_PFI_Output_Select(unsigned n) { if (n < 1 || n > NUM_PFI_OUTPUT_SELECT_REGS) { - printk("%s: invalid pfi output select register=%i\n", + pr_err("%s: invalid pfi output select register=%i\n", __func__, n); return M_Offset_PFI_Output_Select_1; } @@ -1171,7 +1171,7 @@ static inline unsigned MSeries_PLL_In_Source_Select_RTSI_Bits(unsigned RTSI_channel) { if (RTSI_channel > 7) { - printk("%s: bug, invalid RTSI_channel=%i\n", __func__, + pr_err("%s: bug, invalid RTSI_channel=%i\n", __func__, RTSI_channel); return 0; } @@ -1192,7 +1192,7 @@ static inline unsigned MSeries_PLL_Divisor_Bits(unsigned divisor) { static const unsigned max_divisor = 0x10; if (divisor < 1 || divisor > max_divisor) { - printk("%s: bug, invalid divisor=%i\n", __func__, divisor); + pr_err("%s: bug, invalid divisor=%i\n", __func__, divisor); return 0; } return (divisor & 0xf) << 8; @@ -1202,7 +1202,7 @@ static inline unsigned MSeries_PLL_Multiplier_Bits(unsigned multiplier) { static const unsigned max_multiplier = 0x100; if (multiplier < 1 || multiplier > max_multiplier) { - printk("%s: bug, invalid multiplier=%i\n", __func__, + pr_err("%s: bug, invalid multiplier=%i\n", __func__, multiplier); return 0; } @@ -1464,7 +1464,7 @@ struct ni_private { unsigned short ai_fifo_buffer[0x2000]; uint8_t eeprom_buffer[M_SERIES_EEPROM_SIZE]; - uint32_t serial_number; + __be32 serial_number; struct mite_struct *mite; struct mite_channel *ai_mite_chan; diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c index 26e7291c4a51..6037bec77ef1 100644 --- a/drivers/staging/comedi/drivers/ni_tiocmd.c +++ b/drivers/staging/comedi/drivers/ni_tiocmd.c @@ -371,9 +371,8 @@ static void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, of gate interrupt via dma read/write and report bogus gate errors */ if (counter->counter_dev->variant != - ni_gpct_variant_660x) { + ni_gpct_variant_660x) *gate_error = 1; - } } } if (gxx_status & GI_TC_ERROR(cidx)) { @@ -450,11 +449,10 @@ void ni_tio_handle_interrupt(struct ni_gpct *counter, return; } gpct_mite_status = mite_get_status(counter->mite_chan); - if (gpct_mite_status & CHSR_LINKC) { + if (gpct_mite_status & CHSR_LINKC) writel(CHOR_CLRLC, counter->mite_chan->mite->mite_io_addr + MITE_CHOR(counter->mite_chan->channel)); - } mite_sync_input_dma(counter->mite_chan, s); spin_unlock_irqrestore(&counter->lock, flags); } diff --git a/drivers/staging/comedi/drivers/ni_usb6501.c b/drivers/staging/comedi/drivers/ni_usb6501.c index df7ada8611f4..3b5a1b90366d 100644 --- a/drivers/staging/comedi/drivers/ni_usb6501.c +++ b/drivers/staging/comedi/drivers/ni_usb6501.c @@ -561,7 +561,7 @@ static int ni6501_auto_attach(struct comedi_device *dev, /* Counter subdevice */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = SDF_READABLE | SDF_WRITEABLE | SDF_LSAMPL; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL; s->n_chan = 1; s->maxdata = 0xffffffff; s->insn_read = ni6501_cnt_insn_read; diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c index 47f4887108a7..938aebc8e0ea 100644 --- a/drivers/staging/comedi/drivers/pcl711.c +++ b/drivers/staging/comedi/drivers/pcl711.c @@ -156,7 +156,6 @@ static const struct pcl711_board boardtypes[] = { }; struct pcl711_private { - unsigned int ntrig; unsigned int divisor1; unsigned int divisor2; }; @@ -199,7 +198,6 @@ static int pcl711_ai_cancel(struct comedi_device *dev, static irqreturn_t pcl711_interrupt(int irq, void *d) { struct comedi_device *dev = d; - struct pcl711_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; struct comedi_cmd *cmd = &s->async->cmd; unsigned int data; @@ -213,16 +211,14 @@ static irqreturn_t pcl711_interrupt(int irq, void *d) outb(PCL711_INT_STAT_CLR, dev->iobase + PCL711_INT_STAT_REG); - if (comedi_buf_put(s, data) == 0) { - s->async->events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; - } else { - s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; - if (cmd->stop_src == TRIG_COUNT && !(--devpriv->ntrig)) { - pcl711_ai_set_mode(dev, PCL711_MODE_SOFTTRIG); - s->async->events |= COMEDI_CB_EOA; - } - } - comedi_event(dev, s); + comedi_buf_write_samples(s, &data, 1); + + if (cmd->stop_src == TRIG_COUNT && + s->async->scans_done >= cmd->stop_arg) + s->async->events |= COMEDI_CB_EOA; + + comedi_handle_events(dev, s); + return IRQ_HANDLED; } @@ -373,14 +369,10 @@ static void pcl711_ai_load_counters(struct comedi_device *dev) static int pcl711_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { - struct pcl711_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; pcl711_set_changain(dev, s, cmd->chanlist[0]); - if (cmd->stop_src == TRIG_COUNT) - devpriv->ntrig = cmd->stop_arg; - if (cmd->scan_begin_src == TRIG_TIMER) { pcl711_ai_load_counters(dev); outb(PCL711_INT_STAT_CLR, dev->iobase + PCL711_INT_STAT_REG); @@ -505,7 +497,6 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->maxdata = 0xfff; s->range_table = &range_bipolar5; s->insn_write = pcl711_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c index dc179bd02dfd..86f713fdf1d0 100644 --- a/drivers/staging/comedi/drivers/pcl726.c +++ b/drivers/staging/comedi/drivers/pcl726.c @@ -235,9 +235,8 @@ static irqreturn_t pcl726_interrupt(int irq, void *d) if (devpriv->cmd_running) { pcl726_intr_cancel(dev, s); - comedi_buf_put(s, 0); - s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS); - comedi_event(dev, s); + comedi_buf_write_samples(s, &s->state, 1); + comedi_handle_events(dev, s); } return IRQ_HANDLED; @@ -377,7 +376,6 @@ static int pcl726_attach(struct comedi_device *dev, s->maxdata = 0x0fff; s->range_table_list = devpriv->rangelist; s->insn_write = pcl726_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index fd5ea6e01619..ac243ca5e0f8 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -512,7 +512,6 @@ struct pcl812_private { unsigned int last_ai_chanspec; unsigned char mode_reg_int; /* there is stored INT number for some card */ unsigned int ai_poll_ptr; /* how many sampes transfer poll */ - unsigned int ai_act_scan; /* how many scans we finished */ unsigned int dmapages; unsigned int hwdmasize; unsigned long dmabuf[2]; /* PTR to DMA buf */ @@ -556,8 +555,8 @@ static void pcl812_ai_setup_dma(struct comedi_device *dev, /* we use EOS, so adapt DMA buffer to one scan */ if (devpriv->ai_eos) { - devpriv->dmabytestomove[0] = cfc_bytes_per_scan(s); - devpriv->dmabytestomove[1] = cfc_bytes_per_scan(s); + devpriv->dmabytestomove[0] = comedi_bytes_per_scan(s); + devpriv->dmabytestomove[1] = comedi_bytes_per_scan(s); devpriv->dma_runs_to_end = 1; } else { devpriv->dmabytestomove[0] = devpriv->hwdmasize; @@ -572,7 +571,7 @@ static void pcl812_ai_setup_dma(struct comedi_device *dev, devpriv->dma_runs_to_end = 1; } else { /* how many samples we must transfer? */ - bytes = cmd->stop_arg * cfc_bytes_per_scan(s); + bytes = cmd->stop_arg * comedi_bytes_per_scan(s); /* how many DMA pages we must fill */ devpriv->dma_runs_to_end = @@ -807,9 +806,7 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_dma = 0; } - devpriv->ai_act_scan = 0; devpriv->ai_poll_ptr = 0; - s->async->cur_chan = 0; /* don't we want wake up every scan? */ if (cmd->flags & CMDF_WAKE_EOS) { @@ -841,21 +838,10 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static bool pcl812_ai_next_chan(struct comedi_device *dev, struct comedi_subdevice *s) { - struct pcl812_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - s->async->events |= COMEDI_CB_BLOCK; - - s->async->cur_chan++; - if (s->async->cur_chan >= cmd->chanlist_len) { - s->async->cur_chan = 0; - devpriv->ai_act_scan++; - s->async->events |= COMEDI_CB_EOS; - } - if (cmd->stop_src == TRIG_COUNT && - devpriv->ai_act_scan >= cmd->stop_arg) { - /* all data sampled */ + s->async->scans_done >= cmd->stop_arg) { s->async->events |= COMEDI_CB_EOA; return false; } @@ -867,7 +853,9 @@ static void pcl812_handle_eoc(struct comedi_device *dev, struct comedi_subdevice *s) { struct comedi_cmd *cmd = &s->async->cmd; + unsigned int chan = s->async->cur_chan; unsigned int next_chan; + unsigned short val; if (pcl812_ai_eoc(dev, s, NULL, 0)) { dev_dbg(dev->class_dev, "A/D cmd IRQ without DRDY!\n"); @@ -875,13 +863,12 @@ static void pcl812_handle_eoc(struct comedi_device *dev, return; } - comedi_buf_put(s, pcl812_ai_get_sample(dev, s)); + val = pcl812_ai_get_sample(dev, s); + comedi_buf_write_samples(s, &val, 1); /* Set up next channel. Added by abbotti 2010-01-20, but untested. */ - next_chan = s->async->cur_chan + 1; - if (next_chan >= cmd->chanlist_len) - next_chan = 0; - if (cmd->chanlist[s->async->cur_chan] != cmd->chanlist[next_chan]) + next_chan = s->async->cur_chan; + if (cmd->chanlist[chan] != cmd->chanlist[next_chan]) pcl812_ai_set_chan_range(dev, cmd->chanlist[next_chan], 0); pcl812_ai_next_chan(dev, s); @@ -893,9 +880,11 @@ static void transfer_from_dma_buf(struct comedi_device *dev, unsigned int bufptr, unsigned int len) { unsigned int i; + unsigned short val; for (i = len; i; i--) { - comedi_buf_put(s, ptr[bufptr++]); + val = ptr[bufptr++]; + comedi_buf_write_samples(s, &val, 1); if (!pcl812_ai_next_chan(dev, s)) break; @@ -939,7 +928,7 @@ static irqreturn_t pcl812_interrupt(int irq, void *d) pcl812_ai_clear_eoc(dev); - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } @@ -1335,7 +1324,6 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) break; } s->insn_write = pcl812_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index aa6487132017..73deb4bd5c93 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -122,7 +122,6 @@ struct pcl816_private { int next_dma_buf; /* which DMA buffer will be used next round */ long dma_runs_to_end; /* how many we must permorm DMA transfer to end of record */ unsigned long last_dma_run; /* how many bytes we must transfer on last DMA page */ - int ai_act_scan; /* how many scans we finished */ unsigned int ai_poll_ptr; /* how many sampes transfer poll */ unsigned int divisor1; unsigned int divisor2; @@ -160,7 +159,7 @@ static void pcl816_ai_setup_dma(struct comedi_device *dev, bytes = devpriv->hwdmasize; if (cmd->stop_src == TRIG_COUNT) { /* how many */ - bytes = cmd->stop_arg * cfc_bytes_per_scan(s); + bytes = cmd->stop_arg * comedi_bytes_per_scan(s); /* how many DMA pages we must fill */ devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize; @@ -286,21 +285,10 @@ static int pcl816_ai_eoc(struct comedi_device *dev, static bool pcl816_ai_next_chan(struct comedi_device *dev, struct comedi_subdevice *s) { - struct pcl816_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - s->async->events |= COMEDI_CB_BLOCK; - - s->async->cur_chan++; - if (s->async->cur_chan >= cmd->chanlist_len) { - s->async->cur_chan = 0; - devpriv->ai_act_scan++; - s->async->events |= COMEDI_CB_EOS; - } - if (cmd->stop_src == TRIG_COUNT && - devpriv->ai_act_scan >= cmd->stop_arg) { - /* all data sampled */ + s->async->scans_done >= cmd->stop_arg) { s->async->events |= COMEDI_CB_EOA; return false; } @@ -313,10 +301,12 @@ static void transfer_from_dma_buf(struct comedi_device *dev, unsigned short *ptr, unsigned int bufptr, unsigned int len) { + unsigned short val; int i; for (i = 0; i < len; i++) { - comedi_buf_put(s, ptr[bufptr++]); + val = ptr[bufptr++]; + comedi_buf_write_samples(s, &val, 1); if (!pcl816_ai_next_chan(dev, s)) return; @@ -355,7 +345,7 @@ static irqreturn_t pcl816_interrupt(int irq, void *d) pcl816_ai_clear_eoc(dev); - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } @@ -508,8 +498,6 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) pcl816_ai_setup_chanlist(dev, cmd->chanlist, seglen); udelay(1); - devpriv->ai_act_scan = 0; - s->async->cur_chan = 0; devpriv->ai_cmd_running = 1; devpriv->ai_poll_ptr = 0; devpriv->ai_cmd_canceled = 0; @@ -566,7 +554,7 @@ static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_poll_ptr = top1; /* new buffer position */ spin_unlock_irqrestore(&dev->spinlock, flags); - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return comedi_buf_n_bytes_ready(s); } diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index ac19e83ce62a..8edea35532a9 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -313,8 +313,6 @@ struct pcl818_private { unsigned long last_dma_run; /* how many bytes we must transfer on last DMA page */ unsigned int ns_min; /* manimal allowed delay between samples (in us) for actual card */ int i8253_osc_base; /* 1/frequency of on board oscilator in ns */ - int ai_act_scan; /* how many scans we finished */ - int ai_act_chan; /* actual position in actual scan */ unsigned int act_chanlist[16]; /* MUX setting for actual AI operations */ unsigned int act_chanlist_len; /* how long is actual MUX list */ unsigned int act_chanlist_pos; /* actual position in MUX list */ @@ -352,7 +350,7 @@ static void pcl818_ai_setup_dma(struct comedi_device *dev, disable_dma(devpriv->dma); /* disable dma */ bytes = devpriv->hwdmasize; if (cmd->stop_src == TRIG_COUNT) { - bytes = cmd->stop_arg * cfc_bytes_per_scan(s); + bytes = cmd->stop_arg * comedi_bytes_per_scan(s); devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize; devpriv->last_dma_run = bytes % devpriv->hwdmasize; devpriv->dma_runs_to_end--; @@ -521,21 +519,12 @@ static bool pcl818_ai_next_chan(struct comedi_device *dev, struct pcl818_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - s->async->events |= COMEDI_CB_BLOCK; - devpriv->act_chanlist_pos++; if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) devpriv->act_chanlist_pos = 0; - s->async->cur_chan++; - if (s->async->cur_chan >= cmd->chanlist_len) { - s->async->cur_chan = 0; - devpriv->ai_act_scan--; - s->async->events |= COMEDI_CB_EOS; - } - - if (cmd->stop_src == TRIG_COUNT && devpriv->ai_act_scan == 0) { - /* all data sampled */ + if (cmd->stop_src == TRIG_COUNT && + s->async->scans_done >= cmd->stop_arg) { s->async->events |= COMEDI_CB_EOA; return false; } @@ -560,7 +549,7 @@ static void pcl818_handle_eoc(struct comedi_device *dev, if (pcl818_ai_dropout(dev, s, chan)) return; - comedi_buf_put(s, val); + comedi_buf_write_samples(s, &val, 1); pcl818_ai_next_chan(dev, s); } @@ -589,7 +578,7 @@ static void pcl818_handle_dma(struct comedi_device *dev, if (pcl818_ai_dropout(dev, s, chan)) break; - comedi_buf_put(s, val); + comedi_buf_write_samples(s, &val, 1); if (!pcl818_ai_next_chan(dev, s)) break; @@ -630,7 +619,7 @@ static void pcl818_handle_fifo(struct comedi_device *dev, if (pcl818_ai_dropout(dev, s, chan)) break; - comedi_buf_put(s, val); + comedi_buf_write_samples(s, &val, 1); if (!pcl818_ai_next_chan(dev, s)) break; @@ -642,6 +631,7 @@ static irqreturn_t pcl818_interrupt(int irq, void *d) struct comedi_device *dev = d; struct pcl818_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; + struct comedi_cmd *cmd = &s->async->cmd; if (!dev->attached || !devpriv->ai_cmd_running) { pcl818_ai_clear_eoc(dev); @@ -655,7 +645,7 @@ static irqreturn_t pcl818_interrupt(int irq, void *d) * being reprogrammed while a DMA transfer is in * progress. */ - devpriv->ai_act_scan = 0; + s->async->scans_done = cmd->stop_arg; s->cancel(dev, s); return IRQ_HANDLED; } @@ -669,7 +659,7 @@ static irqreturn_t pcl818_interrupt(int irq, void *d) pcl818_ai_clear_eoc(dev); - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } @@ -829,8 +819,6 @@ static int pcl818_ai_cmd(struct comedi_device *dev, pcl818_ai_setup_chanlist(dev, cmd->chanlist, seglen); devpriv->ai_data_len = s->async->prealloc_bufsz; - devpriv->ai_act_scan = cmd->stop_arg; - devpriv->ai_act_chan = 0; devpriv->ai_cmd_running = 1; devpriv->ai_cmd_canceled = 0; devpriv->act_chanlist_pos = 0; @@ -873,7 +861,8 @@ static int pcl818_ai_cancel(struct comedi_device *dev, if (devpriv->dma) { if (cmd->stop_src == TRIG_NONE || - (cmd->stop_src == TRIG_COUNT && devpriv->ai_act_scan > 0)) { + (cmd->stop_src == TRIG_COUNT && + s->async->scans_done < cmd->stop_arg)) { if (!devpriv->ai_cmd_canceled) { /* * Wait for running dma transfer to end, @@ -1169,7 +1158,6 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->range_table = &range_unknown; } s->insn_write = pcl818_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index fc40ee2b34e9..f0059e935da0 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -190,7 +190,6 @@ struct pcmmio_private { spinlock_t pagelock; /* protects the page registers */ spinlock_t spinlock; /* protects the member variables */ unsigned int enabled_mask; - unsigned int stop_count; unsigned int active:1; }; @@ -337,7 +336,6 @@ static void pcmmio_handle_dio_intr(struct comedi_device *dev, { struct pcmmio_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - unsigned int oldevents = s->async->events; unsigned int val = 0; unsigned long flags; int i; @@ -357,31 +355,16 @@ static void pcmmio_handle_dio_intr(struct comedi_device *dev, val |= (1 << i); } - /* Write the scan to the buffer. */ - if (comedi_buf_put(s, val) && - comedi_buf_put(s, val >> 16)) { - s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS); - } else { - /* Overflow! Stop acquisition!! */ - /* TODO: STOP_ACQUISITION_CALL_HERE!! */ - pcmmio_stop_intr(dev, s); - } + comedi_buf_write_samples(s, &val, 1); - /* Check for end of acquisition. */ - if (cmd->stop_src == TRIG_COUNT && devpriv->stop_count > 0) { - devpriv->stop_count--; - if (devpriv->stop_count == 0) { - s->async->events |= COMEDI_CB_EOA; - /* TODO: STOP_ACQUISITION_CALL_HERE!! */ - pcmmio_stop_intr(dev, s); - } - } + if (cmd->stop_src == TRIG_COUNT && + s->async->scans_done >= cmd->stop_arg) + s->async->events |= COMEDI_CB_EOA; done: spin_unlock_irqrestore(&devpriv->spinlock, flags); - if (oldevents != s->async->events) - comedi_event(dev, s); + comedi_handle_events(dev, s); } static irqreturn_t interrupt_pcmmio(int irq, void *d) @@ -481,8 +464,6 @@ static int pcmmio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) spin_lock_irqsave(&devpriv->spinlock, flags); devpriv->active = 1; - devpriv->stop_count = cmd->stop_arg; - /* Set up start of acquisition. */ if (cmd->start_src == TRIG_INT) s->async->inttrig = pcmmio_inttrig_start_intr; @@ -751,7 +732,6 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->maxdata = 0xffff; s->range_table = &pcmmio_ao_ranges; s->insn_write = pcmmio_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) @@ -774,7 +754,7 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_config = pcmmio_dio_insn_config; if (dev->irq) { dev->read_subdev = s; - s->subdev_flags |= SDF_CMD_READ; + s->subdev_flags |= SDF_CMD_READ | SDF_LSAMPL | SDF_PACKED; s->len_chanlist = s->n_chan; s->cancel = pcmmio_cancel; s->do_cmd = pcmmio_cmd; diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index d4fe2ec25ecf..0f5483b6147f 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -130,7 +130,6 @@ struct pcmuio_asic { spinlock_t pagelock; /* protects the page registers */ spinlock_t spinlock; /* protects member variables */ unsigned int enabled_mask; - unsigned int stop_count; unsigned int active:1; }; @@ -317,7 +316,6 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev, int asic = pcmuio_subdevice_to_asic(s); struct pcmuio_asic *chip = &devpriv->asics[asic]; struct comedi_cmd *cmd = &s->async->cmd; - unsigned oldevents = s->async->events; unsigned int val = 0; unsigned long flags; unsigned int i; @@ -337,33 +335,16 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev, val |= (1 << i); } - /* Write the scan to the buffer. */ - if (comedi_buf_put(s, val) && - comedi_buf_put(s, val >> 16)) { - s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS); - } else { - /* Overflow! Stop acquisition!! */ - /* TODO: STOP_ACQUISITION_CALL_HERE!! */ - pcmuio_stop_intr(dev, s); - } + comedi_buf_write_samples(s, &val, 1); - /* Check for end of acquisition. */ - if (cmd->stop_src == TRIG_COUNT) { - if (chip->stop_count > 0) { - chip->stop_count--; - if (chip->stop_count == 0) { - s->async->events |= COMEDI_CB_EOA; - /* TODO: STOP_ACQUISITION_CALL_HERE!! */ - pcmuio_stop_intr(dev, s); - } - } - } + if (cmd->stop_src == TRIG_COUNT && + s->async->scans_done >= cmd->stop_arg) + s->async->events |= COMEDI_CB_EOA; done: spin_unlock_irqrestore(&chip->spinlock, flags); - if (oldevents != s->async->events) - comedi_event(dev, s); + comedi_handle_events(dev, s); } static int pcmuio_handle_asic_interrupt(struct comedi_device *dev, int asic) @@ -487,8 +468,6 @@ static int pcmuio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) spin_lock_irqsave(&chip->spinlock, flags); chip->active = 1; - chip->stop_count = cmd->stop_arg; - /* Set up start of acquisition. */ if (cmd->start_src == TRIG_INT) s->async->inttrig = pcmuio_inttrig_start_intr; @@ -614,7 +593,8 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) if ((i == 0 && dev->irq) || (i == 2 && devpriv->irq2)) { /* setup the interrupt subdevice */ dev->read_subdev = s; - s->subdev_flags |= SDF_CMD_READ; + s->subdev_flags |= SDF_CMD_READ | SDF_LSAMPL | + SDF_PACKED; s->len_chanlist = s->n_chan; s->cancel = pcmuio_cancel; s->do_cmd = pcmuio_cmd; diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index 6407df0404f0..96098110b0b3 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -65,8 +65,6 @@ struct daqp_private { enum { semaphore, buffer } interrupt_mode; struct completion eos; - - int count; }; /* The DAQP communicates with the system through a 16 byte I/O window. */ @@ -194,6 +192,7 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id) struct comedi_device *dev = dev_id; struct daqp_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; + struct comedi_cmd *cmd = &s->async->cmd; int loop_limit = 10000; int status; @@ -221,18 +220,16 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id) data |= inb(dev->iobase + DAQP_FIFO) << 8; data ^= 0x8000; - comedi_buf_put(s, data); + comedi_buf_write_samples(s, &data, 1); /* If there's a limit, decrement it * and stop conversion if zero */ - if (devpriv->count > 0) { - devpriv->count--; - if (devpriv->count == 0) { - s->async->events |= COMEDI_CB_EOA; - break; - } + if (cmd->stop_src == TRIG_COUNT && + s->async->scans_done >= cmd->stop_arg) { + s->async->events |= COMEDI_CB_EOA; + break; } if ((loop_limit--) <= 0) @@ -245,9 +242,7 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id) s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; } - s->async->events |= COMEDI_CB_BLOCK; - - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } return IRQ_HANDLED; } @@ -575,12 +570,16 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) */ if (cmd->stop_src == TRIG_COUNT) { - devpriv->count = cmd->stop_arg * cmd->scan_end_arg; - threshold = 2 * devpriv->count; - while (threshold > DAQP_FIFO_SIZE * 3 / 4) - threshold /= 2; + unsigned long long nsamples; + unsigned long long nbytes; + + nsamples = (unsigned long long)cmd->stop_arg * + cmd->scan_end_arg; + nbytes = nsamples * comedi_bytes_per_sample(s); + while (nbytes > DAQP_FIFO_SIZE * 3 / 4) + nbytes /= 2; + threshold = nbytes; } else { - devpriv->count = -1; threshold = DAQP_FIFO_SIZE / 2; } @@ -736,12 +735,11 @@ static int daqp_auto_attach(struct comedi_device *dev, s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 2; s->maxdata = 0x0fff; s->range_table = &range_bipolar5; s->insn_write = daqp_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) @@ -756,7 +754,7 @@ static int daqp_auto_attach(struct comedi_device *dev, s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 1; s->maxdata = 1; s->insn_bits = daqp_do_insn_bits; diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 7d4cb140959c..581aa58d9c0a 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -379,7 +379,6 @@ struct rtd_private { long ai_count; /* total transfer size (samples) */ int xfer_count; /* # to transfer data. 0->1/2FIFO */ int flags; /* flag event modes */ - DECLARE_BITMAP(chan_is_bipolar, RTD_MAX_CHANLIST); unsigned fifosz; }; @@ -438,7 +437,6 @@ static unsigned short rtd_convert_chan_gain(struct comedi_device *dev, unsigned int chanspec, int index) { const struct rtd_boardinfo *board = dev->board_ptr; - struct rtd_private *devpriv = dev->private; unsigned int chan = CR_CHAN(chanspec); unsigned int range = CR_RANGE(chanspec); unsigned int aref = CR_AREF(chanspec); @@ -451,17 +449,14 @@ static unsigned short rtd_convert_chan_gain(struct comedi_device *dev, /* +-5 range */ r |= 0x000; r |= (range & 0x7) << 4; - __set_bit(index, devpriv->chan_is_bipolar); } else if (range < board->range_uni10) { /* +-10 range */ r |= 0x100; r |= ((range - board->range_bip10) & 0x7) << 4; - __set_bit(index, devpriv->chan_is_bipolar); } else { /* +10 range */ r |= 0x200; r |= ((range - board->range_uni10) & 0x7) << 4; - __clear_bit(index, devpriv->chan_is_bipolar); } switch (aref) { @@ -561,6 +556,7 @@ static int rtd_ai_rinsn(struct comedi_device *dev, unsigned int *data) { struct rtd_private *devpriv = dev->private; + unsigned int range = CR_RANGE(insn->chanspec); int ret; int n; @@ -586,9 +582,11 @@ static int rtd_ai_rinsn(struct comedi_device *dev, /* read data */ d = readw(devpriv->las1 + LAS1_ADC_FIFO); d = d >> 3; /* low 3 bits are marker lines */ - if (test_bit(0, devpriv->chan_is_bipolar)) - /* convert to comedi unsigned data */ + + /* convert bipolar data to comedi unsigned data */ + if (comedi_range_is_bipolar(s, range)) d = comedi_offset_munge(s, d); + data[n] = d & s->maxdata; } @@ -606,9 +604,12 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, int count) { struct rtd_private *devpriv = dev->private; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; int ii; for (ii = 0; ii < count; ii++) { + unsigned int range = CR_RANGE(cmd->chanlist[async->cur_chan]); unsigned short d; if (0 == devpriv->ai_count) { /* done */ @@ -618,41 +619,13 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, d = readw(devpriv->las1 + LAS1_ADC_FIFO); d = d >> 3; /* low 3 bits are marker lines */ - if (test_bit(s->async->cur_chan, devpriv->chan_is_bipolar)) - /* convert to comedi unsigned data */ - d = comedi_offset_munge(s, d); - d &= s->maxdata; - - if (!comedi_buf_put(s, d)) - return -1; - - if (devpriv->ai_count > 0) /* < 0, means read forever */ - devpriv->ai_count--; - } - return 0; -} - -/* - unknown amout of data is waiting in fifo. -*/ -static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s) -{ - struct rtd_private *devpriv = dev->private; - - while (readl(dev->mmio + LAS0_ADC) & FS_ADC_NOT_EMPTY) { - unsigned short d = readw(devpriv->las1 + LAS1_ADC_FIFO); - - if (0 == devpriv->ai_count) { /* done */ - continue; /* read rest */ - } - d = d >> 3; /* low 3 bits are marker lines */ - if (test_bit(s->async->cur_chan, devpriv->chan_is_bipolar)) - /* convert to comedi unsigned data */ + /* convert bipolar data to comedi unsigned data */ + if (comedi_range_is_bipolar(s, range)) d = comedi_offset_munge(s, d); d &= s->maxdata; - if (!comedi_buf_put(s, d)) + if (!comedi_buf_write_samples(s, &d, 1)) return -1; if (devpriv->ai_count > 0) /* < 0, means read forever */ @@ -703,8 +676,6 @@ static irqreturn_t rtd_interrupt(int irq, void *d) if (0 == devpriv->ai_count) goto xfer_done; - - comedi_event(dev, s); } else if (devpriv->xfer_count > 0) { if (fifo_status & FS_ADC_NOT_EMPTY) { /* FIFO not empty */ @@ -713,8 +684,6 @@ static irqreturn_t rtd_interrupt(int irq, void *d) if (0 == devpriv->ai_count) goto xfer_done; - - comedi_event(dev, s); } } } @@ -726,28 +695,16 @@ static irqreturn_t rtd_interrupt(int irq, void *d) /* clear the interrupt */ writew(status, dev->mmio + LAS0_CLEAR); readw(dev->mmio + LAS0_CLEAR); + + comedi_handle_events(dev, s); + return IRQ_HANDLED; xfer_abort: - writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR); s->async->events |= COMEDI_CB_ERROR; - devpriv->ai_count = 0; /* stop and don't transfer any more */ - /* fall into xfer_done */ xfer_done: - /* pacer stop source: SOFTWARE */ - writel(0, dev->mmio + LAS0_PACER_STOP); - writel(0, dev->mmio + LAS0_PACER); /* stop pacer */ - writel(0, dev->mmio + LAS0_ADC_CONVERSION); - writew(0, dev->mmio + LAS0_IT); - - if (devpriv->ai_count > 0) { /* there shouldn't be anything left */ - fifo_status = readl(dev->mmio + LAS0_ADC); - ai_read_dregs(dev, s); /* read anything left in FIFO */ - } - - s->async->events |= COMEDI_CB_EOA; /* signal end to comedi */ - comedi_event(dev, s); + s->async->events |= COMEDI_CB_EOA; /* clear the interrupt */ status = readw(dev->mmio + LAS0_IT); @@ -757,6 +714,8 @@ xfer_done: fifo_status = readl(dev->mmio + LAS0_ADC); overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff; + comedi_handle_events(dev, s); + return IRQ_HANDLED; } @@ -1083,6 +1042,7 @@ static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_count = 0; /* stop and don't transfer any more */ status = readw(dev->mmio + LAS0_IT); overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff; + writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR); return 0; } @@ -1303,7 +1263,6 @@ static int rtd_auto_attach(struct comedi_device *dev, s->maxdata = 0x0fff; s->range_table = &rtd_ao_range; s->insn_write = rtd_ao_winsn; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c index e3d9f44cefb9..67b4b378bd01 100644 --- a/drivers/staging/comedi/drivers/rti800.c +++ b/drivers/staging/comedi/drivers/rti800.c @@ -313,7 +313,6 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it) ? rti800_ao_ranges[it->options[7]] : &range_unknown; s->insn_write = rti800_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c index c81b01c40f12..96c3974207ae 100644 --- a/drivers/staging/comedi/drivers/rti802.c +++ b/drivers/staging/comedi/drivers/rti802.c @@ -100,7 +100,6 @@ static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->maxdata = 0xfff; s->n_chan = 8; s->insn_write = rti802_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 75872c6aec2a..6f3e8a08e75c 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -583,7 +583,6 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->maxdata = 0xffff; s->range_table = &range_bipolar10; s->insn_write = s526_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 0e7621e890c3..14932c5f3798 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -78,7 +78,6 @@ struct s626_buffer_dma { struct s626_private { uint8_t ai_cmd_running; /* ai_cmd is running */ - int ai_sample_count; /* number of samples to acquire */ unsigned int ai_sample_timer; /* time between samples in * units of the timer */ int ai_convert_count; /* conversion counter */ @@ -1480,7 +1479,6 @@ static bool s626_handle_eos_interrupt(struct comedi_device *dev) * from the final ADC of the previous poll list scan. */ uint32_t *readaddr = (uint32_t *)devpriv->ana_buf.logical_base + 1; - bool finished = false; int i; /* get the data and hand it over to comedi */ @@ -1494,36 +1492,21 @@ static bool s626_handle_eos_interrupt(struct comedi_device *dev) tempdata = s626_ai_reg_to_uint(*readaddr); readaddr++; - /* put data into read buffer */ - cfc_write_to_buffer(s, tempdata); + comedi_buf_write_samples(s, &tempdata, 1); } - /* end of scan occurs */ - async->events |= COMEDI_CB_EOS; + if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg) + async->events |= COMEDI_CB_EOA; - if (cmd->stop_src == TRIG_COUNT) { - devpriv->ai_sample_count--; - if (devpriv->ai_sample_count <= 0) { - devpriv->ai_cmd_running = 0; - - /* Stop RPS program */ - s626_mc_disable(dev, S626_MC1_ERPS1, S626_P_MC1); - - /* send end of acquisition */ - async->events |= COMEDI_CB_EOA; - - /* disable master interrupt */ - finished = true; - } - } + if (async->events & COMEDI_CB_CANCEL_MASK) + devpriv->ai_cmd_running = 0; if (devpriv->ai_cmd_running && cmd->scan_begin_src == TRIG_EXT) s626_dio_set_irq(dev, cmd->scan_begin_arg); - /* tell comedi that data is there */ - comedi_event(dev, s); + comedi_handle_events(dev, s); - return finished; + return !devpriv->ai_cmd_running; } static irqreturn_t s626_irq_handler(int irq, void *d) @@ -1970,13 +1953,13 @@ static int s626_ns_to_timer(unsigned int *nanosec, unsigned int flags) switch (flags & CMDF_ROUND_MASK) { case CMDF_ROUND_NEAREST: default: - divider = (*nanosec + base / 2) / base; + divider = DIV_ROUND_CLOSEST(*nanosec, base); break; case CMDF_ROUND_DOWN: divider = (*nanosec) / base; break; case CMDF_ROUND_UP: - divider = (*nanosec + base - 1) / base; + divider = DIV_ROUND_UP(*nanosec, base); break; } @@ -2102,8 +2085,6 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) break; } - devpriv->ai_sample_count = cmd->stop_arg; - s626_reset_adc(dev, ppl); switch (cmd->start_src) { @@ -2820,7 +2801,6 @@ static int s626_auto_attach(struct comedi_device *dev, s->maxdata = 0x3fff; s->range_table = &range_bipolar10; s->insn_write = s626_ao_insn_write; - s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index 167f82418cb4..71226ee9064e 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -742,7 +742,7 @@ static int serial2002_attach(struct comedi_device *dev, /* digital output subdevice */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 0; s->maxdata = 1; s->range_table = &range_digital; @@ -760,7 +760,7 @@ static int serial2002_attach(struct comedi_device *dev, /* analog output subdevice */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 0; s->maxdata = 1; s->range_table = NULL; diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 5adbfedf780f..4737dbf8e01d 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -1,37 +1,34 @@ /* - comedi/drivers/usbdux.c - Copyright (C) 2003-2007 Bernd Porr, Bernd.Porr@f2s.com - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + * usbdux.c + * Copyright (C) 2003-2014 Bernd Porr, mail@berndporr.me.uk + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ + /* -Driver: usbdux -Description: University of Stirling USB DAQ & INCITE Technology Limited -Devices: [ITL] USB-DUX (usbdux.o) -Author: Bernd Porr <BerndPorr@f2s.com> -Updated: 8 Dec 2008 -Status: Stable -Configuration options: - You have to upload firmware with the -i option. The - firmware is usually installed under /usr/share/usb or - /usr/local/share/usb or /lib/firmware. - -Connection scheme for the counter at the digital port: - 0=/CLK0, 1=UP/DOWN0, 2=RESET0, 4=/CLK1, 5=UP/DOWN1, 6=RESET1. - The sampling rate of the counter is approximately 500Hz. - -Please note that under USB2.0 the length of the channel list determines -the max sampling rate. If you sample only one channel you get 8kHz -sampling rate. If you sample two channels you get 4kHz and so on. -*/ + * Driver: usbdux + * Description: University of Stirling USB DAQ & INCITE Technology Limited + * Devices: (ITL) USB-DUX [usbdux] + * Author: Bernd Porr <mail@berndporr.me.uk> + * Updated: 10 Oct 2014 + * Status: Stable + * Connection scheme for the counter at the digital port: + * 0=/CLK0, 1=UP/DOWN0, 2=RESET0, 4=/CLK1, 5=UP/DOWN1, 6=RESET1. + * The sampling rate of the counter is approximately 500Hz. + * + * Note that under USB2.0 the length of the channel list determines + * the max sampling rate. If you sample only one channel you get 8kHz + * sampling rate. If you sample two channels you get 4kHz and so on. + */ + /* * I must give credit here to Chris Baugher who * wrote the driver for AT-MIO-16d. I used some parts of this @@ -205,9 +202,6 @@ struct usbdux_private { unsigned int ao_cmd_running:1; unsigned int pwm_cmd_running:1; - /* number of samples to acquire */ - int ai_sample_count; - int ao_sample_count; /* time between samples in units of the timer */ unsigned int ai_timer; unsigned int ao_timer; @@ -253,128 +247,107 @@ static int usbdux_ai_cancel(struct comedi_device *dev, return 0; } -/* analogue IN - interrupt service routine */ +static void usbduxsub_ai_handle_urb(struct comedi_device *dev, + struct comedi_subdevice *s, + struct urb *urb) +{ + struct usbdux_private *devpriv = dev->private; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; + int ret; + int i; + + devpriv->ai_counter--; + if (devpriv->ai_counter == 0) { + devpriv->ai_counter = devpriv->ai_timer; + + /* get the data from the USB bus and hand it over to comedi */ + for (i = 0; i < cmd->chanlist_len; i++) { + unsigned int range = CR_RANGE(cmd->chanlist[i]); + uint16_t val = le16_to_cpu(devpriv->in_buf[i]); + + /* bipolar data is two's-complement */ + if (comedi_range_is_bipolar(s, range)) + val ^= ((s->maxdata + 1) >> 1); + + /* transfer data */ + if (!comedi_buf_write_samples(s, &val, 1)) + return; + } + + if (cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) + async->events |= COMEDI_CB_EOA; + } + + /* if command is still running, resubmit urb */ + if (!(async->events & COMEDI_CB_CANCEL_MASK)) { + urb->dev = comedi_to_usb_dev(dev); + ret = usb_submit_urb(urb, GFP_ATOMIC); + if (ret < 0) { + dev_err(dev->class_dev, + "urb resubmit failed in int-context! err=%d\n", + ret); + if (ret == -EL2NSYNC) + dev_err(dev->class_dev, + "buggy USB host controller or bug in IRQ handler!\n"); + async->events |= COMEDI_CB_ERROR; + } + } +} + static void usbduxsub_ai_isoc_irq(struct urb *urb) { struct comedi_device *dev = urb->context; struct comedi_subdevice *s = dev->read_subdev; + struct comedi_async *async = s->async; struct usbdux_private *devpriv = dev->private; - struct comedi_cmd *cmd = &s->async->cmd; - int i, err; - /* first we test if something unusual has just happened */ + /* exit if not running a command, do not resubmit urb */ + if (!devpriv->ai_cmd_running) + return; + switch (urb->status) { case 0: /* copy the result in the transfer buffer */ memcpy(devpriv->in_buf, urb->transfer_buffer, SIZEINBUF); + usbduxsub_ai_handle_urb(dev, s, urb); break; + case -EILSEQ: - /* error in the ISOchronous data */ - /* we don't copy the data into the transfer buffer */ - /* and recycle the last data byte */ + /* + * error in the ISOchronous data + * we don't copy the data into the transfer buffer + * and recycle the last data byte + */ dev_dbg(dev->class_dev, "CRC error in ISO IN stream\n"); + usbduxsub_ai_handle_urb(dev, s, urb); break; case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: case -ECONNABORTED: - /* happens after an unlink command */ - if (devpriv->ai_cmd_running) { - s->async->events |= COMEDI_CB_EOA; - s->async->events |= COMEDI_CB_ERROR; - comedi_event(dev, s); - /* stop the transfer w/o unlink */ - usbdux_ai_stop(dev, 0); - } - return; + /* after an unlink command, unplug, ... etc */ + async->events |= COMEDI_CB_ERROR; + break; default: - /* a real error on the bus */ - /* pass error to comedi if we are really running a command */ - if (devpriv->ai_cmd_running) { - dev_err(dev->class_dev, - "Non-zero urb status received in ai intr context: %d\n", - urb->status); - s->async->events |= COMEDI_CB_EOA; - s->async->events |= COMEDI_CB_ERROR; - comedi_event(dev, s); - /* don't do an unlink here */ - usbdux_ai_stop(dev, 0); - } - return; + /* a real error */ + dev_err(dev->class_dev, + "Non-zero urb status received in ai intr context: %d\n", + urb->status); + async->events |= COMEDI_CB_ERROR; + break; } /* - * at this point we are reasonably sure that nothing dodgy has happened - * are we running a command? + * comedi_handle_events() cannot be used in this driver. The (*cancel) + * operation would unlink the urb. */ - if (unlikely(!devpriv->ai_cmd_running)) { - /* - * not running a command, do not continue execution if no - * asynchronous command is running in particular not resubmit - */ - return; - } - - urb->dev = comedi_to_usb_dev(dev); - - /* resubmit the urb */ - err = usb_submit_urb(urb, GFP_ATOMIC); - if (unlikely(err < 0)) { - dev_err(dev->class_dev, - "urb resubmit failed in int-context! err=%d\n", err); - if (err == -EL2NSYNC) - dev_err(dev->class_dev, - "buggy USB host controller or bug in IRQ handler!\n"); - s->async->events |= COMEDI_CB_EOA; - s->async->events |= COMEDI_CB_ERROR; - comedi_event(dev, s); - /* don't do an unlink here */ + if (async->events & COMEDI_CB_CANCEL_MASK) usbdux_ai_stop(dev, 0); - return; - } - - devpriv->ai_counter--; - if (likely(devpriv->ai_counter > 0)) - return; - - /* timer zero, transfer measurements to comedi */ - devpriv->ai_counter = devpriv->ai_timer; - - /* test, if we transmit only a fixed number of samples */ - if (cmd->stop_src == TRIG_COUNT) { - /* not continuous, fixed number of samples */ - devpriv->ai_sample_count--; - /* all samples received? */ - if (devpriv->ai_sample_count < 0) { - /* prevent a resubmit next time */ - usbdux_ai_stop(dev, 0); - /* say comedi that the acquistion is over */ - s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); - return; - } - } - /* get the data from the USB bus and hand it over to comedi */ - for (i = 0; i < cmd->chanlist_len; i++) { - unsigned int range = CR_RANGE(cmd->chanlist[i]); - uint16_t val = le16_to_cpu(devpriv->in_buf[i]); - - /* bipolar data is two's-complement */ - if (comedi_range_is_bipolar(s, range)) - val ^= ((s->maxdata + 1) >> 1); - /* transfer data */ - err = comedi_buf_put(s, val); - if (unlikely(err == 0)) { - /* buffer overflow */ - usbdux_ai_stop(dev, 0); - return; - } - } - /* tell comedi that data is there */ - s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; comedi_event(dev, s); } @@ -402,71 +375,25 @@ static int usbdux_ao_cancel(struct comedi_device *dev, return 0; } -static void usbduxsub_ao_isoc_irq(struct urb *urb) +static void usbduxsub_ao_handle_urb(struct comedi_device *dev, + struct comedi_subdevice *s, + struct urb *urb) { - struct comedi_device *dev = urb->context; - struct comedi_subdevice *s = dev->write_subdev; struct usbdux_private *devpriv = dev->private; - struct comedi_cmd *cmd = &s->async->cmd; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; uint8_t *datap; int ret; int i; - switch (urb->status) { - case 0: - /* success */ - break; - - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - case -ECONNABORTED: - /* after an unlink command, unplug, ... etc */ - /* no unlink needed here. Already shutting down. */ - if (devpriv->ao_cmd_running) { - s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); - usbdux_ao_stop(dev, 0); - } - return; - - default: - /* a real error */ - if (devpriv->ao_cmd_running) { - dev_err(dev->class_dev, - "Non-zero urb status received in ao intr context: %d\n", - urb->status); - s->async->events |= COMEDI_CB_ERROR; - s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); - /* we do an unlink if we are in the high speed mode */ - usbdux_ao_stop(dev, 0); - } - return; - } - - /* are we actually running? */ - if (!devpriv->ao_cmd_running) - return; - - /* normal operation: executing a command in this subdevice */ devpriv->ao_counter--; - if ((int)devpriv->ao_counter <= 0) { - /* timer zero */ + if (devpriv->ao_counter == 0) { devpriv->ao_counter = devpriv->ao_timer; - /* handle non continous acquisition */ - if (cmd->stop_src == TRIG_COUNT) { - /* fixed number of samples */ - devpriv->ao_sample_count--; - if (devpriv->ao_sample_count < 0) { - /* all samples transmitted */ - usbdux_ao_stop(dev, 0); - s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); - /* no resubmit of the urb */ - return; - } + if (cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) { + async->events |= COMEDI_CB_EOA; + return; } /* transmit data to the USB bus */ @@ -476,26 +403,25 @@ static void usbduxsub_ao_isoc_irq(struct urb *urb) unsigned int chan = CR_CHAN(cmd->chanlist[i]); unsigned short val; - ret = comedi_buf_get(s, &val); - if (ret < 0) { + if (!comedi_buf_read_samples(s, &val, 1)) { dev_err(dev->class_dev, "buffer underflow\n"); - s->async->events |= (COMEDI_CB_EOA | - COMEDI_CB_OVERFLOW); + async->events |= COMEDI_CB_OVERFLOW; + return; } + /* pointer to the DA */ *datap++ = val & 0xff; *datap++ = (val >> 8) & 0xff; *datap++ = chan << 6; s->readback[chan] = val; - - s->async->events |= COMEDI_CB_BLOCK; - comedi_event(dev, s); } } - urb->transfer_buffer_length = SIZEOUTBUF; - urb->dev = comedi_to_usb_dev(dev); - urb->status = 0; - if (devpriv->ao_cmd_running) { + + /* if command is still running, resubmit urb for BULK transfer */ + if (!(async->events & COMEDI_CB_CANCEL_MASK)) { + urb->transfer_buffer_length = SIZEOUTBUF; + urb->dev = comedi_to_usb_dev(dev); + urb->status = 0; if (devpriv->high_speed) urb->interval = 8; /* uframes */ else @@ -512,16 +438,54 @@ static void usbduxsub_ao_isoc_irq(struct urb *urb) if (ret == -EL2NSYNC) dev_err(dev->class_dev, "buggy USB host controller or bug in IRQ handling!\n"); - - s->async->events |= COMEDI_CB_EOA; - s->async->events |= COMEDI_CB_ERROR; - comedi_event(dev, s); - /* don't do an unlink here */ - usbdux_ao_stop(dev, 0); + async->events |= COMEDI_CB_ERROR; } } } +static void usbduxsub_ao_isoc_irq(struct urb *urb) +{ + struct comedi_device *dev = urb->context; + struct comedi_subdevice *s = dev->write_subdev; + struct comedi_async *async = s->async; + struct usbdux_private *devpriv = dev->private; + + /* exit if not running a command, do not resubmit urb */ + if (!devpriv->ao_cmd_running) + return; + + switch (urb->status) { + case 0: + usbduxsub_ao_handle_urb(dev, s, urb); + break; + + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + case -ECONNABORTED: + /* after an unlink command, unplug, ... etc */ + async->events |= COMEDI_CB_ERROR; + break; + + default: + /* a real error */ + dev_err(dev->class_dev, + "Non-zero urb status received in ao intr context: %d\n", + urb->status); + async->events |= COMEDI_CB_ERROR; + break; + } + + /* + * comedi_handle_events() cannot be used in this driver. The (*cancel) + * operation would unlink the urb. + */ + if (async->events & COMEDI_CB_CANCEL_MASK) + usbdux_ao_stop(dev, 0); + + comedi_event(dev, s); +} + static int usbdux_submit_urbs(struct comedi_device *dev, struct urb **urbs, int num_urbs, int input_urb) @@ -725,9 +689,6 @@ static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (devpriv->ai_cmd_running) goto ai_cmd_exit; - /* set current channel of the running acquisition to zero */ - s->async->cur_chan = 0; - devpriv->dux_commands[1] = len; for (i = 0; i < len; ++i) { unsigned int chan = CR_CHAN(cmd->chanlist[i]); @@ -765,14 +726,6 @@ static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_counter = devpriv->ai_timer; - if (cmd->stop_src == TRIG_COUNT) { - /* data arrives as one packet */ - devpriv->ai_sample_count = cmd->stop_arg; - } else { - /* continous acquisition */ - devpriv->ai_sample_count = 0; - } - if (cmd->start_src == TRIG_NOW) { /* enable this acquisition operation */ devpriv->ai_cmd_running = 1; @@ -1023,9 +976,6 @@ static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (devpriv->ao_cmd_running) goto ao_cmd_exit; - /* set current channel of the running acquisition to zero */ - s->async->cur_chan = 0; - /* we count in steps of 1ms (125us) */ /* 125us mode not used yet */ if (0) { /* (devpriv->high_speed) */ @@ -1044,24 +994,6 @@ static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ao_counter = devpriv->ao_timer; - if (cmd->stop_src == TRIG_COUNT) { - /* not continuous */ - /* counter */ - /* high speed also scans everything at once */ - if (0) { /* (devpriv->high_speed) */ - devpriv->ao_sample_count = cmd->stop_arg * - cmd->scan_end_arg; - } else { - /* there's no scan as the scan has been */ - /* perf inside the FX2 */ - /* data arrives as one packet */ - devpriv->ao_sample_count = cmd->stop_arg; - } - } else { - /* continous acquisition */ - devpriv->ao_sample_count = 0; - } - if (cmd->start_src == TRIG_NOW) { /* enable this acquisition operation */ devpriv->ao_cmd_running = 1; diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index f85818dd5e11..ddc4cb9d5ed4 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Bernd Porr, Bernd.Porr@f2s.com + * Copyright (C) 2004-2014 Bernd Porr, mail@berndporr.me.uk * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,6 +13,15 @@ */ /* + * Driver: usbduxfast + * Description: University of Stirling USB DAQ & INCITE Technology Limited + * Devices: (ITL) USB-DUX [usbduxfast] + * Author: Bernd Porr <mail@berndporr.me.uk> + * Updated: 10 Oct 2014 + * Status: stable + */ + +/* * I must give credit here to Chris Baugher who * wrote the driver for AT-MIO-16d. I used some parts of this * driver. I also must give credits to David Brownell @@ -152,7 +161,6 @@ struct usbduxfast_private { uint8_t *duxbuf; int8_t *inbuf; short int ai_cmd_running; /* asynchronous command is running */ - long int ai_sample_count; /* number of samples to acquire */ int ignore; /* counter which ignores the first buffers */ struct semaphore sem; @@ -227,114 +235,82 @@ static int usbduxfast_ai_cancel(struct comedi_device *dev, return ret; } -/* - * analogue IN - * interrupt service routine - */ +static void usbduxfast_ai_handle_urb(struct comedi_device *dev, + struct comedi_subdevice *s, + struct urb *urb) +{ + struct usbduxfast_private *devpriv = dev->private; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; + int ret; + + if (devpriv->ignore) { + devpriv->ignore--; + } else { + unsigned int nsamples; + + nsamples = comedi_bytes_to_samples(s, urb->actual_length); + nsamples = comedi_nsamples_left(s, nsamples); + comedi_buf_write_samples(s, urb->transfer_buffer, nsamples); + + if (cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) + async->events |= COMEDI_CB_EOA; + } + + /* if command is still running, resubmit urb for BULK transfer */ + if (!(async->events & COMEDI_CB_CANCEL_MASK)) { + urb->dev = comedi_to_usb_dev(dev); + urb->status = 0; + ret = usb_submit_urb(urb, GFP_ATOMIC); + if (ret < 0) { + dev_err(dev->class_dev, "urb resubm failed: %d", ret); + async->events |= COMEDI_CB_ERROR; + } + } +} + static void usbduxfast_ai_interrupt(struct urb *urb) { struct comedi_device *dev = urb->context; struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async = s->async; - struct comedi_cmd *cmd = &async->cmd; - struct usb_device *usb = comedi_to_usb_dev(dev); struct usbduxfast_private *devpriv = dev->private; - int n, err; - /* are we running a command? */ - if (unlikely(!devpriv->ai_cmd_running)) { - /* - * not running a command - * do not continue execution if no asynchronous command - * is running in particular not resubmit - */ + /* exit if not running a command, do not resubmit urb */ + if (!devpriv->ai_cmd_running) return; - } - /* first we test if something unusual has just happened */ switch (urb->status) { case 0: + usbduxfast_ai_handle_urb(dev, s, urb); break; - /* - * happens after an unlink command or when the device - * is plugged out - */ case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: case -ECONNABORTED: - /* tell this comedi */ - async->events |= COMEDI_CB_EOA; + /* after an unlink command, unplug, ... etc */ async->events |= COMEDI_CB_ERROR; - comedi_event(dev, s); - /* stop the transfer w/o unlink */ - usbduxfast_ai_stop(dev, 0); - return; + break; default: + /* a real error */ dev_err(dev->class_dev, "non-zero urb status received in ai intr context: %d\n", urb->status); - async->events |= COMEDI_CB_EOA; async->events |= COMEDI_CB_ERROR; - comedi_event(dev, s); - usbduxfast_ai_stop(dev, 0); - return; - } - - if (!devpriv->ignore) { - if (cmd->stop_src == TRIG_COUNT) { - /* not continuous, fixed number of samples */ - n = urb->actual_length / sizeof(uint16_t); - if (unlikely(devpriv->ai_sample_count < n)) { - unsigned int num_bytes; - - /* partial sample received */ - num_bytes = devpriv->ai_sample_count * - sizeof(uint16_t); - cfc_write_array_to_buffer(s, - urb->transfer_buffer, - num_bytes); - usbduxfast_ai_stop(dev, 0); - /* tell comedi that the acquistion is over */ - async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); - return; - } - devpriv->ai_sample_count -= n; - } - /* write the full buffer to comedi */ - err = cfc_write_array_to_buffer(s, urb->transfer_buffer, - urb->actual_length); - if (unlikely(err == 0)) { - /* buffer overflow */ - usbduxfast_ai_stop(dev, 0); - return; - } - - /* tell comedi that data is there */ - comedi_event(dev, s); - } else { - /* ignore this packet */ - devpriv->ignore--; + break; } /* - * command is still running - * resubmit urb for BULK transfer + * comedi_handle_events() cannot be used in this driver. The (*cancel) + * operation would unlink the urb. */ - urb->dev = usb; - urb->status = 0; - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0) { - dev_err(dev->class_dev, - "urb resubm failed: %d", err); - async->events |= COMEDI_CB_EOA; - async->events |= COMEDI_CB_ERROR; - comedi_event(dev, s); + if (async->events & COMEDI_CB_CANCEL_MASK) usbduxfast_ai_stop(dev, 0); - } + + comedi_event(dev, s); } static int usbduxfast_submit_urb(struct comedi_device *dev) @@ -499,8 +475,6 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, up(&devpriv->sem); return -EBUSY; } - /* set current channel of the running acquisition to zero */ - s->async->cur_chan = 0; /* * ignore the first buffers from the device if there @@ -810,11 +784,6 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, return result; } - if (cmd->stop_src == TRIG_COUNT) - devpriv->ai_sample_count = cmd->stop_arg * cmd->scan_end_arg; - else /* TRIG_NONE */ - devpriv->ai_sample_count = 0; - if ((cmd->start_src == TRIG_NOW) || (cmd->start_src == TRIG_EXT)) { /* enable this acquisition operation */ devpriv->ai_cmd_running = 1; diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index ebd68e365bac..dc19435b6520 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -1,6 +1,6 @@ /* * usbduxsigma.c - * Copyright (C) 2011 Bernd Porr, Bernd.Porr@f2s.com + * Copyright (C) 2011-2014 Bernd Porr, mail@berndporr.me.uk * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,9 +17,9 @@ * Driver: usbduxsigma * Description: University of Stirling USB DAQ & INCITE Technology Limited * Devices: (ITL) USB-DUX [usbduxsigma] - * Author: Bernd Porr <BerndPorr@f2s.com> - * Updated: 8 Nov 2011 - * Status: testing + * Author: Bernd Porr <mail@berndporr.me.uk> + * Updated: 10 Oct 2014 + * Status: stable */ /* @@ -164,9 +164,6 @@ struct usbduxsigma_private { unsigned ao_cmd_running:1; unsigned pwm_cmd_running:1; - /* number of samples to acquire */ - int ai_sample_count; - int ao_sample_count; /* time between samples in units of the timer */ unsigned int ai_timer; unsigned int ao_timer; @@ -211,23 +208,75 @@ static int usbduxsigma_ai_cancel(struct comedi_device *dev, return 0; } -static void usbduxsigma_ai_urb_complete(struct urb *urb) +static void usbduxsigma_ai_handle_urb(struct comedi_device *dev, + struct comedi_subdevice *s, + struct urb *urb) { - struct comedi_device *dev = urb->context; struct usbduxsigma_private *devpriv = dev->private; - struct comedi_subdevice *s = dev->read_subdev; - struct comedi_cmd *cmd = &s->async->cmd; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; unsigned int dio_state; uint32_t val; int ret; int i; - /* first we test if something unusual has just happened */ + devpriv->ai_counter--; + if (devpriv->ai_counter == 0) { + devpriv->ai_counter = devpriv->ai_timer; + + /* get the state of the dio pins to allow external trigger */ + dio_state = be32_to_cpu(devpriv->in_buf[0]); + + /* get the data from the USB bus and hand it over to comedi */ + for (i = 0; i < cmd->chanlist_len; i++) { + /* transfer data, note first byte is the DIO state */ + val = be32_to_cpu(devpriv->in_buf[i+1]); + val &= 0x00ffffff; /* strip status byte */ + val ^= 0x00800000; /* convert to unsigned */ + + if (!comedi_buf_write_samples(s, &val, 1)) + return; + } + + if (cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) + async->events |= COMEDI_CB_EOA; + } + + /* if command is still running, resubmit urb */ + if (!(async->events & COMEDI_CB_CANCEL_MASK)) { + urb->dev = comedi_to_usb_dev(dev); + ret = usb_submit_urb(urb, GFP_ATOMIC); + if (ret < 0) { + dev_err(dev->class_dev, + "%s: urb resubmit failed (%d)\n", + __func__, ret); + if (ret == -EL2NSYNC) + dev_err(dev->class_dev, + "buggy USB host controller or bug in IRQ handler\n"); + async->events |= COMEDI_CB_ERROR; + } + } +} + +static void usbduxsigma_ai_urb_complete(struct urb *urb) +{ + struct comedi_device *dev = urb->context; + struct usbduxsigma_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->read_subdev; + struct comedi_async *async = s->async; + + /* exit if not running a command, do not resubmit urb */ + if (!devpriv->ai_cmd_running) + return; + switch (urb->status) { case 0: /* copy the result in the transfer buffer */ memcpy(devpriv->in_buf, urb->transfer_buffer, SIZEINBUF); + usbduxsigma_ai_handle_urb(dev, s, urb); break; + case -EILSEQ: /* * error in the ISOchronous data @@ -235,7 +284,7 @@ static void usbduxsigma_ai_urb_complete(struct urb *urb) * and recycle the last data byte */ dev_dbg(dev->class_dev, "CRC error in ISO IN stream\n"); - + usbduxsigma_ai_handle_urb(dev, s, urb); break; case -ECONNRESET: @@ -243,86 +292,24 @@ static void usbduxsigma_ai_urb_complete(struct urb *urb) case -ESHUTDOWN: case -ECONNABORTED: /* happens after an unlink command */ - if (devpriv->ai_cmd_running) { - usbduxsigma_ai_stop(dev, 0); /* w/o unlink */ - /* we are still running a command, tell comedi */ - s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR); - comedi_event(dev, s); - } - return; + async->events |= COMEDI_CB_ERROR; + break; default: - /* - * a real error on the bus - * pass error to comedi if we are really running a command - */ - if (devpriv->ai_cmd_running) { - dev_err(dev->class_dev, - "%s: non-zero urb status (%d)\n", - __func__, urb->status); - usbduxsigma_ai_stop(dev, 0); /* w/o unlink */ - s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR); - comedi_event(dev, s); - } - return; - } - - if (unlikely(!devpriv->ai_cmd_running)) - return; - - urb->dev = comedi_to_usb_dev(dev); - - ret = usb_submit_urb(urb, GFP_ATOMIC); - if (unlikely(ret < 0)) { - dev_err(dev->class_dev, "%s: urb resubmit failed (%d)\n", - __func__, ret); - if (ret == -EL2NSYNC) - dev_err(dev->class_dev, - "buggy USB host controller or bug in IRQ handler\n"); - usbduxsigma_ai_stop(dev, 0); /* w/o unlink */ - s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR); - comedi_event(dev, s); - return; - } - - /* get the state of the dio pins to allow external trigger */ - dio_state = be32_to_cpu(devpriv->in_buf[0]); - - devpriv->ai_counter--; - if (likely(devpriv->ai_counter > 0)) - return; - - /* timer zero, transfer measurements to comedi */ - devpriv->ai_counter = devpriv->ai_timer; - - if (cmd->stop_src == TRIG_COUNT) { - /* not continuous, fixed number of samples */ - devpriv->ai_sample_count--; - if (devpriv->ai_sample_count < 0) { - usbduxsigma_ai_stop(dev, 0); /* w/o unlink */ - /* acquistion is over, tell comedi */ - s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); - return; - } + /* a real error */ + dev_err(dev->class_dev, "%s: non-zero urb status (%d)\n", + __func__, urb->status); + async->events |= COMEDI_CB_ERROR; + break; } - /* get the data from the USB bus and hand it over to comedi */ - for (i = 0; i < cmd->chanlist_len; i++) { - /* transfer data, note first byte is the DIO state */ - val = be32_to_cpu(devpriv->in_buf[i+1]); - val &= 0x00ffffff; /* strip status byte */ - val ^= 0x00800000; /* convert to unsigned */ + /* + * comedi_handle_events() cannot be used in this driver. The (*cancel) + * operation would unlink the urb. + */ + if (async->events & COMEDI_CB_CANCEL_MASK) + usbduxsigma_ai_stop(dev, 0); - ret = cfc_write_array_to_buffer(s, &val, sizeof(uint32_t)); - if (unlikely(ret == 0)) { - /* buffer overflow */ - usbduxsigma_ai_stop(dev, 0); /* w/o unlink */ - return; - } - } - /* tell comedi that data is there */ - s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS); comedi_event(dev, s); } @@ -349,64 +336,25 @@ static int usbduxsigma_ao_cancel(struct comedi_device *dev, return 0; } -static void usbduxsigma_ao_urb_complete(struct urb *urb) +static void usbduxsigma_ao_handle_urb(struct comedi_device *dev, + struct comedi_subdevice *s, + struct urb *urb) { - struct comedi_device *dev = urb->context; struct usbduxsigma_private *devpriv = dev->private; - struct comedi_subdevice *s = dev->write_subdev; - struct comedi_cmd *cmd = &s->async->cmd; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; uint8_t *datap; int ret; int i; - switch (urb->status) { - case 0: - /* success */ - break; - - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - case -ECONNABORTED: - /* happens after an unlink command */ - if (devpriv->ao_cmd_running) { - usbduxsigma_ao_stop(dev, 0); /* w/o unlink */ - s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); - } - return; - - default: - /* a real error */ - if (devpriv->ao_cmd_running) { - dev_err(dev->class_dev, - "%s: non-zero urb status (%d)\n", - __func__, urb->status); - usbduxsigma_ao_stop(dev, 0); /* w/o unlink */ - s->async->events |= (COMEDI_CB_ERROR | COMEDI_CB_EOA); - comedi_event(dev, s); - } - return; - } - - if (!devpriv->ao_cmd_running) - return; - devpriv->ao_counter--; - if ((int)devpriv->ao_counter <= 0) { - /* timer zero, transfer from comedi */ + if (devpriv->ao_counter == 0) { devpriv->ao_counter = devpriv->ao_timer; - if (cmd->stop_src == TRIG_COUNT) { - /* not continuous, fixed number of samples */ - devpriv->ao_sample_count--; - if (devpriv->ao_sample_count < 0) { - usbduxsigma_ao_stop(dev, 0); /* w/o unlink */ - /* acquistion is over, tell comedi */ - s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); - return; - } + if (cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) { + async->events |= COMEDI_CB_EOA; + return; } /* transmit data to the USB bus */ @@ -416,46 +364,86 @@ static void usbduxsigma_ao_urb_complete(struct urb *urb) unsigned int chan = CR_CHAN(cmd->chanlist[i]); unsigned short val; - ret = comedi_buf_get(s, &val); - if (ret < 0) { + if (!comedi_buf_read_samples(s, &val, 1)) { dev_err(dev->class_dev, "buffer underflow\n"); - s->async->events |= (COMEDI_CB_EOA | - COMEDI_CB_OVERFLOW); + async->events |= COMEDI_CB_OVERFLOW; + return; } + *datap++ = val; *datap++ = chan; s->readback[chan] = val; - - s->async->events |= COMEDI_CB_BLOCK; - comedi_event(dev, s); } } - urb->transfer_buffer_length = SIZEOUTBUF; - urb->dev = comedi_to_usb_dev(dev); - urb->status = 0; - if (devpriv->high_speed) - urb->interval = 8; /* uframes */ - else - urb->interval = 1; /* frames */ - urb->number_of_packets = 1; - urb->iso_frame_desc[0].offset = 0; - urb->iso_frame_desc[0].length = SIZEOUTBUF; - urb->iso_frame_desc[0].status = 0; - ret = usb_submit_urb(urb, GFP_ATOMIC); - if (ret < 0) { - dev_err(dev->class_dev, - "%s: urb resubmit failed (%d)\n", - __func__, ret); - if (ret == -EL2NSYNC) + /* if command is still running, resubmit urb */ + if (!(async->events & COMEDI_CB_CANCEL_MASK)) { + urb->transfer_buffer_length = SIZEOUTBUF; + urb->dev = comedi_to_usb_dev(dev); + urb->status = 0; + if (devpriv->high_speed) + urb->interval = 8; /* uframes */ + else + urb->interval = 1; /* frames */ + urb->number_of_packets = 1; + urb->iso_frame_desc[0].offset = 0; + urb->iso_frame_desc[0].length = SIZEOUTBUF; + urb->iso_frame_desc[0].status = 0; + ret = usb_submit_urb(urb, GFP_ATOMIC); + if (ret < 0) { dev_err(dev->class_dev, - "buggy USB host controller or bug in IRQ handler\n"); - usbduxsigma_ao_stop(dev, 0); /* w/o unlink */ - s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR); - comedi_event(dev, s); + "%s: urb resubmit failed (%d)\n", + __func__, ret); + if (ret == -EL2NSYNC) + dev_err(dev->class_dev, + "buggy USB host controller or bug in IRQ handler\n"); + async->events |= COMEDI_CB_ERROR; + } } } +static void usbduxsigma_ao_urb_complete(struct urb *urb) +{ + struct comedi_device *dev = urb->context; + struct usbduxsigma_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->write_subdev; + struct comedi_async *async = s->async; + + /* exit if not running a command, do not resubmit urb */ + if (!devpriv->ao_cmd_running) + return; + + switch (urb->status) { + case 0: + usbduxsigma_ao_handle_urb(dev, s, urb); + break; + + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + case -ECONNABORTED: + /* happens after an unlink command */ + async->events |= COMEDI_CB_ERROR; + break; + + default: + /* a real error */ + dev_err(dev->class_dev, "%s: non-zero urb status (%d)\n", + __func__, urb->status); + async->events |= COMEDI_CB_ERROR; + break; + } + + /* + * comedi_handle_events() cannot be used in this driver. The (*cancel) + * operation would unlink the urb. + */ + if (async->events & COMEDI_CB_CANCEL_MASK) + usbduxsigma_ao_stop(dev, 0); + + comedi_event(dev, s); +} + static int usbduxsigma_submit_urbs(struct comedi_device *dev, struct urb **urbs, int num_urbs, int input_urb) @@ -584,14 +572,6 @@ static int usbduxsigma_ai_cmdtest(struct comedi_device *dev, if (devpriv->ai_timer < 1) err |= -EINVAL; - if (cmd->stop_src == TRIG_COUNT) { - /* data arrives as one packet */ - devpriv->ai_sample_count = cmd->stop_arg; - } else { - /* continuous acquisition */ - devpriv->ai_sample_count = 0; - } - if (err) return 4; @@ -692,8 +672,6 @@ static int usbduxsigma_ai_cmd(struct comedi_device *dev, down(&devpriv->sem); - /* set current channel of the running acquisition to zero */ - s->async->cur_chan = 0; for (i = 0; i < len; i++) { unsigned int chan = CR_CHAN(cmd->chanlist[i]); @@ -957,25 +935,6 @@ static int usbduxsigma_ao_cmdtest(struct comedi_device *dev, if (devpriv->ao_timer < 1) err |= -EINVAL; - if (cmd->stop_src == TRIG_COUNT) { - /* not continuous, use counter */ - if (high_speed) { - /* high speed also scans everything at once */ - devpriv->ao_sample_count = cmd->stop_arg * - cmd->scan_end_arg; - } else { - /* - * There's no scan as the scan has been - * handled inside the FX2. Data arrives as - * one packet. - */ - devpriv->ao_sample_count = cmd->stop_arg; - } - } else { - /* continuous acquisition */ - devpriv->ao_sample_count = 0; - } - if (err) return 4; @@ -991,9 +950,6 @@ static int usbduxsigma_ao_cmd(struct comedi_device *dev, down(&devpriv->sem); - /* set current channel of the running acquisition to zero */ - s->async->cur_chan = 0; - devpriv->ao_counter = devpriv->ao_timer; if (cmd->start_src == TRIG_NOW) { diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index 71003416edcf..a19a56ee0eef 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -797,7 +797,7 @@ static int vmk80xx_init_subdevices(struct comedi_device *dev) /* Analog output subdevice */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND; s->n_chan = boardinfo->ao_nchans; s->maxdata = 0x00ff; s->range_table = boardinfo->range; @@ -819,7 +819,7 @@ static int vmk80xx_init_subdevices(struct comedi_device *dev) /* Digital output subdevice */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 8; s->maxdata = 1; s->range_table = &range_digital; @@ -834,7 +834,7 @@ static int vmk80xx_init_subdevices(struct comedi_device *dev) s->insn_read = vmk80xx_cnt_insn_read; s->insn_config = vmk80xx_cnt_insn_config; if (devpriv->model == VMK8055_MODEL) { - s->subdev_flags |= SDF_WRITEABLE; + s->subdev_flags |= SDF_WRITABLE; s->insn_write = vmk80xx_cnt_insn_write; } @@ -842,7 +842,7 @@ static int vmk80xx_init_subdevices(struct comedi_device *dev) if (devpriv->model == VMK8061_MODEL) { s = &dev->subdevices[5]; s->type = COMEDI_SUBD_PWM; - s->subdev_flags = SDF_READABLE | SDF_WRITEABLE; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = boardinfo->pwm_nchans; s->maxdata = boardinfo->pwm_maxdata; s->insn_read = vmk80xx_pwm_insn_read; diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c index b6849545b810..9a1dc56f21d1 100644 --- a/drivers/staging/comedi/range.c +++ b/drivers/staging/comedi/range.c @@ -97,39 +97,6 @@ int do_rangeinfo_ioctl(struct comedi_device *dev, return 0; } -static int aref_invalid(struct comedi_subdevice *s, unsigned int chanspec) -{ - unsigned int aref; - - /* disable reporting invalid arefs... maybe someday */ - return 0; - - aref = CR_AREF(chanspec); - switch (aref) { - case AREF_DIFF: - if (s->subdev_flags & SDF_DIFF) - return 0; - break; - case AREF_COMMON: - if (s->subdev_flags & SDF_COMMON) - return 0; - break; - case AREF_GROUND: - if (s->subdev_flags & SDF_GROUND) - return 0; - break; - case AREF_OTHER: - if (s->subdev_flags & SDF_OTHER) - return 0; - break; - default: - break; - } - dev_dbg(s->device->class_dev, "subdevice does not support aref %i", - aref); - return 1; -} - /** * comedi_check_chanlist() - Validate each element in a chanlist. * @s: comedi_subdevice struct @@ -153,8 +120,7 @@ int comedi_check_chanlist(struct comedi_subdevice *s, int n, else range_len = 0; if (chan >= s->n_chan || - CR_RANGE(chanspec) >= range_len || - aref_invalid(s, chanspec)) { + CR_RANGE(chanspec) >= range_len) { dev_warn(dev->class_dev, "bad chanlist[%d]=0x%08x chan=%d range length=%d\n", i, chanspec, chan, range_len); diff --git a/drivers/staging/cptm1217/clearpad_tm1217.c b/drivers/staging/cptm1217/clearpad_tm1217.c index edf9ff2ea25b..7f265ce0dd13 100644 --- a/drivers/staging/cptm1217/clearpad_tm1217.c +++ b/drivers/staging/cptm1217/clearpad_tm1217.c @@ -278,7 +278,7 @@ static void cp_tm1217_get_data(struct cp_tm1217_device *ts) static irqreturn_t cp_tm1217_sample_thread(int irq, void *handle) { - struct cp_tm1217_device *ts = (struct cp_tm1217_device *) handle; + struct cp_tm1217_device *ts = handle; u8 req[2]; int retval; diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index d0be1cebf5a9..bdb5317e3d9d 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -65,144 +65,6 @@ #include "dgap.h" -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Digi International, http://www.digi.com"); -MODULE_DESCRIPTION("Driver for the Digi International EPCA PCI based product line"); -MODULE_SUPPORTED_DEVICE("dgap"); - -static int dgap_start(void); -static void dgap_init_globals(void); -static struct board_t *dgap_found_board(struct pci_dev *pdev, int id, - int boardnum); -static void dgap_cleanup_board(struct board_t *brd); -static void dgap_poll_handler(ulong dummy); -static int dgap_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); -static void dgap_remove_one(struct pci_dev *dev); -static int dgap_do_remap(struct board_t *brd); -static void dgap_release_remap(struct board_t *brd); -static irqreturn_t dgap_intr(int irq, void *voidbrd); - -static int dgap_tty_open(struct tty_struct *tty, struct file *file); -static void dgap_tty_close(struct tty_struct *tty, struct file *file); -static int dgap_block_til_ready(struct tty_struct *tty, struct file *file, - struct channel_t *ch); -static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd, - unsigned long arg); -static int dgap_tty_digigeta(struct channel_t *ch, - struct digi_t __user *retinfo); -static int dgap_tty_digiseta(struct channel_t *ch, struct board_t *bd, - struct un_t *un, struct digi_t __user *new_info); -static int dgap_tty_digigetedelay(struct tty_struct *tty, int __user *retinfo); -static int dgap_tty_digisetedelay(struct channel_t *ch, struct board_t *bd, - struct un_t *un, int __user *new_info); -static int dgap_tty_write_room(struct tty_struct *tty); -static int dgap_tty_chars_in_buffer(struct tty_struct *tty); -static void dgap_tty_start(struct tty_struct *tty); -static void dgap_tty_stop(struct tty_struct *tty); -static void dgap_tty_throttle(struct tty_struct *tty); -static void dgap_tty_unthrottle(struct tty_struct *tty); -static void dgap_tty_flush_chars(struct tty_struct *tty); -static void dgap_tty_flush_buffer(struct tty_struct *tty); -static void dgap_tty_hangup(struct tty_struct *tty); -static int dgap_wait_for_drain(struct tty_struct *tty); -static int dgap_set_modem_info(struct channel_t *ch, struct board_t *bd, - struct un_t *un, unsigned int command, - unsigned int __user *value); -static int dgap_get_modem_info(struct channel_t *ch, - unsigned int __user *value); -static int dgap_tty_digisetcustombaud(struct channel_t *ch, struct board_t *bd, - struct un_t *un, int __user *new_info); -static int dgap_tty_digigetcustombaud(struct channel_t *ch, struct un_t *un, - int __user *retinfo); -static int dgap_tty_tiocmget(struct tty_struct *tty); -static int dgap_tty_tiocmset(struct tty_struct *tty, unsigned int set, - unsigned int clear); -static int dgap_tty_send_break(struct tty_struct *tty, int msec); -static void dgap_tty_wait_until_sent(struct tty_struct *tty, int timeout); -static int dgap_tty_write(struct tty_struct *tty, const unsigned char *buf, - int count); -static void dgap_tty_set_termios(struct tty_struct *tty, - struct ktermios *old_termios); -static int dgap_tty_put_char(struct tty_struct *tty, unsigned char c); -static void dgap_tty_send_xchar(struct tty_struct *tty, char ch); - -static int dgap_tty_register(struct board_t *brd); -static void dgap_tty_unregister(struct board_t *brd); -static int dgap_tty_init(struct board_t *); -static void dgap_tty_free(struct board_t *); -static void dgap_cleanup_tty(struct board_t *); -static void dgap_carrier(struct channel_t *ch); -static void dgap_input(struct channel_t *ch); - -/* - * Our function prototypes from dgap_fep5 - */ -static void dgap_cmdw_ext(struct channel_t *ch, u16 cmd, u16 word, uint ncmds); -static int dgap_event(struct board_t *bd); - -static void dgap_poll_tasklet(unsigned long data); -static void dgap_cmdb(struct channel_t *ch, u8 cmd, u8 byte1, - u8 byte2, uint ncmds); -static void dgap_cmdw(struct channel_t *ch, u8 cmd, u16 word, uint ncmds); -static void dgap_wmove(struct channel_t *ch, char *buf, uint cnt); -static int dgap_param(struct channel_t *ch, struct board_t *bd, u32 un_type); -static void dgap_parity_scan(struct channel_t *ch, unsigned char *cbuf, - unsigned char *fbuf, int *len); -static uint dgap_get_custom_baud(struct channel_t *ch); -static void dgap_firmware_reset_port(struct channel_t *ch); - -/* - * Function prototypes from dgap_parse.c. - */ -static int dgap_gettok(char **in); -static char *dgap_getword(char **in); -static int dgap_checknode(struct cnode *p); - -/* - * Function prototypes from dgap_sysfs.h - */ -static void dgap_create_ports_sysfiles(struct board_t *bd); -static void dgap_remove_ports_sysfiles(struct board_t *bd); - -static int dgap_create_driver_sysfiles(struct pci_driver *); -static void dgap_remove_driver_sysfiles(struct pci_driver *); - -static void dgap_create_tty_sysfs(struct un_t *un, struct device *c); -static void dgap_remove_tty_sysfs(struct device *c); - -/* - * Function prototypes from dgap_parse.h - */ -static int dgap_parsefile(char **in); -static struct cnode *dgap_find_config(int type, int bus, int slot); -static uint dgap_config_get_num_prts(struct board_t *bd); -static char *dgap_create_config_string(struct board_t *bd, char *string); -static uint dgap_config_get_useintr(struct board_t *bd); -static uint dgap_config_get_altpin(struct board_t *bd); - -static void dgap_do_bios_load(struct board_t *brd, const u8 *ubios, int len); -static void dgap_do_fep_load(struct board_t *brd, const u8 *ufep, int len); -#ifdef DIGI_CONCENTRATORS_SUPPORTED -static void dgap_do_conc_load(struct board_t *brd, u8 *uaddr, int len); -#endif -static int dgap_alloc_flipbuf(struct board_t *brd); -static void dgap_free_flipbuf(struct board_t *brd); -static int dgap_request_irq(struct board_t *brd); -static void dgap_free_irq(struct board_t *brd); - -static void dgap_get_vpd(struct board_t *brd); -static void dgap_do_reset_board(struct board_t *brd); -static int dgap_test_bios(struct board_t *brd); -static int dgap_test_fep(struct board_t *brd); -static int dgap_tty_register_ports(struct board_t *brd); -static int dgap_firmware_load(struct pci_dev *pdev, int card_type, - struct board_t *brd); -static void dgap_cleanup_nodes(void); - -static void dgap_cleanup_module(void); - -module_exit(dgap_cleanup_module); - /* * File operations permitted on Control/Management major. */ @@ -218,7 +80,6 @@ static int dgap_poll_tick = 20; /* Poll interval - 20 ms */ static struct class *dgap_class; -static struct board_t *dgap_boards_by_major[256]; static uint dgap_count = 500; /* @@ -297,13 +158,6 @@ static struct board_id dgap_ids[] = { {0,} /* 0 terminated list. */ }; -static struct pci_driver dgap_driver = { - .name = "dgap", - .probe = dgap_init_one, - .id_table = dgap_pci_tbl, - .remove = dgap_remove_one, -}; - struct firmware_info { u8 *conf_name; /* dgap.conf */ u8 *bios_name; /* BIOS filename */ @@ -366,29 +220,6 @@ static struct ktermios dgap_default_termios = { .c_line = 0, }; -static const struct tty_operations dgap_tty_ops = { - .open = dgap_tty_open, - .close = dgap_tty_close, - .write = dgap_tty_write, - .write_room = dgap_tty_write_room, - .flush_buffer = dgap_tty_flush_buffer, - .chars_in_buffer = dgap_tty_chars_in_buffer, - .flush_chars = dgap_tty_flush_chars, - .ioctl = dgap_tty_ioctl, - .set_termios = dgap_tty_set_termios, - .stop = dgap_tty_stop, - .start = dgap_tty_start, - .throttle = dgap_tty_throttle, - .unthrottle = dgap_tty_unthrottle, - .hangup = dgap_tty_hangup, - .put_char = dgap_tty_put_char, - .tiocmget = dgap_tty_tiocmget, - .tiocmset = dgap_tty_tiocmset, - .break_ctl = dgap_tty_send_break, - .wait_until_sent = dgap_tty_wait_until_sent, - .send_xchar = dgap_tty_send_xchar -}; - /* * Our needed internal static variables from dgap_parse.c */ @@ -456,1078 +287,1226 @@ static struct toklist dgap_tlist[] = { { 0, NULL } }; -/************************************************************************ - * - * Driver load/unload functions - * - ************************************************************************/ /* - * init_module() - * - * Module load. This is where it all starts. + * dgap_sindex: much like index(), but it looks for a match of any character in + * the group, and returns that position. If the first character is a ^, then + * this will match the first occurrence not in that group. */ -static int dgap_init_module(void) +static char *dgap_sindex(char *string, char *group) { - int rc; + char *ptr; - pr_info("%s, Digi International Part Number %s\n", DG_NAME, DG_PART); + if (!string || !group) + return NULL; - rc = dgap_start(); - if (rc) - return rc; + if (*group == '^') { + group++; + for (; *string; string++) { + for (ptr = group; *ptr; ptr++) { + if (*ptr == *string) + break; + } + if (*ptr == '\0') + return string; + } + } else { + for (; *string; string++) { + for (ptr = group; *ptr; ptr++) { + if (*ptr == *string) + return string; + } + } + } - rc = pci_register_driver(&dgap_driver); - if (rc) - goto err_cleanup; + return NULL; +} - rc = dgap_create_driver_sysfiles(&dgap_driver); - if (rc) - goto err_cleanup; +/* + * get a word from the input stream, also keep track of current line number. + * words are separated by whitespace. + */ +static char *dgap_getword(char **in) +{ + char *ret_ptr = *in; - dgap_driver_state = DRIVER_READY; + char *ptr = dgap_sindex(*in, " \t\n"); - return 0; + /* If no word found, return null */ + if (!ptr) + return NULL; -err_cleanup: + /* Mark new location for our buffer */ + *ptr = '\0'; + *in = ptr + 1; - dgap_cleanup_module(); + /* Eat any extra spaces/tabs/newlines that might be present */ + while (*in && **in && ((**in == ' ') || + (**in == '\t') || + (**in == '\n'))) { + **in = '\0'; + *in = *in + 1; + } - return rc; + return ret_ptr; } -module_init(dgap_init_module); + /* - * Start of driver. + * Get a token from the input file; return 0 if end of file is reached */ -static int dgap_start(void) +static int dgap_gettok(char **in) { - int rc; - unsigned long flags; - struct device *device; - - /* - * make sure that the globals are - * init'd before we do anything else - */ - dgap_init_globals(); - - dgap_numboards = 0; + char *w; + struct toklist *t; - pr_info("For the tools package please visit http://www.digi.com\n"); + if (strstr(dgap_cword, "board")) { + w = dgap_getword(in); + snprintf(dgap_cword, MAXCWORD, "%s", w); + for (t = dgap_brdtype; t->token != 0; t++) { + if (!strcmp(w, t->string)) + return t->token; + } + } else { + while ((w = dgap_getword(in))) { + snprintf(dgap_cword, MAXCWORD, "%s", w); + for (t = dgap_tlist; t->token != 0; t++) { + if (!strcmp(w, t->string)) + return t->token; + } + } + } - /* - * Register our base character device into the kernel. - */ + return 0; +} - /* - * Register management/dpa devices - */ - rc = register_chrdev(DIGI_DGAP_MAJOR, "dgap", &dgap_board_fops); - if (rc < 0) - return rc; +/* + * dgap_checknode: see if all the necessary info has been supplied for a node + * before creating the next node. + */ +static int dgap_checknode(struct cnode *p) +{ + switch (p->type) { + case LNODE: + if (p->u.line.v_speed == 0) { + pr_err("line speed not specified"); + return 1; + } + return 0; - dgap_class = class_create(THIS_MODULE, "dgap_mgmt"); - if (IS_ERR(dgap_class)) { - rc = PTR_ERR(dgap_class); - goto failed_class; - } + case CNODE: + if (p->u.conc.v_speed == 0) { + pr_err("concentrator line speed not specified"); + return 1; + } + if (p->u.conc.v_nport == 0) { + pr_err("number of ports on concentrator not specified"); + return 1; + } + if (p->u.conc.v_id == 0) { + pr_err("concentrator id letter not specified"); + return 1; + } + return 0; - device = device_create(dgap_class, NULL, - MKDEV(DIGI_DGAP_MAJOR, 0), - NULL, "dgap_mgmt"); - if (IS_ERR(device)) { - rc = PTR_ERR(device); - goto failed_device; + case MNODE: + if (p->u.module.v_nport == 0) { + pr_err("number of ports on EBI module not specified"); + return 1; + } + if (p->u.module.v_id == 0) { + pr_err("EBI module id letter not specified"); + return 1; + } + return 0; } + return 0; +} - /* Start the poller */ - spin_lock_irqsave(&dgap_poll_lock, flags); - init_timer(&dgap_poll_timer); - dgap_poll_timer.function = dgap_poll_handler; - dgap_poll_timer.data = 0; - dgap_poll_time = jiffies + dgap_jiffies_from_ms(dgap_poll_tick); - dgap_poll_timer.expires = dgap_poll_time; - spin_unlock_irqrestore(&dgap_poll_lock, flags); +/* + * Given a board pointer, returns whether we should use interrupts or not. + */ +static uint dgap_config_get_useintr(struct board_t *bd) +{ + struct cnode *p; - add_timer(&dgap_poll_timer); + if (!bd) + return 0; - return rc; + for (p = bd->bd_config; p; p = p->next) { + if (p->type == INTRNODE) { + /* + * check for pcxr types. + */ + return p->u.useintr; + } + } -failed_device: - class_destroy(dgap_class); -failed_class: - unregister_chrdev(DIGI_DGAP_MAJOR, "dgap"); - return rc; + /* If not found, then don't turn on interrupts. */ + return 0; } -static int dgap_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) +/* + * Given a board pointer, returns whether we turn on altpin or not. + */ +static uint dgap_config_get_altpin(struct board_t *bd) { - int rc; - struct board_t *brd; + struct cnode *p; - if (dgap_numboards >= MAXBOARDS) - return -EPERM; + if (!bd) + return 0; - rc = pci_enable_device(pdev); - if (rc) - return -EIO; + for (p = bd->bd_config; p; p = p->next) { + if (p->type == ANODE) { + /* + * check for pcxr types. + */ + return p->u.altpin; + } + } - brd = dgap_found_board(pdev, ent->driver_data, dgap_numboards); - if (IS_ERR(brd)) - return PTR_ERR(brd); + /* If not found, then don't turn on interrupts. */ + return 0; +} - rc = dgap_firmware_load(pdev, ent->driver_data, brd); - if (rc) - goto cleanup_brd; +/* + * Given a specific type of board, if found, detached link and + * returns the first occurrence in the list. + */ +static struct cnode *dgap_find_config(int type, int bus, int slot) +{ + struct cnode *p, *prev, *prev2, *found; - rc = dgap_alloc_flipbuf(brd); - if (rc) - goto cleanup_brd; + p = &dgap_head; - rc = dgap_tty_register(brd); - if (rc) - goto free_flipbuf; + while (p->next) { + prev = p; + p = p->next; - rc = dgap_request_irq(brd); - if (rc) - goto unregister_tty; + if (p->type != BNODE) + continue; - /* - * Do tty device initialization. - */ - rc = dgap_tty_init(brd); - if (rc < 0) - goto free_irq; + if (p->u.board.type != type) + continue; - rc = dgap_tty_register_ports(brd); - if (rc) - goto tty_free; + if (p->u.board.v_pcibus && + p->u.board.pcibus != bus) + continue; - brd->state = BOARD_READY; - brd->dpastatus = BD_RUNNING; + if (p->u.board.v_pcislot && + p->u.board.pcislot != slot) + continue; - dgap_board[dgap_numboards++] = brd; + found = p; + /* + * Keep walking thru the list till we + * find the next board. + */ + while (p->next) { + prev2 = p; + p = p->next; - return 0; + if (p->type != BNODE) + continue; -tty_free: - dgap_tty_free(brd); -free_irq: - dgap_free_irq(brd); -unregister_tty: - dgap_tty_unregister(brd); -free_flipbuf: - dgap_free_flipbuf(brd); -cleanup_brd: - dgap_cleanup_nodes(); - dgap_release_remap(brd); - kfree(brd); + /* + * Mark the end of our 1 board + * chain of configs. + */ + prev2->next = NULL; - return rc; -} + /* + * Link the "next" board to the + * previous board, effectively + * "unlinking" our board from + * the main config. + */ + prev->next = p; -static void dgap_remove_one(struct pci_dev *dev) -{ - /* Do Nothing */ + return found; + } + /* + * It must be the last board in the list. + */ + prev->next = NULL; + return found; + } + return NULL; } /* - * dgap_cleanup_module() - * - * Module unload. This is where it all ends. + * Given a board pointer, walks the config link, counting up + * all ports user specified should be on the board. + * (This does NOT mean they are all actually present right now tho) */ -static void dgap_cleanup_module(void) +static uint dgap_config_get_num_prts(struct board_t *bd) { - int i; - ulong lock_flags; - - spin_lock_irqsave(&dgap_poll_lock, lock_flags); - dgap_poll_stop = 1; - spin_unlock_irqrestore(&dgap_poll_lock, lock_flags); - - /* Turn off poller right away. */ - del_timer_sync(&dgap_poll_timer); + int count = 0; + struct cnode *p; - dgap_remove_driver_sysfiles(&dgap_driver); + if (!bd) + return 0; - device_destroy(dgap_class, MKDEV(DIGI_DGAP_MAJOR, 0)); - class_destroy(dgap_class); - unregister_chrdev(DIGI_DGAP_MAJOR, "dgap"); + for (p = bd->bd_config; p; p = p->next) { - for (i = 0; i < dgap_numboards; ++i) { - dgap_remove_ports_sysfiles(dgap_board[i]); - dgap_cleanup_tty(dgap_board[i]); - dgap_cleanup_board(dgap_board[i]); + switch (p->type) { + case BNODE: + /* + * check for pcxr types. + */ + if (p->u.board.type > EPCFE) + count += p->u.board.nport; + break; + case CNODE: + count += p->u.conc.nport; + break; + case MNODE: + count += p->u.module.nport; + break; + } } - - dgap_cleanup_nodes(); - - if (dgap_numboards) - pci_unregister_driver(&dgap_driver); + return count; } -/* - * dgap_cleanup_board() - * - * Free all the memory associated with a board - */ -static void dgap_cleanup_board(struct board_t *brd) +static char *dgap_create_config_string(struct board_t *bd, char *string) { - int i; - - if (!brd || brd->magic != DGAP_BOARD_MAGIC) - return; - - dgap_free_irq(brd); - - tasklet_kill(&brd->helper_tasklet); + char *ptr = string; + struct cnode *p; + struct cnode *q; + int speed; - dgap_release_remap(brd); + if (!bd) { + *ptr = 0xff; + return string; + } - /* Free all allocated channels structs */ - for (i = 0; i < MAXPORTS ; i++) - kfree(brd->channels[i]); + for (p = bd->bd_config; p; p = p->next) { - kfree(brd->flipbuf); - kfree(brd->flipflagbuf); + switch (p->type) { + case LNODE: + *ptr = '\0'; + ptr++; + *ptr = p->u.line.speed; + ptr++; + break; + case CNODE: + /* + * Because the EPC/con concentrators can have EM modules + * hanging off of them, we have to walk ahead in the + * list and keep adding the number of ports on each EM + * to the config. UGH! + */ + speed = p->u.conc.speed; + q = p->next; + if (q && (q->type == MNODE)) { + *ptr = (p->u.conc.nport + 0x80); + ptr++; + p = q; + while (q->next && (q->next->type) == MNODE) { + *ptr = (q->u.module.nport + 0x80); + ptr++; + p = q; + q = q->next; + } + *ptr = q->u.module.nport; + ptr++; + } else { + *ptr = p->u.conc.nport; + ptr++; + } - dgap_board[brd->boardnum] = NULL; + *ptr = speed; + ptr++; + break; + } + } - kfree(brd); + *ptr = 0xff; + return string; } /* - * dgap_found_board() - * - * A board has been found, init it. + * Parse a configuration file read into memory as a string. */ -static struct board_t *dgap_found_board(struct pci_dev *pdev, int id, - int boardnum) +static int dgap_parsefile(char **in) { - struct board_t *brd; - unsigned int pci_irq; - int i; - int ret; - - /* get the board structure and prep it */ - brd = kzalloc(sizeof(struct board_t), GFP_KERNEL); - if (!brd) - return ERR_PTR(-ENOMEM); + struct cnode *p, *brd, *line, *conc; + int rc; + char *s; + int linecnt = 0; - /* store the info for the board we've found */ - brd->magic = DGAP_BOARD_MAGIC; - brd->boardnum = boardnum; - brd->vendor = dgap_pci_tbl[id].vendor; - brd->device = dgap_pci_tbl[id].device; - brd->pdev = pdev; - brd->pci_bus = pdev->bus->number; - brd->pci_slot = PCI_SLOT(pdev->devfn); - brd->name = dgap_ids[id].name; - brd->maxports = dgap_ids[id].maxports; - brd->type = dgap_ids[id].config_type; - brd->dpatype = dgap_ids[id].dpatype; - brd->dpastatus = BD_NOFEP; - init_waitqueue_head(&brd->state_wait); + p = &dgap_head; + brd = line = conc = NULL; - spin_lock_init(&brd->bd_lock); + /* perhaps we are adding to an existing list? */ + while (p->next) + p = p->next; - brd->inhibit_poller = FALSE; - brd->wait_for_bios = 0; - brd->wait_for_fep = 0; + /* file must start with a BEGIN */ + while ((rc = dgap_gettok(in)) != BEGIN) { + if (rc == 0) { + pr_err("unexpected EOF"); + return -1; + } + } - for (i = 0; i < MAXPORTS; i++) - brd->channels[i] = NULL; + for (; ;) { + int board_type = 0; + int conc_type = 0; + int module_type = 0; - /* store which card & revision we have */ - pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &brd->subvendor); - pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &brd->subdevice); - pci_read_config_byte(pdev, PCI_REVISION_ID, &brd->rev); + rc = dgap_gettok(in); + if (rc == 0) { + pr_err("unexpected EOF"); + return -1; + } - pci_irq = pdev->irq; - brd->irq = pci_irq; + switch (rc) { + case BEGIN: /* should only be 1 begin */ + pr_err("unexpected config_begin\n"); + return -1; - /* get the PCI Base Address Registers */ + case END: + return 0; - /* Xr Jupiter and EPC use BAR 2 */ - if (brd->device == PCI_DEV_XRJ_DID || brd->device == PCI_DEV_EPCJ_DID) { - brd->membase = pci_resource_start(pdev, 2); - brd->membase_end = pci_resource_end(pdev, 2); - } - /* Everyone else uses BAR 0 */ - else { - brd->membase = pci_resource_start(pdev, 0); - brd->membase_end = pci_resource_end(pdev, 0); - } + case BOARD: /* board info */ + if (dgap_checknode(p)) + return -1; - if (!brd->membase) { - ret = -ENODEV; - goto free_brd; - } + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - if (brd->membase & 1) - brd->membase &= ~3; - else - brd->membase &= ~15; + p = p->next; - /* - * On the PCI boards, there is no IO space allocated - * The I/O registers will be in the first 3 bytes of the - * upper 2MB of the 4MB memory space. The board memory - * will be mapped into the low 2MB of the 4MB memory space - */ - brd->port = brd->membase + PCI_IO_OFFSET; - brd->port_end = brd->port + PCI_IO_SIZE; + p->type = BNODE; + p->u.board.status = kstrdup("No", GFP_KERNEL); + line = conc = NULL; + brd = p; + linecnt = -1; - /* - * Special initialization for non-PLX boards - */ - if (brd->device != PCI_DEV_XRJ_DID && brd->device != PCI_DEV_EPCJ_DID) { - unsigned short cmd; + board_type = dgap_gettok(in); + if (board_type == 0) { + pr_err("board !!type not specified"); + return -1; + } - pci_write_config_byte(pdev, 0x40, 0); - pci_write_config_byte(pdev, 0x46, 0); + p->u.board.type = board_type; - /* Limit burst length to 2 doubleword transactions */ - pci_write_config_byte(pdev, 0x42, 1); + break; - /* - * Enable IO and mem if not already done. - * This was needed for support on Itanium. - */ - pci_read_config_word(pdev, PCI_COMMAND, &cmd); - cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY); - pci_write_config_word(pdev, PCI_COMMAND, cmd); - } + case IO: /* i/o port */ + if (p->type != BNODE) { + pr_err("IO port only valid for boards"); + return -1; + } + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + p->u.board.portstr = kstrdup(s, GFP_KERNEL); + if (kstrtol(s, 0, &p->u.board.port)) { + pr_err("bad number for IO port"); + return -1; + } + p->u.board.v_port = 1; + break; - /* init our poll helper tasklet */ - tasklet_init(&brd->helper_tasklet, dgap_poll_tasklet, - (unsigned long) brd); + case MEM: /* memory address */ + if (p->type != BNODE) { + pr_err("memory address only valid for boards"); + return -1; + } + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + p->u.board.addrstr = kstrdup(s, GFP_KERNEL); + if (kstrtoul(s, 0, &p->u.board.addr)) { + pr_err("bad number for memory address"); + return -1; + } + p->u.board.v_addr = 1; + break; - ret = dgap_do_remap(brd); - if (ret) - goto free_brd; + case PCIINFO: /* pci information */ + if (p->type != BNODE) { + pr_err("memory address only valid for boards"); + return -1; + } + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + p->u.board.pcibusstr = kstrdup(s, GFP_KERNEL); + if (kstrtoul(s, 0, &p->u.board.pcibus)) { + pr_err("bad number for pci bus"); + return -1; + } + p->u.board.v_pcibus = 1; + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + p->u.board.pcislotstr = kstrdup(s, GFP_KERNEL); + if (kstrtoul(s, 0, &p->u.board.pcislot)) { + pr_err("bad number for pci slot"); + return -1; + } + p->u.board.v_pcislot = 1; + break; - pr_info("dgap: board %d: %s (rev %d), irq %ld\n", - boardnum, brd->name, brd->rev, brd->irq); + case METHOD: + if (p->type != BNODE) { + pr_err("install method only valid for boards"); + return -1; + } + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + p->u.board.method = kstrdup(s, GFP_KERNEL); + p->u.board.v_method = 1; + break; - return brd; + case STATUS: + if (p->type != BNODE) { + pr_err("config status only valid for boards"); + return -1; + } + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + p->u.board.status = kstrdup(s, GFP_KERNEL); + break; -free_brd: - kfree(brd); + case NPORTS: /* number of ports */ + if (p->type == BNODE) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.board.nport)) { + pr_err("bad number for number of ports"); + return -1; + } + p->u.board.v_nport = 1; + } else if (p->type == CNODE) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.conc.nport)) { + pr_err("bad number for number of ports"); + return -1; + } + p->u.conc.v_nport = 1; + } else if (p->type == MNODE) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.module.nport)) { + pr_err("bad number for number of ports"); + return -1; + } + p->u.module.v_nport = 1; + } else { + pr_err("nports only valid for concentrators or modules"); + return -1; + } + break; - return ERR_PTR(ret); -} + case ID: /* letter ID used in tty name */ + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + p->u.board.status = kstrdup(s, GFP_KERNEL); -static int dgap_request_irq(struct board_t *brd) -{ - int rc; + if (p->type == CNODE) { + p->u.conc.id = kstrdup(s, GFP_KERNEL); + p->u.conc.v_id = 1; + } else if (p->type == MNODE) { + p->u.module.id = kstrdup(s, GFP_KERNEL); + p->u.module.v_id = 1; + } else { + pr_err("id only valid for concentrators or modules"); + return -1; + } + break; - if (!brd || brd->magic != DGAP_BOARD_MAGIC) - return -ENODEV; + case STARTO: /* start offset of ID */ + if (p->type == BNODE) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.board.start)) { + pr_err("bad number for start of tty count"); + return -1; + } + p->u.board.v_start = 1; + } else if (p->type == CNODE) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.conc.start)) { + pr_err("bad number for start of tty count"); + return -1; + } + p->u.conc.v_start = 1; + } else if (p->type == MNODE) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.module.start)) { + pr_err("bad number for start of tty count"); + return -1; + } + p->u.module.v_start = 1; + } else { + pr_err("start only valid for concentrators or modules"); + return -1; + } + break; - /* - * Set up our interrupt handler if we are set to do interrupts. - */ - if (dgap_config_get_useintr(brd) && brd->irq) { + case TTYN: /* tty name prefix */ + if (dgap_checknode(p)) + return -1; - rc = request_irq(brd->irq, dgap_intr, IRQF_SHARED, "DGAP", brd); + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - if (!rc) - brd->intr_used = 1; - } - return 0; -} + p = p->next; + p->type = TNODE; -static void dgap_free_irq(struct board_t *brd) -{ - if (brd->intr_used && brd->irq) - free_irq(brd->irq, brd); -} + s = dgap_getword(in); + if (!s) { + pr_err("unexpeced end of file"); + return -1; + } + p->u.ttyname = kstrdup(s, GFP_KERNEL); + if (!p->u.ttyname) + return -1; -static int dgap_firmware_load(struct pci_dev *pdev, int card_type, - struct board_t *brd) -{ - const struct firmware *fw; - char *tmp_ptr; - int ret; - char *dgap_config_buf; + break; - dgap_get_vpd(brd); - dgap_do_reset_board(brd); + case CU: /* cu name prefix */ + if (dgap_checknode(p)) + return -1; - if (fw_info[card_type].conf_name) { - ret = request_firmware(&fw, fw_info[card_type].conf_name, - &pdev->dev); - if (ret) { - dev_err(&pdev->dev, "config file %s not found\n", - fw_info[card_type].conf_name); - return ret; - } + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - dgap_config_buf = kzalloc(fw->size + 1, GFP_KERNEL); - if (!dgap_config_buf) { - release_firmware(fw); - return -ENOMEM; - } + p = p->next; + p->type = CUNODE; - memcpy(dgap_config_buf, fw->data, fw->size); - release_firmware(fw); + s = dgap_getword(in); + if (!s) { + pr_err("unexpeced end of file"); + return -1; + } + p->u.cuname = kstrdup(s, GFP_KERNEL); + if (!p->u.cuname) + return -1; - /* - * preserve dgap_config_buf - * as dgap_parsefile would - * otherwise alter it. - */ - tmp_ptr = dgap_config_buf; + break; - if (dgap_parsefile(&tmp_ptr) != 0) { - kfree(dgap_config_buf); - return -EINVAL; - } - kfree(dgap_config_buf); - } + case LINE: /* line information */ + if (dgap_checknode(p)) + return -1; + if (!brd) { + pr_err("must specify board before line info"); + return -1; + } + switch (brd->u.board.type) { + case PPCM: + pr_err("line not valid for PC/em"); + return -1; + } - /* - * Match this board to a config the user created for us. - */ - brd->bd_config = - dgap_find_config(brd->type, brd->pci_bus, brd->pci_slot); + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - /* - * Because the 4 port Xr products share the same PCI ID - * as the 8 port Xr products, if we receive a NULL config - * back, and this is a PAPORT8 board, retry with a - * PAPORT4 attempt as well. - */ - if (brd->type == PAPORT8 && !brd->bd_config) - brd->bd_config = - dgap_find_config(PAPORT4, brd->pci_bus, brd->pci_slot); + p = p->next; + p->type = LNODE; + conc = NULL; + line = p; + linecnt++; + break; - if (!brd->bd_config) { - dev_err(&pdev->dev, "No valid configuration found\n"); - return -EINVAL; - } + case CONC: /* concentrator information */ + if (dgap_checknode(p)) + return -1; + if (!line) { + pr_err("must specify line info before concentrator"); + return -1; + } - if (fw_info[card_type].bios_name) { - ret = request_firmware(&fw, fw_info[card_type].bios_name, - &pdev->dev); - if (ret) { - dev_err(&pdev->dev, "bios file %s not found\n", - fw_info[card_type].bios_name); - return ret; - } - dgap_do_bios_load(brd, fw->data, fw->size); - release_firmware(fw); + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - /* Wait for BIOS to test board... */ - ret = dgap_test_bios(brd); - if (ret) - return ret; - } + p = p->next; + p->type = CNODE; + conc = p; - if (fw_info[card_type].fep_name) { - ret = request_firmware(&fw, fw_info[card_type].fep_name, - &pdev->dev); - if (ret) { - dev_err(&pdev->dev, "dgap: fep file %s not found\n", - fw_info[card_type].fep_name); - return ret; - } - dgap_do_fep_load(brd, fw->data, fw->size); - release_firmware(fw); + if (linecnt) + brd->u.board.conc2++; + else + brd->u.board.conc1++; - /* Wait for FEP to load on board... */ - ret = dgap_test_fep(brd); - if (ret) - return ret; - } + conc_type = dgap_gettok(in); + if (conc_type == 0 || conc_type != CX || + conc_type != EPC) { + pr_err("failed to set a type of concentratros"); + return -1; + } -#ifdef DIGI_CONCENTRATORS_SUPPORTED - /* - * If this is a CX or EPCX, we need to see if the firmware - * is requesting a concentrator image from us. - */ - if ((bd->type == PCX) || (bd->type == PEPC)) { - chk_addr = (u16 *) (vaddr + DOWNREQ); - /* Nonzero if FEP is requesting concentrator image. */ - check = readw(chk_addr); - vaddr = brd->re_map_membase; - } + p->u.conc.type = conc_type; - if (fw_info[card_type].con_name && check && vaddr) { - ret = request_firmware(&fw, fw_info[card_type].con_name, - &pdev->dev); - if (ret) { - dev_err(&pdev->dev, "conc file %s not found\n", - fw_info[card_type].con_name); - return ret; - } - /* Put concentrator firmware loading code here */ - offset = readw((u16 *) (vaddr + DOWNREQ)); - memcpy_toio(offset, fw->data, fw->size); + break; - dgap_do_conc_load(brd, (char *)fw->data, fw->size) - release_firmware(fw); - } -#endif + case MOD: /* EBI module */ + if (dgap_checknode(p)) + return -1; + if (!brd) { + pr_err("must specify board info before EBI modules"); + return -1; + } + switch (brd->u.board.type) { + case PPCM: + linecnt = 0; + break; + default: + if (!conc) { + pr_err("must specify concentrator info before EBI module"); + return -1; + } + } - return 0; -} + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; -/* - * Remap PCI memory. - */ -static int dgap_do_remap(struct board_t *brd) -{ - if (!brd || brd->magic != DGAP_BOARD_MAGIC) - return -EIO; + p = p->next; + p->type = MNODE; - if (!request_mem_region(brd->membase, 0x200000, "dgap")) - return -ENOMEM; + if (linecnt) + brd->u.board.module2++; + else + brd->u.board.module1++; - if (!request_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000, - "dgap")) { - release_mem_region(brd->membase, 0x200000); - return -ENOMEM; - } + module_type = dgap_gettok(in); + if (module_type == 0 || module_type != PORTS || + module_type != MODEM) { + pr_err("failed to set a type of module"); + return -1; + } - brd->re_map_membase = ioremap(brd->membase, 0x200000); - if (!brd->re_map_membase) { - release_mem_region(brd->membase, 0x200000); - release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000); - return -ENOMEM; - } + p->u.module.type = module_type; - brd->re_map_port = ioremap((brd->membase + PCI_IO_OFFSET), 0x200000); - if (!brd->re_map_port) { - release_mem_region(brd->membase, 0x200000); - release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000); - iounmap(brd->re_map_membase); - return -ENOMEM; - } + break; - return 0; -} + case CABLE: + if (p->type == LNODE) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + p->u.line.cable = kstrdup(s, GFP_KERNEL); + p->u.line.v_cable = 1; + } + break; -static void dgap_release_remap(struct board_t *brd) -{ - if (brd->re_map_membase) { - release_mem_region(brd->membase, 0x200000); - iounmap(brd->re_map_membase); - } + case SPEED: /* sync line speed indication */ + if (p->type == LNODE) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.line.speed)) { + pr_err("bad number for line speed"); + return -1; + } + p->u.line.v_speed = 1; + } else if (p->type == CNODE) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.conc.speed)) { + pr_err("bad number for line speed"); + return -1; + } + p->u.conc.v_speed = 1; + } else { + pr_err("speed valid only for lines or concentrators."); + return -1; + } + break; - if (brd->re_map_port) { - release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000); - iounmap(brd->re_map_port); - } -} -/***************************************************************************** -* -* Function: -* -* dgap_poll_handler -* -* Author: -* -* Scott H Kilau -* -* Parameters: -* -* dummy -- ignored -* -* Return Values: -* -* none -* -* Description: -* -* As each timer expires, it determines (a) whether the "transmit" -* waiter needs to be woken up, and (b) whether the poller needs to -* be rescheduled. -* -******************************************************************************/ + case CONNECT: + if (p->type == CNODE) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + p->u.conc.connect = kstrdup(s, GFP_KERNEL); + p->u.conc.v_connect = 1; + } + break; + case PRINT: /* transparent print name prefix */ + if (dgap_checknode(p)) + return -1; -static void dgap_poll_handler(ulong dummy) -{ - int i; - struct board_t *brd; - unsigned long lock_flags; - ulong new_time; + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - dgap_poll_counter++; + p = p->next; + p->type = PNODE; - /* - * Do not start the board state machine until - * driver tells us its up and running, and has - * everything it needs. - */ - if (dgap_driver_state != DRIVER_READY) - goto schedule_poller; + s = dgap_getword(in); + if (!s) { + pr_err("unexpeced end of file"); + return -1; + } + p->u.printname = kstrdup(s, GFP_KERNEL); + if (!p->u.printname) + return -1; - /* - * If we have just 1 board, or the system is not SMP, - * then use the typical old style poller. - * Otherwise, use our new tasklet based poller, which should - * speed things up for multiple boards. - */ - if ((dgap_numboards == 1) || (num_online_cpus() <= 1)) { - for (i = 0; i < dgap_numboards; i++) { + break; - brd = dgap_board[i]; + case CMAJOR: /* major number */ + if (dgap_checknode(p)) + return -1; - if (brd->state == BOARD_FAILED) - continue; - if (!brd->intr_running) - /* Call the real board poller directly */ - dgap_poll_tasklet((unsigned long) brd); - } - } else { - /* - * Go thru each board, kicking off a - * tasklet for each if needed - */ - for (i = 0; i < dgap_numboards; i++) { - brd = dgap_board[i]; + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - /* - * Attempt to grab the board lock. - * - * If we can't get it, no big deal, the next poll - * will get it. Basically, I just really don't want - * to spin in here, because I want to kick off my - * tasklets as fast as I can, and then get out the - * poller. - */ - if (!spin_trylock(&brd->bd_lock)) - continue; + p = p->next; + p->type = JNODE; - /* - * If board is in a failed state, don't bother - * scheduling a tasklet - */ - if (brd->state == BOARD_FAILED) { - spin_unlock(&brd->bd_lock); - continue; + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; } + if (kstrtol(s, 0, &p->u.majornumber)) { + pr_err("bad number for major number"); + return -1; + } + break; - /* Schedule a poll helper task */ - if (!brd->intr_running) - tasklet_schedule(&brd->helper_tasklet); - - /* - * Can't do DGAP_UNLOCK here, as we don't have - * lock_flags because we did a trylock above. - */ - spin_unlock(&brd->bd_lock); - } - } + case ALTPIN: /* altpin setting */ + if (dgap_checknode(p)) + return -1; -schedule_poller: + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - /* - * Schedule ourself back at the nominal wakeup interval. - */ - spin_lock_irqsave(&dgap_poll_lock, lock_flags); - dgap_poll_time += dgap_jiffies_from_ms(dgap_poll_tick); + p = p->next; + p->type = ANODE; - new_time = dgap_poll_time - jiffies; + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.altpin)) { + pr_err("bad number for altpin"); + return -1; + } + break; - if ((ulong) new_time >= 2 * dgap_poll_tick) { - dgap_poll_time = - jiffies + dgap_jiffies_from_ms(dgap_poll_tick); - } + case USEINTR: /* enable interrupt setting */ + if (dgap_checknode(p)) + return -1; - dgap_poll_timer.function = dgap_poll_handler; - dgap_poll_timer.data = 0; - dgap_poll_timer.expires = dgap_poll_time; - spin_unlock_irqrestore(&dgap_poll_lock, lock_flags); + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - if (!dgap_poll_stop) - add_timer(&dgap_poll_timer); -} + p = p->next; + p->type = INTRNODE; + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.useintr)) { + pr_err("bad number for useintr"); + return -1; + } + break; -/* - * dgap_intr() - * - * Driver interrupt handler. - */ -static irqreturn_t dgap_intr(int irq, void *voidbrd) -{ - struct board_t *brd = (struct board_t *) voidbrd; + case TTSIZ: /* size of tty structure */ + if (dgap_checknode(p)) + return -1; - if (!brd) - return IRQ_NONE; + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - /* - * Check to make sure its for us. - */ - if (brd->magic != DGAP_BOARD_MAGIC) - return IRQ_NONE; + p = p->next; + p->type = TSNODE; - brd->intr_count++; + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.ttysize)) { + pr_err("bad number for ttysize"); + return -1; + } + break; - /* - * Schedule tasklet to run at a better time. - */ - tasklet_schedule(&brd->helper_tasklet); - return IRQ_HANDLED; -} + case CHSIZ: /* channel structure size */ + if (dgap_checknode(p)) + return -1; -/* - * dgap_init_globals() - * - * This is where we initialize the globals from the static insmod - * configuration variables. These are declared near the head of - * this file. - */ -static void dgap_init_globals(void) -{ - int i; + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - for (i = 0; i < MAXBOARDS; i++) - dgap_board[i] = NULL; + p = p->next; + p->type = CSNODE; - init_timer(&dgap_poll_timer); -} + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.chsize)) { + pr_err("bad number for chsize"); + return -1; + } + break; -/************************************************************************ - * - * TTY Initialization/Cleanup Functions - * - ************************************************************************/ + case BSSIZ: /* board structure size */ + if (dgap_checknode(p)) + return -1; -/* - * dgap_tty_register() - * - * Init the tty subsystem for this board. - */ -static int dgap_tty_register(struct board_t *brd) -{ - int rc; + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - brd->serial_driver = tty_alloc_driver(MAXPORTS, 0); - if (IS_ERR(brd->serial_driver)) - return PTR_ERR(brd->serial_driver); + p = p->next; + p->type = BSNODE; - snprintf(brd->serial_name, MAXTTYNAMELEN, "tty_dgap_%d_", - brd->boardnum); - brd->serial_driver->name = brd->serial_name; - brd->serial_driver->name_base = 0; - brd->serial_driver->major = 0; - brd->serial_driver->minor_start = 0; - brd->serial_driver->type = TTY_DRIVER_TYPE_SERIAL; - brd->serial_driver->subtype = SERIAL_TYPE_NORMAL; - brd->serial_driver->init_termios = dgap_default_termios; - brd->serial_driver->driver_name = DRVSTR; - brd->serial_driver->flags = (TTY_DRIVER_REAL_RAW | - TTY_DRIVER_DYNAMIC_DEV | - TTY_DRIVER_HARDWARE_BREAK); - - /* The kernel wants space to store pointers to tty_structs */ - brd->serial_driver->ttys = - kzalloc(MAXPORTS * sizeof(struct tty_struct *), GFP_KERNEL); - if (!brd->serial_driver->ttys) { - rc = -ENOMEM; - goto free_serial_drv; - } + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.bssize)) { + pr_err("bad number for bssize"); + return -1; + } + break; - /* - * Entry points for driver. Called by the kernel from - * tty_io.c and n_tty.c. - */ - tty_set_operations(brd->serial_driver, &dgap_tty_ops); + case UNTSIZ: /* sched structure size */ + if (dgap_checknode(p)) + return -1; - /* - * If we're doing transparent print, we have to do all of the above - * again, separately so we don't get the LD confused about what major - * we are when we get into the dgap_tty_open() routine. - */ - brd->print_driver = tty_alloc_driver(MAXPORTS, 0); - if (IS_ERR(brd->print_driver)) { - rc = PTR_ERR(brd->print_driver); - goto free_serial_drv; - } + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - snprintf(brd->print_name, MAXTTYNAMELEN, "pr_dgap_%d_", - brd->boardnum); - brd->print_driver->name = brd->print_name; - brd->print_driver->name_base = 0; - brd->print_driver->major = 0; - brd->print_driver->minor_start = 0; - brd->print_driver->type = TTY_DRIVER_TYPE_SERIAL; - brd->print_driver->subtype = SERIAL_TYPE_NORMAL; - brd->print_driver->init_termios = dgap_default_termios; - brd->print_driver->driver_name = DRVSTR; - brd->print_driver->flags = (TTY_DRIVER_REAL_RAW | - TTY_DRIVER_DYNAMIC_DEV | - TTY_DRIVER_HARDWARE_BREAK); - - /* The kernel wants space to store pointers to tty_structs */ - brd->print_driver->ttys = - kzalloc(MAXPORTS * sizeof(struct tty_struct *), GFP_KERNEL); - if (!brd->print_driver->ttys) { - rc = -ENOMEM; - goto free_print_drv; - } + p = p->next; + p->type = USNODE; - /* - * Entry points for driver. Called by the kernel from - * tty_io.c and n_tty.c. - */ - tty_set_operations(brd->print_driver, &dgap_tty_ops); + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.unsize)) { + pr_err("bad number for schedsize"); + return -1; + } + break; - /* Register tty devices */ - rc = tty_register_driver(brd->serial_driver); - if (rc < 0) - goto free_print_drv; + case F2SIZ: /* f2200 structure size */ + if (dgap_checknode(p)) + return -1; - /* Register Transparent Print devices */ - rc = tty_register_driver(brd->print_driver); - if (rc < 0) - goto unregister_serial_drv; + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - dgap_boards_by_major[brd->serial_driver->major] = brd; - brd->dgap_serial_major = brd->serial_driver->major; + p = p->next; + p->type = FSNODE; - dgap_boards_by_major[brd->print_driver->major] = brd; - brd->dgap_transparent_print_major = brd->print_driver->major; + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.f2size)) { + pr_err("bad number for f2200size"); + return -1; + } + break; - return 0; + case VPSIZ: /* vpix structure size */ + if (dgap_checknode(p)) + return -1; -unregister_serial_drv: - tty_unregister_driver(brd->serial_driver); -free_print_drv: - put_tty_driver(brd->print_driver); -free_serial_drv: - put_tty_driver(brd->serial_driver); + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - return rc; -} + p = p->next; + p->type = VSNODE; -static void dgap_tty_unregister(struct board_t *brd) -{ - tty_unregister_driver(brd->print_driver); - tty_unregister_driver(brd->serial_driver); - put_tty_driver(brd->print_driver); - put_tty_driver(brd->serial_driver); + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.vpixsize)) { + pr_err("bad number for vpixsize"); + return -1; + } + break; + } + } } -/* - * dgap_tty_init() - * - * Init the tty subsystem. Called once per board after board has been - * downloaded and init'ed. - */ -static int dgap_tty_init(struct board_t *brd) +static void dgap_cleanup_nodes(void) { - int i; - int tlw; - uint true_count; - u8 __iomem *vaddr; - u8 modem; - struct channel_t *ch; - struct bs_t __iomem *bs; - struct cm_t __iomem *cm; - int ret; - - /* - * Initialize board structure elements. - */ - - vaddr = brd->re_map_membase; - true_count = readw((vaddr + NCHAN)); - - brd->nasync = dgap_config_get_num_prts(brd); - - if (!brd->nasync) - brd->nasync = brd->maxports; + struct cnode *p; - if (brd->nasync > brd->maxports) - brd->nasync = brd->maxports; + p = &dgap_head; - if (true_count != brd->nasync) { - dev_warn(&brd->pdev->dev, - "%s configured for %d ports, has %d ports.\n", - brd->name, brd->nasync, true_count); + while (p) { + struct cnode *tmp = p->next; - if ((brd->type == PPCM) && - (true_count == 64 || true_count == 0)) { - dev_warn(&brd->pdev->dev, - "Please make SURE the EBI cable running from the card\n"); - dev_warn(&brd->pdev->dev, - "to each EM module is plugged into EBI IN!\n"); + if (p->type == NULLNODE) { + p = tmp; + continue; } - brd->nasync = true_count; - - /* If no ports, don't bother going any further */ - if (!brd->nasync) { - brd->state = BOARD_FAILED; - brd->dpastatus = BD_NOFEP; - return -EIO; + switch (p->type) { + case BNODE: + kfree(p->u.board.portstr); + kfree(p->u.board.addrstr); + kfree(p->u.board.pcibusstr); + kfree(p->u.board.pcislotstr); + kfree(p->u.board.method); + break; + case CNODE: + kfree(p->u.conc.id); + kfree(p->u.conc.connect); + break; + case MNODE: + kfree(p->u.module.id); + break; + case TNODE: + kfree(p->u.ttyname); + break; + case CUNODE: + kfree(p->u.cuname); + break; + case LNODE: + kfree(p->u.line.cable); + break; + case PNODE: + kfree(p->u.printname); + break; } - } - /* - * Allocate channel memory that might not have been allocated - * when the driver was first loaded. - */ - for (i = 0; i < brd->nasync; i++) { - brd->channels[i] = - kzalloc(sizeof(struct channel_t), GFP_KERNEL); - if (!brd->channels[i]) { - ret = -ENOMEM; - goto free_chan; - } + kfree(p->u.board.status); + kfree(p); + p = tmp; } +} - ch = brd->channels[0]; - vaddr = brd->re_map_membase; - - bs = (struct bs_t __iomem *) ((ulong) vaddr + CHANBUF); - cm = (struct cm_t __iomem *) ((ulong) vaddr + CMDBUF); - - brd->bd_bs = bs; - - /* Set up channel variables */ - for (i = 0; i < brd->nasync; i++, ch = brd->channels[i], bs++) { - - spin_lock_init(&ch->ch_lock); - - /* Store all our magic numbers */ - ch->magic = DGAP_CHANNEL_MAGIC; - ch->ch_tun.magic = DGAP_UNIT_MAGIC; - ch->ch_tun.un_type = DGAP_SERIAL; - ch->ch_tun.un_ch = ch; - ch->ch_tun.un_dev = i; - - ch->ch_pun.magic = DGAP_UNIT_MAGIC; - ch->ch_pun.un_type = DGAP_PRINT; - ch->ch_pun.un_ch = ch; - ch->ch_pun.un_dev = i; +/* + * Retrives the current custom baud rate from FEP memory, + * and returns it back to the user. + * Returns 0 on error. + */ +static uint dgap_get_custom_baud(struct channel_t *ch) +{ + u8 __iomem *vaddr; + ulong offset; + uint value; - ch->ch_vaddr = vaddr; - ch->ch_bs = bs; - ch->ch_cm = cm; - ch->ch_bd = brd; - ch->ch_portnum = i; - ch->ch_digi = dgap_digi_init; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return 0; - /* - * Set up digi dsr and dcd bits based on altpin flag. - */ - if (dgap_config_get_altpin(brd)) { - ch->ch_dsr = DM_CD; - ch->ch_cd = DM_DSR; - ch->ch_digi.digi_flags |= DIGI_ALTPIN; - } else { - ch->ch_cd = DM_CD; - ch->ch_dsr = DM_DSR; - } + if (!ch->ch_bd || ch->ch_bd->magic != DGAP_BOARD_MAGIC) + return 0; - ch->ch_taddr = vaddr + (ioread16(&(ch->ch_bs->tx_seg)) << 4); - ch->ch_raddr = vaddr + (ioread16(&(ch->ch_bs->rx_seg)) << 4); - ch->ch_tx_win = 0; - ch->ch_rx_win = 0; - ch->ch_tsize = readw(&(ch->ch_bs->tx_max)) + 1; - ch->ch_rsize = readw(&(ch->ch_bs->rx_max)) + 1; - ch->ch_tstart = 0; - ch->ch_rstart = 0; + if (!(ch->ch_bd->bd_flags & BD_FEP5PLUS)) + return 0; - /* - * Set queue water marks, interrupt mask, - * and general tty parameters. - */ - tlw = ch->ch_tsize >= 2000 ? ((ch->ch_tsize * 5) / 8) : - ch->ch_tsize / 2; - ch->ch_tlw = tlw; + vaddr = ch->ch_bd->re_map_membase; - dgap_cmdw(ch, STLOW, tlw, 0); + if (!vaddr) + return 0; - dgap_cmdw(ch, SRLOW, ch->ch_rsize / 2, 0); + /* + * Go get from fep mem, what the fep + * believes the custom baud rate is. + */ + offset = (ioread16(vaddr + ECS_SEG) << 4) + (ch->ch_portnum * 0x28) + + LINE_SPEED; - dgap_cmdw(ch, SRHIGH, 7 * ch->ch_rsize / 8, 0); + value = readw(vaddr + offset); + return value; +} - ch->ch_mistat = readb(&(ch->ch_bs->m_stat)); +/* + * Remap PCI memory. + */ +static int dgap_remap(struct board_t *brd) +{ + if (!brd || brd->magic != DGAP_BOARD_MAGIC) + return -EIO; - init_waitqueue_head(&ch->ch_flags_wait); - init_waitqueue_head(&ch->ch_tun.un_flags_wait); - init_waitqueue_head(&ch->ch_pun.un_flags_wait); + if (!request_mem_region(brd->membase, 0x200000, "dgap")) + return -ENOMEM; - /* Turn on all modem interrupts for now */ - modem = (DM_CD | DM_DSR | DM_CTS | DM_RI); - writeb(modem, &(ch->ch_bs->m_int)); + if (!request_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000, + "dgap")) { + release_mem_region(brd->membase, 0x200000); + return -ENOMEM; + } - /* - * Set edelay to 0 if interrupts are turned on, - * otherwise set edelay to the usual 100. - */ - if (brd->intr_used) - writew(0, &(ch->ch_bs->edelay)); - else - writew(100, &(ch->ch_bs->edelay)); + brd->re_map_membase = ioremap(brd->membase, 0x200000); + if (!brd->re_map_membase) { + release_mem_region(brd->membase, 0x200000); + release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000); + return -ENOMEM; + } - writeb(1, &(ch->ch_bs->idata)); + brd->re_map_port = ioremap((brd->membase + PCI_IO_OFFSET), 0x200000); + if (!brd->re_map_port) { + release_mem_region(brd->membase, 0x200000); + release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000); + iounmap(brd->re_map_membase); + return -ENOMEM; } return 0; - -free_chan: - while (--i >= 0) { - kfree(brd->channels[i]); - brd->channels[i] = NULL; - } - return ret; } -/* - * dgap_tty_free() - * - * Free the channles which are allocated in dgap_tty_init(). - */ -static void dgap_tty_free(struct board_t *brd) +static void dgap_unmap(struct board_t *brd) { - int i; - - for (i = 0; i < brd->nasync; i++) - kfree(brd->channels[i]); + iounmap(brd->re_map_port); + iounmap(brd->re_map_membase); + release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000); + release_mem_region(brd->membase, 0x200000); } + /* - * dgap_cleanup_tty() + * dgap_parity_scan() * - * Uninitialize the TTY portion of this driver. Free all memory and - * resources. + * Convert the FEP5 way of reporting parity errors and breaks into + * the Linux line discipline way. */ -static void dgap_cleanup_tty(struct board_t *brd) +static void dgap_parity_scan(struct channel_t *ch, unsigned char *cbuf, + unsigned char *fbuf, int *len) { - struct device *dev; - int i; + int l = *len; + int count = 0; + unsigned char *in, *cout, *fout; + unsigned char c; - dgap_boards_by_major[brd->serial_driver->major] = NULL; - brd->dgap_serial_major = 0; - for (i = 0; i < brd->nasync; i++) { - tty_port_destroy(&brd->serial_ports[i]); - dev = brd->channels[i]->ch_tun.un_sysfs; - dgap_remove_tty_sysfs(dev); - tty_unregister_device(brd->serial_driver, i); - } - tty_unregister_driver(brd->serial_driver); - put_tty_driver(brd->serial_driver); - kfree(brd->serial_ports); + in = cbuf; + cout = cbuf; + fout = fbuf; - dgap_boards_by_major[brd->print_driver->major] = NULL; - brd->dgap_transparent_print_major = 0; - for (i = 0; i < brd->nasync; i++) { - tty_port_destroy(&brd->printer_ports[i]); - dev = brd->channels[i]->ch_pun.un_sysfs; - dgap_remove_tty_sysfs(dev); - tty_unregister_device(brd->print_driver, i); + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return; + + while (l--) { + c = *in++; + switch (ch->pscan_state) { + default: + /* reset to sanity and fall through */ + ch->pscan_state = 0; + + case 0: + /* No FF seen yet */ + if (c == (unsigned char) '\377') + /* delete this character from stream */ + ch->pscan_state = 1; + else { + *cout++ = c; + *fout++ = TTY_NORMAL; + count += 1; + } + break; + + case 1: + /* first FF seen */ + if (c == (unsigned char) '\377') { + /* doubled ff, transform to single ff */ + *cout++ = c; + *fout++ = TTY_NORMAL; + count += 1; + ch->pscan_state = 0; + } else { + /* save value examination in next state */ + ch->pscan_savechar = c; + ch->pscan_state = 2; + } + break; + + case 2: + /* third character of ff sequence */ + + *cout++ = c; + + if (ch->pscan_savechar == 0x0) { + + if (c == 0x0) { + ch->ch_err_break++; + *fout++ = TTY_BREAK; + } else { + ch->ch_err_parity++; + *fout++ = TTY_PARITY; + } + } + + count += 1; + ch->pscan_state = 0; + } } - tty_unregister_driver(brd->print_driver); - put_tty_driver(brd->print_driver); - kfree(brd->printer_ports); + *len = count; } /*======================================================================= @@ -1738,6 +1717,33 @@ static void dgap_input(struct channel_t *ch) } +static void dgap_write_wakeup(struct board_t *bd, struct channel_t *ch, + struct un_t *un, u32 mask, + unsigned long *irq_flags1, + unsigned long *irq_flags2) +{ + if (!(un->un_flags & mask)) + return; + + un->un_flags &= ~mask; + + if (!(un->un_flags & UN_ISOPEN)) + return; + + if ((un->un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + un->un_tty->ldisc->ops->write_wakeup) { + spin_unlock_irqrestore(&ch->ch_lock, *irq_flags2); + spin_unlock_irqrestore(&bd->bd_lock, *irq_flags1); + + (un->un_tty->ldisc->ops->write_wakeup)(un->un_tty); + + spin_lock_irqsave(&bd->bd_lock, *irq_flags1); + spin_lock_irqsave(&ch->ch_lock, *irq_flags2); + } + wake_up_interruptible(&un->un_tty->write_wait); + wake_up_interruptible(&un->un_flags_wait); +} + /************************************************************************ * Determines when CARRIER changes state and takes appropriate * action. @@ -1852,163 +1858,1207 @@ static void dgap_carrier(struct channel_t *ch) ch->ch_flags &= ~CH_CD; } -/************************************************************************ +/*======================================================================= * - * TTY Entry points and helper functions + * dgap_event - FEP to host event processing routine. * - ************************************************************************/ - -/* - * dgap_tty_open() + * bd - Board of current event. * - */ -static int dgap_tty_open(struct tty_struct *tty, struct file *file) + *=======================================================================*/ +static int dgap_event(struct board_t *bd) { - struct board_t *brd; struct channel_t *ch; - struct un_t *un; - struct bs_t __iomem *bs; - uint major; - uint minor; - int rc; ulong lock_flags; ulong lock_flags2; - u16 head; + struct bs_t __iomem *bs; + u8 __iomem *event; + u8 __iomem *vaddr; + struct ev_t __iomem *eaddr; + uint head; + uint tail; + int port; + int reason; + int modem; + int b1; - major = MAJOR(tty_devnum(tty)); - minor = MINOR(tty_devnum(tty)); + if (!bd || bd->magic != DGAP_BOARD_MAGIC) + return -EIO; + + spin_lock_irqsave(&bd->bd_lock, lock_flags); + + vaddr = bd->re_map_membase; - if (major > 255) + if (!vaddr) { + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); return -EIO; + } - /* Get board pointer from our array of majors we have allocated */ - brd = dgap_boards_by_major[major]; - if (!brd) + eaddr = (struct ev_t __iomem *) (vaddr + EVBUF); + + /* Get our head and tail */ + head = readw(&(eaddr->ev_head)); + tail = readw(&(eaddr->ev_tail)); + + /* + * Forget it if pointers out of range. + */ + + if (head >= EVMAX - EVSTART || tail >= EVMAX - EVSTART || + (head | tail) & 03) { + /* Let go of board lock */ + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); return -EIO; + } /* - * If board is not yet up to a state of READY, go to - * sleep waiting for it to happen or they cancel the open. + * Loop to process all the events in the buffer. */ - rc = wait_event_interruptible(brd->state_wait, - (brd->state & BOARD_READY)); + while (tail != head) { - if (rc) - return rc; + /* + * Get interrupt information. + */ - spin_lock_irqsave(&brd->bd_lock, lock_flags); + event = bd->re_map_membase + tail + EVSTART; - /* The wait above should guarantee this cannot happen */ - if (brd->state != BOARD_READY) { - spin_unlock_irqrestore(&brd->bd_lock, lock_flags); - return -EIO; + port = ioread8(event); + reason = ioread8(event + 1); + modem = ioread8(event + 2); + b1 = ioread8(event + 3); + + /* + * Make sure the interrupt is valid. + */ + if (port >= bd->nasync) + goto next; + + if (!(reason & (IFMODEM | IFBREAK | IFTLW | IFTEM | IFDATA))) + goto next; + + ch = bd->channels[port]; + + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + goto next; + + /* + * If we have made it here, the event was valid. + * Lock down the channel. + */ + spin_lock_irqsave(&ch->ch_lock, lock_flags2); + + bs = ch->ch_bs; + + if (!bs) { + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + goto next; + } + + /* + * Process received data. + */ + if (reason & IFDATA) { + + /* + * ALL LOCKS *MUST* BE DROPPED BEFORE CALLING INPUT! + * input could send some data to ld, which in turn + * could do a callback to one of our other functions. + */ + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + + dgap_input(ch); + + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); + + if (ch->ch_flags & CH_RACTIVE) + ch->ch_flags |= CH_RENABLE; + else + writeb(1, &(bs->idata)); + + if (ch->ch_flags & CH_RWAIT) { + ch->ch_flags &= ~CH_RWAIT; + + wake_up_interruptible + (&ch->ch_tun.un_flags_wait); + } + } + + /* + * Process Modem change signals. + */ + if (reason & IFMODEM) { + ch->ch_mistat = modem; + dgap_carrier(ch); + } + + /* + * Process break. + */ + if (reason & IFBREAK) { + + if (ch->ch_tun.un_tty) { + /* A break has been indicated */ + ch->ch_err_break++; + tty_buffer_request_room + (ch->ch_tun.un_tty->port, 1); + tty_insert_flip_char(ch->ch_tun.un_tty->port, + 0, TTY_BREAK); + tty_flip_buffer_push(ch->ch_tun.un_tty->port); + } + } + + /* + * Process Transmit low. + */ + if (reason & IFTLW) { + dgap_write_wakeup(bd, ch, &ch->ch_tun, UN_LOW, + &lock_flags, &lock_flags2); + dgap_write_wakeup(bd, ch, &ch->ch_pun, UN_LOW, + &lock_flags, &lock_flags2); + if (ch->ch_flags & CH_WLOW) { + ch->ch_flags &= ~CH_WLOW; + wake_up_interruptible(&ch->ch_flags_wait); + } + } + + /* + * Process Transmit empty. + */ + if (reason & IFTEM) { + dgap_write_wakeup(bd, ch, &ch->ch_tun, UN_EMPTY, + &lock_flags, &lock_flags2); + dgap_write_wakeup(bd, ch, &ch->ch_pun, UN_EMPTY, + &lock_flags, &lock_flags2); + if (ch->ch_flags & CH_WEMPTY) { + ch->ch_flags &= ~CH_WEMPTY; + wake_up_interruptible(&ch->ch_flags_wait); + } + } + + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + +next: + tail = (tail + 4) & (EVMAX - EVSTART - 4); } - /* If opened device is greater than our number of ports, bail. */ - if (MINOR(tty_devnum(tty)) > brd->nasync) { - spin_unlock_irqrestore(&brd->bd_lock, lock_flags); - return -EIO; + writew(tail, &(eaddr->ev_tail)); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + + return 0; +} + +/* + * Our board poller function. + */ +static void dgap_poll_tasklet(unsigned long data) +{ + struct board_t *bd = (struct board_t *) data; + ulong lock_flags; + char __iomem *vaddr; + u16 head, tail; + + if (!bd || (bd->magic != DGAP_BOARD_MAGIC)) + return; + + if (bd->inhibit_poller) + return; + + spin_lock_irqsave(&bd->bd_lock, lock_flags); + + vaddr = bd->re_map_membase; + + /* + * If board is ready, parse deeper to see if there is anything to do. + */ + if (bd->state == BOARD_READY) { + + struct ev_t __iomem *eaddr; + + if (!bd->re_map_membase) { + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return; + } + if (!bd->re_map_port) { + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return; + } + + if (!bd->nasync) + goto out; + + eaddr = (struct ev_t __iomem *) (vaddr + EVBUF); + + /* Get our head and tail */ + head = readw(&(eaddr->ev_head)); + tail = readw(&(eaddr->ev_tail)); + + /* + * If there is an event pending. Go service it. + */ + if (head != tail) { + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + dgap_event(bd); + spin_lock_irqsave(&bd->bd_lock, lock_flags); + } + +out: + /* + * If board is doing interrupts, ACK the interrupt. + */ + if (bd && bd->intr_running) + readb(bd->re_map_port + 2); + + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return; } - ch = brd->channels[minor]; - if (!ch) { - spin_unlock_irqrestore(&brd->bd_lock, lock_flags); - return -EIO; + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); +} + +/* + * dgap_found_board() + * + * A board has been found, init it. + */ +static struct board_t *dgap_found_board(struct pci_dev *pdev, int id, + int boardnum) +{ + struct board_t *brd; + unsigned int pci_irq; + int i; + int ret; + + /* get the board structure and prep it */ + brd = kzalloc(sizeof(struct board_t), GFP_KERNEL); + if (!brd) + return ERR_PTR(-ENOMEM); + + /* store the info for the board we've found */ + brd->magic = DGAP_BOARD_MAGIC; + brd->boardnum = boardnum; + brd->vendor = dgap_pci_tbl[id].vendor; + brd->device = dgap_pci_tbl[id].device; + brd->pdev = pdev; + brd->pci_bus = pdev->bus->number; + brd->pci_slot = PCI_SLOT(pdev->devfn); + brd->name = dgap_ids[id].name; + brd->maxports = dgap_ids[id].maxports; + brd->type = dgap_ids[id].config_type; + brd->dpatype = dgap_ids[id].dpatype; + brd->dpastatus = BD_NOFEP; + init_waitqueue_head(&brd->state_wait); + + spin_lock_init(&brd->bd_lock); + + brd->inhibit_poller = FALSE; + brd->wait_for_bios = 0; + brd->wait_for_fep = 0; + + for (i = 0; i < MAXPORTS; i++) + brd->channels[i] = NULL; + + /* store which card & revision we have */ + pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &brd->subvendor); + pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &brd->subdevice); + pci_read_config_byte(pdev, PCI_REVISION_ID, &brd->rev); + + pci_irq = pdev->irq; + brd->irq = pci_irq; + + /* get the PCI Base Address Registers */ + + /* Xr Jupiter and EPC use BAR 2 */ + if (brd->device == PCI_DEV_XRJ_DID || brd->device == PCI_DEV_EPCJ_DID) { + brd->membase = pci_resource_start(pdev, 2); + brd->membase_end = pci_resource_end(pdev, 2); + } + /* Everyone else uses BAR 0 */ + else { + brd->membase = pci_resource_start(pdev, 0); + brd->membase_end = pci_resource_end(pdev, 0); } - /* Grab channel lock */ - spin_lock_irqsave(&ch->ch_lock, lock_flags2); + if (!brd->membase) { + ret = -ENODEV; + goto free_brd; + } - /* Figure out our type */ - if (major == brd->dgap_serial_major) { - un = &brd->channels[minor]->ch_tun; - un->un_type = DGAP_SERIAL; - } else if (major == brd->dgap_transparent_print_major) { - un = &brd->channels[minor]->ch_pun; - un->un_type = DGAP_PRINT; + if (brd->membase & 1) + brd->membase &= ~3; + else + brd->membase &= ~15; + + /* + * On the PCI boards, there is no IO space allocated + * The I/O registers will be in the first 3 bytes of the + * upper 2MB of the 4MB memory space. The board memory + * will be mapped into the low 2MB of the 4MB memory space + */ + brd->port = brd->membase + PCI_IO_OFFSET; + brd->port_end = brd->port + PCI_IO_SIZE; + + /* + * Special initialization for non-PLX boards + */ + if (brd->device != PCI_DEV_XRJ_DID && brd->device != PCI_DEV_EPCJ_DID) { + unsigned short cmd; + + pci_write_config_byte(pdev, 0x40, 0); + pci_write_config_byte(pdev, 0x46, 0); + + /* Limit burst length to 2 doubleword transactions */ + pci_write_config_byte(pdev, 0x42, 1); + + /* + * Enable IO and mem if not already done. + * This was needed for support on Itanium. + */ + pci_read_config_word(pdev, PCI_COMMAND, &cmd); + cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY); + pci_write_config_word(pdev, PCI_COMMAND, cmd); + } + + /* init our poll helper tasklet */ + tasklet_init(&brd->helper_tasklet, dgap_poll_tasklet, + (unsigned long) brd); + + ret = dgap_remap(brd); + if (ret) + goto free_brd; + + pr_info("dgap: board %d: %s (rev %d), irq %ld\n", + boardnum, brd->name, brd->rev, brd->irq); + + return brd; + +free_brd: + kfree(brd); + + return ERR_PTR(ret); +} + +/* + * dgap_intr() + * + * Driver interrupt handler. + */ +static irqreturn_t dgap_intr(int irq, void *voidbrd) +{ + struct board_t *brd = voidbrd; + + if (!brd) + return IRQ_NONE; + + /* + * Check to make sure its for us. + */ + if (brd->magic != DGAP_BOARD_MAGIC) + return IRQ_NONE; + + brd->intr_count++; + + /* + * Schedule tasklet to run at a better time. + */ + tasklet_schedule(&brd->helper_tasklet); + return IRQ_HANDLED; +} + +/***************************************************************************** +* +* Function: +* +* dgap_poll_handler +* +* Author: +* +* Scott H Kilau +* +* Parameters: +* +* dummy -- ignored +* +* Return Values: +* +* none +* +* Description: +* +* As each timer expires, it determines (a) whether the "transmit" +* waiter needs to be woken up, and (b) whether the poller needs to +* be rescheduled. +* +******************************************************************************/ + +static void dgap_poll_handler(ulong dummy) +{ + unsigned int i; + struct board_t *brd; + unsigned long lock_flags; + ulong new_time; + + dgap_poll_counter++; + + /* + * Do not start the board state machine until + * driver tells us its up and running, and has + * everything it needs. + */ + if (dgap_driver_state != DRIVER_READY) + goto schedule_poller; + + /* + * If we have just 1 board, or the system is not SMP, + * then use the typical old style poller. + * Otherwise, use our new tasklet based poller, which should + * speed things up for multiple boards. + */ + if ((dgap_numboards == 1) || (num_online_cpus() <= 1)) { + for (i = 0; i < dgap_numboards; i++) { + + brd = dgap_board[i]; + + if (brd->state == BOARD_FAILED) + continue; + if (!brd->intr_running) + /* Call the real board poller directly */ + dgap_poll_tasklet((unsigned long) brd); + } } else { - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&brd->bd_lock, lock_flags); - return -EIO; + /* + * Go thru each board, kicking off a + * tasklet for each if needed + */ + for (i = 0; i < dgap_numboards; i++) { + brd = dgap_board[i]; + + /* + * Attempt to grab the board lock. + * + * If we can't get it, no big deal, the next poll + * will get it. Basically, I just really don't want + * to spin in here, because I want to kick off my + * tasklets as fast as I can, and then get out the + * poller. + */ + if (!spin_trylock(&brd->bd_lock)) + continue; + + /* + * If board is in a failed state, don't bother + * scheduling a tasklet + */ + if (brd->state == BOARD_FAILED) { + spin_unlock(&brd->bd_lock); + continue; + } + + /* Schedule a poll helper task */ + if (!brd->intr_running) + tasklet_schedule(&brd->helper_tasklet); + + /* + * Can't do DGAP_UNLOCK here, as we don't have + * lock_flags because we did a trylock above. + */ + spin_unlock(&brd->bd_lock); + } } - /* Store our unit into driver_data, so we always have it available. */ - tty->driver_data = un; +schedule_poller: /* - * Error if channel info pointer is NULL. + * Schedule ourself back at the nominal wakeup interval. */ - bs = ch->ch_bs; - if (!bs) { - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&brd->bd_lock, lock_flags); - return -EIO; + spin_lock_irqsave(&dgap_poll_lock, lock_flags); + dgap_poll_time += dgap_jiffies_from_ms(dgap_poll_tick); + + new_time = dgap_poll_time - jiffies; + + if ((ulong) new_time >= 2 * dgap_poll_tick) { + dgap_poll_time = + jiffies + dgap_jiffies_from_ms(dgap_poll_tick); + } + + dgap_poll_timer.function = dgap_poll_handler; + dgap_poll_timer.data = 0; + dgap_poll_timer.expires = dgap_poll_time; + spin_unlock_irqrestore(&dgap_poll_lock, lock_flags); + + if (!dgap_poll_stop) + add_timer(&dgap_poll_timer); +} + +/*======================================================================= + * + * dgap_cmdb - Sends a 2 byte command to the FEP. + * + * ch - Pointer to channel structure. + * cmd - Command to be sent. + * byte1 - Integer containing first byte to be sent. + * byte2 - Integer containing second byte to be sent. + * ncmds - Wait until ncmds or fewer cmds are left + * in the cmd buffer before returning. + * + *=======================================================================*/ +static void dgap_cmdb(struct channel_t *ch, u8 cmd, u8 byte1, + u8 byte2, uint ncmds) +{ + char __iomem *vaddr; + struct __iomem cm_t *cm_addr; + uint count; + uint n; + u16 head; + u16 tail; + + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return; + + /* + * Check if board is still alive. + */ + if (ch->ch_bd->state == BOARD_FAILED) + return; + + /* + * Make sure the pointers are in range before + * writing to the FEP memory. + */ + vaddr = ch->ch_bd->re_map_membase; + + if (!vaddr) + return; + + cm_addr = (struct cm_t __iomem *) (vaddr + CMDBUF); + head = readw(&(cm_addr->cm_head)); + + /* + * Forget it if pointers out of range. + */ + if (head >= (CMDMAX - CMDSTART) || (head & 03)) { + ch->ch_bd->state = BOARD_FAILED; + return; } /* - * Initialize tty's + * Put the data in the circular command buffer. */ - if (!(un->un_flags & UN_ISOPEN)) { - /* Store important variables. */ - un->un_tty = tty; + writeb(cmd, (vaddr + head + CMDSTART + 0)); + writeb((u8) ch->ch_portnum, (vaddr + head + CMDSTART + 1)); + writeb(byte1, (vaddr + head + CMDSTART + 2)); + writeb(byte2, (vaddr + head + CMDSTART + 3)); - /* Maybe do something here to the TTY struct as well? */ + head = (head + 4) & (CMDMAX - CMDSTART - 4); + + writew(head, &(cm_addr->cm_head)); + + /* + * Wait if necessary before updating the head + * pointer to limit the number of outstanding + * commands to the FEP. If the time spent waiting + * is outlandish, declare the FEP dead. + */ + for (count = dgap_count ;;) { + + head = readw(&(cm_addr->cm_head)); + tail = readw(&(cm_addr->cm_tail)); + + n = (head - tail) & (CMDMAX - CMDSTART - 4); + + if (n <= ncmds * sizeof(struct cm_t)) + break; + + if (--count == 0) { + ch->ch_bd->state = BOARD_FAILED; + return; + } + udelay(10); } +} + +/*======================================================================= + * + * dgap_cmdw - Sends a 1 word command to the FEP. + * + * ch - Pointer to channel structure. + * cmd - Command to be sent. + * word - Integer containing word to be sent. + * ncmds - Wait until ncmds or fewer cmds are left + * in the cmd buffer before returning. + * + *=======================================================================*/ +static void dgap_cmdw(struct channel_t *ch, u8 cmd, u16 word, uint ncmds) +{ + char __iomem *vaddr; + struct __iomem cm_t *cm_addr; + uint count; + uint n; + u16 head; + u16 tail; + + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return; /* - * Initialize if neither terminal or printer is open. + * Check if board is still alive. */ - if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & UN_ISOPEN)) { + if (ch->ch_bd->state == BOARD_FAILED) + return; - ch->ch_mforce = 0; - ch->ch_mval = 0; + /* + * Make sure the pointers are in range before + * writing to the FEP memory. + */ + vaddr = ch->ch_bd->re_map_membase; + if (!vaddr) + return; + + cm_addr = (struct cm_t __iomem *) (vaddr + CMDBUF); + head = readw(&(cm_addr->cm_head)); + + /* + * Forget it if pointers out of range. + */ + if (head >= (CMDMAX - CMDSTART) || (head & 03)) { + ch->ch_bd->state = BOARD_FAILED; + return; + } + + /* + * Put the data in the circular command buffer. + */ + writeb(cmd, (vaddr + head + CMDSTART + 0)); + writeb((u8) ch->ch_portnum, (vaddr + head + CMDSTART + 1)); + writew((u16) word, (vaddr + head + CMDSTART + 2)); + + head = (head + 4) & (CMDMAX - CMDSTART - 4); + + writew(head, &(cm_addr->cm_head)); + + /* + * Wait if necessary before updating the head + * pointer to limit the number of outstanding + * commands to the FEP. If the time spent waiting + * is outlandish, declare the FEP dead. + */ + for (count = dgap_count ;;) { + + head = readw(&(cm_addr->cm_head)); + tail = readw(&(cm_addr->cm_tail)); + + n = (head - tail) & (CMDMAX - CMDSTART - 4); + + if (n <= ncmds * sizeof(struct cm_t)) + break; + + if (--count == 0) { + ch->ch_bd->state = BOARD_FAILED; + return; + } + udelay(10); + } +} + +/*======================================================================= + * + * dgap_cmdw_ext - Sends a extended word command to the FEP. + * + * ch - Pointer to channel structure. + * cmd - Command to be sent. + * word - Integer containing word to be sent. + * ncmds - Wait until ncmds or fewer cmds are left + * in the cmd buffer before returning. + * + *=======================================================================*/ +static void dgap_cmdw_ext(struct channel_t *ch, u16 cmd, u16 word, uint ncmds) +{ + char __iomem *vaddr; + struct __iomem cm_t *cm_addr; + uint count; + uint n; + u16 head; + u16 tail; + + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return; + + /* + * Check if board is still alive. + */ + if (ch->ch_bd->state == BOARD_FAILED) + return; + + /* + * Make sure the pointers are in range before + * writing to the FEP memory. + */ + vaddr = ch->ch_bd->re_map_membase; + if (!vaddr) + return; + + cm_addr = (struct cm_t __iomem *) (vaddr + CMDBUF); + head = readw(&(cm_addr->cm_head)); + + /* + * Forget it if pointers out of range. + */ + if (head >= (CMDMAX - CMDSTART) || (head & 03)) { + ch->ch_bd->state = BOARD_FAILED; + return; + } + + /* + * Put the data in the circular command buffer. + */ + + /* Write an FF to tell the FEP that we want an extended command */ + writeb((u8) 0xff, (vaddr + head + CMDSTART + 0)); + + writeb((u8) ch->ch_portnum, (vaddr + head + CMDSTART + 1)); + writew((u16) cmd, (vaddr + head + CMDSTART + 2)); + + /* + * If the second part of the command won't fit, + * put it at the beginning of the circular buffer. + */ + if (((head + 4) >= ((CMDMAX - CMDSTART)) || (head & 03))) + writew((u16) word, (vaddr + CMDSTART)); + else + writew((u16) word, (vaddr + head + CMDSTART + 4)); + + head = (head + 8) & (CMDMAX - CMDSTART - 4); + + writew(head, &(cm_addr->cm_head)); + + /* + * Wait if necessary before updating the head + * pointer to limit the number of outstanding + * commands to the FEP. If the time spent waiting + * is outlandish, declare the FEP dead. + */ + for (count = dgap_count ;;) { + + head = readw(&(cm_addr->cm_head)); + tail = readw(&(cm_addr->cm_tail)); + + n = (head - tail) & (CMDMAX - CMDSTART - 4); + + if (n <= ncmds * sizeof(struct cm_t)) + break; + + if (--count == 0) { + ch->ch_bd->state = BOARD_FAILED; + return; + } + udelay(10); + } +} + +/*======================================================================= + * + * dgap_wmove - Write data to FEP buffer. + * + * ch - Pointer to channel structure. + * buf - Poiter to characters to be moved. + * cnt - Number of characters to move. + * + *=======================================================================*/ +static void dgap_wmove(struct channel_t *ch, char *buf, uint cnt) +{ + int n; + char __iomem *taddr; + struct bs_t __iomem *bs; + u16 head; + + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return; + + /* + * Check parameters. + */ + bs = ch->ch_bs; + head = readw(&(bs->tx_head)); + + /* + * If pointers are out of range, just return. + */ + if ((cnt > ch->ch_tsize) || + (unsigned)(head - ch->ch_tstart) >= ch->ch_tsize) + return; + + /* + * If the write wraps over the top of the circular buffer, + * move the portion up to the wrap point, and reset the + * pointers to the bottom. + */ + n = ch->ch_tstart + ch->ch_tsize - head; + + if (cnt >= n) { + cnt -= n; + taddr = ch->ch_taddr + head; + memcpy_toio(taddr, buf, n); + head = ch->ch_tstart; + buf += n; + } + + /* + * Move rest of data. + */ + taddr = ch->ch_taddr + head; + n = cnt; + memcpy_toio(taddr, buf, n); + head += cnt; + + writew(head, &(bs->tx_head)); +} + +/* + * Calls the firmware to reset this channel. + */ +static void dgap_firmware_reset_port(struct channel_t *ch) +{ + dgap_cmdb(ch, CHRESET, 0, 0, 0); + + /* + * Now that the channel is reset, we need to make sure + * all the current settings get reapplied to the port + * in the firmware. + * + * So we will set the driver's cache of firmware + * settings all to 0, and then call param. + */ + ch->ch_fepiflag = 0; + ch->ch_fepcflag = 0; + ch->ch_fepoflag = 0; + ch->ch_fepstartc = 0; + ch->ch_fepstopc = 0; + ch->ch_fepastartc = 0; + ch->ch_fepastopc = 0; + ch->ch_mostat = 0; + ch->ch_hflow = 0; +} + +/*======================================================================= + * + * dgap_param - Set Digi parameters. + * + * struct tty_struct * - TTY for port. + * + *=======================================================================*/ +static int dgap_param(struct channel_t *ch, struct board_t *bd, u32 un_type) +{ + u16 head; + u16 cflag; + u16 iflag; + u8 mval; + u8 hflow; + + /* + * If baud rate is zero, flush queues, and set mval to drop DTR. + */ + if ((ch->ch_c_cflag & (CBAUD)) == 0) { + + /* flush rx */ + head = readw(&(ch->ch_bs->rx_head)); + writew(head, &(ch->ch_bs->rx_tail)); + + /* flush tx */ + head = readw(&(ch->ch_bs->tx_head)); + writew(head, &(ch->ch_bs->tx_tail)); + ch->ch_flags |= (CH_BAUD0); + + /* Drop RTS and DTR */ + ch->ch_mval &= ~(D_RTS(ch)|D_DTR(ch)); + mval = D_DTR(ch) | D_RTS(ch); + ch->ch_baud_info = 0; + + } else if (ch->ch_custom_speed && (bd->bd_flags & BD_FEP5PLUS)) { /* - * Flush input queue. + * Tell the fep to do the command */ - head = readw(&(bs->rx_head)); - writew(head, &(bs->rx_tail)); - ch->ch_flags = 0; - ch->pscan_state = 0; - ch->pscan_savechar = 0; + dgap_cmdw_ext(ch, 0xff01, ch->ch_custom_speed, 0); - ch->ch_c_cflag = tty->termios.c_cflag; - ch->ch_c_iflag = tty->termios.c_iflag; - ch->ch_c_oflag = tty->termios.c_oflag; - ch->ch_c_lflag = tty->termios.c_lflag; - ch->ch_startc = tty->termios.c_cc[VSTART]; - ch->ch_stopc = tty->termios.c_cc[VSTOP]; + /* + * Now go get from fep mem, what the fep + * believes the custom baud rate is. + */ + ch->ch_custom_speed = dgap_get_custom_baud(ch); + ch->ch_baud_info = ch->ch_custom_speed; - /* TODO: flush our TTY struct here? */ + /* Handle transition from B0 */ + if (ch->ch_flags & CH_BAUD0) { + ch->ch_flags &= ~(CH_BAUD0); + ch->ch_mval |= (D_RTS(ch)|D_DTR(ch)); + } + mval = D_DTR(ch) | D_RTS(ch); + + } else { + /* + * Set baud rate, character size, and parity. + */ + + + int iindex = 0; + int jindex = 0; + int baud = 0; + + ulong bauds[4][16] = { + { /* slowbaud */ + 0, 50, 75, 110, + 134, 150, 200, 300, + 600, 1200, 1800, 2400, + 4800, 9600, 19200, 38400 }, + { /* slowbaud & CBAUDEX */ + 0, 57600, 115200, 230400, + 460800, 150, 200, 921600, + 600, 1200, 1800, 2400, + 4800, 9600, 19200, 38400 }, + { /* fastbaud */ + 0, 57600, 76800, 115200, + 14400, 57600, 230400, 76800, + 115200, 230400, 28800, 460800, + 921600, 9600, 19200, 38400 }, + { /* fastbaud & CBAUDEX */ + 0, 57600, 115200, 230400, + 460800, 150, 200, 921600, + 600, 1200, 1800, 2400, + 4800, 9600, 19200, 38400 } + }; + + /* + * Only use the TXPrint baud rate if the + * terminal unit is NOT open + */ + if (!(ch->ch_tun.un_flags & UN_ISOPEN) && + un_type == DGAP_PRINT) + baud = C_BAUD(ch->ch_pun.un_tty) & 0xff; + else + baud = C_BAUD(ch->ch_tun.un_tty) & 0xff; + + if (ch->ch_c_cflag & CBAUDEX) + iindex = 1; + + if (ch->ch_digi.digi_flags & DIGI_FAST) + iindex += 2; + + jindex = baud; + + if ((iindex >= 0) && (iindex < 4) && + (jindex >= 0) && (jindex < 16)) + baud = bauds[iindex][jindex]; + else + baud = 0; + + if (baud == 0) + baud = 9600; + + ch->ch_baud_info = baud; + + /* + * CBAUD has bit position 0x1000 set these days to + * indicate Linux baud rate remap. + * We use a different bit assignment for high speed. + * Clear this bit out while grabbing the parts of + * "cflag" we want. + */ + cflag = ch->ch_c_cflag & ((CBAUD ^ CBAUDEX) | PARODD | PARENB | + CSTOPB | CSIZE); + + /* + * HUPCL bit is used by FEP to indicate fast baud + * table is to be used. + */ + if ((ch->ch_digi.digi_flags & DIGI_FAST) || + (ch->ch_c_cflag & CBAUDEX)) + cflag |= HUPCL; + + if ((ch->ch_c_cflag & CBAUDEX) && + !(ch->ch_digi.digi_flags & DIGI_FAST)) { + /* + * The below code is trying to guarantee that only + * baud rates 115200, 230400, 460800, 921600 are + * remapped. We use exclusive or because the various + * baud rates share common bit positions and therefore + * can't be tested for easily. + */ + tcflag_t tcflag = (ch->ch_c_cflag & CBAUD) | CBAUDEX; + int baudpart = 0; + + /* + * Map high speed requests to index + * into FEP's baud table + */ + switch (tcflag) { + case B57600: + baudpart = 1; + break; +#ifdef B76800 + case B76800: + baudpart = 2; + break; +#endif + case B115200: + baudpart = 3; + break; + case B230400: + baudpart = 9; + break; + case B460800: + baudpart = 11; + break; +#ifdef B921600 + case B921600: + baudpart = 12; + break; +#endif + default: + baudpart = 0; + } + + if (baudpart) + cflag = (cflag & ~(CBAUD | CBAUDEX)) | baudpart; + } + + cflag &= 0xffff; + + if (cflag != ch->ch_fepcflag) { + ch->ch_fepcflag = (u16) (cflag & 0xffff); + + /* + * Okay to have channel and board + * locks held calling this + */ + dgap_cmdw(ch, SCFLAG, (u16) cflag, 0); + } + + /* Handle transition from B0 */ + if (ch->ch_flags & CH_BAUD0) { + ch->ch_flags &= ~(CH_BAUD0); + ch->ch_mval |= (D_RTS(ch)|D_DTR(ch)); + } + mval = D_DTR(ch) | D_RTS(ch); } - dgap_carrier(ch); /* - * Run param in case we changed anything + * Get input flags. */ - dgap_param(ch, brd, un->un_type); + iflag = ch->ch_c_iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK | + INPCK | ISTRIP | IXON | IXANY | IXOFF); + + if ((ch->ch_startc == _POSIX_VDISABLE) || + (ch->ch_stopc == _POSIX_VDISABLE)) { + iflag &= ~(IXON | IXOFF); + ch->ch_c_iflag &= ~(IXON | IXOFF); + } /* - * follow protocol for opening port + * Only the IBM Xr card can switch between + * 232 and 422 modes on the fly + */ + if (bd->device == PCI_DEV_XR_IBM_DID) { + if (ch->ch_digi.digi_flags & DIGI_422) + dgap_cmdb(ch, SCOMMODE, MODE_422, 0, 0); + else + dgap_cmdb(ch, SCOMMODE, MODE_232, 0, 0); + } + + if (ch->ch_digi.digi_flags & DIGI_ALTPIN) + iflag |= IALTPIN; + + if (iflag != ch->ch_fepiflag) { + ch->ch_fepiflag = iflag; + + /* Okay to have channel and board locks held calling this */ + dgap_cmdw(ch, SIFLAG, (u16) ch->ch_fepiflag, 0); + } + + /* + * Select hardware handshaking. */ + hflow = 0; - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&brd->bd_lock, lock_flags); + if (ch->ch_c_cflag & CRTSCTS) + hflow |= (D_RTS(ch) | D_CTS(ch)); + if (ch->ch_digi.digi_flags & RTSPACE) + hflow |= D_RTS(ch); + if (ch->ch_digi.digi_flags & DTRPACE) + hflow |= D_DTR(ch); + if (ch->ch_digi.digi_flags & CTSPACE) + hflow |= D_CTS(ch); + if (ch->ch_digi.digi_flags & DSRPACE) + hflow |= D_DSR(ch); + if (ch->ch_digi.digi_flags & DCDPACE) + hflow |= D_CD(ch); - rc = dgap_block_til_ready(tty, file, ch); + if (hflow != ch->ch_hflow) { + ch->ch_hflow = hflow; - if (!un->un_tty) - return -ENODEV; + /* Okay to have channel and board locks held calling this */ + dgap_cmdb(ch, SHFLOW, (u8) hflow, 0xff, 0); + } - /* No going back now, increment our unit and channel counters */ - spin_lock_irqsave(&ch->ch_lock, lock_flags); - ch->ch_open_count++; - un->un_open_count++; - un->un_flags |= (UN_ISOPEN); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags); + /* + * Set RTS and/or DTR Toggle if needed, + * but only if product is FEP5+ based. + */ + if (bd->bd_flags & BD_FEP5PLUS) { + u16 hflow2 = 0; - return rc; + if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) + hflow2 |= (D_RTS(ch)); + if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) + hflow2 |= (D_DTR(ch)); + + dgap_cmdw_ext(ch, 0xff03, hflow2, 0); + } + + /* + * Set modem control lines. + */ + + mval ^= ch->ch_mforce & (mval ^ ch->ch_mval); + + if (ch->ch_mostat ^ mval) { + ch->ch_mostat = mval; + + /* Okay to have channel and board locks held calling this */ + dgap_cmdb(ch, SMODEM, (u8) mval, D_RTS(ch)|D_DTR(ch), 0); + } + + /* + * Read modem signals, and then call carrier function. + */ + ch->ch_mistat = readb(&(ch->ch_bs->m_stat)); + dgap_carrier(ch); + + /* + * Set the start and stop characters. + */ + if (ch->ch_startc != ch->ch_fepstartc || + ch->ch_stopc != ch->ch_fepstopc) { + ch->ch_fepstartc = ch->ch_startc; + ch->ch_fepstopc = ch->ch_stopc; + + /* Okay to have channel and board locks held calling this */ + dgap_cmdb(ch, SFLOWC, ch->ch_fepstartc, ch->ch_fepstopc, 0); + } + + /* + * Set the Auxiliary start and stop characters. + */ + if (ch->ch_astartc != ch->ch_fepastartc || + ch->ch_astopc != ch->ch_fepastopc) { + ch->ch_fepastartc = ch->ch_astartc; + ch->ch_fepastopc = ch->ch_astopc; + + /* Okay to have channel and board locks held calling this */ + dgap_cmdb(ch, SAFLOWC, ch->ch_fepastartc, ch->ch_fepastopc, 0); + } + + return 0; } /* @@ -2143,15 +3193,18 @@ static int dgap_block_til_ready(struct tty_struct *tty, struct file *file, } /* - * dgap_tty_hangup() + * dgap_tty_flush_buffer() * - * Hangup the port. Like a close, but don't wait for output to drain. + * Flush Tx buffer (make in == out) */ -static void dgap_tty_hangup(struct tty_struct *tty) +static void dgap_tty_flush_buffer(struct tty_struct *tty) { struct board_t *bd; struct channel_t *ch; struct un_t *un; + ulong lock_flags; + ulong lock_flags2; + u16 head; if (!tty || tty->magic != TTY_MAGIC) return; @@ -2168,21 +3221,39 @@ static void dgap_tty_hangup(struct tty_struct *tty) if (!bd || bd->magic != DGAP_BOARD_MAGIC) return; - /* flush the transmit queues */ - dgap_tty_flush_buffer(tty); + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); + + ch->ch_flags &= ~CH_STOP; + head = readw(&(ch->ch_bs->tx_head)); + dgap_cmdw(ch, FLUSHTX, (u16) head, 0); + dgap_cmdw(ch, RESUMETX, 0, 0); + if (ch->ch_tun.un_flags & (UN_LOW|UN_EMPTY)) { + ch->ch_tun.un_flags &= ~(UN_LOW|UN_EMPTY); + wake_up_interruptible(&ch->ch_tun.un_flags_wait); + } + if (ch->ch_pun.un_flags & (UN_LOW|UN_EMPTY)) { + ch->ch_pun.un_flags &= ~(UN_LOW|UN_EMPTY); + wake_up_interruptible(&ch->ch_pun.un_flags_wait); + } + + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + if (waitqueue_active(&tty->write_wait)) + wake_up_interruptible(&tty->write_wait); + tty_wakeup(tty); } /* - * dgap_tty_close() + * dgap_tty_hangup() * + * Hangup the port. Like a close, but don't wait for output to drain. */ -static void dgap_tty_close(struct tty_struct *tty, struct file *file) +static void dgap_tty_hangup(struct tty_struct *tty) { - struct ktermios *ts; struct board_t *bd; struct channel_t *ch; struct un_t *un; - ulong lock_flags; if (!tty || tty->magic != TTY_MAGIC) return; @@ -2199,107 +3270,8 @@ static void dgap_tty_close(struct tty_struct *tty, struct file *file) if (!bd || bd->magic != DGAP_BOARD_MAGIC) return; - ts = &tty->termios; - - spin_lock_irqsave(&ch->ch_lock, lock_flags); - - /* - * Determine if this is the last close or not - and if we agree about - * which type of close it is with the Line Discipline - */ - if ((tty->count == 1) && (un->un_open_count != 1)) { - /* - * Uh, oh. tty->count is 1, which means that the tty - * structure will be freed. un_open_count should always - * be one in these conditions. If it's greater than - * one, we've got real problems, since it means the - * serial port won't be shutdown. - */ - un->un_open_count = 1; - } - - if (--un->un_open_count < 0) - un->un_open_count = 0; - - ch->ch_open_count--; - - if (ch->ch_open_count && un->un_open_count) { - spin_unlock_irqrestore(&ch->ch_lock, lock_flags); - return; - } - - /* OK, its the last close on the unit */ - - un->un_flags |= UN_CLOSING; - - tty->closing = 1; - - /* - * Only officially close channel if count is 0 and - * DIGI_PRINTER bit is not set. - */ - if ((ch->ch_open_count == 0) && - !(ch->ch_digi.digi_flags & DIGI_PRINTER)) { - - ch->ch_flags &= ~(CH_RXBLOCK); - - spin_unlock_irqrestore(&ch->ch_lock, lock_flags); - - /* wait for output to drain */ - /* This will also return if we take an interrupt */ - - dgap_wait_for_drain(tty); - - dgap_tty_flush_buffer(tty); - tty_ldisc_flush(tty); - - spin_lock_irqsave(&ch->ch_lock, lock_flags); - - tty->closing = 0; - - /* - * If we have HUPCL set, lower DTR and RTS - */ - if (ch->ch_c_cflag & HUPCL) { - ch->ch_mostat &= ~(D_RTS(ch)|D_DTR(ch)); - dgap_cmdb(ch, SMODEM, 0, D_DTR(ch)|D_RTS(ch), 0); - - /* - * Go to sleep to ensure RTS/DTR - * have been dropped for modems to see it. - */ - spin_unlock_irqrestore(&ch->ch_lock, - lock_flags); - - /* .25 second delay for dropping RTS/DTR */ - schedule_timeout_interruptible(msecs_to_jiffies(250)); - - spin_lock_irqsave(&ch->ch_lock, lock_flags); - } - - ch->pscan_state = 0; - ch->pscan_savechar = 0; - ch->ch_baud_info = 0; - - } - - /* - * turn off print device when closing print device. - */ - if ((un->un_type == DGAP_PRINT) && (ch->ch_flags & CH_PRON)) { - dgap_wmove(ch, ch->ch_digi.digi_offstr, - (int) ch->ch_digi.digi_offlen); - ch->ch_flags &= ~CH_PRON; - } - - un->un_tty = NULL; - un->un_flags &= ~(UN_ISOPEN | UN_CLOSING); - tty->driver_data = NULL; - - wake_up_interruptible(&ch->ch_flags_wait); - wake_up_interruptible(&un->un_flags_wait); - - spin_unlock_irqrestore(&ch->ch_lock, lock_flags); + /* flush the transmit queues */ + dgap_tty_flush_buffer(tty); } /* @@ -2599,22 +3571,6 @@ static int dgap_tty_write_room(struct tty_struct *tty) } /* - * dgap_tty_put_char() - * - * Put a character into ch->ch_buf - * - * - used by the line discipline for OPOST processing - */ -static int dgap_tty_put_char(struct tty_struct *tty, unsigned char c) -{ - /* - * Simply call tty_write. - */ - dgap_tty_write(tty, &c, 1); - return 1; -} - -/* * dgap_tty_write() * * Take data from the user or kernel and send it out to the FEP. @@ -2629,7 +3585,6 @@ static int dgap_tty_write(struct tty_struct *tty, const unsigned char *buf, char __iomem *vaddr; u16 head, tail, tmask, remain; int bufcount, n; - int orig_count; ulong lock_flags; if (!tty) @@ -2650,13 +3605,6 @@ static int dgap_tty_write(struct tty_struct *tty, const unsigned char *buf, if (!count) return 0; - /* - * Store original amount of characters passed in. - * This helps to figure out if we should ask the FEP - * to send us an event when it has more space available. - */ - orig_count = count; - spin_lock_irqsave(&ch->ch_lock, lock_flags); /* Get our space available for the channel from the board */ @@ -2784,6 +3732,22 @@ static int dgap_tty_write(struct tty_struct *tty, const unsigned char *buf, } /* + * dgap_tty_put_char() + * + * Put a character into ch->ch_buf + * + * - used by the line discipline for OPOST processing + */ +static int dgap_tty_put_char(struct tty_struct *tty, unsigned char c) +{ + /* + * Simply call tty_write. + */ + dgap_tty_write(tty, &c, 1); + return 1; +} + +/* * Return modem signals to ld. */ static int dgap_tty_tiocmget(struct tty_struct *tty) @@ -3444,13 +4408,189 @@ static void dgap_tty_unthrottle(struct tty_struct *tty) spin_unlock_irqrestore(&bd->bd_lock, lock_flags); } -static void dgap_tty_start(struct tty_struct *tty) +static struct board_t *find_board_by_major(unsigned int major) { - struct board_t *bd; + unsigned int i; + + for (i = 0; i < MAXBOARDS; i++) { + struct board_t *brd = dgap_board[i]; + + if (!brd) + return NULL; + if (major == brd->serial_driver->major || + major == brd->print_driver->major) + return brd; + } + + return NULL; +} + +/************************************************************************ + * + * TTY Entry points and helper functions + * + ************************************************************************/ + +/* + * dgap_tty_open() + * + */ +static int dgap_tty_open(struct tty_struct *tty, struct file *file) +{ + struct board_t *brd; struct channel_t *ch; struct un_t *un; + struct bs_t __iomem *bs; + uint major; + uint minor; + int rc; ulong lock_flags; ulong lock_flags2; + u16 head; + + major = MAJOR(tty_devnum(tty)); + minor = MINOR(tty_devnum(tty)); + + brd = find_board_by_major(major); + if (!brd) + return -EIO; + + /* + * If board is not yet up to a state of READY, go to + * sleep waiting for it to happen or they cancel the open. + */ + rc = wait_event_interruptible(brd->state_wait, + (brd->state & BOARD_READY)); + + if (rc) + return rc; + + spin_lock_irqsave(&brd->bd_lock, lock_flags); + + /* The wait above should guarantee this cannot happen */ + if (brd->state != BOARD_READY) { + spin_unlock_irqrestore(&brd->bd_lock, lock_flags); + return -EIO; + } + + /* If opened device is greater than our number of ports, bail. */ + if (MINOR(tty_devnum(tty)) > brd->nasync) { + spin_unlock_irqrestore(&brd->bd_lock, lock_flags); + return -EIO; + } + + ch = brd->channels[minor]; + if (!ch) { + spin_unlock_irqrestore(&brd->bd_lock, lock_flags); + return -EIO; + } + + /* Grab channel lock */ + spin_lock_irqsave(&ch->ch_lock, lock_flags2); + + /* Figure out our type */ + if (major == brd->serial_driver->major) { + un = &brd->channels[minor]->ch_tun; + un->un_type = DGAP_SERIAL; + } else if (major == brd->print_driver->major) { + un = &brd->channels[minor]->ch_pun; + un->un_type = DGAP_PRINT; + } else { + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&brd->bd_lock, lock_flags); + return -EIO; + } + + /* Store our unit into driver_data, so we always have it available. */ + tty->driver_data = un; + + /* + * Error if channel info pointer is NULL. + */ + bs = ch->ch_bs; + if (!bs) { + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&brd->bd_lock, lock_flags); + return -EIO; + } + + /* + * Initialize tty's + */ + if (!(un->un_flags & UN_ISOPEN)) { + /* Store important variables. */ + un->un_tty = tty; + + /* Maybe do something here to the TTY struct as well? */ + } + + /* + * Initialize if neither terminal or printer is open. + */ + if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & UN_ISOPEN)) { + + ch->ch_mforce = 0; + ch->ch_mval = 0; + + /* + * Flush input queue. + */ + head = readw(&(bs->rx_head)); + writew(head, &(bs->rx_tail)); + + ch->ch_flags = 0; + ch->pscan_state = 0; + ch->pscan_savechar = 0; + + ch->ch_c_cflag = tty->termios.c_cflag; + ch->ch_c_iflag = tty->termios.c_iflag; + ch->ch_c_oflag = tty->termios.c_oflag; + ch->ch_c_lflag = tty->termios.c_lflag; + ch->ch_startc = tty->termios.c_cc[VSTART]; + ch->ch_stopc = tty->termios.c_cc[VSTOP]; + + /* TODO: flush our TTY struct here? */ + } + + dgap_carrier(ch); + /* + * Run param in case we changed anything + */ + dgap_param(ch, brd, un->un_type); + + /* + * follow protocol for opening port + */ + + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&brd->bd_lock, lock_flags); + + rc = dgap_block_til_ready(tty, file, ch); + + if (!un->un_tty) + return -ENODEV; + + /* No going back now, increment our unit and channel counters */ + spin_lock_irqsave(&ch->ch_lock, lock_flags); + ch->ch_open_count++; + un->un_open_count++; + un->un_flags |= (UN_ISOPEN); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); + + return rc; +} + +/* + * dgap_tty_close() + * + */ +static void dgap_tty_close(struct tty_struct *tty, struct file *file) +{ + struct ktermios *ts; + struct board_t *bd; + struct channel_t *ch; + struct un_t *un; + ulong lock_flags; if (!tty || tty->magic != TTY_MAGIC) return; @@ -3467,16 +4607,110 @@ static void dgap_tty_start(struct tty_struct *tty) if (!bd || bd->magic != DGAP_BOARD_MAGIC) return; - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); + ts = &tty->termios; - dgap_cmdw(ch, RESUMETX, 0, 0); + spin_lock_irqsave(&ch->ch_lock, lock_flags); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + /* + * Determine if this is the last close or not - and if we agree about + * which type of close it is with the Line Discipline + */ + if ((tty->count == 1) && (un->un_open_count != 1)) { + /* + * Uh, oh. tty->count is 1, which means that the tty + * structure will be freed. un_open_count should always + * be one in these conditions. If it's greater than + * one, we've got real problems, since it means the + * serial port won't be shutdown. + */ + un->un_open_count = 1; + } + + if (--un->un_open_count < 0) + un->un_open_count = 0; + + ch->ch_open_count--; + + if (ch->ch_open_count && un->un_open_count) { + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); + return; + } + + /* OK, its the last close on the unit */ + + un->un_flags |= UN_CLOSING; + + tty->closing = 1; + + /* + * Only officially close channel if count is 0 and + * DIGI_PRINTER bit is not set. + */ + if ((ch->ch_open_count == 0) && + !(ch->ch_digi.digi_flags & DIGI_PRINTER)) { + + ch->ch_flags &= ~(CH_RXBLOCK); + + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); + + /* wait for output to drain */ + /* This will also return if we take an interrupt */ + + dgap_wait_for_drain(tty); + + dgap_tty_flush_buffer(tty); + tty_ldisc_flush(tty); + + spin_lock_irqsave(&ch->ch_lock, lock_flags); + + tty->closing = 0; + + /* + * If we have HUPCL set, lower DTR and RTS + */ + if (ch->ch_c_cflag & HUPCL) { + ch->ch_mostat &= ~(D_RTS(ch)|D_DTR(ch)); + dgap_cmdb(ch, SMODEM, 0, D_DTR(ch)|D_RTS(ch), 0); + + /* + * Go to sleep to ensure RTS/DTR + * have been dropped for modems to see it. + */ + spin_unlock_irqrestore(&ch->ch_lock, + lock_flags); + + /* .25 second delay for dropping RTS/DTR */ + schedule_timeout_interruptible(msecs_to_jiffies(250)); + + spin_lock_irqsave(&ch->ch_lock, lock_flags); + } + + ch->pscan_state = 0; + ch->pscan_savechar = 0; + ch->ch_baud_info = 0; + + } + + /* + * turn off print device when closing print device. + */ + if ((un->un_type == DGAP_PRINT) && (ch->ch_flags & CH_PRON)) { + dgap_wmove(ch, ch->ch_digi.digi_offstr, + (int) ch->ch_digi.digi_offlen); + ch->ch_flags &= ~CH_PRON; + } + + un->un_tty = NULL; + un->un_flags &= ~(UN_ISOPEN | UN_CLOSING); + tty->driver_data = NULL; + + wake_up_interruptible(&ch->ch_flags_wait); + wake_up_interruptible(&un->un_flags_wait); + + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); } -static void dgap_tty_stop(struct tty_struct *tty) +static void dgap_tty_start(struct tty_struct *tty) { struct board_t *bd; struct channel_t *ch; @@ -3502,26 +4736,13 @@ static void dgap_tty_stop(struct tty_struct *tty) spin_lock_irqsave(&bd->bd_lock, lock_flags); spin_lock_irqsave(&ch->ch_lock, lock_flags2); - dgap_cmdw(ch, PAUSETX, 0, 0); + dgap_cmdw(ch, RESUMETX, 0, 0); spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); spin_unlock_irqrestore(&bd->bd_lock, lock_flags); } -/* - * dgap_tty_flush_chars() - * - * Flush the cook buffer - * - * Note to self, and any other poor souls who venture here: - * - * flush in this case DOES NOT mean dispose of the data. - * instead, it means "stop buffering and send it if you - * haven't already." Just guess how I figured that out... SRW 2-Jun-98 - * - * It is also always called in interrupt context - JAR 8-Sept-99 - */ -static void dgap_tty_flush_chars(struct tty_struct *tty) +static void dgap_tty_stop(struct tty_struct *tty) { struct board_t *bd; struct channel_t *ch; @@ -3547,25 +4768,32 @@ static void dgap_tty_flush_chars(struct tty_struct *tty) spin_lock_irqsave(&bd->bd_lock, lock_flags); spin_lock_irqsave(&ch->ch_lock, lock_flags2); - /* TODO: Do something here */ + dgap_cmdw(ch, PAUSETX, 0, 0); spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); spin_unlock_irqrestore(&bd->bd_lock, lock_flags); } /* - * dgap_tty_flush_buffer() + * dgap_tty_flush_chars() * - * Flush Tx buffer (make in == out) + * Flush the cook buffer + * + * Note to self, and any other poor souls who venture here: + * + * flush in this case DOES NOT mean dispose of the data. + * instead, it means "stop buffering and send it if you + * haven't already." Just guess how I figured that out... SRW 2-Jun-98 + * + * It is also always called in interrupt context - JAR 8-Sept-99 */ -static void dgap_tty_flush_buffer(struct tty_struct *tty) +static void dgap_tty_flush_chars(struct tty_struct *tty) { struct board_t *bd; struct channel_t *ch; struct un_t *un; ulong lock_flags; ulong lock_flags2; - u16 head; if (!tty || tty->magic != TTY_MAGIC) return; @@ -3585,24 +4813,10 @@ static void dgap_tty_flush_buffer(struct tty_struct *tty) spin_lock_irqsave(&bd->bd_lock, lock_flags); spin_lock_irqsave(&ch->ch_lock, lock_flags2); - ch->ch_flags &= ~CH_STOP; - head = readw(&(ch->ch_bs->tx_head)); - dgap_cmdw(ch, FLUSHTX, (u16) head, 0); - dgap_cmdw(ch, RESUMETX, 0, 0); - if (ch->ch_tun.un_flags & (UN_LOW|UN_EMPTY)) { - ch->ch_tun.un_flags &= ~(UN_LOW|UN_EMPTY); - wake_up_interruptible(&ch->ch_tun.un_flags_wait); - } - if (ch->ch_pun.un_flags & (UN_LOW|UN_EMPTY)) { - ch->ch_pun.un_flags &= ~(UN_LOW|UN_EMPTY); - wake_up_interruptible(&ch->ch_pun.un_flags_wait); - } + /* TODO: Do something here */ spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - if (waitqueue_active(&tty->write_wait)) - wake_up_interruptible(&tty->write_wait); - tty_wakeup(tty); } /***************************************************************************** @@ -3996,1614 +5210,151 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd, } } -static int dgap_alloc_flipbuf(struct board_t *brd) -{ - /* - * allocate flip buffer for board. - */ - brd->flipbuf = kmalloc(MYFLIPLEN, GFP_KERNEL); - if (!brd->flipbuf) - return -ENOMEM; - - brd->flipflagbuf = kmalloc(MYFLIPLEN, GFP_KERNEL); - if (!brd->flipflagbuf) { - kfree(brd->flipbuf); - return -ENOMEM; - } - - return 0; -} - -static void dgap_free_flipbuf(struct board_t *brd) -{ - kfree(brd->flipbuf); - kfree(brd->flipflagbuf); -} - -/* - * Create pr and tty device entries - */ -static int dgap_tty_register_ports(struct board_t *brd) -{ - struct channel_t *ch; - int i; - int ret; - - brd->serial_ports = kcalloc(brd->nasync, sizeof(*brd->serial_ports), - GFP_KERNEL); - if (!brd->serial_ports) - return -ENOMEM; - - brd->printer_ports = kcalloc(brd->nasync, sizeof(*brd->printer_ports), - GFP_KERNEL); - if (!brd->printer_ports) { - ret = -ENOMEM; - goto free_serial_ports; - } - - for (i = 0; i < brd->nasync; i++) { - tty_port_init(&brd->serial_ports[i]); - tty_port_init(&brd->printer_ports[i]); - } - - ch = brd->channels[0]; - for (i = 0; i < brd->nasync; i++, ch = brd->channels[i]) { - - struct device *classp; - - classp = tty_port_register_device(&brd->serial_ports[i], - brd->serial_driver, - i, NULL); - - if (IS_ERR(classp)) { - ret = PTR_ERR(classp); - goto unregister_ttys; - } - - dgap_create_tty_sysfs(&ch->ch_tun, classp); - ch->ch_tun.un_sysfs = classp; - - classp = tty_port_register_device(&brd->printer_ports[i], - brd->print_driver, - i, NULL); - - if (IS_ERR(classp)) { - ret = PTR_ERR(classp); - goto unregister_ttys; - } - - dgap_create_tty_sysfs(&ch->ch_pun, classp); - ch->ch_pun.un_sysfs = classp; - } - dgap_create_ports_sysfiles(brd); - - return 0; - -unregister_ttys: - while (i >= 0) { - ch = brd->channels[i]; - if (ch->ch_tun.un_sysfs) { - dgap_remove_tty_sysfs(ch->ch_tun.un_sysfs); - tty_unregister_device(brd->serial_driver, i); - } - - if (ch->ch_pun.un_sysfs) { - dgap_remove_tty_sysfs(ch->ch_pun.un_sysfs); - tty_unregister_device(brd->print_driver, i); - } - i--; - } - - for (i = 0; i < brd->nasync; i++) { - tty_port_destroy(&brd->serial_ports[i]); - tty_port_destroy(&brd->printer_ports[i]); - } - - kfree(brd->printer_ports); - brd->printer_ports = NULL; - -free_serial_ports: - kfree(brd->serial_ports); - brd->serial_ports = NULL; - - return ret; -} - -/* - * Copies the BIOS code from the user to the board, - * and starts the BIOS running. - */ -static void dgap_do_bios_load(struct board_t *brd, const u8 *ubios, int len) -{ - u8 __iomem *addr; - uint offset; - int i; - - if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase) - return; - - addr = brd->re_map_membase; - - /* - * clear POST area - */ - for (i = 0; i < 16; i++) - writeb(0, addr + POSTAREA + i); - - /* - * Download bios - */ - offset = 0x1000; - memcpy_toio(addr + offset, ubios, len); - - writel(0x0bf00401, addr); - writel(0, (addr + 4)); - - /* Clear the reset, and change states. */ - writeb(FEPCLR, brd->re_map_port); -} - -/* - * Checks to see if the BIOS completed running on the card. - */ -static int dgap_test_bios(struct board_t *brd) -{ - u8 __iomem *addr; - u16 word; - u16 err1; - u16 err2; - - if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase) - return -EINVAL; - - addr = brd->re_map_membase; - word = readw(addr + POSTAREA); - - /* - * It can take 5-6 seconds for a board to - * pass the bios self test and post results. - * Give it 10 seconds. - */ - brd->wait_for_bios = 0; - while (brd->wait_for_bios < 1000) { - /* Check to see if BIOS thinks board is good. (GD). */ - if (word == *(u16 *) "GD") - return 0; - msleep_interruptible(10); - brd->wait_for_bios++; - word = readw(addr + POSTAREA); - } - - /* Gave up on board after too long of time taken */ - err1 = readw(addr + SEQUENCE); - err2 = readw(addr + ERROR); - dev_warn(&brd->pdev->dev, "%s failed diagnostics. Error #(%x,%x).\n", - brd->name, err1, err2); - brd->state = BOARD_FAILED; - brd->dpastatus = BD_NOBIOS; - - return -EIO; -} - -/* - * Copies the FEP code from the user to the board, - * and starts the FEP running. - */ -static void dgap_do_fep_load(struct board_t *brd, const u8 *ufep, int len) -{ - u8 __iomem *addr; - uint offset; - - if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase) - return; - - addr = brd->re_map_membase; - - /* - * Download FEP - */ - offset = 0x1000; - memcpy_toio(addr + offset, ufep, len); - - /* - * If board is a concentrator product, we need to give - * it its config string describing how the concentrators look. - */ - if ((brd->type == PCX) || (brd->type == PEPC)) { - u8 string[100]; - u8 __iomem *config; - u8 *xconfig; - int i = 0; - - xconfig = dgap_create_config_string(brd, string); - - /* Write string to board memory */ - config = addr + CONFIG; - for (; i < CONFIGSIZE; i++, config++, xconfig++) { - writeb(*xconfig, config); - if ((*xconfig & 0xff) == 0xff) - break; - } - } - - writel(0xbfc01004, (addr + 0xc34)); - writel(0x3, (addr + 0xc30)); - -} - -/* - * Waits for the FEP to report thats its ready for us to use. - */ -static int dgap_test_fep(struct board_t *brd) -{ - u8 __iomem *addr; - u16 word; - u16 err1; - u16 err2; - - if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase) - return -EINVAL; - - addr = brd->re_map_membase; - word = readw(addr + FEPSTAT); - - /* - * It can take 2-3 seconds for the FEP to - * be up and running. Give it 5 secs. - */ - brd->wait_for_fep = 0; - while (brd->wait_for_fep < 500) { - /* Check to see if FEP is up and running now. */ - if (word == *(u16 *) "OS") { - /* - * Check to see if the board can support FEP5+ commands. - */ - word = readw(addr + FEP5_PLUS); - if (word == *(u16 *) "5A") - brd->bd_flags |= BD_FEP5PLUS; - - return 0; - } - msleep_interruptible(10); - brd->wait_for_fep++; - word = readw(addr + FEPSTAT); - } - - /* Gave up on board after too long of time taken */ - err1 = readw(addr + SEQUENCE); - err2 = readw(addr + ERROR); - dev_warn(&brd->pdev->dev, - "FEPOS for %s not functioning. Error #(%x,%x).\n", - brd->name, err1, err2); - brd->state = BOARD_FAILED; - brd->dpastatus = BD_NOFEP; - - return -EIO; -} - -/* - * Physically forces the FEP5 card to reset itself. - */ -static void dgap_do_reset_board(struct board_t *brd) -{ - u8 check; - u32 check1; - u32 check2; - int i; - - if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || - !brd->re_map_membase || !brd->re_map_port) - return; - - /* FEPRST does not vary among supported boards */ - writeb(FEPRST, brd->re_map_port); - - for (i = 0; i <= 1000; i++) { - check = readb(brd->re_map_port) & 0xe; - if (check == FEPRST) - break; - udelay(10); - - } - if (i > 1000) { - dev_warn(&brd->pdev->dev, - "dgap: Board not resetting... Failing board.\n"); - brd->state = BOARD_FAILED; - brd->dpastatus = BD_NOFEP; - return; - } - - /* - * Make sure there really is memory out there. - */ - writel(0xa55a3cc3, (brd->re_map_membase + LOWMEM)); - writel(0x5aa5c33c, (brd->re_map_membase + HIGHMEM)); - check1 = readl(brd->re_map_membase + LOWMEM); - check2 = readl(brd->re_map_membase + HIGHMEM); - - if ((check1 != 0xa55a3cc3) || (check2 != 0x5aa5c33c)) { - dev_warn(&brd->pdev->dev, - "No memory at %p for board.\n", - brd->re_map_membase); - brd->state = BOARD_FAILED; - brd->dpastatus = BD_NOFEP; - return; - } -} - -#ifdef DIGI_CONCENTRATORS_SUPPORTED -/* - * Sends a concentrator image into the FEP5 board. - */ -static void dgap_do_conc_load(struct board_t *brd, u8 *uaddr, int len) -{ - char __iomem *vaddr; - u16 offset; - struct downld_t *to_dp; - - if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase) - return; - - vaddr = brd->re_map_membase; - - offset = readw((u16 *) (vaddr + DOWNREQ)); - to_dp = (struct downld_t *) (vaddr + (int) offset); - memcpy_toio(to_dp, uaddr, len); - - /* Tell card we have data for it */ - writew(0, vaddr + (DOWNREQ)); - - brd->conc_dl_status = NO_PENDING_CONCENTRATOR_REQUESTS; -} -#endif - -#define EXPANSION_ROM_SIZE (64 * 1024) -#define FEP5_ROM_MAGIC (0xFEFFFFFF) - -static void dgap_get_vpd(struct board_t *brd) -{ - u32 magic; - u32 base_offset; - u16 rom_offset; - u16 vpd_offset; - u16 image_length; - u16 i; - u8 byte1; - u8 byte2; - - /* - * Poke the magic number at the PCI Rom Address location. - * If VPD is supported, the value read from that address - * will be non-zero. - */ - magic = FEP5_ROM_MAGIC; - pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic); - pci_read_config_dword(brd->pdev, PCI_ROM_ADDRESS, &magic); - - /* VPD not supported, bail */ - if (!magic) - return; - - /* - * To get to the OTPROM memory, we have to send the boards base - * address or'ed with 1 into the PCI Rom Address location. - */ - magic = brd->membase | 0x01; - pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic); - pci_read_config_dword(brd->pdev, PCI_ROM_ADDRESS, &magic); - - byte1 = readb(brd->re_map_membase); - byte2 = readb(brd->re_map_membase + 1); - - /* - * If the board correctly swapped to the OTPROM memory, - * the first 2 bytes (header) should be 0x55, 0xAA - */ - if (byte1 == 0x55 && byte2 == 0xAA) { - - base_offset = 0; - - /* - * We have to run through all the OTPROM memory looking - * for the VPD offset. - */ - while (base_offset <= EXPANSION_ROM_SIZE) { - - /* - * Lots of magic numbers here. - * - * The VPD offset is located inside the ROM Data - * Structure. - * - * We also have to remember the length of each - * ROM Data Structure, so we can "hop" to the next - * entry if the VPD isn't in the current - * ROM Data Structure. - */ - rom_offset = readw(brd->re_map_membase + - base_offset + 0x18); - image_length = readw(brd->re_map_membase + - rom_offset + 0x10) * 512; - vpd_offset = readw(brd->re_map_membase + - rom_offset + 0x08); - - /* Found the VPD entry */ - if (vpd_offset) - break; - - /* We didn't find a VPD entry, go to next ROM entry. */ - base_offset += image_length; - - byte1 = readb(brd->re_map_membase + base_offset); - byte2 = readb(brd->re_map_membase + base_offset + 1); - - /* - * If the new ROM offset doesn't have 0x55, 0xAA - * as its header, we have run out of ROM. - */ - if (byte1 != 0x55 || byte2 != 0xAA) - break; - } - - /* - * If we have a VPD offset, then mark the board - * as having a valid VPD, and copy VPDSIZE (512) bytes of - * that VPD to the buffer we have in our board structure. - */ - if (vpd_offset) { - brd->bd_flags |= BD_HAS_VPD; - for (i = 0; i < VPDSIZE; i++) { - brd->vpd[i] = readb(brd->re_map_membase + - vpd_offset + i); - } - } - } - - /* - * We MUST poke the magic number at the PCI Rom Address location again. - * This makes the card report the regular board memory back to us, - * rather than the OTPROM memory. - */ - magic = FEP5_ROM_MAGIC; - pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic); -} - -/* - * Our board poller function. - */ -static void dgap_poll_tasklet(unsigned long data) -{ - struct board_t *bd = (struct board_t *) data; - ulong lock_flags; - char __iomem *vaddr; - u16 head, tail; - - if (!bd || (bd->magic != DGAP_BOARD_MAGIC)) - return; - - if (bd->inhibit_poller) - return; - - spin_lock_irqsave(&bd->bd_lock, lock_flags); - - vaddr = bd->re_map_membase; - - /* - * If board is ready, parse deeper to see if there is anything to do. - */ - if (bd->state == BOARD_READY) { - - struct ev_t __iomem *eaddr; - - if (!bd->re_map_membase) { - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return; - } - if (!bd->re_map_port) { - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return; - } - - if (!bd->nasync) - goto out; - - eaddr = (struct ev_t __iomem *) (vaddr + EVBUF); - - /* Get our head and tail */ - head = readw(&(eaddr->ev_head)); - tail = readw(&(eaddr->ev_tail)); - - /* - * If there is an event pending. Go service it. - */ - if (head != tail) { - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - dgap_event(bd); - spin_lock_irqsave(&bd->bd_lock, lock_flags); - } - -out: - /* - * If board is doing interrupts, ACK the interrupt. - */ - if (bd && bd->intr_running) - readb(bd->re_map_port + 2); - - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return; - } - - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); -} - -/*======================================================================= - * - * dgap_cmdb - Sends a 2 byte command to the FEP. - * - * ch - Pointer to channel structure. - * cmd - Command to be sent. - * byte1 - Integer containing first byte to be sent. - * byte2 - Integer containing second byte to be sent. - * ncmds - Wait until ncmds or fewer cmds are left - * in the cmd buffer before returning. - * - *=======================================================================*/ -static void dgap_cmdb(struct channel_t *ch, u8 cmd, u8 byte1, - u8 byte2, uint ncmds) -{ - char __iomem *vaddr; - struct __iomem cm_t *cm_addr; - uint count; - uint n; - u16 head; - u16 tail; - - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return; - - /* - * Check if board is still alive. - */ - if (ch->ch_bd->state == BOARD_FAILED) - return; - - /* - * Make sure the pointers are in range before - * writing to the FEP memory. - */ - vaddr = ch->ch_bd->re_map_membase; - - if (!vaddr) - return; - - cm_addr = (struct cm_t __iomem *) (vaddr + CMDBUF); - head = readw(&(cm_addr->cm_head)); - - /* - * Forget it if pointers out of range. - */ - if (head >= (CMDMAX - CMDSTART) || (head & 03)) { - ch->ch_bd->state = BOARD_FAILED; - return; - } - - /* - * Put the data in the circular command buffer. - */ - writeb(cmd, (vaddr + head + CMDSTART + 0)); - writeb((u8) ch->ch_portnum, (vaddr + head + CMDSTART + 1)); - writeb(byte1, (vaddr + head + CMDSTART + 2)); - writeb(byte2, (vaddr + head + CMDSTART + 3)); - - head = (head + 4) & (CMDMAX - CMDSTART - 4); - - writew(head, &(cm_addr->cm_head)); - - /* - * Wait if necessary before updating the head - * pointer to limit the number of outstanding - * commands to the FEP. If the time spent waiting - * is outlandish, declare the FEP dead. - */ - for (count = dgap_count ;;) { - - head = readw(&(cm_addr->cm_head)); - tail = readw(&(cm_addr->cm_tail)); - - n = (head - tail) & (CMDMAX - CMDSTART - 4); - - if (n <= ncmds * sizeof(struct cm_t)) - break; - - if (--count == 0) { - ch->ch_bd->state = BOARD_FAILED; - return; - } - udelay(10); - } -} - -/*======================================================================= - * - * dgap_cmdw - Sends a 1 word command to the FEP. - * - * ch - Pointer to channel structure. - * cmd - Command to be sent. - * word - Integer containing word to be sent. - * ncmds - Wait until ncmds or fewer cmds are left - * in the cmd buffer before returning. - * - *=======================================================================*/ -static void dgap_cmdw(struct channel_t *ch, u8 cmd, u16 word, uint ncmds) -{ - char __iomem *vaddr; - struct __iomem cm_t *cm_addr; - uint count; - uint n; - u16 head; - u16 tail; - - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return; - - /* - * Check if board is still alive. - */ - if (ch->ch_bd->state == BOARD_FAILED) - return; - - /* - * Make sure the pointers are in range before - * writing to the FEP memory. - */ - vaddr = ch->ch_bd->re_map_membase; - if (!vaddr) - return; - - cm_addr = (struct cm_t __iomem *) (vaddr + CMDBUF); - head = readw(&(cm_addr->cm_head)); - - /* - * Forget it if pointers out of range. - */ - if (head >= (CMDMAX - CMDSTART) || (head & 03)) { - ch->ch_bd->state = BOARD_FAILED; - return; - } - - /* - * Put the data in the circular command buffer. - */ - writeb(cmd, (vaddr + head + CMDSTART + 0)); - writeb((u8) ch->ch_portnum, (vaddr + head + CMDSTART + 1)); - writew((u16) word, (vaddr + head + CMDSTART + 2)); - - head = (head + 4) & (CMDMAX - CMDSTART - 4); - - writew(head, &(cm_addr->cm_head)); - - /* - * Wait if necessary before updating the head - * pointer to limit the number of outstanding - * commands to the FEP. If the time spent waiting - * is outlandish, declare the FEP dead. - */ - for (count = dgap_count ;;) { - - head = readw(&(cm_addr->cm_head)); - tail = readw(&(cm_addr->cm_tail)); - - n = (head - tail) & (CMDMAX - CMDSTART - 4); - - if (n <= ncmds * sizeof(struct cm_t)) - break; - - if (--count == 0) { - ch->ch_bd->state = BOARD_FAILED; - return; - } - udelay(10); - } -} - -/*======================================================================= - * - * dgap_cmdw_ext - Sends a extended word command to the FEP. - * - * ch - Pointer to channel structure. - * cmd - Command to be sent. - * word - Integer containing word to be sent. - * ncmds - Wait until ncmds or fewer cmds are left - * in the cmd buffer before returning. - * - *=======================================================================*/ -static void dgap_cmdw_ext(struct channel_t *ch, u16 cmd, u16 word, uint ncmds) -{ - char __iomem *vaddr; - struct __iomem cm_t *cm_addr; - uint count; - uint n; - u16 head; - u16 tail; - - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return; - - /* - * Check if board is still alive. - */ - if (ch->ch_bd->state == BOARD_FAILED) - return; - - /* - * Make sure the pointers are in range before - * writing to the FEP memory. - */ - vaddr = ch->ch_bd->re_map_membase; - if (!vaddr) - return; - - cm_addr = (struct cm_t __iomem *) (vaddr + CMDBUF); - head = readw(&(cm_addr->cm_head)); - - /* - * Forget it if pointers out of range. - */ - if (head >= (CMDMAX - CMDSTART) || (head & 03)) { - ch->ch_bd->state = BOARD_FAILED; - return; - } - - /* - * Put the data in the circular command buffer. - */ - - /* Write an FF to tell the FEP that we want an extended command */ - writeb((u8) 0xff, (vaddr + head + CMDSTART + 0)); - - writeb((u8) ch->ch_portnum, (vaddr + head + CMDSTART + 1)); - writew((u16) cmd, (vaddr + head + CMDSTART + 2)); - - /* - * If the second part of the command won't fit, - * put it at the beginning of the circular buffer. - */ - if (((head + 4) >= ((CMDMAX - CMDSTART)) || (head & 03))) - writew((u16) word, (vaddr + CMDSTART)); - else - writew((u16) word, (vaddr + head + CMDSTART + 4)); - - head = (head + 8) & (CMDMAX - CMDSTART - 4); - - writew(head, &(cm_addr->cm_head)); - - /* - * Wait if necessary before updating the head - * pointer to limit the number of outstanding - * commands to the FEP. If the time spent waiting - * is outlandish, declare the FEP dead. - */ - for (count = dgap_count ;;) { - - head = readw(&(cm_addr->cm_head)); - tail = readw(&(cm_addr->cm_tail)); - - n = (head - tail) & (CMDMAX - CMDSTART - 4); - - if (n <= ncmds * sizeof(struct cm_t)) - break; - - if (--count == 0) { - ch->ch_bd->state = BOARD_FAILED; - return; - } - udelay(10); - } -} +static const struct tty_operations dgap_tty_ops = { + .open = dgap_tty_open, + .close = dgap_tty_close, + .write = dgap_tty_write, + .write_room = dgap_tty_write_room, + .flush_buffer = dgap_tty_flush_buffer, + .chars_in_buffer = dgap_tty_chars_in_buffer, + .flush_chars = dgap_tty_flush_chars, + .ioctl = dgap_tty_ioctl, + .set_termios = dgap_tty_set_termios, + .stop = dgap_tty_stop, + .start = dgap_tty_start, + .throttle = dgap_tty_throttle, + .unthrottle = dgap_tty_unthrottle, + .hangup = dgap_tty_hangup, + .put_char = dgap_tty_put_char, + .tiocmget = dgap_tty_tiocmget, + .tiocmset = dgap_tty_tiocmset, + .break_ctl = dgap_tty_send_break, + .wait_until_sent = dgap_tty_wait_until_sent, + .send_xchar = dgap_tty_send_xchar +}; -/*======================================================================= - * - * dgap_wmove - Write data to FEP buffer. +/************************************************************************ * - * ch - Pointer to channel structure. - * buf - Poiter to characters to be moved. - * cnt - Number of characters to move. + * TTY Initialization/Cleanup Functions * - *=======================================================================*/ -static void dgap_wmove(struct channel_t *ch, char *buf, uint cnt) -{ - int n; - char __iomem *taddr; - struct bs_t __iomem *bs; - u16 head; - - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return; - - /* - * Check parameters. - */ - bs = ch->ch_bs; - head = readw(&(bs->tx_head)); - - /* - * If pointers are out of range, just return. - */ - if ((cnt > ch->ch_tsize) || - (unsigned)(head - ch->ch_tstart) >= ch->ch_tsize) - return; - - /* - * If the write wraps over the top of the circular buffer, - * move the portion up to the wrap point, and reset the - * pointers to the bottom. - */ - n = ch->ch_tstart + ch->ch_tsize - head; - - if (cnt >= n) { - cnt -= n; - taddr = ch->ch_taddr + head; - memcpy_toio(taddr, buf, n); - head = ch->ch_tstart; - buf += n; - } - - /* - * Move rest of data. - */ - taddr = ch->ch_taddr + head; - n = cnt; - memcpy_toio(taddr, buf, n); - head += cnt; - - writew(head, &(bs->tx_head)); -} - -/* - * Retrives the current custom baud rate from FEP memory, - * and returns it back to the user. - * Returns 0 on error. - */ -static uint dgap_get_custom_baud(struct channel_t *ch) -{ - u8 __iomem *vaddr; - ulong offset; - uint value; - - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return 0; - - if (!ch->ch_bd || ch->ch_bd->magic != DGAP_BOARD_MAGIC) - return 0; - - if (!(ch->ch_bd->bd_flags & BD_FEP5PLUS)) - return 0; - - vaddr = ch->ch_bd->re_map_membase; - - if (!vaddr) - return 0; - - /* - * Go get from fep mem, what the fep - * believes the custom baud rate is. - */ - offset = (ioread16(vaddr + ECS_SEG) << 4) + (ch->ch_portnum * 0x28) - + LINE_SPEED; - - value = readw(vaddr + offset); - return value; -} + ************************************************************************/ /* - * Calls the firmware to reset this channel. - */ -static void dgap_firmware_reset_port(struct channel_t *ch) -{ - dgap_cmdb(ch, CHRESET, 0, 0, 0); - - /* - * Now that the channel is reset, we need to make sure - * all the current settings get reapplied to the port - * in the firmware. - * - * So we will set the driver's cache of firmware - * settings all to 0, and then call param. - */ - ch->ch_fepiflag = 0; - ch->ch_fepcflag = 0; - ch->ch_fepoflag = 0; - ch->ch_fepstartc = 0; - ch->ch_fepstopc = 0; - ch->ch_fepastartc = 0; - ch->ch_fepastopc = 0; - ch->ch_mostat = 0; - ch->ch_hflow = 0; -} - -/*======================================================================= - * - * dgap_param - Set Digi parameters. - * - * struct tty_struct * - TTY for port. + * dgap_tty_register() * - *=======================================================================*/ -static int dgap_param(struct channel_t *ch, struct board_t *bd, u32 un_type) + * Init the tty subsystem for this board. + */ +static int dgap_tty_register(struct board_t *brd) { - u16 head; - u16 cflag; - u16 iflag; - u8 mval; - u8 hflow; - - /* - * If baud rate is zero, flush queues, and set mval to drop DTR. - */ - if ((ch->ch_c_cflag & (CBAUD)) == 0) { - - /* flush rx */ - head = readw(&(ch->ch_bs->rx_head)); - writew(head, &(ch->ch_bs->rx_tail)); - - /* flush tx */ - head = readw(&(ch->ch_bs->tx_head)); - writew(head, &(ch->ch_bs->tx_tail)); - - ch->ch_flags |= (CH_BAUD0); - - /* Drop RTS and DTR */ - ch->ch_mval &= ~(D_RTS(ch)|D_DTR(ch)); - mval = D_DTR(ch) | D_RTS(ch); - ch->ch_baud_info = 0; - - } else if (ch->ch_custom_speed && (bd->bd_flags & BD_FEP5PLUS)) { - /* - * Tell the fep to do the command - */ - - dgap_cmdw_ext(ch, 0xff01, ch->ch_custom_speed, 0); - - /* - * Now go get from fep mem, what the fep - * believes the custom baud rate is. - */ - ch->ch_custom_speed = dgap_get_custom_baud(ch); - ch->ch_baud_info = ch->ch_custom_speed; - - /* Handle transition from B0 */ - if (ch->ch_flags & CH_BAUD0) { - ch->ch_flags &= ~(CH_BAUD0); - ch->ch_mval |= (D_RTS(ch)|D_DTR(ch)); - } - mval = D_DTR(ch) | D_RTS(ch); - - } else { - /* - * Set baud rate, character size, and parity. - */ - - - int iindex = 0; - int jindex = 0; - int baud = 0; - - ulong bauds[4][16] = { - { /* slowbaud */ - 0, 50, 75, 110, - 134, 150, 200, 300, - 600, 1200, 1800, 2400, - 4800, 9600, 19200, 38400 }, - { /* slowbaud & CBAUDEX */ - 0, 57600, 115200, 230400, - 460800, 150, 200, 921600, - 600, 1200, 1800, 2400, - 4800, 9600, 19200, 38400 }, - { /* fastbaud */ - 0, 57600, 76800, 115200, - 14400, 57600, 230400, 76800, - 115200, 230400, 28800, 460800, - 921600, 9600, 19200, 38400 }, - { /* fastbaud & CBAUDEX */ - 0, 57600, 115200, 230400, - 460800, 150, 200, 921600, - 600, 1200, 1800, 2400, - 4800, 9600, 19200, 38400 } - }; - - /* - * Only use the TXPrint baud rate if the - * terminal unit is NOT open - */ - if (!(ch->ch_tun.un_flags & UN_ISOPEN) && - un_type == DGAP_PRINT) - baud = C_BAUD(ch->ch_pun.un_tty) & 0xff; - else - baud = C_BAUD(ch->ch_tun.un_tty) & 0xff; - - if (ch->ch_c_cflag & CBAUDEX) - iindex = 1; - - if (ch->ch_digi.digi_flags & DIGI_FAST) - iindex += 2; - - jindex = baud; - - if ((iindex >= 0) && (iindex < 4) && - (jindex >= 0) && (jindex < 16)) - baud = bauds[iindex][jindex]; - else - baud = 0; - - if (baud == 0) - baud = 9600; - - ch->ch_baud_info = baud; - - /* - * CBAUD has bit position 0x1000 set these days to - * indicate Linux baud rate remap. - * We use a different bit assignment for high speed. - * Clear this bit out while grabbing the parts of - * "cflag" we want. - */ - cflag = ch->ch_c_cflag & ((CBAUD ^ CBAUDEX) | PARODD | PARENB | - CSTOPB | CSIZE); - - /* - * HUPCL bit is used by FEP to indicate fast baud - * table is to be used. - */ - if ((ch->ch_digi.digi_flags & DIGI_FAST) || - (ch->ch_c_cflag & CBAUDEX)) - cflag |= HUPCL; - - if ((ch->ch_c_cflag & CBAUDEX) && - !(ch->ch_digi.digi_flags & DIGI_FAST)) { - /* - * The below code is trying to guarantee that only - * baud rates 115200, 230400, 460800, 921600 are - * remapped. We use exclusive or because the various - * baud rates share common bit positions and therefore - * can't be tested for easily. - */ - tcflag_t tcflag = (ch->ch_c_cflag & CBAUD) | CBAUDEX; - int baudpart = 0; - - /* - * Map high speed requests to index - * into FEP's baud table - */ - switch (tcflag) { - case B57600: - baudpart = 1; - break; -#ifdef B76800 - case B76800: - baudpart = 2; - break; -#endif - case B115200: - baudpart = 3; - break; - case B230400: - baudpart = 9; - break; - case B460800: - baudpart = 11; - break; -#ifdef B921600 - case B921600: - baudpart = 12; - break; -#endif - default: - baudpart = 0; - } - - if (baudpart) - cflag = (cflag & ~(CBAUD | CBAUDEX)) | baudpart; - } - - cflag &= 0xffff; - - if (cflag != ch->ch_fepcflag) { - ch->ch_fepcflag = (u16) (cflag & 0xffff); - - /* - * Okay to have channel and board - * locks held calling this - */ - dgap_cmdw(ch, SCFLAG, (u16) cflag, 0); - } - - /* Handle transition from B0 */ - if (ch->ch_flags & CH_BAUD0) { - ch->ch_flags &= ~(CH_BAUD0); - ch->ch_mval |= (D_RTS(ch)|D_DTR(ch)); - } - mval = D_DTR(ch) | D_RTS(ch); - } - - /* - * Get input flags. - */ - iflag = ch->ch_c_iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK | - INPCK | ISTRIP | IXON | IXANY | IXOFF); - - if ((ch->ch_startc == _POSIX_VDISABLE) || - (ch->ch_stopc == _POSIX_VDISABLE)) { - iflag &= ~(IXON | IXOFF); - ch->ch_c_iflag &= ~(IXON | IXOFF); - } - - /* - * Only the IBM Xr card can switch between - * 232 and 422 modes on the fly - */ - if (bd->device == PCI_DEV_XR_IBM_DID) { - if (ch->ch_digi.digi_flags & DIGI_422) - dgap_cmdb(ch, SCOMMODE, MODE_422, 0, 0); - else - dgap_cmdb(ch, SCOMMODE, MODE_232, 0, 0); - } - - if (ch->ch_digi.digi_flags & DIGI_ALTPIN) - iflag |= IALTPIN; - - if (iflag != ch->ch_fepiflag) { - ch->ch_fepiflag = iflag; - - /* Okay to have channel and board locks held calling this */ - dgap_cmdw(ch, SIFLAG, (u16) ch->ch_fepiflag, 0); - } - - /* - * Select hardware handshaking. - */ - hflow = 0; - - if (ch->ch_c_cflag & CRTSCTS) - hflow |= (D_RTS(ch) | D_CTS(ch)); - if (ch->ch_digi.digi_flags & RTSPACE) - hflow |= D_RTS(ch); - if (ch->ch_digi.digi_flags & DTRPACE) - hflow |= D_DTR(ch); - if (ch->ch_digi.digi_flags & CTSPACE) - hflow |= D_CTS(ch); - if (ch->ch_digi.digi_flags & DSRPACE) - hflow |= D_DSR(ch); - if (ch->ch_digi.digi_flags & DCDPACE) - hflow |= D_CD(ch); + int rc; - if (hflow != ch->ch_hflow) { - ch->ch_hflow = hflow; + brd->serial_driver = tty_alloc_driver(MAXPORTS, + TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV | + TTY_DRIVER_HARDWARE_BREAK); + if (IS_ERR(brd->serial_driver)) + return PTR_ERR(brd->serial_driver); - /* Okay to have channel and board locks held calling this */ - dgap_cmdb(ch, SHFLOW, (u8) hflow, 0xff, 0); - } + snprintf(brd->serial_name, MAXTTYNAMELEN, "tty_dgap_%d_", + brd->boardnum); + brd->serial_driver->name = brd->serial_name; + brd->serial_driver->name_base = 0; + brd->serial_driver->major = 0; + brd->serial_driver->minor_start = 0; + brd->serial_driver->type = TTY_DRIVER_TYPE_SERIAL; + brd->serial_driver->subtype = SERIAL_TYPE_NORMAL; + brd->serial_driver->init_termios = dgap_default_termios; + brd->serial_driver->driver_name = DRVSTR; /* - * Set RTS and/or DTR Toggle if needed, - * but only if product is FEP5+ based. + * Entry points for driver. Called by the kernel from + * tty_io.c and n_tty.c. */ - if (bd->bd_flags & BD_FEP5PLUS) { - u16 hflow2 = 0; - - if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) - hflow2 |= (D_RTS(ch)); - if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) - hflow2 |= (D_DTR(ch)); - - dgap_cmdw_ext(ch, 0xff03, hflow2, 0); - } + tty_set_operations(brd->serial_driver, &dgap_tty_ops); /* - * Set modem control lines. + * If we're doing transparent print, we have to do all of the above + * again, separately so we don't get the LD confused about what major + * we are when we get into the dgap_tty_open() routine. */ - - mval ^= ch->ch_mforce & (mval ^ ch->ch_mval); - - if (ch->ch_mostat ^ mval) { - ch->ch_mostat = mval; - - /* Okay to have channel and board locks held calling this */ - dgap_cmdb(ch, SMODEM, (u8) mval, D_RTS(ch)|D_DTR(ch), 0); + brd->print_driver = tty_alloc_driver(MAXPORTS, + TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV | + TTY_DRIVER_HARDWARE_BREAK); + if (IS_ERR(brd->print_driver)) { + rc = PTR_ERR(brd->print_driver); + goto free_serial_drv; } - /* - * Read modem signals, and then call carrier function. - */ - ch->ch_mistat = readb(&(ch->ch_bs->m_stat)); - dgap_carrier(ch); + snprintf(brd->print_name, MAXTTYNAMELEN, "pr_dgap_%d_", + brd->boardnum); + brd->print_driver->name = brd->print_name; + brd->print_driver->name_base = 0; + brd->print_driver->major = 0; + brd->print_driver->minor_start = 0; + brd->print_driver->type = TTY_DRIVER_TYPE_SERIAL; + brd->print_driver->subtype = SERIAL_TYPE_NORMAL; + brd->print_driver->init_termios = dgap_default_termios; + brd->print_driver->driver_name = DRVSTR; /* - * Set the start and stop characters. + * Entry points for driver. Called by the kernel from + * tty_io.c and n_tty.c. */ - if (ch->ch_startc != ch->ch_fepstartc || - ch->ch_stopc != ch->ch_fepstopc) { - ch->ch_fepstartc = ch->ch_startc; - ch->ch_fepstopc = ch->ch_stopc; - - /* Okay to have channel and board locks held calling this */ - dgap_cmdb(ch, SFLOWC, ch->ch_fepstartc, ch->ch_fepstopc, 0); - } + tty_set_operations(brd->print_driver, &dgap_tty_ops); - /* - * Set the Auxiliary start and stop characters. - */ - if (ch->ch_astartc != ch->ch_fepastartc || - ch->ch_astopc != ch->ch_fepastopc) { - ch->ch_fepastartc = ch->ch_astartc; - ch->ch_fepastopc = ch->ch_astopc; + /* Register tty devices */ + rc = tty_register_driver(brd->serial_driver); + if (rc < 0) + goto free_print_drv; - /* Okay to have channel and board locks held calling this */ - dgap_cmdb(ch, SAFLOWC, ch->ch_fepastartc, ch->ch_fepastopc, 0); - } + /* Register Transparent Print devices */ + rc = tty_register_driver(brd->print_driver); + if (rc < 0) + goto unregister_serial_drv; return 0; -} - -/* - * dgap_parity_scan() - * - * Convert the FEP5 way of reporting parity errors and breaks into - * the Linux line discipline way. - */ -static void dgap_parity_scan(struct channel_t *ch, unsigned char *cbuf, - unsigned char *fbuf, int *len) -{ - int l = *len; - int count = 0; - unsigned char *in, *cout, *fout; - unsigned char c; - - in = cbuf; - cout = cbuf; - fout = fbuf; - - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return; - while (l--) { - c = *in++; - switch (ch->pscan_state) { - default: - /* reset to sanity and fall through */ - ch->pscan_state = 0; - - case 0: - /* No FF seen yet */ - if (c == (unsigned char) '\377') - /* delete this character from stream */ - ch->pscan_state = 1; - else { - *cout++ = c; - *fout++ = TTY_NORMAL; - count += 1; - } - break; - - case 1: - /* first FF seen */ - if (c == (unsigned char) '\377') { - /* doubled ff, transform to single ff */ - *cout++ = c; - *fout++ = TTY_NORMAL; - count += 1; - ch->pscan_state = 0; - } else { - /* save value examination in next state */ - ch->pscan_savechar = c; - ch->pscan_state = 2; - } - break; - - case 2: - /* third character of ff sequence */ - - *cout++ = c; - - if (ch->pscan_savechar == 0x0) { - - if (c == 0x0) { - ch->ch_err_break++; - *fout++ = TTY_BREAK; - } else { - ch->ch_err_parity++; - *fout++ = TTY_PARITY; - } - } +unregister_serial_drv: + tty_unregister_driver(brd->serial_driver); +free_print_drv: + put_tty_driver(brd->print_driver); +free_serial_drv: + put_tty_driver(brd->serial_driver); - count += 1; - ch->pscan_state = 0; - } - } - *len = count; + return rc; } -static void dgap_write_wakeup(struct board_t *bd, struct channel_t *ch, - struct un_t *un, u32 mask, - unsigned long *irq_flags1, - unsigned long *irq_flags2) +static void dgap_tty_unregister(struct board_t *brd) { - if (!(un->un_flags & mask)) - return; - - un->un_flags &= ~mask; - - if (!(un->un_flags & UN_ISOPEN)) - return; - - if ((un->un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - un->un_tty->ldisc->ops->write_wakeup) { - spin_unlock_irqrestore(&ch->ch_lock, *irq_flags2); - spin_unlock_irqrestore(&bd->bd_lock, *irq_flags1); - - (un->un_tty->ldisc->ops->write_wakeup)(un->un_tty); - - spin_lock_irqsave(&bd->bd_lock, *irq_flags1); - spin_lock_irqsave(&ch->ch_lock, *irq_flags2); - } - wake_up_interruptible(&un->un_tty->write_wait); - wake_up_interruptible(&un->un_flags_wait); + tty_unregister_driver(brd->print_driver); + tty_unregister_driver(brd->serial_driver); + put_tty_driver(brd->print_driver); + put_tty_driver(brd->serial_driver); } -/*======================================================================= - * - * dgap_event - FEP to host event processing routine. - * - * bd - Board of current event. - * - *=======================================================================*/ -static int dgap_event(struct board_t *bd) +static int dgap_alloc_flipbuf(struct board_t *brd) { - struct channel_t *ch; - ulong lock_flags; - ulong lock_flags2; - struct bs_t __iomem *bs; - u8 __iomem *event; - u8 __iomem *vaddr; - struct ev_t __iomem *eaddr; - uint head; - uint tail; - int port; - int reason; - int modem; - int b1; - - if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return -EIO; - - spin_lock_irqsave(&bd->bd_lock, lock_flags); - - vaddr = bd->re_map_membase; - - if (!vaddr) { - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return -EIO; - } - - eaddr = (struct ev_t __iomem *) (vaddr + EVBUF); - - /* Get our head and tail */ - head = readw(&(eaddr->ev_head)); - tail = readw(&(eaddr->ev_tail)); - - /* - * Forget it if pointers out of range. - */ - - if (head >= EVMAX - EVSTART || tail >= EVMAX - EVSTART || - (head | tail) & 03) { - /* Let go of board lock */ - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return -EIO; - } - /* - * Loop to process all the events in the buffer. + * allocate flip buffer for board. */ - while (tail != head) { - - /* - * Get interrupt information. - */ - - event = bd->re_map_membase + tail + EVSTART; - - port = ioread8(event); - reason = ioread8(event + 1); - modem = ioread8(event + 2); - b1 = ioread8(event + 3); - - /* - * Make sure the interrupt is valid. - */ - if (port >= bd->nasync) - goto next; - - if (!(reason & (IFMODEM | IFBREAK | IFTLW | IFTEM | IFDATA))) - goto next; - - ch = bd->channels[port]; - - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - goto next; - - /* - * If we have made it here, the event was valid. - * Lock down the channel. - */ - spin_lock_irqsave(&ch->ch_lock, lock_flags2); - - bs = ch->ch_bs; - - if (!bs) { - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - goto next; - } - - /* - * Process received data. - */ - if (reason & IFDATA) { - - /* - * ALL LOCKS *MUST* BE DROPPED BEFORE CALLING INPUT! - * input could send some data to ld, which in turn - * could do a callback to one of our other functions. - */ - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - - dgap_input(ch); - - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); - - if (ch->ch_flags & CH_RACTIVE) - ch->ch_flags |= CH_RENABLE; - else - writeb(1, &(bs->idata)); - - if (ch->ch_flags & CH_RWAIT) { - ch->ch_flags &= ~CH_RWAIT; - - wake_up_interruptible - (&ch->ch_tun.un_flags_wait); - } - } - - /* - * Process Modem change signals. - */ - if (reason & IFMODEM) { - ch->ch_mistat = modem; - dgap_carrier(ch); - } - - /* - * Process break. - */ - if (reason & IFBREAK) { - - if (ch->ch_tun.un_tty) { - /* A break has been indicated */ - ch->ch_err_break++; - tty_buffer_request_room - (ch->ch_tun.un_tty->port, 1); - tty_insert_flip_char(ch->ch_tun.un_tty->port, - 0, TTY_BREAK); - tty_flip_buffer_push(ch->ch_tun.un_tty->port); - } - } - - /* - * Process Transmit low. - */ - if (reason & IFTLW) { - dgap_write_wakeup(bd, ch, &ch->ch_tun, UN_LOW, - &lock_flags, &lock_flags2); - dgap_write_wakeup(bd, ch, &ch->ch_pun, UN_LOW, - &lock_flags, &lock_flags2); - if (ch->ch_flags & CH_WLOW) { - ch->ch_flags &= ~CH_WLOW; - wake_up_interruptible(&ch->ch_flags_wait); - } - } - - /* - * Process Transmit empty. - */ - if (reason & IFTEM) { - dgap_write_wakeup(bd, ch, &ch->ch_tun, UN_EMPTY, - &lock_flags, &lock_flags2); - dgap_write_wakeup(bd, ch, &ch->ch_pun, UN_EMPTY, - &lock_flags, &lock_flags2); - if (ch->ch_flags & CH_WEMPTY) { - ch->ch_flags &= ~CH_WEMPTY; - wake_up_interruptible(&ch->ch_flags_wait); - } - } - - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + brd->flipbuf = kmalloc(MYFLIPLEN, GFP_KERNEL); + if (!brd->flipbuf) + return -ENOMEM; -next: - tail = (tail + 4) & (EVMAX - EVSTART - 4); + brd->flipflagbuf = kmalloc(MYFLIPLEN, GFP_KERNEL); + if (!brd->flipflagbuf) { + kfree(brd->flipbuf); + return -ENOMEM; } - writew(tail, &(eaddr->ev_tail)); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return 0; } -static ssize_t dgap_driver_version_show(struct device_driver *ddp, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%s\n", DG_PART); -} -static DRIVER_ATTR(version, S_IRUSR, dgap_driver_version_show, NULL); - - -static ssize_t dgap_driver_boards_show(struct device_driver *ddp, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", dgap_numboards); -} -static DRIVER_ATTR(boards, S_IRUSR, dgap_driver_boards_show, NULL); - - -static ssize_t dgap_driver_maxboards_show(struct device_driver *ddp, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", MAXBOARDS); -} -static DRIVER_ATTR(maxboards, S_IRUSR, dgap_driver_maxboards_show, NULL); - - -static ssize_t dgap_driver_pollcounter_show(struct device_driver *ddp, - char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%ld\n", dgap_poll_counter); -} -static DRIVER_ATTR(pollcounter, S_IRUSR, dgap_driver_pollcounter_show, NULL); - -static ssize_t dgap_driver_pollrate_show(struct device_driver *ddp, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%dms\n", dgap_poll_tick); -} - -static ssize_t dgap_driver_pollrate_store(struct device_driver *ddp, - const char *buf, size_t count) -{ - if (sscanf(buf, "%d\n", &dgap_poll_tick) != 1) - return -EINVAL; - return count; -} -static DRIVER_ATTR(pollrate, (S_IRUSR | S_IWUSR), dgap_driver_pollrate_show, - dgap_driver_pollrate_store); - -static int dgap_create_driver_sysfiles(struct pci_driver *dgap_driver) -{ - int rc = 0; - struct device_driver *driverfs = &dgap_driver->driver; - - rc |= driver_create_file(driverfs, &driver_attr_version); - rc |= driver_create_file(driverfs, &driver_attr_boards); - rc |= driver_create_file(driverfs, &driver_attr_maxboards); - rc |= driver_create_file(driverfs, &driver_attr_pollrate); - rc |= driver_create_file(driverfs, &driver_attr_pollcounter); - - return rc; -} - -static void dgap_remove_driver_sysfiles(struct pci_driver *dgap_driver) +static void dgap_free_flipbuf(struct board_t *brd) { - struct device_driver *driverfs = &dgap_driver->driver; - - driver_remove_file(driverfs, &driver_attr_version); - driver_remove_file(driverfs, &driver_attr_boards); - driver_remove_file(driverfs, &driver_attr_maxboards); - driver_remove_file(driverfs, &driver_attr_pollrate); - driver_remove_file(driverfs, &driver_attr_pollcounter); + kfree(brd->flipbuf); + kfree(brd->flipflagbuf); } static struct board_t *dgap_verify_board(struct device *p) @@ -5626,7 +5377,7 @@ static ssize_t dgap_ports_state_show(struct device *p, { struct board_t *bd; int count = 0; - int i; + unsigned int i; bd = dgap_verify_board(p); if (!bd) @@ -5647,7 +5398,7 @@ static ssize_t dgap_ports_baud_show(struct device *p, { struct board_t *bd; int count = 0; - int i; + unsigned int i; bd = dgap_verify_board(p); if (!bd) @@ -5668,7 +5419,7 @@ static ssize_t dgap_ports_msignals_show(struct device *p, { struct board_t *bd; int count = 0; - int i; + unsigned int i; bd = dgap_verify_board(p); if (!bd) @@ -5705,7 +5456,7 @@ static ssize_t dgap_ports_iflag_show(struct device *p, { struct board_t *bd; int count = 0; - int i; + unsigned int i; bd = dgap_verify_board(p); if (!bd) @@ -5725,7 +5476,7 @@ static ssize_t dgap_ports_cflag_show(struct device *p, { struct board_t *bd; int count = 0; - int i; + unsigned int i; bd = dgap_verify_board(p); if (!bd) @@ -5745,7 +5496,7 @@ static ssize_t dgap_ports_oflag_show(struct device *p, { struct board_t *bd; int count = 0; - int i; + unsigned int i; bd = dgap_verify_board(p); if (!bd) @@ -5765,7 +5516,7 @@ static ssize_t dgap_ports_lflag_show(struct device *p, { struct board_t *bd; int count = 0; - int i; + unsigned int i; bd = dgap_verify_board(p); if (!bd) @@ -5785,7 +5536,7 @@ static ssize_t dgap_ports_digi_flag_show(struct device *p, { struct board_t *bd; int count = 0; - int i; + unsigned int i; bd = dgap_verify_board(p); if (!bd) @@ -5805,7 +5556,7 @@ static ssize_t dgap_ports_rxcount_show(struct device *p, { struct board_t *bd; int count = 0; - int i; + unsigned int i; bd = dgap_verify_board(p); if (!bd) @@ -5825,7 +5576,7 @@ static ssize_t dgap_ports_txcount_show(struct device *p, { struct board_t *bd; int count = 0; - int i; + unsigned int i; bd = dgap_verify_board(p); if (!bd) @@ -5839,39 +5590,6 @@ static ssize_t dgap_ports_txcount_show(struct device *p, } static DEVICE_ATTR(ports_txcount, S_IRUSR, dgap_ports_txcount_show, NULL); -/* this function creates the sys files that will export each signal status - * to sysfs each value will be put in a separate filename - */ -static void dgap_create_ports_sysfiles(struct board_t *bd) -{ - dev_set_drvdata(&bd->pdev->dev, bd); - device_create_file(&(bd->pdev->dev), &dev_attr_ports_state); - device_create_file(&(bd->pdev->dev), &dev_attr_ports_baud); - device_create_file(&(bd->pdev->dev), &dev_attr_ports_msignals); - device_create_file(&(bd->pdev->dev), &dev_attr_ports_iflag); - device_create_file(&(bd->pdev->dev), &dev_attr_ports_cflag); - device_create_file(&(bd->pdev->dev), &dev_attr_ports_oflag); - device_create_file(&(bd->pdev->dev), &dev_attr_ports_lflag); - device_create_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag); - device_create_file(&(bd->pdev->dev), &dev_attr_ports_rxcount); - device_create_file(&(bd->pdev->dev), &dev_attr_ports_txcount); -} - -/* removes all the sys files created for that port */ -static void dgap_remove_ports_sysfiles(struct board_t *bd) -{ - device_remove_file(&(bd->pdev->dev), &dev_attr_ports_state); - device_remove_file(&(bd->pdev->dev), &dev_attr_ports_baud); - device_remove_file(&(bd->pdev->dev), &dev_attr_ports_msignals); - device_remove_file(&(bd->pdev->dev), &dev_attr_ports_iflag); - device_remove_file(&(bd->pdev->dev), &dev_attr_ports_cflag); - device_remove_file(&(bd->pdev->dev), &dev_attr_ports_oflag); - device_remove_file(&(bd->pdev->dev), &dev_attr_ports_lflag); - device_remove_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag); - device_remove_file(&(bd->pdev->dev), &dev_attr_ports_rxcount); - device_remove_file(&(bd->pdev->dev), &dev_attr_ports_txcount); -} - static ssize_t dgap_tty_state_show(struct device *d, struct device_attribute *attr, char *buf) @@ -6242,7 +5960,6 @@ static ssize_t dgap_tty_name_show(struct device *d, } ncount += cptr->u.module.nport; - } } @@ -6266,1086 +5983,1211 @@ static struct attribute *dgap_sysfs_tty_entries[] = { NULL }; -static struct attribute_group dgap_tty_attribute_group = { - .name = NULL, - .attrs = dgap_sysfs_tty_entries, -}; -static void dgap_create_tty_sysfs(struct un_t *un, struct device *c) +/* this function creates the sys files that will export each signal status + * to sysfs each value will be put in a separate filename + */ +static void dgap_create_ports_sysfiles(struct board_t *bd) { - int ret; - - ret = sysfs_create_group(&c->kobj, &dgap_tty_attribute_group); - if (ret) - return; - - dev_set_drvdata(c, un); - + dev_set_drvdata(&bd->pdev->dev, bd); + device_create_file(&(bd->pdev->dev), &dev_attr_ports_state); + device_create_file(&(bd->pdev->dev), &dev_attr_ports_baud); + device_create_file(&(bd->pdev->dev), &dev_attr_ports_msignals); + device_create_file(&(bd->pdev->dev), &dev_attr_ports_iflag); + device_create_file(&(bd->pdev->dev), &dev_attr_ports_cflag); + device_create_file(&(bd->pdev->dev), &dev_attr_ports_oflag); + device_create_file(&(bd->pdev->dev), &dev_attr_ports_lflag); + device_create_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag); + device_create_file(&(bd->pdev->dev), &dev_attr_ports_rxcount); + device_create_file(&(bd->pdev->dev), &dev_attr_ports_txcount); } -static void dgap_remove_tty_sysfs(struct device *c) +/* removes all the sys files created for that port */ +static void dgap_remove_ports_sysfiles(struct board_t *bd) { - sysfs_remove_group(&c->kobj, &dgap_tty_attribute_group); + device_remove_file(&(bd->pdev->dev), &dev_attr_ports_state); + device_remove_file(&(bd->pdev->dev), &dev_attr_ports_baud); + device_remove_file(&(bd->pdev->dev), &dev_attr_ports_msignals); + device_remove_file(&(bd->pdev->dev), &dev_attr_ports_iflag); + device_remove_file(&(bd->pdev->dev), &dev_attr_ports_cflag); + device_remove_file(&(bd->pdev->dev), &dev_attr_ports_oflag); + device_remove_file(&(bd->pdev->dev), &dev_attr_ports_lflag); + device_remove_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag); + device_remove_file(&(bd->pdev->dev), &dev_attr_ports_rxcount); + device_remove_file(&(bd->pdev->dev), &dev_attr_ports_txcount); } -static void dgap_cleanup_nodes(void) +/* + * Copies the BIOS code from the user to the board, + * and starts the BIOS running. + */ +static void dgap_do_bios_load(struct board_t *brd, const u8 *ubios, int len) { - struct cnode *p; + u8 __iomem *addr; + uint offset; + unsigned int i; - p = &dgap_head; + if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase) + return; - while (p) { - struct cnode *tmp = p->next; + addr = brd->re_map_membase; - if (p->type == NULLNODE) { - p = tmp; - continue; - } + /* + * clear POST area + */ + for (i = 0; i < 16; i++) + writeb(0, addr + POSTAREA + i); - switch (p->type) { - case BNODE: - kfree(p->u.board.portstr); - kfree(p->u.board.addrstr); - kfree(p->u.board.pcibusstr); - kfree(p->u.board.pcislotstr); - kfree(p->u.board.method); - break; - case CNODE: - kfree(p->u.conc.id); - kfree(p->u.conc.connect); - break; - case MNODE: - kfree(p->u.module.id); - break; - case TNODE: - kfree(p->u.ttyname); - break; - case CUNODE: - kfree(p->u.cuname); - break; - case LNODE: - kfree(p->u.line.cable); - break; - case PNODE: - kfree(p->u.printname); - break; - } + /* + * Download bios + */ + offset = 0x1000; + memcpy_toio(addr + offset, ubios, len); - kfree(p->u.board.status); - kfree(p); - p = tmp; - } + writel(0x0bf00401, addr); + writel(0, (addr + 4)); + + /* Clear the reset, and change states. */ + writeb(FEPCLR, brd->re_map_port); } + /* - * Parse a configuration file read into memory as a string. + * Checks to see if the BIOS completed running on the card. */ -static int dgap_parsefile(char **in) +static int dgap_test_bios(struct board_t *brd) { - struct cnode *p, *brd, *line, *conc; - int rc; - char *s; - int linecnt = 0; + u8 __iomem *addr; + u16 word; + u16 err1; + u16 err2; - p = &dgap_head; - brd = line = conc = NULL; + if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase) + return -EINVAL; - /* perhaps we are adding to an existing list? */ - while (p->next) - p = p->next; + addr = brd->re_map_membase; + word = readw(addr + POSTAREA); - /* file must start with a BEGIN */ - while ((rc = dgap_gettok(in)) != BEGIN) { - if (rc == 0) { - pr_err("unexpected EOF"); - return -1; - } + /* + * It can take 5-6 seconds for a board to + * pass the bios self test and post results. + * Give it 10 seconds. + */ + brd->wait_for_bios = 0; + while (brd->wait_for_bios < 1000) { + /* Check to see if BIOS thinks board is good. (GD). */ + if (word == *(u16 *) "GD") + return 0; + msleep_interruptible(10); + brd->wait_for_bios++; + word = readw(addr + POSTAREA); } - for (; ;) { - int board_type = 0; - int conc_type = 0; - int module_type = 0; + /* Gave up on board after too long of time taken */ + err1 = readw(addr + SEQUENCE); + err2 = readw(addr + ERROR); + dev_warn(&brd->pdev->dev, "%s failed diagnostics. Error #(%x,%x).\n", + brd->name, err1, err2); + brd->state = BOARD_FAILED; + brd->dpastatus = BD_NOBIOS; - rc = dgap_gettok(in); - if (rc == 0) { - pr_err("unexpected EOF"); - return -1; - } + return -EIO; +} - switch (rc) { - case BEGIN: /* should only be 1 begin */ - pr_err("unexpected config_begin\n"); - return -1; +/* + * Copies the FEP code from the user to the board, + * and starts the FEP running. + */ +static void dgap_do_fep_load(struct board_t *brd, const u8 *ufep, int len) +{ + u8 __iomem *addr; + uint offset; - case END: - return 0; + if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase) + return; - case BOARD: /* board info */ - if (dgap_checknode(p)) - return -1; + addr = brd->re_map_membase; - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + /* + * Download FEP + */ + offset = 0x1000; + memcpy_toio(addr + offset, ufep, len); - p = p->next; + /* + * If board is a concentrator product, we need to give + * it its config string describing how the concentrators look. + */ + if ((brd->type == PCX) || (brd->type == PEPC)) { + u8 string[100]; + u8 __iomem *config; + u8 *xconfig; + unsigned int i = 0; - p->type = BNODE; - p->u.board.status = kstrdup("No", GFP_KERNEL); - line = conc = NULL; - brd = p; - linecnt = -1; + xconfig = dgap_create_config_string(brd, string); - board_type = dgap_gettok(in); - if (board_type == 0) { - pr_err("board !!type not specified"); - return -1; - } + /* Write string to board memory */ + config = addr + CONFIG; + for (; i < CONFIGSIZE; i++, config++, xconfig++) { + writeb(*xconfig, config); + if ((*xconfig & 0xff) == 0xff) + break; + } + } - p->u.board.type = board_type; + writel(0xbfc01004, (addr + 0xc34)); + writel(0x3, (addr + 0xc30)); - break; +} - case IO: /* i/o port */ - if (p->type != BNODE) { - pr_err("IO port only vaild for boards"); - return -1; - } - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - p->u.board.portstr = kstrdup(s, GFP_KERNEL); - if (kstrtol(s, 0, &p->u.board.port)) { - pr_err("bad number for IO port"); - return -1; - } - p->u.board.v_port = 1; - break; +/* + * Waits for the FEP to report thats its ready for us to use. + */ +static int dgap_test_fep(struct board_t *brd) +{ + u8 __iomem *addr; + u16 word; + u16 err1; + u16 err2; - case MEM: /* memory address */ - if (p->type != BNODE) { - pr_err("memory address only vaild for boards"); - return -1; - } - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - p->u.board.addrstr = kstrdup(s, GFP_KERNEL); - if (kstrtoul(s, 0, &p->u.board.addr)) { - pr_err("bad number for memory address"); - return -1; - } - p->u.board.v_addr = 1; - break; + if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase) + return -EINVAL; - case PCIINFO: /* pci information */ - if (p->type != BNODE) { - pr_err("memory address only vaild for boards"); - return -1; - } - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - p->u.board.pcibusstr = kstrdup(s, GFP_KERNEL); - if (kstrtoul(s, 0, &p->u.board.pcibus)) { - pr_err("bad number for pci bus"); - return -1; - } - p->u.board.v_pcibus = 1; - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - p->u.board.pcislotstr = kstrdup(s, GFP_KERNEL); - if (kstrtoul(s, 0, &p->u.board.pcislot)) { - pr_err("bad number for pci slot"); - return -1; - } - p->u.board.v_pcislot = 1; - break; + addr = brd->re_map_membase; + word = readw(addr + FEPSTAT); - case METHOD: - if (p->type != BNODE) { - pr_err("install method only vaild for boards"); - return -1; - } - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - p->u.board.method = kstrdup(s, GFP_KERNEL); - p->u.board.v_method = 1; - break; + /* + * It can take 2-3 seconds for the FEP to + * be up and running. Give it 5 secs. + */ + brd->wait_for_fep = 0; + while (brd->wait_for_fep < 500) { + /* Check to see if FEP is up and running now. */ + if (word == *(u16 *) "OS") { + /* + * Check to see if the board can support FEP5+ commands. + */ + word = readw(addr + FEP5_PLUS); + if (word == *(u16 *) "5A") + brd->bd_flags |= BD_FEP5PLUS; - case STATUS: - if (p->type != BNODE) { - pr_err("config status only vaild for boards"); - return -1; - } - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - p->u.board.status = kstrdup(s, GFP_KERNEL); - break; + return 0; + } + msleep_interruptible(10); + brd->wait_for_fep++; + word = readw(addr + FEPSTAT); + } - case NPORTS: /* number of ports */ - if (p->type == BNODE) { - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.board.nport)) { - pr_err("bad number for number of ports"); - return -1; - } - p->u.board.v_nport = 1; - } else if (p->type == CNODE) { - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.conc.nport)) { - pr_err("bad number for number of ports"); - return -1; - } - p->u.conc.v_nport = 1; - } else if (p->type == MNODE) { - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.module.nport)) { - pr_err("bad number for number of ports"); - return -1; - } - p->u.module.v_nport = 1; - } else { - pr_err("nports only valid for concentrators or modules"); - return -1; - } - break; + /* Gave up on board after too long of time taken */ + err1 = readw(addr + SEQUENCE); + err2 = readw(addr + ERROR); + dev_warn(&brd->pdev->dev, + "FEPOS for %s not functioning. Error #(%x,%x).\n", + brd->name, err1, err2); + brd->state = BOARD_FAILED; + brd->dpastatus = BD_NOFEP; - case ID: /* letter ID used in tty name */ - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } + return -EIO; +} - p->u.board.status = kstrdup(s, GFP_KERNEL); +/* + * Physically forces the FEP5 card to reset itself. + */ +static void dgap_do_reset_board(struct board_t *brd) +{ + u8 check; + u32 check1; + u32 check2; + unsigned int i; - if (p->type == CNODE) { - p->u.conc.id = kstrdup(s, GFP_KERNEL); - p->u.conc.v_id = 1; - } else if (p->type == MNODE) { - p->u.module.id = kstrdup(s, GFP_KERNEL); - p->u.module.v_id = 1; - } else { - pr_err("id only valid for concentrators or modules"); - return -1; - } - break; + if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || + !brd->re_map_membase || !brd->re_map_port) + return; - case STARTO: /* start offset of ID */ - if (p->type == BNODE) { - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.board.start)) { - pr_err("bad number for start of tty count"); - return -1; - } - p->u.board.v_start = 1; - } else if (p->type == CNODE) { - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.conc.start)) { - pr_err("bad number for start of tty count"); - return -1; - } - p->u.conc.v_start = 1; - } else if (p->type == MNODE) { - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.module.start)) { - pr_err("bad number for start of tty count"); - return -1; - } - p->u.module.v_start = 1; - } else { - pr_err("start only valid for concentrators or modules"); - return -1; - } + /* FEPRST does not vary among supported boards */ + writeb(FEPRST, brd->re_map_port); + + for (i = 0; i <= 1000; i++) { + check = readb(brd->re_map_port) & 0xe; + if (check == FEPRST) break; + udelay(10); - case TTYN: /* tty name prefix */ - if (dgap_checknode(p)) - return -1; + } + if (i > 1000) { + dev_warn(&brd->pdev->dev, + "dgap: Board not resetting... Failing board.\n"); + brd->state = BOARD_FAILED; + brd->dpastatus = BD_NOFEP; + return; + } - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + /* + * Make sure there really is memory out there. + */ + writel(0xa55a3cc3, (brd->re_map_membase + LOWMEM)); + writel(0x5aa5c33c, (brd->re_map_membase + HIGHMEM)); + check1 = readl(brd->re_map_membase + LOWMEM); + check2 = readl(brd->re_map_membase + HIGHMEM); - p = p->next; - p->type = TNODE; + if ((check1 != 0xa55a3cc3) || (check2 != 0x5aa5c33c)) { + dev_warn(&brd->pdev->dev, + "No memory at %p for board.\n", + brd->re_map_membase); + brd->state = BOARD_FAILED; + brd->dpastatus = BD_NOFEP; + return; + } +} - s = dgap_getword(in); - if (!s) { - pr_err("unexpeced end of file"); - return -1; - } - p->u.ttyname = kstrdup(s, GFP_KERNEL); - if (!p->u.ttyname) - return -1; +#ifdef DIGI_CONCENTRATORS_SUPPORTED +/* + * Sends a concentrator image into the FEP5 board. + */ +static void dgap_do_conc_load(struct board_t *brd, u8 *uaddr, int len) +{ + char __iomem *vaddr; + u16 offset; + struct downld_t *to_dp; - break; + if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase) + return; - case CU: /* cu name prefix */ - if (dgap_checknode(p)) - return -1; + vaddr = brd->re_map_membase; - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + offset = readw((u16 *) (vaddr + DOWNREQ)); + to_dp = (struct downld_t *) (vaddr + (int) offset); + memcpy_toio(to_dp, uaddr, len); - p = p->next; - p->type = CUNODE; + /* Tell card we have data for it */ + writew(0, vaddr + (DOWNREQ)); - s = dgap_getword(in); - if (!s) { - pr_err("unexpeced end of file"); - return -1; - } - p->u.cuname = kstrdup(s, GFP_KERNEL); - if (!p->u.cuname) - return -1; + brd->conc_dl_status = NO_PENDING_CONCENTRATOR_REQUESTS; +} +#endif - break; +#define EXPANSION_ROM_SIZE (64 * 1024) +#define FEP5_ROM_MAGIC (0xFEFFFFFF) - case LINE: /* line information */ - if (dgap_checknode(p)) - return -1; - if (!brd) { - pr_err("must specify board before line info"); - return -1; - } - switch (brd->u.board.type) { - case PPCM: - pr_err("line not vaild for PC/em"); - return -1; - } +static void dgap_get_vpd(struct board_t *brd) +{ + u32 magic; + u32 base_offset; + u16 rom_offset; + u16 vpd_offset; + u16 image_length; + u16 i; + u8 byte1; + u8 byte2; - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + /* + * Poke the magic number at the PCI Rom Address location. + * If VPD is supported, the value read from that address + * will be non-zero. + */ + magic = FEP5_ROM_MAGIC; + pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic); + pci_read_config_dword(brd->pdev, PCI_ROM_ADDRESS, &magic); - p = p->next; - p->type = LNODE; - conc = NULL; - line = p; - linecnt++; - break; + /* VPD not supported, bail */ + if (!magic) + return; - case CONC: /* concentrator information */ - if (dgap_checknode(p)) - return -1; - if (!line) { - pr_err("must specify line info before concentrator"); - return -1; - } + /* + * To get to the OTPROM memory, we have to send the boards base + * address or'ed with 1 into the PCI Rom Address location. + */ + magic = brd->membase | 0x01; + pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic); + pci_read_config_dword(brd->pdev, PCI_ROM_ADDRESS, &magic); - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + byte1 = readb(brd->re_map_membase); + byte2 = readb(brd->re_map_membase + 1); - p = p->next; - p->type = CNODE; - conc = p; + /* + * If the board correctly swapped to the OTPROM memory, + * the first 2 bytes (header) should be 0x55, 0xAA + */ + if (byte1 == 0x55 && byte2 == 0xAA) { - if (linecnt) - brd->u.board.conc2++; - else - brd->u.board.conc1++; + base_offset = 0; - conc_type = dgap_gettok(in); - if (conc_type == 0 || conc_type != CX || - conc_type != EPC) { - pr_err("failed to set a type of concentratros"); - return -1; - } + /* + * We have to run through all the OTPROM memory looking + * for the VPD offset. + */ + while (base_offset <= EXPANSION_ROM_SIZE) { - p->u.conc.type = conc_type; + /* + * Lots of magic numbers here. + * + * The VPD offset is located inside the ROM Data + * Structure. + * + * We also have to remember the length of each + * ROM Data Structure, so we can "hop" to the next + * entry if the VPD isn't in the current + * ROM Data Structure. + */ + rom_offset = readw(brd->re_map_membase + + base_offset + 0x18); + image_length = readw(brd->re_map_membase + + rom_offset + 0x10) * 512; + vpd_offset = readw(brd->re_map_membase + + rom_offset + 0x08); - break; + /* Found the VPD entry */ + if (vpd_offset) + break; - case MOD: /* EBI module */ - if (dgap_checknode(p)) - return -1; - if (!brd) { - pr_err("must specify board info before EBI modules"); - return -1; - } - switch (brd->u.board.type) { - case PPCM: - linecnt = 0; + /* We didn't find a VPD entry, go to next ROM entry. */ + base_offset += image_length; + + byte1 = readb(brd->re_map_membase + base_offset); + byte2 = readb(brd->re_map_membase + base_offset + 1); + + /* + * If the new ROM offset doesn't have 0x55, 0xAA + * as its header, we have run out of ROM. + */ + if (byte1 != 0x55 || byte2 != 0xAA) break; - default: - if (!conc) { - pr_err("must specify concentrator info before EBI module"); - return -1; - } + } + + /* + * If we have a VPD offset, then mark the board + * as having a valid VPD, and copy VPDSIZE (512) bytes of + * that VPD to the buffer we have in our board structure. + */ + if (vpd_offset) { + brd->bd_flags |= BD_HAS_VPD; + for (i = 0; i < VPDSIZE; i++) { + brd->vpd[i] = readb(brd->re_map_membase + + vpd_offset + i); } + } + } - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + /* + * We MUST poke the magic number at the PCI Rom Address location again. + * This makes the card report the regular board memory back to us, + * rather than the OTPROM memory. + */ + magic = FEP5_ROM_MAGIC; + pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic); +} - p = p->next; - p->type = MNODE; - if (linecnt) - brd->u.board.module2++; - else - brd->u.board.module1++; +static ssize_t dgap_driver_version_show(struct device_driver *ddp, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", DG_PART); +} +static DRIVER_ATTR(version, S_IRUSR, dgap_driver_version_show, NULL); - module_type = dgap_gettok(in); - if (module_type == 0 || module_type != PORTS || - module_type != MODEM) { - pr_err("failed to set a type of module"); - return -1; - } - p->u.module.type = module_type; +static ssize_t dgap_driver_boards_show(struct device_driver *ddp, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", dgap_numboards); +} +static DRIVER_ATTR(boards, S_IRUSR, dgap_driver_boards_show, NULL); - break; - case CABLE: - if (p->type == LNODE) { - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - p->u.line.cable = kstrdup(s, GFP_KERNEL); - p->u.line.v_cable = 1; - } - break; +static ssize_t dgap_driver_maxboards_show(struct device_driver *ddp, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", MAXBOARDS); +} +static DRIVER_ATTR(maxboards, S_IRUSR, dgap_driver_maxboards_show, NULL); - case SPEED: /* sync line speed indication */ - if (p->type == LNODE) { - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.line.speed)) { - pr_err("bad number for line speed"); - return -1; - } - p->u.line.v_speed = 1; - } else if (p->type == CNODE) { - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.conc.speed)) { - pr_err("bad number for line speed"); - return -1; - } - p->u.conc.v_speed = 1; - } else { - pr_err("speed valid only for lines or concentrators."); - return -1; - } - break; - case CONNECT: - if (p->type == CNODE) { - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - p->u.conc.connect = kstrdup(s, GFP_KERNEL); - p->u.conc.v_connect = 1; - } - break; - case PRINT: /* transparent print name prefix */ - if (dgap_checknode(p)) - return -1; +static ssize_t dgap_driver_pollcounter_show(struct device_driver *ddp, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%ld\n", dgap_poll_counter); +} +static DRIVER_ATTR(pollcounter, S_IRUSR, dgap_driver_pollcounter_show, NULL); - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; +static ssize_t dgap_driver_pollrate_show(struct device_driver *ddp, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%dms\n", dgap_poll_tick); +} - p = p->next; - p->type = PNODE; +static ssize_t dgap_driver_pollrate_store(struct device_driver *ddp, + const char *buf, size_t count) +{ + if (sscanf(buf, "%d\n", &dgap_poll_tick) != 1) + return -EINVAL; + return count; +} +static DRIVER_ATTR(pollrate, (S_IRUSR | S_IWUSR), dgap_driver_pollrate_show, + dgap_driver_pollrate_store); - s = dgap_getword(in); - if (!s) { - pr_err("unexpeced end of file"); - return -1; - } - p->u.printname = kstrdup(s, GFP_KERNEL); - if (!p->u.printname) - return -1; - break; +static int dgap_create_driver_sysfiles(struct pci_driver *dgap_driver) +{ + int rc = 0; + struct device_driver *driverfs = &dgap_driver->driver; - case CMAJOR: /* major number */ - if (dgap_checknode(p)) - return -1; + rc |= driver_create_file(driverfs, &driver_attr_version); + rc |= driver_create_file(driverfs, &driver_attr_boards); + rc |= driver_create_file(driverfs, &driver_attr_maxboards); + rc |= driver_create_file(driverfs, &driver_attr_pollrate); + rc |= driver_create_file(driverfs, &driver_attr_pollcounter); - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + return rc; +} - p = p->next; - p->type = JNODE; +static void dgap_remove_driver_sysfiles(struct pci_driver *dgap_driver) +{ + struct device_driver *driverfs = &dgap_driver->driver; - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.majornumber)) { - pr_err("bad number for major number"); - return -1; - } - break; + driver_remove_file(driverfs, &driver_attr_version); + driver_remove_file(driverfs, &driver_attr_boards); + driver_remove_file(driverfs, &driver_attr_maxboards); + driver_remove_file(driverfs, &driver_attr_pollrate); + driver_remove_file(driverfs, &driver_attr_pollcounter); +} - case ALTPIN: /* altpin setting */ - if (dgap_checknode(p)) - return -1; +static struct attribute_group dgap_tty_attribute_group = { + .name = NULL, + .attrs = dgap_sysfs_tty_entries, +}; - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; +static void dgap_create_tty_sysfs(struct un_t *un, struct device *c) +{ + int ret; - p = p->next; - p->type = ANODE; + ret = sysfs_create_group(&c->kobj, &dgap_tty_attribute_group); + if (ret) + return; - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.altpin)) { - pr_err("bad number for altpin"); - return -1; - } - break; + dev_set_drvdata(c, un); - case USEINTR: /* enable interrupt setting */ - if (dgap_checknode(p)) - return -1; +} - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; +static void dgap_remove_tty_sysfs(struct device *c) +{ + sysfs_remove_group(&c->kobj, &dgap_tty_attribute_group); +} - p = p->next; - p->type = INTRNODE; - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.useintr)) { - pr_err("bad number for useintr"); - return -1; - } - break; +/* + * Create pr and tty device entries + */ +static int dgap_tty_register_ports(struct board_t *brd) +{ + struct channel_t *ch; + int i; + int ret; - case TTSIZ: /* size of tty structure */ - if (dgap_checknode(p)) - return -1; + brd->serial_ports = kcalloc(brd->nasync, sizeof(*brd->serial_ports), + GFP_KERNEL); + if (!brd->serial_ports) + return -ENOMEM; - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + brd->printer_ports = kcalloc(brd->nasync, sizeof(*brd->printer_ports), + GFP_KERNEL); + if (!brd->printer_ports) { + ret = -ENOMEM; + goto free_serial_ports; + } - p = p->next; - p->type = TSNODE; + for (i = 0; i < brd->nasync; i++) { + tty_port_init(&brd->serial_ports[i]); + tty_port_init(&brd->printer_ports[i]); + } - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.ttysize)) { - pr_err("bad number for ttysize"); - return -1; - } - break; + ch = brd->channels[0]; + for (i = 0; i < brd->nasync; i++, ch = brd->channels[i]) { - case CHSIZ: /* channel structure size */ - if (dgap_checknode(p)) - return -1; + struct device *classp; - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + classp = tty_port_register_device(&brd->serial_ports[i], + brd->serial_driver, + i, NULL); - p = p->next; - p->type = CSNODE; + if (IS_ERR(classp)) { + ret = PTR_ERR(classp); + goto unregister_ttys; + } - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.chsize)) { - pr_err("bad number for chsize"); - return -1; - } - break; + dgap_create_tty_sysfs(&ch->ch_tun, classp); + ch->ch_tun.un_sysfs = classp; - case BSSIZ: /* board structure size */ - if (dgap_checknode(p)) - return -1; + classp = tty_port_register_device(&brd->printer_ports[i], + brd->print_driver, + i, NULL); - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + if (IS_ERR(classp)) { + ret = PTR_ERR(classp); + goto unregister_ttys; + } - p = p->next; - p->type = BSNODE; + dgap_create_tty_sysfs(&ch->ch_pun, classp); + ch->ch_pun.un_sysfs = classp; + } + dgap_create_ports_sysfiles(brd); - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.bssize)) { - pr_err("bad number for bssize"); - return -1; - } - break; + return 0; - case UNTSIZ: /* sched structure size */ - if (dgap_checknode(p)) - return -1; +unregister_ttys: + while (i >= 0) { + ch = brd->channels[i]; + if (ch->ch_tun.un_sysfs) { + dgap_remove_tty_sysfs(ch->ch_tun.un_sysfs); + tty_unregister_device(brd->serial_driver, i); + } - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + if (ch->ch_pun.un_sysfs) { + dgap_remove_tty_sysfs(ch->ch_pun.un_sysfs); + tty_unregister_device(brd->print_driver, i); + } + i--; + } - p = p->next; - p->type = USNODE; + for (i = 0; i < brd->nasync; i++) { + tty_port_destroy(&brd->serial_ports[i]); + tty_port_destroy(&brd->printer_ports[i]); + } - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.unsize)) { - pr_err("bad number for schedsize"); - return -1; - } - break; + kfree(brd->printer_ports); + brd->printer_ports = NULL; - case F2SIZ: /* f2200 structure size */ - if (dgap_checknode(p)) - return -1; +free_serial_ports: + kfree(brd->serial_ports); + brd->serial_ports = NULL; - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + return ret; +} - p = p->next; - p->type = FSNODE; +/* + * dgap_cleanup_tty() + * + * Uninitialize the TTY portion of this driver. Free all memory and + * resources. + */ +static void dgap_cleanup_tty(struct board_t *brd) +{ + struct device *dev; + unsigned int i; - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.f2size)) { - pr_err("bad number for f2200size"); - return -1; - } - break; + for (i = 0; i < brd->nasync; i++) { + tty_port_destroy(&brd->serial_ports[i]); + dev = brd->channels[i]->ch_tun.un_sysfs; + dgap_remove_tty_sysfs(dev); + tty_unregister_device(brd->serial_driver, i); + } + tty_unregister_driver(brd->serial_driver); + put_tty_driver(brd->serial_driver); + kfree(brd->serial_ports); - case VPSIZ: /* vpix structure size */ - if (dgap_checknode(p)) - return -1; + for (i = 0; i < brd->nasync; i++) { + tty_port_destroy(&brd->printer_ports[i]); + dev = brd->channels[i]->ch_pun.un_sysfs; + dgap_remove_tty_sysfs(dev); + tty_unregister_device(brd->print_driver, i); + } + tty_unregister_driver(brd->print_driver); + put_tty_driver(brd->print_driver); + kfree(brd->printer_ports); +} - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; +static int dgap_request_irq(struct board_t *brd) +{ + int rc; - p = p->next; - p->type = VSNODE; + if (!brd || brd->magic != DGAP_BOARD_MAGIC) + return -ENODEV; - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.vpixsize)) { - pr_err("bad number for vpixsize"); - return -1; - } - break; - } + /* + * Set up our interrupt handler if we are set to do interrupts. + */ + if (dgap_config_get_useintr(brd) && brd->irq) { + + rc = request_irq(brd->irq, dgap_intr, IRQF_SHARED, "DGAP", brd); + + if (!rc) + brd->intr_used = 1; } + return 0; } -/* - * dgap_sindex: much like index(), but it looks for a match of any character in - * the group, and returns that position. If the first character is a ^, then - * this will match the first occurrence not in that group. - */ -static char *dgap_sindex(char *string, char *group) +static void dgap_free_irq(struct board_t *brd) { - char *ptr; + if (brd->intr_used && brd->irq) + free_irq(brd->irq, brd); +} - if (!string || !group) - return (char *) NULL; +static int dgap_firmware_load(struct pci_dev *pdev, int card_type, + struct board_t *brd) +{ + const struct firmware *fw; + char *tmp_ptr; + int ret; + char *dgap_config_buf; - if (*group == '^') { - group++; - for (; *string; string++) { - for (ptr = group; *ptr; ptr++) { - if (*ptr == *string) - break; - } - if (*ptr == '\0') - return string; + dgap_get_vpd(brd); + dgap_do_reset_board(brd); + + if (fw_info[card_type].conf_name) { + ret = request_firmware(&fw, fw_info[card_type].conf_name, + &pdev->dev); + if (ret) { + dev_err(&pdev->dev, "config file %s not found\n", + fw_info[card_type].conf_name); + return ret; } - } else { - for (; *string; string++) { - for (ptr = group; *ptr; ptr++) { - if (*ptr == *string) - return string; - } + + dgap_config_buf = kzalloc(fw->size + 1, GFP_KERNEL); + if (!dgap_config_buf) { + release_firmware(fw); + return -ENOMEM; + } + + memcpy(dgap_config_buf, fw->data, fw->size); + release_firmware(fw); + + /* + * preserve dgap_config_buf + * as dgap_parsefile would + * otherwise alter it. + */ + tmp_ptr = dgap_config_buf; + + if (dgap_parsefile(&tmp_ptr) != 0) { + kfree(dgap_config_buf); + return -EINVAL; } + kfree(dgap_config_buf); } - return (char *) NULL; -} + /* + * Match this board to a config the user created for us. + */ + brd->bd_config = + dgap_find_config(brd->type, brd->pci_bus, brd->pci_slot); -/* - * Get a token from the input file; return 0 if end of file is reached - */ -static int dgap_gettok(char **in) -{ - char *w; - struct toklist *t; + /* + * Because the 4 port Xr products share the same PCI ID + * as the 8 port Xr products, if we receive a NULL config + * back, and this is a PAPORT8 board, retry with a + * PAPORT4 attempt as well. + */ + if (brd->type == PAPORT8 && !brd->bd_config) + brd->bd_config = + dgap_find_config(PAPORT4, brd->pci_bus, brd->pci_slot); - if (strstr(dgap_cword, "board")) { - w = dgap_getword(in); - snprintf(dgap_cword, MAXCWORD, "%s", w); - for (t = dgap_brdtype; t->token != 0; t++) { - if (!strcmp(w, t->string)) - return t->token; + if (!brd->bd_config) { + dev_err(&pdev->dev, "No valid configuration found\n"); + return -EINVAL; + } + + if (fw_info[card_type].bios_name) { + ret = request_firmware(&fw, fw_info[card_type].bios_name, + &pdev->dev); + if (ret) { + dev_err(&pdev->dev, "bios file %s not found\n", + fw_info[card_type].bios_name); + return ret; } - } else { - while ((w = dgap_getword(in))) { - snprintf(dgap_cword, MAXCWORD, "%s", w); - for (t = dgap_tlist; t->token != 0; t++) { - if (!strcmp(w, t->string)) - return t->token; - } + dgap_do_bios_load(brd, fw->data, fw->size); + release_firmware(fw); + + /* Wait for BIOS to test board... */ + ret = dgap_test_bios(brd); + if (ret) + return ret; + } + + if (fw_info[card_type].fep_name) { + ret = request_firmware(&fw, fw_info[card_type].fep_name, + &pdev->dev); + if (ret) { + dev_err(&pdev->dev, "dgap: fep file %s not found\n", + fw_info[card_type].fep_name); + return ret; + } + dgap_do_fep_load(brd, fw->data, fw->size); + release_firmware(fw); + + /* Wait for FEP to load on board... */ + ret = dgap_test_fep(brd); + if (ret) + return ret; + } + +#ifdef DIGI_CONCENTRATORS_SUPPORTED + /* + * If this is a CX or EPCX, we need to see if the firmware + * is requesting a concentrator image from us. + */ + if ((bd->type == PCX) || (bd->type == PEPC)) { + chk_addr = (u16 *) (vaddr + DOWNREQ); + /* Nonzero if FEP is requesting concentrator image. */ + check = readw(chk_addr); + vaddr = brd->re_map_membase; + } + + if (fw_info[card_type].con_name && check && vaddr) { + ret = request_firmware(&fw, fw_info[card_type].con_name, + &pdev->dev); + if (ret) { + dev_err(&pdev->dev, "conc file %s not found\n", + fw_info[card_type].con_name); + return ret; } + /* Put concentrator firmware loading code here */ + offset = readw((u16 *) (vaddr + DOWNREQ)); + memcpy_toio(offset, fw->data, fw->size); + + dgap_do_conc_load(brd, (char *)fw->data, fw->size) + release_firmware(fw); } +#endif return 0; } /* - * get a word from the input stream, also keep track of current line number. - * words are separated by whitespace. + * dgap_tty_init() + * + * Init the tty subsystem. Called once per board after board has been + * downloaded and init'ed. */ -static char *dgap_getword(char **in) +static int dgap_tty_init(struct board_t *brd) { - char *ret_ptr = *in; + int i; + int tlw; + uint true_count; + u8 __iomem *vaddr; + u8 modem; + struct channel_t *ch; + struct bs_t __iomem *bs; + struct cm_t __iomem *cm; + int ret; - char *ptr = dgap_sindex(*in, " \t\n"); + /* + * Initialize board structure elements. + */ - /* If no word found, return null */ - if (!ptr) - return NULL; + vaddr = brd->re_map_membase; + true_count = readw((vaddr + NCHAN)); - /* Mark new location for our buffer */ - *ptr = '\0'; - *in = ptr + 1; + brd->nasync = dgap_config_get_num_prts(brd); - /* Eat any extra spaces/tabs/newlines that might be present */ - while (*in && **in && ((**in == ' ') || - (**in == '\t') || - (**in == '\n'))) { - **in = '\0'; - *in = *in + 1; - } + if (!brd->nasync) + brd->nasync = brd->maxports; - return ret_ptr; -} + if (brd->nasync > brd->maxports) + brd->nasync = brd->maxports; -/* - * dgap_checknode: see if all the necessary info has been supplied for a node - * before creating the next node. - */ -static int dgap_checknode(struct cnode *p) -{ - switch (p->type) { - case LNODE: - if (p->u.line.v_speed == 0) { - pr_err("line speed not specified"); - return 1; - } - return 0; + if (true_count != brd->nasync) { + dev_warn(&brd->pdev->dev, + "%s configured for %d ports, has %d ports.\n", + brd->name, brd->nasync, true_count); - case CNODE: - if (p->u.conc.v_speed == 0) { - pr_err("concentrator line speed not specified"); - return 1; - } - if (p->u.conc.v_nport == 0) { - pr_err("number of ports on concentrator not specified"); - return 1; + if ((brd->type == PPCM) && + (true_count == 64 || true_count == 0)) { + dev_warn(&brd->pdev->dev, + "Please make SURE the EBI cable running from the card\n"); + dev_warn(&brd->pdev->dev, + "to each EM module is plugged into EBI IN!\n"); } - if (p->u.conc.v_id == 0) { - pr_err("concentrator id letter not specified"); - return 1; + + brd->nasync = true_count; + + /* If no ports, don't bother going any further */ + if (!brd->nasync) { + brd->state = BOARD_FAILED; + brd->dpastatus = BD_NOFEP; + return -EIO; } - return 0; + } - case MNODE: - if (p->u.module.v_nport == 0) { - pr_err("number of ports on EBI module not specified"); - return 1; + /* + * Allocate channel memory that might not have been allocated + * when the driver was first loaded. + */ + for (i = 0; i < brd->nasync; i++) { + brd->channels[i] = + kzalloc(sizeof(struct channel_t), GFP_KERNEL); + if (!brd->channels[i]) { + ret = -ENOMEM; + goto free_chan; } - if (p->u.module.v_id == 0) { - pr_err("EBI module id letter not specified"); - return 1; + } + + ch = brd->channels[0]; + vaddr = brd->re_map_membase; + + bs = (struct bs_t __iomem *) ((ulong) vaddr + CHANBUF); + cm = (struct cm_t __iomem *) ((ulong) vaddr + CMDBUF); + + brd->bd_bs = bs; + + /* Set up channel variables */ + for (i = 0; i < brd->nasync; i++, ch = brd->channels[i], bs++) { + + spin_lock_init(&ch->ch_lock); + + /* Store all our magic numbers */ + ch->magic = DGAP_CHANNEL_MAGIC; + ch->ch_tun.magic = DGAP_UNIT_MAGIC; + ch->ch_tun.un_type = DGAP_SERIAL; + ch->ch_tun.un_ch = ch; + ch->ch_tun.un_dev = i; + + ch->ch_pun.magic = DGAP_UNIT_MAGIC; + ch->ch_pun.un_type = DGAP_PRINT; + ch->ch_pun.un_ch = ch; + ch->ch_pun.un_dev = i; + + ch->ch_vaddr = vaddr; + ch->ch_bs = bs; + ch->ch_cm = cm; + ch->ch_bd = brd; + ch->ch_portnum = i; + ch->ch_digi = dgap_digi_init; + + /* + * Set up digi dsr and dcd bits based on altpin flag. + */ + if (dgap_config_get_altpin(brd)) { + ch->ch_dsr = DM_CD; + ch->ch_cd = DM_DSR; + ch->ch_digi.digi_flags |= DIGI_ALTPIN; + } else { + ch->ch_cd = DM_CD; + ch->ch_dsr = DM_DSR; } - return 0; + + ch->ch_taddr = vaddr + (ioread16(&(ch->ch_bs->tx_seg)) << 4); + ch->ch_raddr = vaddr + (ioread16(&(ch->ch_bs->rx_seg)) << 4); + ch->ch_tx_win = 0; + ch->ch_rx_win = 0; + ch->ch_tsize = readw(&(ch->ch_bs->tx_max)) + 1; + ch->ch_rsize = readw(&(ch->ch_bs->rx_max)) + 1; + ch->ch_tstart = 0; + ch->ch_rstart = 0; + + /* + * Set queue water marks, interrupt mask, + * and general tty parameters. + */ + tlw = ch->ch_tsize >= 2000 ? ((ch->ch_tsize * 5) / 8) : + ch->ch_tsize / 2; + ch->ch_tlw = tlw; + + dgap_cmdw(ch, STLOW, tlw, 0); + + dgap_cmdw(ch, SRLOW, ch->ch_rsize / 2, 0); + + dgap_cmdw(ch, SRHIGH, 7 * ch->ch_rsize / 8, 0); + + ch->ch_mistat = readb(&(ch->ch_bs->m_stat)); + + init_waitqueue_head(&ch->ch_flags_wait); + init_waitqueue_head(&ch->ch_tun.un_flags_wait); + init_waitqueue_head(&ch->ch_pun.un_flags_wait); + + /* Turn on all modem interrupts for now */ + modem = (DM_CD | DM_DSR | DM_CTS | DM_RI); + writeb(modem, &(ch->ch_bs->m_int)); + + /* + * Set edelay to 0 if interrupts are turned on, + * otherwise set edelay to the usual 100. + */ + if (brd->intr_used) + writew(0, &(ch->ch_bs->edelay)); + else + writew(100, &(ch->ch_bs->edelay)); + + writeb(1, &(ch->ch_bs->idata)); } + return 0; + +free_chan: + while (--i >= 0) { + kfree(brd->channels[i]); + brd->channels[i] = NULL; + } + return ret; } /* - * Given a board pointer, returns whether we should use interrupts or not. + * dgap_tty_free() + * + * Free the channles which are allocated in dgap_tty_init(). */ -static uint dgap_config_get_useintr(struct board_t *bd) +static void dgap_tty_free(struct board_t *brd) { - struct cnode *p; + int i; - if (!bd) - return 0; + for (i = 0; i < brd->nasync; i++) + kfree(brd->channels[i]); +} - for (p = bd->bd_config; p; p = p->next) { - if (p->type == INTRNODE) { - /* - * check for pcxr types. - */ - return p->u.useintr; - } - } +static int dgap_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + int rc; + struct board_t *brd; + + if (dgap_numboards >= MAXBOARDS) + return -EPERM; + + rc = pci_enable_device(pdev); + if (rc) + return -EIO; + + brd = dgap_found_board(pdev, ent->driver_data, dgap_numboards); + if (IS_ERR(brd)) + return PTR_ERR(brd); + + rc = dgap_firmware_load(pdev, ent->driver_data, brd); + if (rc) + goto cleanup_brd; + + rc = dgap_alloc_flipbuf(brd); + if (rc) + goto cleanup_brd; + + rc = dgap_tty_register(brd); + if (rc) + goto free_flipbuf; + + rc = dgap_request_irq(brd); + if (rc) + goto unregister_tty; + + /* + * Do tty device initialization. + */ + rc = dgap_tty_init(brd); + if (rc < 0) + goto free_irq; + + rc = dgap_tty_register_ports(brd); + if (rc) + goto tty_free; + + brd->state = BOARD_READY; + brd->dpastatus = BD_RUNNING; + + dgap_board[dgap_numboards++] = brd; - /* If not found, then don't turn on interrupts. */ return 0; + +tty_free: + dgap_tty_free(brd); +free_irq: + dgap_free_irq(brd); +unregister_tty: + dgap_tty_unregister(brd); +free_flipbuf: + dgap_free_flipbuf(brd); +cleanup_brd: + dgap_cleanup_nodes(); + dgap_unmap(brd); + kfree(brd); + + return rc; } +static void dgap_remove_one(struct pci_dev *dev) +{ + /* Do Nothing */ +} + +static struct pci_driver dgap_driver = { + .name = "dgap", + .probe = dgap_init_one, + .id_table = dgap_pci_tbl, + .remove = dgap_remove_one, +}; + /* - * Given a board pointer, returns whether we turn on altpin or not. + * Start of driver. */ -static uint dgap_config_get_altpin(struct board_t *bd) +static int dgap_start(void) { - struct cnode *p; + int rc; + unsigned long flags; + struct device *device; - if (!bd) - return 0; + dgap_numboards = 0; - for (p = bd->bd_config; p; p = p->next) { - if (p->type == ANODE) { - /* - * check for pcxr types. - */ - return p->u.altpin; - } + pr_info("For the tools package please visit http://www.digi.com\n"); + + /* + * Register our base character device into the kernel. + */ + + /* + * Register management/dpa devices + */ + rc = register_chrdev(DIGI_DGAP_MAJOR, "dgap", &dgap_board_fops); + if (rc < 0) + return rc; + + dgap_class = class_create(THIS_MODULE, "dgap_mgmt"); + if (IS_ERR(dgap_class)) { + rc = PTR_ERR(dgap_class); + goto failed_class; } - /* If not found, then don't turn on interrupts. */ - return 0; + device = device_create(dgap_class, NULL, + MKDEV(DIGI_DGAP_MAJOR, 0), + NULL, "dgap_mgmt"); + if (IS_ERR(device)) { + rc = PTR_ERR(device); + goto failed_device; + } + + /* Start the poller */ + spin_lock_irqsave(&dgap_poll_lock, flags); + init_timer(&dgap_poll_timer); + dgap_poll_timer.function = dgap_poll_handler; + dgap_poll_timer.data = 0; + dgap_poll_time = jiffies + dgap_jiffies_from_ms(dgap_poll_tick); + dgap_poll_timer.expires = dgap_poll_time; + spin_unlock_irqrestore(&dgap_poll_lock, flags); + + add_timer(&dgap_poll_timer); + + return rc; + +failed_device: + class_destroy(dgap_class); +failed_class: + unregister_chrdev(DIGI_DGAP_MAJOR, "dgap"); + return rc; } -/* - * Given a specific type of board, if found, detached link and - * returns the first occurrence in the list. - */ -static struct cnode *dgap_find_config(int type, int bus, int slot) +static void dgap_stop(void) { - struct cnode *p, *prev, *prev2, *found; + unsigned long lock_flags; - p = &dgap_head; + spin_lock_irqsave(&dgap_poll_lock, lock_flags); + dgap_poll_stop = 1; + spin_unlock_irqrestore(&dgap_poll_lock, lock_flags); - while (p->next) { - prev = p; - p = p->next; + del_timer_sync(&dgap_poll_timer); - if (p->type != BNODE) - continue; + device_destroy(dgap_class, MKDEV(DIGI_DGAP_MAJOR, 0)); + class_destroy(dgap_class); + unregister_chrdev(DIGI_DGAP_MAJOR, "dgap"); +} - if (p->u.board.type != type) - continue; +/* + * dgap_cleanup_board() + * + * Free all the memory associated with a board + */ +static void dgap_cleanup_board(struct board_t *brd) +{ + unsigned int i; - if (p->u.board.v_pcibus && - p->u.board.pcibus != bus) - continue; + if (!brd || brd->magic != DGAP_BOARD_MAGIC) + return; - if (p->u.board.v_pcislot && - p->u.board.pcislot != slot) - continue; + dgap_free_irq(brd); - found = p; - /* - * Keep walking thru the list till we - * find the next board. - */ - while (p->next) { - prev2 = p; - p = p->next; + tasklet_kill(&brd->helper_tasklet); - if (p->type != BNODE) - continue; + dgap_unmap(brd); - /* - * Mark the end of our 1 board - * chain of configs. - */ - prev2->next = NULL; + /* Free all allocated channels structs */ + for (i = 0; i < MAXPORTS ; i++) + kfree(brd->channels[i]); - /* - * Link the "next" board to the - * previous board, effectively - * "unlinking" our board from - * the main config. - */ - prev->next = p; + kfree(brd->flipbuf); + kfree(brd->flipflagbuf); - return found; - } - /* - * It must be the last board in the list. - */ - prev->next = NULL; - return found; - } - return NULL; + dgap_board[brd->boardnum] = NULL; + + kfree(brd); } + +/************************************************************************ + * + * Driver load/unload functions + * + ************************************************************************/ + /* - * Given a board pointer, walks the config link, counting up - * all ports user specified should be on the board. - * (This does NOT mean they are all actually present right now tho) + * init_module() + * + * Module load. This is where it all starts. */ -static uint dgap_config_get_num_prts(struct board_t *bd) +static int dgap_init_module(void) { - int count = 0; - struct cnode *p; + int rc; - if (!bd) - return 0; + pr_info("%s, Digi International Part Number %s\n", DG_NAME, DG_PART); - for (p = bd->bd_config; p; p = p->next) { + rc = dgap_start(); + if (rc) + return rc; - switch (p->type) { - case BNODE: - /* - * check for pcxr types. - */ - if (p->u.board.type > EPCFE) - count += p->u.board.nport; - break; - case CNODE: - count += p->u.conc.nport; - break; - case MNODE: - count += p->u.module.nport; - break; - } - } - return count; + rc = pci_register_driver(&dgap_driver); + if (rc) + goto err_stop; + + rc = dgap_create_driver_sysfiles(&dgap_driver); + if (rc) + goto err_unregister; + + dgap_driver_state = DRIVER_READY; + + return 0; + +err_unregister: + pci_unregister_driver(&dgap_driver); +err_stop: + dgap_stop(); + + return rc; } -static char *dgap_create_config_string(struct board_t *bd, char *string) +/* + * dgap_cleanup_module() + * + * Module unload. This is where it all ends. + */ +static void dgap_cleanup_module(void) { - char *ptr = string; - struct cnode *p; - struct cnode *q; - int speed; + unsigned int i; + ulong lock_flags; - if (!bd) { - *ptr = 0xff; - return string; - } + spin_lock_irqsave(&dgap_poll_lock, lock_flags); + dgap_poll_stop = 1; + spin_unlock_irqrestore(&dgap_poll_lock, lock_flags); - for (p = bd->bd_config; p; p = p->next) { + /* Turn off poller right away. */ + del_timer_sync(&dgap_poll_timer); - switch (p->type) { - case LNODE: - *ptr = '\0'; - ptr++; - *ptr = p->u.line.speed; - ptr++; - break; - case CNODE: - /* - * Because the EPC/con concentrators can have EM modules - * hanging off of them, we have to walk ahead in the - * list and keep adding the number of ports on each EM - * to the config. UGH! - */ - speed = p->u.conc.speed; - q = p->next; - if (q && (q->type == MNODE)) { - *ptr = (p->u.conc.nport + 0x80); - ptr++; - p = q; - while (q->next && (q->next->type) == MNODE) { - *ptr = (q->u.module.nport + 0x80); - ptr++; - p = q; - q = q->next; - } - *ptr = q->u.module.nport; - ptr++; - } else { - *ptr = p->u.conc.nport; - ptr++; - } + dgap_remove_driver_sysfiles(&dgap_driver); - *ptr = speed; - ptr++; - break; - } + device_destroy(dgap_class, MKDEV(DIGI_DGAP_MAJOR, 0)); + class_destroy(dgap_class); + unregister_chrdev(DIGI_DGAP_MAJOR, "dgap"); + + for (i = 0; i < dgap_numboards; ++i) { + dgap_remove_ports_sysfiles(dgap_board[i]); + dgap_cleanup_tty(dgap_board[i]); + dgap_cleanup_board(dgap_board[i]); } - *ptr = 0xff; - return string; + dgap_cleanup_nodes(); + + if (dgap_numboards) + pci_unregister_driver(&dgap_driver); } + +module_init(dgap_init_module); +module_exit(dgap_cleanup_module); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Digi International, http://www.digi.com"); +MODULE_DESCRIPTION("Driver for the Digi International EPCA PCI based product line"); +MODULE_SUPPORTED_DEVICE("dgap"); diff --git a/drivers/staging/dgap/dgap.h b/drivers/staging/dgap/dgap.h index 14e2ed0fe39b..684033156e8c 100644 --- a/drivers/staging/dgap/dgap.h +++ b/drivers/staging/dgap/dgap.h @@ -584,9 +584,6 @@ struct board_t { struct tty_port *printer_ports; char print_name[200]; - u32 dgap_serial_major; - u32 dgap_transparent_print_major; - struct bs_t __iomem *bd_bs; /* Base structure pointer */ char *flipbuf; /* Our flip buffer, alloced if */ diff --git a/drivers/staging/dgnc/dgnc_cls.c b/drivers/staging/dgnc/dgnc_cls.c index a17f4f6095c8..bedc5221b6fc 100644 --- a/drivers/staging/dgnc/dgnc_cls.c +++ b/drivers/staging/dgnc/dgnc_cls.c @@ -724,10 +724,8 @@ static void cls_tasklet(unsigned long data) int state = 0; int ports = 0; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) { - APR(("poll_tasklet() - NULL or bad bd.\n")); + if (!bd || bd->magic != DGNC_BOARD_MAGIC) return; - } /* Cache a couple board values */ spin_lock_irqsave(&bd->bd_lock, flags); @@ -794,25 +792,17 @@ static void cls_tasklet(unsigned long data) */ static irqreturn_t cls_intr(int irq, void *voidbrd) { - struct dgnc_board *brd = (struct dgnc_board *) voidbrd; + struct dgnc_board *brd = voidbrd; uint i = 0; unsigned char poll_reg; unsigned long flags; - if (!brd) { - APR(("Received interrupt (%d) with null board associated\n", - irq)); - return IRQ_NONE; - } - /* - * Check to make sure its for us. + * Check to make sure it didn't receive interrupt with a null board + * associated or a board pointer that wasn't ours. */ - if (brd->magic != DGNC_BOARD_MAGIC) { - APR(("Received interrupt (%d) with a board pointer that wasn't ours!\n", - irq)); + if (!brd || brd->magic != DGNC_BOARD_MAGIC) return IRQ_NONE; - } spin_lock_irqsave(&brd->bd_intr_lock, flags); @@ -928,8 +918,6 @@ static void cls_copy_data_from_uart_to_queue(struct channel_t *ch) ch->ch_equeue[head] = linestatus & (UART_LSR_BI | UART_LSR_PE | UART_LSR_FE); ch->ch_rqueue[head] = readb(&ch->ch_cls_uart->txrx); - dgnc_sniff_nowait_nolock(ch, "UART READ", - ch->ch_rqueue + head, 1); qleft--; @@ -964,7 +952,6 @@ static int cls_drain(struct tty_struct *tty, uint seconds) unsigned long flags; struct channel_t *ch; struct un_t *un; - int rc = 0; if (!tty || tty->magic != TTY_MAGIC) return -ENXIO; @@ -984,12 +971,11 @@ static int cls_drain(struct tty_struct *tty, uint seconds) /* * NOTE: Do something with time passed in. */ - rc = wait_event_interruptible(un->un_flags_wait, - ((un->un_flags & UN_EMPTY) == 0)); /* If ret is non-zero, user ctrl-c'ed us */ - return rc; + return wait_event_interruptible(un->un_flags_wait, + ((un->un_flags & UN_EMPTY) == 0)); } @@ -1098,8 +1084,6 @@ static void cls_copy_data_from_queue_to_uart(struct channel_t *ch) ch->ch_tun.un_flags |= (UN_EMPTY); } writeb(ch->ch_wqueue[ch->ch_w_tail], &ch->ch_cls_uart->txrx); - dgnc_sniff_nowait_nolock(ch, "UART WRITE", - ch->ch_wqueue + ch->ch_w_tail, 1); ch->ch_w_tail++; ch->ch_w_tail &= WQUEUEMASK; ch->ch_txcount++; diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 21546659ff07..ba98ff348112 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -49,16 +49,6 @@ MODULE_AUTHOR("Digi International, http://www.digi.com"); MODULE_DESCRIPTION("Driver for the Digi International Neo and Classic PCI based product line"); MODULE_SUPPORTED_DEVICE("dgnc"); -/* - * insmod command line overrideable parameters - * - * NOTE: we use a set of macros to create the variables, which allows - * us to specify the variable type, name, initial value, and description. - */ -PARM_INT(debug, 0x00, 0644, "Driver debugging level"); -PARM_INT(rawreadok, 1, 0644, "Bypass flip buffers on input"); -PARM_INT(trcbuf_size, 0x100000, 0644, "Debugging trace buffer size."); - /************************************************************************** * * protos for this file @@ -207,8 +197,6 @@ static int __init dgnc_init_module(void) { int rc = 0; - APR(("%s, Digi International Part Number %s\n", DG_NAME, DG_PART)); - /* * Initialize global stuff */ @@ -254,8 +242,6 @@ static int dgnc_start(void) /* make sure that the globals are init'd before we do anything else */ dgnc_init_globals(); - APR(("For the tools package or updated drivers please visit http://www.digi.com\n")); - /* * Register our base character device into the kernel. * This allows the download daemon to connect to the downld device @@ -265,7 +251,7 @@ static int dgnc_start(void) */ rc = register_chrdev(0, "dgnc", &dgnc_BoardFops); if (rc <= 0) { - APR(("Can't register dgnc driver device (%d)\n", rc)); + pr_err(DRVSTR ": Can't register dgnc driver device (%d)\n", rc); return -ENXIO; } dgnc_Major = rc; @@ -281,7 +267,7 @@ static int dgnc_start(void) rc = dgnc_tty_preinit(); if (rc < 0) { - APR(("tty preinit - not enough memory (%d)\n", rc)); + pr_err(DRVSTR ": tty preinit - not enough memory (%d)\n", rc); return rc; } @@ -468,7 +454,8 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) brd->membase = pci_resource_start(pdev, 4); if (!brd->membase) { - APR(("card has no PCI IO resources, failing board.\n")); + dev_err(&brd->pdev->dev, + "Card has no PCI IO resources, failing.\n"); return -ENODEV; } @@ -555,7 +542,8 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) break; default: - APR(("Did not find any compatible Neo or Classic PCI boards in system.\n")); + dev_err(&brd->pdev->dev, + "Didn't find any compatible Neo/Classic PCI boards.\n"); return -ENXIO; } @@ -567,7 +555,7 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) rc = dgnc_tty_register(brd); if (rc < 0) { dgnc_tty_uninit(brd); - APR(("Can't register tty devices (%d)\n", rc)); + pr_err(DRVSTR ": Can't register tty devices (%d)\n", rc); brd->state = BOARD_FAILED; brd->dpastatus = BD_NOFEP; goto failed; @@ -575,7 +563,7 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) rc = dgnc_finalize_board_init(brd); if (rc < 0) { - APR(("Can't finalize board init (%d)\n", rc)); + pr_err(DRVSTR ": Can't finalize board init (%d)\n", rc); brd->state = BOARD_FAILED; brd->dpastatus = BD_NOFEP; @@ -585,7 +573,7 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) rc = dgnc_tty_init(brd); if (rc < 0) { dgnc_tty_uninit(brd); - APR(("Can't init tty devices (%d)\n", rc)); + pr_err(DRVSTR ": Can't init tty devices (%d)\n", rc); brd->state = BOARD_FAILED; brd->dpastatus = BD_NOFEP; @@ -744,9 +732,6 @@ static void dgnc_init_globals(void) { int i = 0; - dgnc_rawreadok = rawreadok; - dgnc_trcbuf_size = trcbuf_size; - dgnc_debug = debug; dgnc_NumBoards = 0; for (i = 0; i < MAXBOARDS; i++) diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index f901957c757f..a8157eba28da 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -42,53 +42,13 @@ * *************************************************************************/ -/* - * Driver identification, error and debugging statments - * - * In theory, you can change all occurrences of "digi" in the next - * three lines, and the driver printk's will all automagically change. - * - * APR((fmt, args, ...)); Always prints message - */ +/* Driver identification and error statments */ #define PROCSTR "dgnc" /* /proc entries */ #define DEVSTR "/dev/dg/dgnc" /* /dev entries */ -#define DRVSTR "dgnc" /* Driver name string - * displayed by APR */ -#define APR(args) do { printk(DRVSTR": "); printk args; \ - } while (0) -#define RAPR(args) do { printk args; } while (0) +#define DRVSTR "dgnc" /* Driver name string */ #define TRC_TO_CONSOLE 1 -/* - * Debugging levels can be set using debug insmod variable - * They can also be compiled out completely. - */ - -#define DBG_INIT (dgnc_debug & 0x01) -#define DBG_BASIC (dgnc_debug & 0x02) -#define DBG_CORE (dgnc_debug & 0x04) - -#define DBG_OPEN (dgnc_debug & 0x08) -#define DBG_CLOSE (dgnc_debug & 0x10) -#define DBG_READ (dgnc_debug & 0x20) -#define DBG_WRITE (dgnc_debug & 0x40) - -#define DBG_IOCTL (dgnc_debug & 0x80) - -#define DBG_PROC (dgnc_debug & 0x100) -#define DBG_PARAM (dgnc_debug & 0x200) -#define DBG_PSCAN (dgnc_debug & 0x400) -#define DBG_EVENT (dgnc_debug & 0x800) - -#define DBG_DRAIN (dgnc_debug & 0x1000) -#define DBG_MSIGS (dgnc_debug & 0x2000) - -#define DBG_MGMT (dgnc_debug & 0x4000) -#define DBG_INTR (dgnc_debug & 0x8000) - -#define DBG_CARR (dgnc_debug & 0x10000) - /* Number of boards we support at once. */ #define MAXBOARDS 20 #define MAXPORTS 8 @@ -134,8 +94,6 @@ #define _POSIX_VDISABLE '\0' #endif -#define SNIFF_MAX 65536 /* Sniff buffer size (2^n) */ -#define SNIFF_MASK (SNIFF_MAX - 1) /* Sniff wrap mask */ /* * All the possible states the driver can be while being loaded. @@ -342,13 +300,6 @@ struct un_t { #define CH_FORCED_STOP 0x20000 /* Output is forcibly stopped */ #define CH_FORCED_STOPI 0x40000 /* Input is forcibly stopped */ -/* - * Definitions for ch_sniff_flags - */ -#define SNIFF_OPEN 0x1 -#define SNIFF_WAIT_DATA 0x2 -#define SNIFF_WAIT_SPACE 0x4 - /* Our Read/Error/Write queue sizes */ #define RQUEUEMASK 0x1FFF /* 8 K - 1 */ @@ -442,21 +393,13 @@ struct channel_t { struct proc_dir_entry *proc_entry_pointer; struct dgnc_proc_entry *dgnc_channel_table; - uint ch_sniff_in; - uint ch_sniff_out; - char *ch_sniff_buf; /* Sniff buffer for proc */ - ulong ch_sniff_flags; /* Channel flags */ - wait_queue_head_t ch_sniff_wait; }; /* * Our Global Variables. */ extern uint dgnc_Major; /* Our driver/mgmt major */ -extern int dgnc_debug; /* Debug variable */ -extern int dgnc_rawreadok; /* Set if user wants rawreads */ extern int dgnc_poll_tick; /* Poll interval - 20 ms */ -extern int dgnc_trcbuf_size; /* Size of the ringbuffer */ extern spinlock_t dgnc_global_lock; /* Driver global spinlock */ extern uint dgnc_NumBoards; /* Total number of boards */ extern struct dgnc_board *dgnc_Board[MAXBOARDS]; /* Array of board structs */ diff --git a/drivers/staging/dgnc/dgnc_kcompat.h b/drivers/staging/dgnc/dgnc_kcompat.h index eaec7e6a28e1..566cad0d33e7 100644 --- a/drivers/staging/dgnc/dgnc_kcompat.h +++ b/drivers/staging/dgnc/dgnc_kcompat.h @@ -43,22 +43,4 @@ # endif -# define PARM_STR(VAR, INIT, PERM, DESC) \ - static char *VAR = INIT; \ - char *dgnc_##VAR; \ - module_param(VAR, charp, PERM); \ - MODULE_PARM_DESC(VAR, DESC); - -# define PARM_INT(VAR, INIT, PERM, DESC) \ - static int VAR = INIT; \ - int dgnc_##VAR; \ - module_param(VAR, int, PERM); \ - MODULE_PARM_DESC(VAR, DESC); - -# define PARM_ULONG(VAR, INIT, PERM, DESC) \ - static ulong VAR = INIT; \ - ulong dgnc_##VAR; \ - module_param(VAR, long, PERM); \ - MODULE_PARM_DESC(VAR, DESC); - #endif /* ! __DGNC_KCOMPAT_H */ diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c index a5bd08fef270..c9a8a9825cfb 100644 --- a/drivers/staging/dgnc/dgnc_neo.c +++ b/drivers/staging/dgnc/dgnc_neo.c @@ -530,10 +530,11 @@ static inline void neo_parse_lsr(struct dgnc_board *brd, uint port) int linestatus; unsigned long flags; - if (!brd) - return; - - if (brd->magic != DGNC_BOARD_MAGIC) + /* + * Check to make sure it didn't receive interrupt with a null board + * associated or a board pointer that wasn't ours. + */ + if (!brd || brd->magic != DGNC_BOARD_MAGIC) return; if (port > brd->maxports) @@ -869,10 +870,8 @@ static void neo_tasklet(unsigned long data) int state = 0; int ports = 0; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) { - APR(("poll_tasklet() - NULL or bad bd.\n")); + if (!bd || bd->magic != DGNC_BOARD_MAGIC) return; - } /* Cache a couple board values */ spin_lock_irqsave(&bd->bd_lock, flags); @@ -945,7 +944,7 @@ static void neo_tasklet(unsigned long data) */ static irqreturn_t neo_intr(int irq, void *voidbrd) { - struct dgnc_board *brd = (struct dgnc_board *) voidbrd; + struct dgnc_board *brd = voidbrd; struct channel_t *ch; int port = 0; int type = 0; @@ -955,18 +954,12 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) unsigned long flags; unsigned long flags2; - if (!brd) { - APR(("Received interrupt (%d) with null board associated\n", irq)); - return IRQ_NONE; - } - /* - * Check to make sure its for us. + * Check to make sure it didn't receive interrupt with a null board + * associated or a board pointer that wasn't ours. */ - if (brd->magic != DGNC_BOARD_MAGIC) { - APR(("Received interrupt (%d) with a board pointer that wasn't ours!\n", irq)); + if (!brd || brd->magic != DGNC_BOARD_MAGIC) return IRQ_NONE; - } brd->intr_count++; @@ -1224,7 +1217,6 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch) /* Copy data from uart to the queue */ memcpy_fromio(ch->ch_rqueue + head, &ch->ch_neo_uart->txrxburst, n); - dgnc_sniff_nowait_nolock(ch, "UART READ", ch->ch_rqueue + head, n); /* * Since RX_FIFO_DATA_ERROR was 0, we are guarenteed @@ -1310,7 +1302,6 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch) memcpy_fromio(ch->ch_rqueue + head, &ch->ch_neo_uart->txrxburst, 1); ch->ch_equeue[head] = (unsigned char) linestatus; - dgnc_sniff_nowait_nolock(ch, "UART READ", ch->ch_rqueue + head, 1); /* Ditch any remaining linestatus value. */ linestatus = 0; @@ -1563,7 +1554,6 @@ static void neo_copy_data_from_queue_to_uart(struct channel_t *ch) } memcpy_toio(&ch->ch_neo_uart->txrxburst, ch->ch_wqueue + tail, s); - dgnc_sniff_nowait_nolock(ch, "UART WRITE", ch->ch_wqueue + tail, s); /* Add and flip queue if needed */ tail = (tail + s) & WQUEUEMASK; diff --git a/drivers/staging/dgnc/dgnc_sysfs.c b/drivers/staging/dgnc/dgnc_sysfs.c index 6c3b387622e9..2fd34ca70c59 100644 --- a/drivers/staging/dgnc/dgnc_sysfs.c +++ b/drivers/staging/dgnc/dgnc_sysfs.c @@ -63,39 +63,6 @@ static ssize_t dgnc_driver_maxboards_show(struct device_driver *ddp, char *buf) } static DRIVER_ATTR(maxboards, S_IRUSR, dgnc_driver_maxboards_show, NULL); -static ssize_t dgnc_driver_debug_show(struct device_driver *ddp, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "0x%x\n", dgnc_debug); -} - -static ssize_t dgnc_driver_debug_store(struct device_driver *ddp, const char *buf, size_t count) -{ - int ret; - - ret = sscanf(buf, "0x%x\n", &dgnc_debug); - if (ret != 1) - return -EINVAL; - return count; -} -static DRIVER_ATTR(debug, (S_IRUSR | S_IWUSR), dgnc_driver_debug_show, dgnc_driver_debug_store); - - -static ssize_t dgnc_driver_rawreadok_show(struct device_driver *ddp, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "0x%x\n", dgnc_rawreadok); -} - -static ssize_t dgnc_driver_rawreadok_store(struct device_driver *ddp, const char *buf, size_t count) -{ - int ret; - - ret = sscanf(buf, "0x%x\n", &dgnc_rawreadok); - if (ret != 1) - return -EINVAL; - return count; -} -static DRIVER_ATTR(rawreadok, (S_IRUSR | S_IWUSR), dgnc_driver_rawreadok_show, dgnc_driver_rawreadok_store); - static ssize_t dgnc_driver_pollrate_show(struct device_driver *ddp, char *buf) { @@ -122,8 +89,6 @@ void dgnc_create_driver_sysfiles(struct pci_driver *dgnc_driver) rc |= driver_create_file(driverfs, &driver_attr_version); rc |= driver_create_file(driverfs, &driver_attr_boards); rc |= driver_create_file(driverfs, &driver_attr_maxboards); - rc |= driver_create_file(driverfs, &driver_attr_debug); - rc |= driver_create_file(driverfs, &driver_attr_rawreadok); rc |= driver_create_file(driverfs, &driver_attr_pollrate); if (rc) printk(KERN_ERR "DGNC: sysfs driver_create_file failed!\n"); @@ -137,8 +102,6 @@ void dgnc_remove_driver_sysfiles(struct pci_driver *dgnc_driver) driver_remove_file(driverfs, &driver_attr_version); driver_remove_file(driverfs, &driver_attr_boards); driver_remove_file(driverfs, &driver_attr_maxboards); - driver_remove_file(driverfs, &driver_attr_debug); - driver_remove_file(driverfs, &driver_attr_rawreadok); driver_remove_file(driverfs, &driver_attr_pollrate); } diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index 03c15069731f..f81a375f8bc1 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -49,7 +49,6 @@ #include <linux/delay.h> /* For udelay */ #include <linux/uaccess.h> /* For copy_from_user/copy_to_user */ #include <linux/pci.h> - #include "dgnc_driver.h" #include "dgnc_tty.h" #include "dgnc_types.h" @@ -233,7 +232,8 @@ int dgnc_tty_register(struct dgnc_board *brd) /* Register tty devices */ rc = tty_register_driver(&brd->SerialDriver); if (rc < 0) { - APR(("Can't register tty device (%d)\n", rc)); + dev_dbg(&brd->pdev->dev, + "Can't register tty device (%d)\n", rc); return rc; } brd->dgnc_Major_Serial_Registered = TRUE; @@ -281,7 +281,9 @@ int dgnc_tty_register(struct dgnc_board *brd) /* Register Transparent Print devices */ rc = tty_register_driver(&brd->PrintDriver); if (rc < 0) { - APR(("Can't register Transparent Print device (%d)\n", rc)); + dev_dbg(&brd->pdev->dev, + "Can't register Transparent Print device(%d)\n", + rc); return rc; } brd->dgnc_Major_TransparentPrint_Registered = TRUE; @@ -371,7 +373,6 @@ int dgnc_tty_init(struct dgnc_board *brd) init_waitqueue_head(&ch->ch_flags_wait); init_waitqueue_head(&ch->ch_tun.un_flags_wait); init_waitqueue_head(&ch->ch_pun.un_flags_wait); - init_waitqueue_head(&ch->ch_sniff_wait); { struct device *classp; @@ -446,127 +447,6 @@ void dgnc_tty_uninit(struct dgnc_board *brd) #define TMPBUFLEN (1024) -/* - * dgnc_sniff - Dump data out to the "sniff" buffer if the - * proc sniff file is opened... - */ -void dgnc_sniff_nowait_nolock(struct channel_t *ch, unsigned char *text, unsigned char *buf, int len) -{ - struct timeval tv; - int n; - int r; - int nbuf; - int i; - int tmpbuflen; - char *tmpbuf; - char *p; - int too_much_data; - - tmpbuf = kzalloc(TMPBUFLEN, GFP_ATOMIC); - if (!tmpbuf) - return; - p = tmpbuf; - - /* Leave if sniff not open */ - if (!(ch->ch_sniff_flags & SNIFF_OPEN)) - goto exit; - - do_gettimeofday(&tv); - - /* Create our header for data dump */ - p += sprintf(p, "<%ld %ld><%s><", tv.tv_sec, tv.tv_usec, text); - tmpbuflen = p - tmpbuf; - - do { - too_much_data = 0; - - for (i = 0; i < len && tmpbuflen < (TMPBUFLEN - 4); i++) { - p += sprintf(p, "%02x ", *buf); - buf++; - tmpbuflen = p - tmpbuf; - } - - if (tmpbuflen < (TMPBUFLEN - 4)) { - if (i > 0) - p += sprintf(p - 1, "%s\n", ">"); - else - p += sprintf(p, "%s\n", ">"); - } else { - too_much_data = 1; - len -= i; - } - - nbuf = strlen(tmpbuf); - p = tmpbuf; - - /* - * Loop while data remains. - */ - while (nbuf > 0 && ch->ch_sniff_buf) { - /* - * Determine the amount of available space left in the - * buffer. If there's none, wait until some appears. - */ - n = (ch->ch_sniff_out - ch->ch_sniff_in - 1) & SNIFF_MASK; - - /* - * If there is no space left to write to in our sniff buffer, - * we have no choice but to drop the data. - * We *cannot* sleep here waiting for space, because this - * function was probably called by the interrupt/timer routines! - */ - if (n == 0) - goto exit; - - /* - * Copy as much data as will fit. - */ - - if (n > nbuf) - n = nbuf; - - r = SNIFF_MAX - ch->ch_sniff_in; - - if (r <= n) { - memcpy(ch->ch_sniff_buf + ch->ch_sniff_in, p, r); - - n -= r; - ch->ch_sniff_in = 0; - p += r; - nbuf -= r; - } - - memcpy(ch->ch_sniff_buf + ch->ch_sniff_in, p, n); - - ch->ch_sniff_in += n; - p += n; - nbuf -= n; - - /* - * Wakeup any thread waiting for data - */ - if (ch->ch_sniff_flags & SNIFF_WAIT_DATA) { - ch->ch_sniff_flags &= ~SNIFF_WAIT_DATA; - wake_up_interruptible(&ch->ch_sniff_wait); - } - } - - /* - * If the user sent us too much data to push into our tmpbuf, - * we need to keep looping around on all the data. - */ - if (too_much_data) { - p = tmpbuf; - tmpbuflen = 0; - } - - } while (too_much_data); - -exit: - kfree(tmpbuf); -} - - /*======================================================================= * * dgnc_wmove - Write data to transmit queue. @@ -781,8 +661,6 @@ void dgnc_input(struct channel_t *ch) tty_insert_flip_string(tp->port, ch->ch_rqueue + tail, s); } - dgnc_sniff_nowait_nolock(ch, "USER READ", ch->ch_rqueue + tail, s); - tail += s; n -= s; /* Flip queue if needed */ @@ -1546,14 +1424,18 @@ static void dgnc_tty_close(struct tty_struct *tty, struct file *file) * one, we've got real problems, since it means the * serial port won't be shutdown. */ - APR(("tty->count is 1, un open count is %d\n", un->un_open_count)); + dev_dbg(tty->dev, + "tty->count is 1, un open count is %d\n", + un->un_open_count); un->un_open_count = 1; } if (un->un_open_count) un->un_open_count--; else - APR(("bad serial port open count of %d\n", un->un_open_count)); + dev_dbg(tty->dev, + "bad serial port open count of %d\n", + un->un_open_count); ch->ch_open_count--; @@ -1974,7 +1856,6 @@ static int dgnc_tty_write(struct tty_struct *tty, if (n >= remain) { n -= remain; memcpy(ch->ch_wqueue + head, buf, remain); - dgnc_sniff_nowait_nolock(ch, "USER WRITE", ch->ch_wqueue + head, remain); head = 0; buf += remain; } @@ -1985,7 +1866,6 @@ static int dgnc_tty_write(struct tty_struct *tty, */ remain = n; memcpy(ch->ch_wqueue + head, buf, remain); - dgnc_sniff_nowait_nolock(ch, "USER WRITE", ch->ch_wqueue + head, remain); head += remain; } @@ -2325,8 +2205,6 @@ static int dgnc_set_modem_info(struct tty_struct *tty, unsigned int command, uns if (!bd || bd->magic != DGNC_BOARD_MAGIC) return ret; - ret = 0; - ret = get_user(arg, value); if (ret) return ret; @@ -3089,7 +2967,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, struct digi_getcounter buf; buf.norun = ch->ch_err_overrun; - buf.noflow = 0; /* The driver doesn't keep this stat */ + buf.noflow = 0; /* The driver doesn't keep this stat */ buf.nframe = ch->ch_err_frame; buf.nparity = ch->ch_err_parity; buf.nbreak = ch->ch_err_break; diff --git a/drivers/staging/dgnc/dgnc_tty.h b/drivers/staging/dgnc/dgnc_tty.h index 58eef257c2ec..3975f0407143 100644 --- a/drivers/staging/dgnc/dgnc_tty.h +++ b/drivers/staging/dgnc/dgnc_tty.h @@ -37,6 +37,4 @@ void dgnc_carrier(struct channel_t *ch); void dgnc_wakeup_writes(struct channel_t *ch); void dgnc_check_queue_flow_control(struct channel_t *ch); -void dgnc_sniff_nowait_nolock(struct channel_t *ch, unsigned char *text, unsigned char *buf, int nbuf); - #endif diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index ed8d86c98f65..eb178fcb7954 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c @@ -2622,7 +2622,7 @@ static int nbu2ss_ep_enable( return -EINVAL; } - ep_type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; + ep_type = usb_endpoint_type(desc); if ((ep_type == USB_ENDPOINT_XFER_CONTROL) || (ep_type == USB_ENDPOINT_XFER_ISOC)) { @@ -2644,7 +2644,7 @@ static int nbu2ss_ep_enable( spin_lock_irqsave(&udc->lock, flags); ep->desc = desc; - ep->epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + ep->epnum = usb_endpoint_num(desc); ep->direct = desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK; ep->ep_type = ep_type; ep->wedged = 0; @@ -2722,8 +2722,7 @@ static void nbu2ss_ep_free_request( if (_req != NULL) { req = container_of(_req, struct nbu2ss_req, req); - if (req != NULL) - kfree(req); + kfree(req); } } diff --git a/drivers/staging/ft1000/ft1000-pcmcia/boot.h b/drivers/staging/ft1000/ft1000-pcmcia/boot.h index 60c015c1c28a..e4a698528520 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/boot.h +++ b/drivers/staging/ft1000/ft1000-pcmcia/boot.h @@ -1,28 +1,28 @@ /*--------------------------------------------------------------------------- - FT1000 driver for Flarion Flash OFDM NIC Device + FT1000 driver for Flarion Flash OFDM NIC Device - Copyright (C) 2002 Flarion Technologies, All rights reserved. + Copyright (C) 2002 Flarion Technologies, All rights reserved. - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) any - later version. This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. You should have received a copy of the GNU General Public - License along with this program; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - - Suite 330, Boston, MA 02111-1307, USA. + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) any + later version. This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - + Suite 330, Boston, MA 02111-1307, USA. --------------------------------------------------------------------------- - File: boot.h + File: boot.h - Description: boatloader + Description: boatloader - History: - 1/11/05 Whc Ported to Linux. + History: + 1/11/05 Whc Ported to Linux. ----------------------------------------------------------------------------*/ + ---------------------------------------------------------------------------*/ #ifndef _BOOTH_ #define _BOOTH_ diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000.h b/drivers/staging/ft1000/ft1000-pcmcia/ft1000.h index 1d52738fff49..5992670f7747 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000.h +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000.h @@ -1,21 +1,21 @@ /*--------------------------------------------------------------------------- - FT1000 driver for Flarion Flash OFDM NIC Device + FT1000 driver for Flarion Flash OFDM NIC Device - Copyright (C) 2002 Flarion Technologies, All rights reserved. + Copyright (C) 2002 Flarion Technologies, All rights reserved. - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) any - later version. This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. You should have received a copy of the GNU General Public - License along with this program; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - - Suite 330, Boston, MA 02111-1307, USA. ---------------------------------------------------------------------------- - Description: Common structures and defines ----------------------------------------------------------------------------*/ + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) any + later version. This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - + Suite 330, Boston, MA 02111-1307, USA. + --------------------------------------------------------------------------- + Description: Common structures and defines + ---------------------------------------------------------------------------*/ #ifndef _FT1000H_ #define _FT1000H_ diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c index 1f8b3ca35c69..922478e1cb57 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c @@ -1,30 +1,30 @@ /*--------------------------------------------------------------------------- - FT1000 driver for Flarion Flash OFDM NIC Device + FT1000 driver for Flarion Flash OFDM NIC Device - Copyright (C) 1999 David A. Hinds. All Rights Reserved. - Copyright (C) 2002 Flarion Technologies, All rights reserved. - Copyright (C) 2006 Patrik Ostrihon, All rights reserved. - Copyright (C) 2006 ProWeb Consulting, a.s, All rights reserved. + Copyright (C) 1999 David A. Hinds. All Rights Reserved. + Copyright (C) 2002 Flarion Technologies, All rights reserved. + Copyright (C) 2006 Patrik Ostrihon, All rights reserved. + Copyright (C) 2006 ProWeb Consulting, a.s, All rights reserved. - The initial developer of the original code is David A. Hinds - <dahinds@users.sourceforge.net>. Portions created by David A. Hinds. + The initial developer of the original code is David A. Hinds + <dahinds@users.sourceforge.net>. Portions created by David A. Hinds. - This file was modified to support the Flarion Flash OFDM NIC Device - by Wai Chan (w.chan@flarion.com). + This file was modified to support the Flarion Flash OFDM NIC Device + by Wai Chan (w.chan@flarion.com). - Port for kernel 2.6 created by Patrik Ostrihon (patrik.ostrihon@pwc.sk) + Port for kernel 2.6 created by Patrik Ostrihon (patrik.ostrihon@pwc.sk) - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) any - later version. This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. You should have received a copy of the GNU General Public - License along with this program; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - - Suite 330, Boston, MA 02111-1307, USA. ------------------------------------------------------------------------------*/ + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) any + later version. This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - + Suite 330, Boston, MA 02111-1307, USA. + -----------------------------------------------------------------------------*/ #include <linux/kernel.h> #include <linux/module.h> @@ -80,11 +80,11 @@ static int ft1000_confcheck(struct pcmcia_device *link, void *priv_data) /*====================================================================== - ft1000_config() is scheduled to run after a CARD_INSERTION event - is received, to configure the PCMCIA socket, and to make the - device available to the system. + ft1000_config() is scheduled to run after a CARD_INSERTION event + is received, to configure the PCMCIA socket, and to make the + device available to the system. -======================================================================*/ + ======================================================================*/ static int ft1000_config(struct pcmcia_device *link) { diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c index c1856f7d1e26..06b0e9cfb9b1 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c @@ -1,24 +1,26 @@ /*--------------------------------------------------------------------------- - FT1000 driver for Flarion Flash OFDM NIC Device - - Copyright (C) 2002 Flarion Technologies, All rights reserved. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) any - later version. This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. You should have received a copy of the GNU General Public - License along with this program; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - - Suite 330, Boston, MA 02111-1307, USA. + FT1000 driver for Flarion Flash OFDM NIC Device + + Copyright (C) 2002 Flarion Technologies, All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) any + later version. This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - + Suite 330, Boston, MA 02111-1307, USA. -------------------------------------------------------------------------- - Description: This module will handshake with the DSP bootloader to - download the DSP runtime image. + Description: This module will handshake with the DSP bootloader to + download the DSP runtime image. ----------------------------------------------------------------------------*/ + ---------------------------------------------------------------------------*/ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define __KERNEL_SYSCALLS__ @@ -99,7 +101,7 @@ struct dsp_file_hdr { u32 version_data_offset; /* Offset were scrambled version data begins. */ u32 version_data_size; /* Size, in words, of scrambled version data. */ u32 nDspImages; /* Number of DSP images in file. */ -} __attribute__ ((packed)); +} __packed; struct dsp_image_info { u32 coff_date; /* Date/time when DSP Coff image was built. */ @@ -110,11 +112,11 @@ struct dsp_image_info { u32 version; /* Embedded version # of DSP code. */ unsigned short checksum; /* Dsp File checksum */ unsigned short pad1; -} __attribute__ ((packed)); +} __packed; void card_bootload(struct net_device *dev) { - struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); + struct ft1000_info *info = (struct ft1000_info *)netdev_priv(dev); unsigned long flags; u32 *pdata; u32 size; @@ -123,7 +125,7 @@ void card_bootload(struct net_device *dev) netdev_dbg(dev, "card_bootload is called\n"); - pdata = (u32 *) bootimage; + pdata = (u32 *)bootimage; size = sizeof(bootimage); /* check for odd word */ @@ -146,7 +148,7 @@ void card_bootload(struct net_device *dev) u16 get_handshake(struct net_device *dev, u16 expected_value) { - struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); + struct ft1000_info *info = (struct ft1000_info *)netdev_priv(dev); u16 handshake; u32 tempx; int loopcnt; @@ -161,12 +163,12 @@ u16 get_handshake(struct net_device *dev, u16 expected_value) } else { tempx = ntohl(ft1000_read_dpram_mag_32 - (dev, DWNLD_MAG_HANDSHAKE_LOC)); - handshake = (u16) tempx; + (dev, DWNLD_MAG_HANDSHAKE_LOC)); + handshake = (u16)tempx; } if ((handshake == expected_value) - || (handshake == HANDSHAKE_RESET_VALUE)) { + || (handshake == HANDSHAKE_RESET_VALUE)) { return handshake; } loopcnt++; @@ -180,7 +182,7 @@ u16 get_handshake(struct net_device *dev, u16 expected_value) void put_handshake(struct net_device *dev, u16 handshake_value) { - struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); + struct ft1000_info *info = (struct ft1000_info *)netdev_priv(dev); u32 tempx; if (info->AsicID == ELECTRABUZZ_ID) { @@ -188,7 +190,7 @@ void put_handshake(struct net_device *dev, u16 handshake_value) DWNLD_HANDSHAKE_LOC); ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, handshake_value); /* Handshake */ } else { - tempx = (u32) handshake_value; + tempx = (u32)handshake_value; tempx = ntohl(tempx); ft1000_write_dpram_mag_32(dev, DWNLD_MAG_HANDSHAKE_LOC, tempx); /* Handshake */ } @@ -196,7 +198,7 @@ void put_handshake(struct net_device *dev, u16 handshake_value) u16 get_request_type(struct net_device *dev) { - struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); + struct ft1000_info *info = (struct ft1000_info *)netdev_priv(dev); u16 request_type; u32 tempx; @@ -206,7 +208,7 @@ u16 get_request_type(struct net_device *dev) } else { tempx = ft1000_read_dpram_mag_32(dev, DWNLD_MAG_TYPE_LOC); tempx = ntohl(tempx); - request_type = (u16) tempx; + request_type = (u16)tempx; } return request_type; @@ -215,7 +217,7 @@ u16 get_request_type(struct net_device *dev) long get_request_value(struct net_device *dev) { - struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); + struct ft1000_info *info = (struct ft1000_info *)netdev_priv(dev); long value; u16 w_val; @@ -244,7 +246,7 @@ long get_request_value(struct net_device *dev) void put_request_value(struct net_device *dev, long lvalue) { - struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); + struct ft1000_info *info = (struct ft1000_info *)netdev_priv(dev); u16 size; u32 tempx; @@ -271,11 +273,11 @@ void put_request_value(struct net_device *dev, long lvalue) u16 hdr_checksum(struct pseudo_hdr *pHdr) { - u16 *usPtr = (u16 *) pHdr; + u16 *usPtr = (u16 *)pHdr; u16 chksum; chksum = ((((((usPtr[0] ^ usPtr[1]) ^ usPtr[2]) ^ usPtr[3]) ^ - usPtr[4]) ^ usPtr[5]) ^ usPtr[6]); + usPtr[4]) ^ usPtr[5]) ^ usPtr[6]); return chksum; } @@ -283,7 +285,7 @@ u16 hdr_checksum(struct pseudo_hdr *pHdr) int card_download(struct net_device *dev, const u8 *pFileStart, size_t FileLength) { - struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); + struct ft1000_info *info = (struct ft1000_info *)netdev_priv(dev); int Status = SUCCESS; u32 uiState; u16 handshake; @@ -316,13 +318,13 @@ int card_download(struct net_device *dev, const u8 *pFileStart, file_version = *(long *)pFileStart; if (file_version != 6) { - printk(KERN_ERR "ft1000: unsupported firmware version %ld\n", file_version); + pr_err("unsupported firmware version %ld\n", file_version); Status = FAILURE; } uiState = STATE_START_DWNLD; - pFileHdr5 = (struct dsp_file_hdr *) pFileStart; + pFileHdr5 = (struct dsp_file_hdr *)pFileStart; pUsFile = (u16 *) ((long)pFileStart + pFileHdr5->loader_offset); pUcFile = (u8 *) ((long)pFileStart + pFileHdr5->loader_offset); @@ -376,7 +378,7 @@ int card_download(struct net_device *dev, const u8 *pFileStart, break; } if ((word_length * 2 + (long)pUcFile) > - (long)pBootEnd) { + (long)pBootEnd) { /* * Error, beyond boot code range. */ @@ -390,8 +392,8 @@ int card_download(struct net_device *dev, const u8 *pFileStart, * Position ASIC DPRAM auto-increment pointer. */ outw(DWNLD_MAG_PS_HDR_LOC, - dev->base_addr + - FT1000_REG_DPRAM_ADDR); + dev->base_addr + + FT1000_REG_DPRAM_ADDR); if (word_length & 0x01) word_length++; word_length = word_length / 2; @@ -402,12 +404,12 @@ int card_download(struct net_device *dev, const u8 *pFileStart, (*pUsFile++ << 16); pUcFile += 4; outl(templong, - dev->base_addr + - FT1000_REG_MAG_DPDATAL); + dev->base_addr + + FT1000_REG_MAG_DPDATAL); } spin_unlock_irqrestore(&info-> - dpram_lock, - flags); + dpram_lock, + flags); break; default: Status = FAILURE; @@ -430,7 +432,7 @@ int card_download(struct net_device *dev, const u8 *pFileStart, switch (request) { case REQUEST_FILE_CHECKSUM: netdev_dbg(dev, - "ft1000_dnld: REQUEST_FOR_CHECKSUM\n"); + "ft1000_dnld: REQUEST_FOR_CHECKSUM\n"); put_request_value(dev, image_chksum); break; case REQUEST_RUN_ADDRESS: @@ -468,7 +470,7 @@ int card_download(struct net_device *dev, const u8 *pFileStart, break; } if ((word_length * 2 + (long)pUcFile) > - (long)pCodeEnd) { + (long)pCodeEnd) { /* * Error, beyond boot code range. */ @@ -479,8 +481,8 @@ int card_download(struct net_device *dev, const u8 *pFileStart, * Position ASIC DPRAM auto-increment pointer. */ outw(DWNLD_MAG_PS_HDR_LOC, - dev->base_addr + - FT1000_REG_DPRAM_ADDR); + dev->base_addr + + FT1000_REG_DPRAM_ADDR); if (word_length & 0x01) word_length++; word_length = word_length / 2; @@ -491,8 +493,8 @@ int card_download(struct net_device *dev, const u8 *pFileStart, (*pUsFile++ << 16); pUcFile += 4; outl(templong, - dev->base_addr + - FT1000_REG_MAG_DPDATAL); + dev->base_addr + + FT1000_REG_MAG_DPDATAL); } break; @@ -502,9 +504,9 @@ int card_download(struct net_device *dev, const u8 *pFileStart, (long)(info->DSPInfoBlklen + 1) / 2; put_request_value(dev, word_length); pMailBoxData = - (struct drv_msg *) &info->DSPInfoBlk[0]; + (struct drv_msg *)&info->DSPInfoBlk[0]; pUsData = - (u16 *) &pMailBoxData->data[0]; + (u16 *)&pMailBoxData->data[0]; /* Provide mutual exclusive access while reading ASIC registers. */ spin_lock_irqsave(&info->dpram_lock, flags); @@ -528,8 +530,8 @@ int card_download(struct net_device *dev, const u8 *pFileStart, * Position ASIC DPRAM auto-increment pointer. */ outw(DWNLD_MAG_PS_HDR_LOC, - dev->base_addr + - FT1000_REG_DPRAM_ADDR); + dev->base_addr + + FT1000_REG_DPRAM_ADDR); if (word_length & 0x01) word_length++; @@ -540,13 +542,13 @@ int card_download(struct net_device *dev, const u8 *pFileStart, templong |= (*pUsData++ << 16); outl(templong, - dev->base_addr + - FT1000_REG_MAG_DPDATAL); + dev->base_addr + + FT1000_REG_MAG_DPDATAL); } } spin_unlock_irqrestore(&info-> - dpram_lock, - flags); + dpram_lock, + flags); break; case REQUEST_VERSION_INFO: @@ -555,8 +557,8 @@ int card_download(struct net_device *dev, const u8 *pFileStart, put_request_value(dev, word_length); pUsFile = (u16 *) ((long)pFileStart + - pFileHdr5-> - version_data_offset); + pFileHdr5-> + version_data_offset); /* Provide mutual exclusive access while reading ASIC registers. */ spin_lock_irqsave(&info->dpram_lock, flags); @@ -564,8 +566,8 @@ int card_download(struct net_device *dev, const u8 *pFileStart, * Position ASIC DPRAM auto-increment pointer. */ outw(DWNLD_MAG_PS_HDR_LOC, - dev->base_addr + - FT1000_REG_DPRAM_ADDR); + dev->base_addr + + FT1000_REG_DPRAM_ADDR); if (word_length & 0x01) word_length++; word_length = word_length / 2; @@ -578,12 +580,12 @@ int card_download(struct net_device *dev, const u8 *pFileStart, templong |= (temp << 16); outl(templong, - dev->base_addr + - FT1000_REG_MAG_DPDATAL); + dev->base_addr + + FT1000_REG_MAG_DPDATAL); } spin_unlock_irqrestore(&info-> - dpram_lock, - flags); + dpram_lock, + flags); break; case REQUEST_CODE_BY_VERSION: @@ -592,14 +594,14 @@ int card_download(struct net_device *dev, const u8 *pFileStart, get_request_value(dev); pDspImageInfoV6 = (struct dsp_image_info *) ((long) - pFileStart - + - sizeof - (struct dsp_file_hdr)); + pFileStart + + + sizeof + (struct dsp_file_hdr)); for (imageN = 0; - imageN < - pFileHdr5->nDspImages; - imageN++) { + imageN < + pFileHdr5->nDspImages; + imageN++) { temp = (u16) (pDspImageInfoV6-> version); @@ -610,30 +612,30 @@ int card_download(struct net_device *dev, const u8 *pFileStart, templong |= (temp << 16); if (templong == - requested_version) { + requested_version) { bGoodVersion = true; pUsFile = (u16 *) ((long) - pFileStart - + - pDspImageInfoV6-> - begin_offset); + pFileStart + + + pDspImageInfoV6-> + begin_offset); pUcFile = (u8 *) ((long) - pFileStart - + - pDspImageInfoV6-> - begin_offset); + pFileStart + + + pDspImageInfoV6-> + begin_offset); pCodeEnd = (u8 *) ((long) - pFileStart - + - pDspImageInfoV6-> - end_offset); + pFileStart + + + pDspImageInfoV6-> + end_offset); run_address = pDspImageInfoV6-> run_address; @@ -645,10 +647,10 @@ int card_download(struct net_device *dev, const u8 *pFileStart, pDspImageInfoV6-> checksum; netdev_dbg(dev, - "ft1000_dnld: image_chksum = 0x%8x\n", - (unsigned - int) - image_chksum); + "ft1000_dnld: image_chksum = 0x%8x\n", + (unsigned + int) + image_chksum); break; } pDspImageInfoV6++; @@ -674,25 +676,25 @@ int card_download(struct net_device *dev, const u8 *pFileStart, break; case STATE_DONE_DWNLD: - if (((unsigned long) (pUcFile) - (unsigned long) pFileStart) >= - (unsigned long) FileLength) { + if (((unsigned long)(pUcFile) - (unsigned long) pFileStart) >= + (unsigned long)FileLength) { uiState = STATE_DONE_FILE; break; } - pHdr = (struct pseudo_hdr *) pUsFile; + pHdr = (struct pseudo_hdr *)pUsFile; if (pHdr->portdest == 0x80 /* DspOAM */ - && (pHdr->portsrc == 0x00 /* Driver */ + && (pHdr->portsrc == 0x00 /* Driver */ || pHdr->portsrc == 0x10 /* FMM */)) { uiState = STATE_SECTION_PROV; } else { netdev_dbg(dev, - "FT1000:download:Download error: Bad Port IDs in Pseudo Record\n"); + "Download error: Bad Port IDs in Pseudo Record\n"); netdev_dbg(dev, "\t Port Source = 0x%2.2x\n", - pHdr->portsrc); + pHdr->portsrc); netdev_dbg(dev, "\t Port Destination = 0x%2.2x\n", - pHdr->portdest); + pHdr->portdest); Status = FAILURE; } @@ -700,7 +702,7 @@ int card_download(struct net_device *dev, const u8 *pFileStart, case STATE_SECTION_PROV: - pHdr = (struct pseudo_hdr *) pUcFile; + pHdr = (struct pseudo_hdr *)pUcFile; if (pHdr->checksum == hdr_checksum(pHdr)) { if (pHdr->portdest != 0x80 /* Dsp OAM */) { @@ -715,8 +717,8 @@ int card_download(struct net_device *dev, const u8 *pFileStart, GFP_ATOMIC); if (pbuffer) { memcpy(pbuffer, (void *)pUcFile, - (u32) (usHdrLength + - sizeof(struct pseudo_hdr))); + (u32) (usHdrLength + + sizeof(struct pseudo_hdr))); /* link provisioning data */ pprov_record = kmalloc(sizeof(struct prov_record), @@ -725,15 +727,15 @@ int card_download(struct net_device *dev, const u8 *pFileStart, pprov_record->pprov_data = pbuffer; list_add_tail(&pprov_record-> - list, - &info->prov_list); + list, + &info->prov_list); /* Move to next entry if available */ pUcFile = - (u8 *) ((unsigned long) pUcFile + - (unsigned long) ((usHdrLength + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr)); + (u8 *)((unsigned long) pUcFile + + (unsigned long) ((usHdrLength + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr)); if ((unsigned long) (pUcFile) - - (unsigned long) (pFileStart) >= - (unsigned long) FileLength) { + (unsigned long) (pFileStart) >= + (unsigned long)FileLength) { uiState = STATE_DONE_FILE; } diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c index 44575c78cf0c..d5475b7270a8 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c @@ -1,22 +1,24 @@ /*--------------------------------------------------------------------------- - FT1000 driver for Flarion Flash OFDM NIC Device - - Copyright (C) 2002 Flarion Technologies, All rights reserved. - Copyright (C) 2006 Patrik Ostrihon, All rights reserved. - Copyright (C) 2006 ProWeb Consulting, a.s, All rights reserved. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) any - later version. This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. You should have received a copy of the GNU General Public - License along with this program; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - - Suite 330, Boston, MA 02111-1307, USA. + FT1000 driver for Flarion Flash OFDM NIC Device + + Copyright (C) 2002 Flarion Technologies, All rights reserved. + Copyright (C) 2006 Patrik Ostrihon, All rights reserved. + Copyright (C) 2006 ProWeb Consulting, a.s, All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) any + later version. This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - + Suite 330, Boston, MA 02111-1307, USA. -------------------------------------------------------------------------*/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/kernel.h> #include <linux/module.h> #include <linux/sched.h> @@ -44,12 +46,6 @@ #include <pcmcia/cisreg.h> #include <pcmcia/ds.h> -#ifdef FT_DEBUG -#define DEBUG(n, args...) printk(KERN_DEBUG args); -#else -#define DEBUG(n, args...) -#endif - #include <linux/delay.h> #include "ft1000.h" @@ -57,7 +53,7 @@ static const struct firmware *fw_entry; static void ft1000_hbchk(u_long data); static struct timer_list poll_timer = { - .function = ft1000_hbchk + .function = ft1000_hbchk }; static u16 cmdbuffer[1024]; @@ -72,7 +68,7 @@ static void ft1000_disable_interrupts(struct net_device *dev); /* new kernel */ MODULE_AUTHOR(""); MODULE_DESCRIPTION - ("Support for Flarion Flash OFDM NIC Device. Support for PCMCIA when used with ft1000_cs."); +("Support for Flarion Flash OFDM NIC Device. Support for PCMCIA when used with ft1000_cs."); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("FT1000"); @@ -80,15 +76,15 @@ MODULE_SUPPORTED_DEVICE("FT1000"); /*--------------------------------------------------------------------------- - Function: ft1000_read_fifo_len - Description: This function will read the ASIC Uplink FIFO status register - which will return the number of bytes remaining in the Uplink FIFO. - Sixteen bytes are subtracted to make sure that the ASIC does not - reach its threshold. - Input: - dev - network device structure - Output: - value - number of bytes available in the ASIC Uplink FIFO. + Function: ft1000_read_fifo_len + Description: This function will read the ASIC Uplink FIFO status register + which will return the number of bytes remaining in the Uplink FIFO. + Sixteen bytes are subtracted to make sure that the ASIC does not + reach its threshold. + Input: + dev - network device structure + Output: + value - number of bytes available in the ASIC Uplink FIFO. -------------------------------------------------------------------------*/ static inline u16 ft1000_read_fifo_len(struct net_device *dev) @@ -103,14 +99,14 @@ static inline u16 ft1000_read_fifo_len(struct net_device *dev) /*--------------------------------------------------------------------------- - Function: ft1000_read_dpram - Description: This function will read the specific area of dpram - (Electrabuzz ASIC only) - Input: - dev - device structure - offset - index of dpram - Output: - value - value of dpram + Function: ft1000_read_dpram + Description: This function will read the specific area of dpram + (Electrabuzz ASIC only) + Input: + dev - device structure + offset - index of dpram + Output: + value - value of dpram -------------------------------------------------------------------------*/ u16 ft1000_read_dpram(struct net_device *dev, int offset) @@ -130,19 +126,19 @@ u16 ft1000_read_dpram(struct net_device *dev, int offset) /*--------------------------------------------------------------------------- - Function: ft1000_write_dpram - Description: This function will write to a specific area of dpram - (Electrabuzz ASIC only) - Input: - dev - device structure - offset - index of dpram - value - value to write - Output: - none. + Function: ft1000_write_dpram + Description: This function will write to a specific area of dpram + (Electrabuzz ASIC only) + Input: + dev - device structure + offset - index of dpram + value - value to write + Output: + none. -------------------------------------------------------------------------*/ static inline void ft1000_write_dpram(struct net_device *dev, - int offset, u16 value) + int offset, u16 value) { struct ft1000_info *info = netdev_priv(dev); unsigned long flags; @@ -156,14 +152,14 @@ static inline void ft1000_write_dpram(struct net_device *dev, /*--------------------------------------------------------------------------- - Function: ft1000_read_dpram_mag_16 - Description: This function will read the specific area of dpram - (Magnemite ASIC only) - Input: - dev - device structure - offset - index of dpram - Output: - value - value of dpram + Function: ft1000_read_dpram_mag_16 + Description: This function will read the specific area of dpram + (Magnemite ASIC only) + Input: + dev - device structure + offset - index of dpram + Output: + value - value of dpram -------------------------------------------------------------------------*/ u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index) @@ -188,19 +184,19 @@ u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index) /*--------------------------------------------------------------------------- - Function: ft1000_write_dpram_mag_16 - Description: This function will write to a specific area of dpram - (Magnemite ASIC only) - Input: - dev - device structure - offset - index of dpram - value - value to write - Output: - none. + Function: ft1000_write_dpram_mag_16 + Description: This function will write to a specific area of dpram + (Magnemite ASIC only) + Input: + dev - device structure + offset - index of dpram + value - value to write + Output: + none. -------------------------------------------------------------------------*/ static inline void ft1000_write_dpram_mag_16(struct net_device *dev, - int offset, u16 value, int Index) + int offset, u16 value, int Index) { struct ft1000_info *info = netdev_priv(dev); unsigned long flags; @@ -218,14 +214,14 @@ static inline void ft1000_write_dpram_mag_16(struct net_device *dev, /*--------------------------------------------------------------------------- - Function: ft1000_read_dpram_mag_32 - Description: This function will read the specific area of dpram - (Magnemite ASIC only) - Input: - dev - device structure - offset - index of dpram - Output: - value - value of dpram + Function: ft1000_read_dpram_mag_32 + Description: This function will read the specific area of dpram + (Magnemite ASIC only) + Input: + dev - device structure + offset - index of dpram + Output: + value - value of dpram -------------------------------------------------------------------------*/ u32 ft1000_read_dpram_mag_32(struct net_device *dev, int offset) @@ -245,15 +241,15 @@ u32 ft1000_read_dpram_mag_32(struct net_device *dev, int offset) /*--------------------------------------------------------------------------- - Function: ft1000_write_dpram_mag_32 - Description: This function will write to a specific area of dpram - (Magnemite ASIC only) - Input: - dev - device structure - offset - index of dpram - value - value to write - Output: - none. + Function: ft1000_write_dpram_mag_32 + Description: This function will write to a specific area of dpram + (Magnemite ASIC only) + Input: + dev - device structure + offset - index of dpram + value - value to write + Output: + none. -------------------------------------------------------------------------*/ void ft1000_write_dpram_mag_32(struct net_device *dev, int offset, u32 value) @@ -270,57 +266,51 @@ void ft1000_write_dpram_mag_32(struct net_device *dev, int offset, u32 value) /*--------------------------------------------------------------------------- - Function: ft1000_enable_interrupts - Description: This function will enable interrupts base on the current interrupt mask. - Input: - dev - device structure - Output: - None. + Function: ft1000_enable_interrupts + Description: This function will enable interrupts base on the current interrupt mask. + Input: + dev - device structure + Output: + None. -------------------------------------------------------------------------*/ static void ft1000_enable_interrupts(struct net_device *dev) { u16 tempword; - DEBUG(1, "ft1000_hw:ft1000_enable_interrupts()\n"); ft1000_write_reg(dev, FT1000_REG_SUP_IMASK, ISR_DEFAULT_MASK); tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK); - DEBUG(1, - "ft1000_hw:ft1000_enable_interrupts:current interrupt enable mask = 0x%x\n", - tempword); + pr_debug("current interrupt enable mask = 0x%x\n", tempword); } /*--------------------------------------------------------------------------- - Function: ft1000_disable_interrupts - Description: This function will disable all interrupts. - Input: - dev - device structure - Output: - None. + Function: ft1000_disable_interrupts + Description: This function will disable all interrupts. + Input: + dev - device structure + Output: + None. -------------------------------------------------------------------------*/ static void ft1000_disable_interrupts(struct net_device *dev) { u16 tempword; - DEBUG(1, "ft1000_hw: ft1000_disable_interrupts()\n"); ft1000_write_reg(dev, FT1000_REG_SUP_IMASK, ISR_MASK_ALL); tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK); - DEBUG(1, - "ft1000_hw:ft1000_disable_interrupts:current interrupt enable mask = 0x%x\n", - tempword); + pr_debug("current interrupt enable mask = 0x%x\n", tempword); } /*--------------------------------------------------------------------------- - Function: ft1000_reset_asic - Description: This function will call the Card Service function to reset the - ASIC. - Input: - dev - device structure - Output: - none + Function: ft1000_reset_asic + Description: This function will call the Card Service function to reset the + ASIC. + Input: + dev - device structure + Output: + none -------------------------------------------------------------------------*/ static void ft1000_reset_asic(struct net_device *dev) @@ -329,8 +319,6 @@ static void ft1000_reset_asic(struct net_device *dev) struct ft1000_pcmcia *pcmcia = info->priv; u16 tempword; - DEBUG(1, "ft1000_hw:ft1000_reset_asic called\n"); - (*info->ft1000_reset) (pcmcia->link); /* @@ -351,22 +339,22 @@ static void ft1000_reset_asic(struct net_device *dev) } /* clear interrupts */ tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR); - DEBUG(1, "ft1000_hw: interrupt status register = 0x%x\n", tempword); + pr_debug("interrupt status register = 0x%x\n", tempword); ft1000_write_reg(dev, FT1000_REG_SUP_ISR, tempword); tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR); - DEBUG(1, "ft1000_hw: interrupt status register = 0x%x\n", tempword); + pr_debug("interrupt status register = 0x%x\n", tempword); } /*--------------------------------------------------------------------------- - Function: ft1000_reset_card - Description: This function will reset the card - Input: - dev - device structure - Output: - status - false (card reset fail) - true (card reset successful) + Function: ft1000_reset_card + Description: This function will reset the card + Input: + dev - device structure + Output: + status - false (card reset fail) + true (card reset successful) -------------------------------------------------------------------------*/ static int ft1000_reset_card(struct net_device *dev) @@ -377,8 +365,6 @@ static int ft1000_reset_card(struct net_device *dev) unsigned long flags; struct prov_record *ptr; - DEBUG(1, "ft1000_hw:ft1000_reset_card called.....\n"); - info->CardReady = 0; info->ProgConStat = 0; info->squeseqnum = 0; @@ -388,8 +374,7 @@ static int ft1000_reset_card(struct net_device *dev) /* Make sure we free any memory reserve for provisioning */ while (list_empty(&info->prov_list) == 0) { - DEBUG(0, - "ft1000_hw:ft1000_reset_card:deleting provisioning record\n"); + pr_debug("deleting provisioning record\n"); ptr = list_entry(info->prov_list.next, struct prov_record, list); list_del(&ptr->list); kfree(ptr->pprov_data); @@ -397,11 +382,10 @@ static int ft1000_reset_card(struct net_device *dev) } if (info->AsicID == ELECTRABUZZ_ID) { - DEBUG(1, "ft1000_hw:ft1000_reset_card:resetting DSP\n"); + pr_debug("resetting DSP\n"); ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT); } else { - DEBUG(1, - "ft1000_hw:ft1000_reset_card:resetting ASIC and DSP\n"); + pr_debug("resetting ASIC and DSP\n"); ft1000_write_reg(dev, FT1000_REG_RESET, (DSP_RESET_BIT | ASIC_RESET_BIT)); } @@ -428,17 +412,16 @@ static int ft1000_reset_card(struct net_device *dev) spin_unlock_irqrestore(&info->dpram_lock, flags); } - DEBUG(1, "ft1000_hw:ft1000_reset_card:resetting ASIC\n"); + pr_debug("resetting ASIC\n"); mdelay(10); /* reset ASIC */ ft1000_reset_asic(dev); - DEBUG(1, "ft1000_hw:ft1000_reset_card:downloading dsp image\n"); + pr_debug("downloading dsp image\n"); if (info->AsicID == MAGNEMITE_ID) { /* Put dsp in reset and take ASIC out of reset */ - DEBUG(0, - "ft1000_hw:ft1000_reset_card:Put DSP in reset and take ASIC out of reset\n"); + pr_debug("Put DSP in reset and take ASIC out of reset\n"); ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT); /* Setting MAGNEMITE ASIC to big endian mode */ @@ -450,7 +433,7 @@ static int ft1000_reset_card(struct net_device *dev) ft1000_write_reg(dev, FT1000_REG_RESET, 0); /* FLARION_DSP_ACTIVE; */ mdelay(10); - DEBUG(0, "ft1000_hw:ft1000_reset_card:Take DSP out of reset\n"); + pr_debug("Take DSP out of reset\n"); /* Wait for 0xfefe indicating dsp ready before starting download */ for (i = 0; i < 50; i++) { @@ -464,8 +447,7 @@ static int ft1000_reset_card(struct net_device *dev) } if (i == 50) { - DEBUG(0, - "ft1000_hw:ft1000_reset_card:No FEFE detected from DSP\n"); + pr_debug("No FEFE detected from DSP\n"); return false; } @@ -476,10 +458,10 @@ static int ft1000_reset_card(struct net_device *dev) } if (card_download(dev, fw_entry->data, fw_entry->size)) { - DEBUG(1, "card download unsuccessful\n"); + pr_debug("card download unsuccessful\n"); return false; } else { - DEBUG(1, "card download successful\n"); + pr_debug("card download successful\n"); } mdelay(10); @@ -494,8 +476,7 @@ static int ft1000_reset_card(struct net_device *dev) /* Initialize DSP heartbeat area to ho */ ft1000_write_dpram(dev, FT1000_HI_HO, ho); tempword = ft1000_read_dpram(dev, FT1000_HI_HO); - DEBUG(1, "ft1000_hw:ft1000_reset_asic:hi_ho value = 0x%x\n", - tempword); + pr_debug("hi_ho value = 0x%x\n", tempword); } else { /* Initialize DSP heartbeat area to ho */ ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, ho_mag, @@ -503,8 +484,7 @@ static int ft1000_reset_card(struct net_device *dev) tempword = ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO, FT1000_MAG_HI_HO_INDX); - DEBUG(1, "ft1000_hw:ft1000_reset_card:hi_ho value = 0x%x\n", - tempword); + pr_debug("hi_ho value = 0x%x\n", tempword); } info->CardReady = 1; @@ -521,14 +501,14 @@ static int ft1000_reset_card(struct net_device *dev) /*--------------------------------------------------------------------------- - Function: ft1000_chkcard - Description: This function will check if the device is presently available on - the system. - Input: - dev - device structure - Output: - status - false (device is not present) - true (device is present) + Function: ft1000_chkcard + Description: This function will check if the device is presently available on + the system. + Input: + dev - device structure + Output: + status - false (device is not present) + true (device is present) -------------------------------------------------------------------------*/ static int ft1000_chkcard(struct net_device *dev) @@ -541,8 +521,7 @@ static int ft1000_chkcard(struct net_device *dev) */ tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK); if (tempword == 0) { - DEBUG(1, - "ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n"); + pr_debug("IMASK = 0 Card not detected\n"); return false; } /* @@ -551,8 +530,7 @@ static int ft1000_chkcard(struct net_device *dev) */ tempword = ft1000_read_reg(dev, FT1000_REG_ASIC_ID); if (tempword == 0xffff) { - DEBUG(1, - "ft1000_hw:ft1000_chkcard: Version = 0xffff Card not detected\n"); + pr_debug("Version = 0xffff Card not detected\n"); return false; } return true; @@ -561,13 +539,13 @@ static int ft1000_chkcard(struct net_device *dev) /*--------------------------------------------------------------------------- - Function: ft1000_hbchk - Description: This function will perform the heart beat check of the DSP as - well as the ASIC. - Input: - dev - device structure - Output: - none + Function: ft1000_hbchk + Description: This function will perform the heart beat check of the DSP as + well as the ASIC. + Input: + dev - device structure + Output: + none -------------------------------------------------------------------------*/ static void ft1000_hbchk(u_long data) @@ -586,11 +564,10 @@ static void ft1000_hbchk(u_long data) } else { tempword = ntohs(ft1000_read_dpram_mag_16 - (dev, FT1000_MAG_HI_HO, - FT1000_MAG_HI_HO_INDX)); + (dev, FT1000_MAG_HI_HO, + FT1000_MAG_HI_HO_INDX)); } - DEBUG(1, "ft1000_hw:ft1000_hbchk:hi_ho value = 0x%x\n", - tempword); + pr_debug("hi_ho value = 0x%x\n", tempword); /* Let's perform another check if ho is not detected */ if (tempword != ho) { if (info->AsicID == ELECTRABUZZ_ID) { @@ -601,8 +578,7 @@ static void ft1000_hbchk(u_long data) } } if (tempword != ho) { - printk(KERN_INFO - "ft1000: heartbeat failed - no ho detected\n"); + pr_info("heartbeat failed - no ho detected\n"); if (info->AsicID == ELECTRABUZZ_ID) { info->DSP_TIME[0] = ft1000_read_dpram(dev, FT1000_DSP_TIMER0); @@ -632,8 +608,7 @@ static void ft1000_hbchk(u_long data) } info->DrvErrNum = DSP_HB_INFO; if (ft1000_reset_card(dev) == 0) { - printk(KERN_INFO - "ft1000: Hardware Failure Detected - PC Card disabled\n"); + pr_info("Hardware Failure Detected - PC Card disabled\n"); info->ProgConStat = 0xff; return; } @@ -650,8 +625,7 @@ static void ft1000_hbchk(u_long data) tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); } if (tempword & FT1000_DB_HB) { - printk(KERN_INFO - "ft1000: heartbeat doorbell not clear by firmware\n"); + pr_info("heartbeat doorbell not clear by firmware\n"); if (info->AsicID == ELECTRABUZZ_ID) { info->DSP_TIME[0] = ft1000_read_dpram(dev, FT1000_DSP_TIMER0); @@ -681,8 +655,7 @@ static void ft1000_hbchk(u_long data) } info->DrvErrNum = DSP_HB_INFO; if (ft1000_reset_card(dev) == 0) { - printk(KERN_INFO - "ft1000: Hardware Failure Detected - PC Card disabled\n"); + pr_info("Hardware Failure Detected - PC Card disabled\n"); info->ProgConStat = 0xff; return; } @@ -708,8 +681,8 @@ static void ft1000_hbchk(u_long data) } else { tempword = ntohs(ft1000_read_dpram_mag_16 - (dev, FT1000_MAG_HI_HO, - FT1000_MAG_HI_HO_INDX)); + (dev, FT1000_MAG_HI_HO, + FT1000_MAG_HI_HO_INDX)); } /* Let's write hi again if fail */ if (tempword != hi) { @@ -730,8 +703,7 @@ static void ft1000_hbchk(u_long data) } if (tempword != hi) { - printk(KERN_INFO - "ft1000: heartbeat failed - cannot write hi into DPRAM\n"); + pr_info("heartbeat failed - cannot write hi into DPRAM\n"); if (info->AsicID == ELECTRABUZZ_ID) { info->DSP_TIME[0] = ft1000_read_dpram(dev, FT1000_DSP_TIMER0); @@ -761,8 +733,7 @@ static void ft1000_hbchk(u_long data) } info->DrvErrNum = DSP_HB_INFO; if (ft1000_reset_card(dev) == 0) { - printk(KERN_INFO - "ft1000: Hardware Failure Detected - PC Card disabled\n"); + pr_info("Hardware Failure Detected - PC Card disabled\n"); info->ProgConStat = 0xff; return; } @@ -778,19 +749,19 @@ static void ft1000_hbchk(u_long data) /* Schedule this module to run every 2 seconds */ poll_timer.expires = jiffies + (2 * HZ); - poll_timer.data = (u_long) dev; + poll_timer.data = (u_long)dev; add_timer(&poll_timer); } /*--------------------------------------------------------------------------- - Function: ft1000_send_cmd - Description: - Input: - Output: + Function: ft1000_send_cmd + Description: + Input: + Output: -------------------------------------------------------------------------*/ -static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, u16 qtype) +static void ft1000_send_cmd(struct net_device *dev, u16 *ptempbuffer, int size, u16 qtype) { struct ft1000_info *info = netdev_priv(dev); int i; @@ -802,26 +773,26 @@ static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, if ((size & 0x0001)) { size++; } - DEBUG(1, "FT1000:ft1000_send_cmd:total length = %d\n", size); - DEBUG(1, "FT1000:ft1000_send_cmd:length = %d\n", ntohs(*ptempbuffer)); + pr_debug("total length = %d\n", size); + pr_debug("length = %d\n", ntohs(*ptempbuffer)); /* * put message into slow queue area * All messages are in the form total_len + pseudo header + message body */ spin_lock_irqsave(&info->dpram_lock, flags); - /* Make sure SLOWQ doorbell is clear */ - tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); - i=0; - while (tempword & FT1000_DB_DPRAM_TX) { - mdelay(10); - i++; - if (i==10) { - spin_unlock_irqrestore(&info->dpram_lock, flags); - return; - } - tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); - } + /* Make sure SLOWQ doorbell is clear */ + tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); + i = 0; + while (tempword & FT1000_DB_DPRAM_TX) { + mdelay(10); + i++; + if (i == 10) { + spin_unlock_irqrestore(&info->dpram_lock, flags); + return; + } + tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); + } if (info->AsicID == ELECTRABUZZ_ID) { ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, @@ -830,8 +801,7 @@ static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, size); /* Write pseudo header and messgae body */ for (i = 0; i < (size >> 1); i++) { - DEBUG(1, "FT1000:ft1000_send_cmd:data %d = 0x%x\n", i, - *ptempbuffer); + pr_debug("data %d = 0x%x\n", i, *ptempbuffer); tempword = htons(*ptempbuffer++); ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, tempword); } @@ -844,18 +814,16 @@ static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, FT1000_DPRAM_MAG_TX_BASE + 1); for (i = 0; i < (size >> 2); i++) { - DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n", - *ptempbuffer); + pr_debug("data = 0x%x\n", *ptempbuffer); outw(*ptempbuffer++, - dev->base_addr + FT1000_REG_MAG_DPDATAL); - DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n", - *ptempbuffer); + dev->base_addr + FT1000_REG_MAG_DPDATAL); + pr_debug("data = 0x%x\n", *ptempbuffer); outw(*ptempbuffer++, - dev->base_addr + FT1000_REG_MAG_DPDATAH); + dev->base_addr + FT1000_REG_MAG_DPDATAH); } - DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n", *ptempbuffer); + pr_debug("data = 0x%x\n", *ptempbuffer); outw(*ptempbuffer++, dev->base_addr + FT1000_REG_MAG_DPDATAL); - DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n", *ptempbuffer); + pr_debug("data = 0x%x\n", *ptempbuffer); outw(*ptempbuffer++, dev->base_addr + FT1000_REG_MAG_DPDATAH); } spin_unlock_irqrestore(&info->dpram_lock, flags); @@ -866,19 +834,19 @@ static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, /*--------------------------------------------------------------------------- - Function: ft1000_receive_cmd - Description: This function will read a message from the dpram area. - Input: - dev - network device structure - pbuffer - caller supply address to buffer - pnxtph - pointer to next pseudo header - Output: - Status = 0 (unsuccessful) - = 1 (successful) + Function: ft1000_receive_cmd + Description: This function will read a message from the dpram area. + Input: + dev - network device structure + pbuffer - caller supply address to buffer + pnxtph - pointer to next pseudo header + Output: + Status = 0 (unsuccessful) + = 1 (successful) -------------------------------------------------------------------------*/ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, - int maxsz, u16 *pnxtph) + int maxsz, u16 *pnxtph) { struct ft1000_info *info = netdev_priv(dev); u16 size; @@ -888,20 +856,18 @@ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, unsigned long flags; if (info->AsicID == ELECTRABUZZ_ID) { - size = ( ft1000_read_dpram(dev, *pnxtph) ) + sizeof(struct pseudo_hdr); + size = (ft1000_read_dpram(dev, *pnxtph)) + sizeof(struct pseudo_hdr); } else { size = ntohs(ft1000_read_dpram_mag_16 - (dev, FT1000_MAG_PH_LEN, - FT1000_MAG_PH_LEN_INDX)) + sizeof(struct pseudo_hdr); + (dev, FT1000_MAG_PH_LEN, + FT1000_MAG_PH_LEN_INDX)) + sizeof(struct pseudo_hdr); } if (size > maxsz) { - DEBUG(1, - "FT1000:ft1000_receive_cmd:Invalid command length = %d\n", - size); + pr_debug("Invalid command length = %d\n", size); return false; } else { - ppseudohdr = (u16 *) pbuffer; + ppseudohdr = (u16 *)pbuffer; spin_lock_irqsave(&info->dpram_lock, flags); if (info->AsicID == ELECTRABUZZ_ID) { ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, @@ -915,26 +881,26 @@ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, FT1000_DPRAM_MAG_RX_BASE); *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAH); - DEBUG(1, "ft1000_hw:received data = 0x%x\n", *pbuffer); + pr_debug("received data = 0x%x\n", *pbuffer); pbuffer++; ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, FT1000_DPRAM_MAG_RX_BASE + 1); for (i = 0; i <= (size >> 2); i++) { *pbuffer = inw(dev->base_addr + - FT1000_REG_MAG_DPDATAL); + FT1000_REG_MAG_DPDATAL); pbuffer++; *pbuffer = inw(dev->base_addr + - FT1000_REG_MAG_DPDATAH); + FT1000_REG_MAG_DPDATAH); pbuffer++; } /* copy odd aligned word */ *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAL); - DEBUG(1, "ft1000_hw:received data = 0x%x\n", *pbuffer); + pr_debug("received data = 0x%x\n", *pbuffer); pbuffer++; *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAH); - DEBUG(1, "ft1000_hw:received data = 0x%x\n", *pbuffer); + pr_debug("received data = 0x%x\n", *pbuffer); pbuffer++; } if (size & 0x0001) { @@ -953,8 +919,7 @@ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, tempword ^= *ppseudohdr++; } if ((tempword != *ppseudohdr)) { - DEBUG(1, - "FT1000:ft1000_receive_cmd:Pseudo header checksum mismatch\n"); + pr_debug("Pseudo header checksum mismatch\n"); /* Drop this message */ return false; } @@ -964,13 +929,13 @@ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, /*--------------------------------------------------------------------------- - Function: ft1000_proc_drvmsg - Description: This function will process the various driver messages. - Input: - dev - device structure - pnxtph - pointer to next pseudo header - Output: - none + Function: ft1000_proc_drvmsg + Description: This function will process the various driver messages. + Input: + dev - device structure + pnxtph - pointer to next pseudo header + Output: + none -------------------------------------------------------------------------*/ static void ft1000_proc_drvmsg(struct net_device *dev) @@ -992,25 +957,24 @@ static void ft1000_proc_drvmsg(struct net_device *dev) u16 wrd; } convert; - if (info->AsicID == ELECTRABUZZ_ID) { - tempword = FT1000_DPRAM_RX_BASE+2; - } - else { - tempword = FT1000_DPRAM_MAG_RX_BASE; - } - if ( ft1000_receive_cmd(dev, &cmdbuffer[0], MAX_CMD_SQSIZE, &tempword) ) { + if (info->AsicID == ELECTRABUZZ_ID) { + tempword = FT1000_DPRAM_RX_BASE+2; + } + else { + tempword = FT1000_DPRAM_MAG_RX_BASE; + } + if (ft1000_receive_cmd(dev, &cmdbuffer[0], MAX_CMD_SQSIZE, &tempword)) { /* Get the message type which is total_len + PSEUDO header + msgtype + message body */ - pdrvmsg = (struct drv_msg *) & cmdbuffer[0]; + pdrvmsg = (struct drv_msg *)&cmdbuffer[0]; msgtype = ntohs(pdrvmsg->type); - DEBUG(1, "Command message type = 0x%x\n", msgtype); + pr_debug("Command message type = 0x%x\n", msgtype); switch (msgtype) { case DSP_PROVISION: - DEBUG(0, - "Got a provisioning request message from DSP\n"); + pr_debug("Got a provisioning request message from DSP\n"); mdelay(25); while (list_empty(&info->prov_list) == 0) { - DEBUG(0, "Sending a provisioning message\n"); + pr_debug("Sending a provisioning message\n"); /* Make sure SLOWQ doorbell is clear */ tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); @@ -1025,25 +989,25 @@ static void ft1000_proc_drvmsg(struct net_device *dev) ptr = list_entry(info->prov_list.next, struct prov_record, list); - len = *(u16 *) ptr->pprov_data; + len = *(u16 *)ptr->pprov_data; len = htons(len); - pmsg = (u16 *) ptr->pprov_data; - ppseudo_hdr = (struct pseudo_hdr *) pmsg; + pmsg = (u16 *)ptr->pprov_data; + ppseudo_hdr = (struct pseudo_hdr *)pmsg; /* Insert slow queue sequence number */ ppseudo_hdr->seq_num = info->squeseqnum++; ppseudo_hdr->portsrc = 0; /* Calculate new checksum */ ppseudo_hdr->checksum = *pmsg++; - DEBUG(1, "checksum = 0x%x\n", - ppseudo_hdr->checksum); + pr_debug("checksum = 0x%x\n", + ppseudo_hdr->checksum); for (i = 1; i < 7; i++) { ppseudo_hdr->checksum ^= *pmsg++; - DEBUG(1, "checksum = 0x%x\n", - ppseudo_hdr->checksum); + pr_debug("checksum = 0x%x\n", + ppseudo_hdr->checksum); } - ft1000_send_cmd (dev, (u16 *)ptr->pprov_data, len, SLOWQ_TYPE); + ft1000_send_cmd(dev, (u16 *)ptr->pprov_data, len, SLOWQ_TYPE); list_del(&ptr->list); kfree(ptr->pprov_data); kfree(ptr); @@ -1055,19 +1019,29 @@ static void ft1000_proc_drvmsg(struct net_device *dev) info->CardReady = 1; break; case MEDIA_STATE: - pmediamsg = (struct media_msg *) & cmdbuffer[0]; + pmediamsg = (struct media_msg *)&cmdbuffer[0]; if (info->ProgConStat != 0xFF) { - if (pmediamsg->state) { - DEBUG(1, "Media is up\n"); - if (info->mediastate == 0) { - netif_carrier_on(dev); - netif_wake_queue(dev); - info->mediastate = 1; - do_gettimeofday(&tv); - info->ConTm = tv.tv_sec; + if (pmediamsg->state) { + pr_debug("Media is up\n"); + if (info->mediastate == 0) { + netif_carrier_on(dev); + netif_wake_queue(dev); + info->mediastate = 1; + do_gettimeofday(&tv); + info->ConTm = tv.tv_sec; + } + } else { + pr_debug("Media is down\n"); + if (info->mediastate == 1) { + info->mediastate = 0; + netif_carrier_off(dev); + netif_stop_queue(dev); + info->ConTm = 0; + } } - } else { - DEBUG(1, "Media is down\n"); + } + else { + pr_debug("Media is down\n"); if (info->mediastate == 1) { info->mediastate = 0; netif_carrier_off(dev); @@ -1075,25 +1049,15 @@ static void ft1000_proc_drvmsg(struct net_device *dev) info->ConTm = 0; } } - } - else { - DEBUG(1, "Media is down\n"); - if (info->mediastate == 1) { - info->mediastate = 0; - netif_carrier_off(dev); - netif_stop_queue(dev); - info->ConTm = 0; - } - } break; case DSP_INIT_MSG: - pdspinitmsg = (struct dsp_init_msg *) & cmdbuffer[0]; + pdspinitmsg = (struct dsp_init_msg *)&cmdbuffer[0]; memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ); - DEBUG(1, "DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n", - info->DspVer[0], info->DspVer[1], info->DspVer[2], - info->DspVer[3]); + pr_debug("DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n", + info->DspVer[0], info->DspVer[1], + info->DspVer[2], info->DspVer[3]); memcpy(info->HwSerNum, pdspinitmsg->HwSerNum, - HWSERNUMSZ); + HWSERNUMSZ); memcpy(info->Sku, pdspinitmsg->Sku, SKUSZ); memcpy(info->eui64, pdspinitmsg->eui64, EUISZ); dev->dev_addr[0] = info->eui64[0]; @@ -1104,34 +1068,33 @@ static void ft1000_proc_drvmsg(struct net_device *dev) dev->dev_addr[5] = info->eui64[7]; if (ntohs(pdspinitmsg->length) == - (sizeof(struct dsp_init_msg) - 20)) { + (sizeof(struct dsp_init_msg) - 20)) { memcpy(info->ProductMode, - pdspinitmsg->ProductMode, MODESZ); + pdspinitmsg->ProductMode, MODESZ); memcpy(info->RfCalVer, pdspinitmsg->RfCalVer, - CALVERSZ); + CALVERSZ); memcpy(info->RfCalDate, pdspinitmsg->RfCalDate, - CALDATESZ); - DEBUG(1, "RFCalVer = 0x%2x 0x%2x\n", - info->RfCalVer[0], info->RfCalVer[1]); + CALDATESZ); + pr_debug("RFCalVer = 0x%2x 0x%2x\n", + info->RfCalVer[0], info->RfCalVer[1]); } - break ; + break; case DSP_STORE_INFO: - DEBUG(1, "FT1000:drivermsg:Got DSP_STORE_INFO\n"); + pr_debug("Got DSP_STORE_INFO\n"); tempword = ntohs(pdrvmsg->length); info->DSPInfoBlklen = tempword; if (tempword < (MAX_DSP_SESS_REC - 4)) { - pmsg = (u16 *) & pdrvmsg->data[0]; + pmsg = (u16 *)&pdrvmsg->data[0]; for (i = 0; i < ((tempword + 1) / 2); i++) { - DEBUG(1, - "FT1000:drivermsg:dsp info data = 0x%x\n", - *pmsg); + pr_debug("dsp info data = 0x%x\n", + *pmsg); info->DSPInfoBlk[i + 10] = *pmsg++; } } break; case DSP_GET_INFO: - DEBUG(1, "FT1000:drivermsg:Got DSP_GET_INFO\n"); + pr_debug("Got DSP_GET_INFO\n"); /* * copy dsp info block to dsp * allow any outstanding ioctl to finish @@ -1152,8 +1115,8 @@ static void ft1000_proc_drvmsg(struct net_device *dev) * Put message into Slow Queue * Form Pseudo header */ - pmsg = (u16 *) info->DSPInfoBlk; - ppseudo_hdr = (struct pseudo_hdr *) pmsg; + pmsg = (u16 *)info->DSPInfoBlk; + ppseudo_hdr = (struct pseudo_hdr *)pmsg; ppseudo_hdr->length = htons(info->DSPInfoBlklen + 4); ppseudo_hdr->source = 0x10; @@ -1177,12 +1140,12 @@ static void ft1000_proc_drvmsg(struct net_device *dev) info->DSPInfoBlk[8] = 0x7200; info->DSPInfoBlk[9] = htons(info->DSPInfoBlklen); - ft1000_send_cmd (dev, (u16 *)info->DSPInfoBlk, (u16)(info->DSPInfoBlklen+4), 0); + ft1000_send_cmd(dev, (u16 *)info->DSPInfoBlk, (u16)(info->DSPInfoBlklen+4), 0); } break; case GET_DRV_ERR_RPT_MSG: - DEBUG(1, "FT1000:drivermsg:Got GET_DRV_ERR_RPT_MSG\n"); + pr_debug("Got GET_DRV_ERR_RPT_MSG\n"); /* * copy driver error message to dsp * allow any outstanding ioctl to finish @@ -1203,8 +1166,8 @@ static void ft1000_proc_drvmsg(struct net_device *dev) * Put message into Slow Queue * Form Pseudo header */ - pmsg = (u16 *) & tempbuffer[0]; - ppseudo_hdr = (struct pseudo_hdr *) pmsg; + pmsg = (u16 *)&tempbuffer[0]; + ppseudo_hdr = (struct pseudo_hdr *)pmsg; ppseudo_hdr->length = htons(0x0012); ppseudo_hdr->source = 0x10; ppseudo_hdr->destination = 0x20; @@ -1220,11 +1183,11 @@ static void ft1000_proc_drvmsg(struct net_device *dev) /* Insert application id */ ppseudo_hdr->portsrc = 0; /* Calculate new checksum */ - ppseudo_hdr->checksum = *pmsg++; - for (i=1; i<7; i++) { - ppseudo_hdr->checksum ^= *pmsg++; - } - pmsg = (u16 *) & tempbuffer[16]; + ppseudo_hdr->checksum = *pmsg++; + for (i = 1; i < 7; i++) { + ppseudo_hdr->checksum ^= *pmsg++; + } + pmsg = (u16 *)&tempbuffer[16]; *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG); *pmsg++ = htons(0x000e); *pmsg++ = htons(info->DSP_TIME[0]); @@ -1239,7 +1202,7 @@ static void ft1000_proc_drvmsg(struct net_device *dev) *pmsg++ = convert.wrd; *pmsg++ = htons(info->DrvErrNum); - ft1000_send_cmd (dev, (u16 *)&tempbuffer[0], (u16)(0x0012), 0); + ft1000_send_cmd(dev, (u16 *)&tempbuffer[0], (u16)(0x0012), 0); info->DrvErrNum = 0; } @@ -1252,14 +1215,14 @@ static void ft1000_proc_drvmsg(struct net_device *dev) /*--------------------------------------------------------------------------- - Function: ft1000_parse_dpram_msg - Description: This function will parse the message received from the DSP - via the DPRAM interface. - Input: - dev - device structure - Output: - status - FAILURE - SUCCESS + Function: ft1000_parse_dpram_msg + Description: This function will parse the message received from the DSP + via the DPRAM interface. + Input: + dev - device structure + Output: + status - FAILURE + SUCCESS -------------------------------------------------------------------------*/ static int ft1000_parse_dpram_msg(struct net_device *dev) @@ -1270,11 +1233,10 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) u16 nxtph; u16 total_len; int i = 0; - int cnt; unsigned long flags; doorbell = ft1000_read_reg(dev, FT1000_REG_DOORBELL); - DEBUG(1, "Doorbell = 0x%x\n", doorbell); + pr_debug("Doorbell = 0x%x\n", doorbell); if (doorbell & FT1000_ASIC_RESET_REQ) { /* Copy DSP session record from info block */ @@ -1291,7 +1253,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) FT1000_DPRAM_MAG_RX_BASE); for (i = 0; i < MAX_DSP_SESS_REC / 2; i++) { outl(info->DSPSess.MagRec[i], - dev->base_addr + FT1000_REG_MAG_DPDATA); + dev->base_addr + FT1000_REG_MAG_DPDATA); } } spin_unlock_irqrestore(&info->dpram_lock, flags); @@ -1299,7 +1261,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) /* clear ASIC RESET request */ ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_ASIC_RESET_REQ); - DEBUG(1, "Got an ASIC RESET Request\n"); + pr_debug("Got an ASIC RESET Request\n"); ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_ASIC_RESET_DSP); @@ -1311,8 +1273,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) } if (doorbell & FT1000_DSP_ASIC_RESET) { - DEBUG(0, - "FT1000:ft1000_parse_dpram_msg: Got a dsp ASIC reset message\n"); + pr_debug("Got a dsp ASIC reset message\n"); ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DSP_ASIC_RESET); udelay(200); @@ -1320,8 +1281,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) } if (doorbell & FT1000_DB_DPRAM_RX) { - DEBUG(1, - "FT1000:ft1000_parse_dpram_msg: Got a slow queue message\n"); + pr_debug("Got a slow queue message\n"); nxtph = FT1000_DPRAM_RX_BASE + 2; if (info->AsicID == ELECTRABUZZ_ID) { total_len = @@ -1329,14 +1289,12 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) } else { total_len = ntohs(ft1000_read_dpram_mag_16 - (dev, FT1000_MAG_TOTAL_LEN, - FT1000_MAG_TOTAL_LEN_INDX)); + (dev, FT1000_MAG_TOTAL_LEN, + FT1000_MAG_TOTAL_LEN_INDX)); } - DEBUG(1, "FT1000:ft1000_parse_dpram_msg:total length = %d\n", - total_len); + pr_debug("total length = %d\n", total_len); if ((total_len < MAX_CMD_SQSIZE) && (total_len > sizeof(struct pseudo_hdr))) { - total_len += nxtph; - cnt = 0; + total_len += nxtph; /* * ft1000_read_reg will return a value that needs to be byteswap * in order to get DSP_QID_OFFSET. @@ -1353,7 +1311,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) (dev, FT1000_MAG_PORT_ID, FT1000_MAG_PORT_ID_INDX) & 0xff); } - DEBUG(1, "DSP_QID = 0x%x\n", portid); + pr_debug("DSP_QID = 0x%x\n", portid); if (portid == DRIVERID) { /* We are assumming one driver message from the DSP at a time. */ @@ -1389,7 +1347,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) FT1000_MAG_DSP_TIMER3_INDX); } info->DrvErrNum = DSP_CONDRESET_INFO; - DEBUG(1, "ft1000_hw:DSP conditional reset requested\n"); + pr_debug("DSP conditional reset requested\n"); ft1000_reset_card(dev); ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_COND_RESET); @@ -1397,9 +1355,9 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) /* let's clear any unexpected doorbells from DSP */ doorbell = doorbell & ~(FT1000_DB_DPRAM_RX | FT1000_ASIC_RESET_REQ | - FT1000_DB_COND_RESET | 0xff00); + FT1000_DB_COND_RESET | 0xff00); if (doorbell) { - DEBUG(1, "Clearing unexpected doorbell = 0x%x\n", doorbell); + pr_debug("Clearing unexpected doorbell = 0x%x\n", doorbell); ft1000_write_reg(dev, FT1000_REG_DOORBELL, doorbell); } @@ -1409,14 +1367,14 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) /*--------------------------------------------------------------------------- - Function: ft1000_flush_fifo - Description: This function will flush one packet from the downlink - FIFO. - Input: - dev - device structure - drv_err - driver error causing the flush fifo - Output: - None. + Function: ft1000_flush_fifo + Description: This function will flush one packet from the downlink + FIFO. + Input: + dev - device structure + drv_err - driver error causing the flush fifo + Output: + None. -------------------------------------------------------------------------*/ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) @@ -1427,7 +1385,6 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) u32 templong; u16 tempword; - DEBUG(1, "ft1000:ft1000_hw:ft1000_flush_fifo called\n"); if (pcmcia->PktIntfErr > MAX_PH_ERR) { if (info->AsicID == ELECTRABUZZ_ID) { info->DSP_TIME[0] = @@ -1514,7 +1471,7 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) */ tempword = inw(dev->base_addr + - FT1000_REG_SUP_IMASK); + FT1000_REG_SUP_IMASK); if (tempword == 0) { /* This indicates that we can not communicate with the ASIC */ info->DrvErrNum = @@ -1533,23 +1490,23 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) } while ((tempword & 0x03) != 0x03); if (info->AsicID == ELECTRABUZZ_ID) { i++; - DEBUG(0, "Flushing FIFO complete = %x\n", tempword); + pr_debug("Flushing FIFO complete = %x\n", tempword); /* Flush last word in FIFO. */ tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO); /* Update FIFO counter for DSP */ i = i * 2; - DEBUG(0, "Flush Data byte count to dsp = %d\n", i); + pr_debug("Flush Data byte count to dsp = %d\n", i); info->fifo_cnt += i; ft1000_write_dpram(dev, FT1000_FIFO_LEN, info->fifo_cnt); } else { - DEBUG(0, "Flushing FIFO complete = %x\n", tempword); + pr_debug("Flushing FIFO complete = %x\n", tempword); /* Flush last word in FIFO */ templong = inl(dev->base_addr + FT1000_REG_MAG_DFR); tempword = inw(dev->base_addr + FT1000_REG_SUP_STAT); - DEBUG(0, "FT1000_REG_SUP_STAT = 0x%x\n", tempword); + pr_debug("FT1000_REG_SUP_STAT = 0x%x\n", tempword); tempword = inw(dev->base_addr + FT1000_REG_MAG_DFSR); - DEBUG(0, "FT1000_REG_MAG_DFSR = 0x%x\n", tempword); + pr_debug("FT1000_REG_MAG_DFSR = 0x%x\n", tempword); } if (DrvErrNum) { pcmcia->PktIntfErr++; @@ -1559,15 +1516,15 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) /*--------------------------------------------------------------------------- - Function: ft1000_copy_up_pkt - Description: This function will pull Flarion packets out of the Downlink - FIFO and convert it to an ethernet packet. The ethernet packet will - then be deliver to the TCP/IP stack. - Input: - dev - device structure - Output: - status - FAILURE - SUCCESS + Function: ft1000_copy_up_pkt + Description: This function will pull Flarion packets out of the Downlink + FIFO and convert it to an ethernet packet. The ethernet packet will + then be deliver to the TCP/IP stack. + Input: + dev - device structure + Output: + status - FAILURE + SUCCESS -------------------------------------------------------------------------*/ static int ft1000_copy_up_pkt(struct net_device *dev) @@ -1583,7 +1540,6 @@ static int ft1000_copy_up_pkt(struct net_device *dev) u32 *ptemplong; u32 templong; - DEBUG(1, "ft1000_copy_up_pkt\n"); /* Read length */ if (info->AsicID == ELECTRABUZZ_ID) { tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO); @@ -1593,10 +1549,10 @@ static int ft1000_copy_up_pkt(struct net_device *dev) len = ntohs(tempword); } chksum = tempword; - DEBUG(1, "Number of Bytes in FIFO = %d\n", len); + pr_debug("Number of Bytes in FIFO = %d\n", len); if (len > ENET_MAX_SIZE) { - DEBUG(0, "size of ethernet packet invalid\n"); + pr_debug("size of ethernet packet invalid\n"); if (info->AsicID == MAGNEMITE_ID) { /* Read High word to complete 32 bit access */ tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH); @@ -1609,7 +1565,7 @@ static int ft1000_copy_up_pkt(struct net_device *dev) skb = dev_alloc_skb(len + 12 + 2); if (skb == NULL) { - DEBUG(0, "No Network buffers available\n"); + pr_debug("No Network buffers available\n"); /* Read High word to complete 32 bit access */ if (info->AsicID == MAGNEMITE_ID) { tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH); @@ -1618,7 +1574,7 @@ static int ft1000_copy_up_pkt(struct net_device *dev) info->stats.rx_errors++; return FAILURE; } - pbuffer = (u8 *) skb_put(skb, len + 12); + pbuffer = (u8 *)skb_put(skb, len + 12); /* Pseudo header */ if (info->AsicID == ELECTRABUZZ_ID) { @@ -1630,37 +1586,37 @@ static int ft1000_copy_up_pkt(struct net_device *dev) tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO); } else { tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH); - DEBUG(1, "Pseudo = 0x%x\n", tempword); + pr_debug("Pseudo = 0x%x\n", tempword); chksum ^= tempword; tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL); - DEBUG(1, "Pseudo = 0x%x\n", tempword); + pr_debug("Pseudo = 0x%x\n", tempword); chksum ^= tempword; tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH); - DEBUG(1, "Pseudo = 0x%x\n", tempword); + pr_debug("Pseudo = 0x%x\n", tempword); chksum ^= tempword; tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL); - DEBUG(1, "Pseudo = 0x%x\n", tempword); + pr_debug("Pseudo = 0x%x\n", tempword); chksum ^= tempword; tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH); - DEBUG(1, "Pseudo = 0x%x\n", tempword); + pr_debug("Pseudo = 0x%x\n", tempword); chksum ^= tempword; tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL); - DEBUG(1, "Pseudo = 0x%x\n", tempword); + pr_debug("Pseudo = 0x%x\n", tempword); chksum ^= tempword; /* read checksum value */ tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH); - DEBUG(1, "Pseudo = 0x%x\n", tempword); + pr_debug("Pseudo = 0x%x\n", tempword); } if (chksum != tempword) { - DEBUG(0, "Packet checksum mismatch 0x%x 0x%x\n", chksum, - tempword); + pr_debug("Packet checksum mismatch 0x%x 0x%x\n", + chksum, tempword); ft1000_flush_fifo(dev, DSP_PKTPHCKSUM_INFO); info->stats.rx_errors++; kfree_skb(skb); @@ -1687,7 +1643,7 @@ static int ft1000_copy_up_pkt(struct net_device *dev) for (i = 0; i < len / 2; i++) { tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO); *pbuffer++ = (u8) (tempword >> 8); - *pbuffer++ = (u8) tempword; + *pbuffer++ = (u8)tempword; if (ft1000_chkcard(dev) == false) { kfree_skb(skb); return FAILURE; @@ -1700,25 +1656,25 @@ static int ft1000_copy_up_pkt(struct net_device *dev) *pbuffer++ = (u8) (tempword >> 8); } } else { - ptemplong = (u32 *) pbuffer; + ptemplong = (u32 *)pbuffer; for (i = 0; i < len / 4; i++) { templong = inl(dev->base_addr + FT1000_REG_MAG_DFR); - DEBUG(1, "Data = 0x%8x\n", templong); + pr_debug("Data = 0x%8x\n", templong); *ptemplong++ = templong; } /* Need to read one more word if odd align. */ if (len & 0x0003) { templong = inl(dev->base_addr + FT1000_REG_MAG_DFR); - DEBUG(1, "Data = 0x%8x\n", templong); + pr_debug("Data = 0x%8x\n", templong); *ptemplong++ = templong; } } - DEBUG(1, "Data passed to Protocol layer:\n"); + pr_debug("Data passed to Protocol layer:\n"); for (i = 0; i < len + 12; i++) { - DEBUG(1, "Protocol Data: 0x%x\n ", *ptemp++); + pr_debug("Protocol Data: 0x%x\n", *ptemp++); } skb->dev = dev; @@ -1745,20 +1701,20 @@ static int ft1000_copy_up_pkt(struct net_device *dev) /*--------------------------------------------------------------------------- - Function: ft1000_copy_down_pkt - Description: This function will take an ethernet packet and convert it to - a Flarion packet prior to sending it to the ASIC Downlink - FIFO. - Input: - dev - device structure - packet - address of ethernet packet - len - length of IP packet - Output: - status - FAILURE - SUCCESS + Function: ft1000_copy_down_pkt + Description: This function will take an ethernet packet and convert it to + a Flarion packet prior to sending it to the ASIC Downlink + FIFO. + Input: + dev - device structure + packet - address of ethernet packet + len - length of IP packet + Output: + status - FAILURE + SUCCESS -------------------------------------------------------------------------*/ -static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) +static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len) { struct ft1000_info *info = netdev_priv(dev); struct ft1000_pcmcia *pcmcia = info->priv; @@ -1770,8 +1726,6 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) int i; u32 *plong; - DEBUG(1, "ft1000_hw: copy_down_pkt()\n"); - /* Check if there is room on the FIFO */ if (len > ft1000_read_fifo_len(dev)) { udelay(10); @@ -1791,8 +1745,7 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) udelay(20); } if (len > ft1000_read_fifo_len(dev)) { - DEBUG(1, - "ft1000_hw:ft1000_copy_down_pkt:Transmit FIFO is fulli - pkt drop\n"); + pr_debug("Transmit FIFO is full - pkt drop\n"); info->stats.tx_errors++; return SUCCESS; } @@ -1823,39 +1776,30 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) if (info->AsicID == ELECTRABUZZ_ID) { /* copy first word to UFIFO_BEG reg */ ft1000_write_reg(dev, FT1000_REG_UFIFO_BEG, pseudo.buff[0]); - DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 0 BEG = 0x%04x\n", - pseudo.buff[0]); + pr_debug("data 0 BEG = 0x%04x\n", pseudo.buff[0]); /* copy subsequent words to UFIFO_MID reg */ ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[1]); - DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 1 MID = 0x%04x\n", - pseudo.buff[1]); + pr_debug("data 1 MID = 0x%04x\n", pseudo.buff[1]); ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[2]); - DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 2 MID = 0x%04x\n", - pseudo.buff[2]); + pr_debug("data 2 MID = 0x%04x\n", pseudo.buff[2]); ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[3]); - DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 3 MID = 0x%04x\n", - pseudo.buff[3]); + pr_debug("data 3 MID = 0x%04x\n", pseudo.buff[3]); ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[4]); - DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 4 MID = 0x%04x\n", - pseudo.buff[4]); + pr_debug("data 4 MID = 0x%04x\n", pseudo.buff[4]); ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[5]); - DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 5 MID = 0x%04x\n", - pseudo.buff[5]); + pr_debug("data 5 MID = 0x%04x\n", pseudo.buff[5]); ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[6]); - DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 6 MID = 0x%04x\n", - pseudo.buff[6]); + pr_debug("data 6 MID = 0x%04x\n", pseudo.buff[6]); ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[7]); - DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 7 MID = 0x%04x\n", - pseudo.buff[7]); + pr_debug("data 7 MID = 0x%04x\n", pseudo.buff[7]); /* Write PPP type + IP Packet into Downlink FIFO */ for (i = 0; i < (len >> 1) - 1; i++) { ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, htons(*packet)); - DEBUG(1, - "ft1000_hw:ft1000_copy_down_pkt:data %d MID = 0x%04x\n", - i + 8, htons(*packet)); + pr_debug("data %d MID = 0x%04x\n", + i + 8, htons(*packet)); packet++; } @@ -1863,41 +1807,33 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) if (len & 0x0001) { ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, htons(*packet)); - DEBUG(1, - "ft1000_hw:ft1000_copy_down_pkt:data MID = 0x%04x\n", - htons(*packet)); + pr_debug("data MID = 0x%04x\n", htons(*packet)); packet++; ft1000_write_reg(dev, FT1000_REG_UFIFO_END, htons(*packet)); - DEBUG(1, - "ft1000_hw:ft1000_copy_down_pkt:data %d MID = 0x%04x\n", - i + 8, htons(*packet)); + pr_debug("data %d MID = 0x%04x\n", + i + 8, htons(*packet)); } else { ft1000_write_reg(dev, FT1000_REG_UFIFO_END, htons(*packet)); - DEBUG(1, - "ft1000_hw:ft1000_copy_down_pkt:data %d MID = 0x%04x\n", - i + 8, htons(*packet)); + pr_debug("data %d MID = 0x%04x\n", + i + 8, htons(*packet)); } } else { - outl(*(u32 *) & pseudo.buff[0], - dev->base_addr + FT1000_REG_MAG_UFDR); - DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n", - *(u32 *) & pseudo.buff[0]); - outl(*(u32 *) & pseudo.buff[2], - dev->base_addr + FT1000_REG_MAG_UFDR); - DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n", - *(u32 *) & pseudo.buff[2]); - outl(*(u32 *) & pseudo.buff[4], - dev->base_addr + FT1000_REG_MAG_UFDR); - DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n", - *(u32 *) & pseudo.buff[4]); - outl(*(u32 *) & pseudo.buff[6], - dev->base_addr + FT1000_REG_MAG_UFDR); - DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n", - *(u32 *) & pseudo.buff[6]); - - plong = (u32 *) packet; + outl(*(u32 *)&pseudo.buff[0], + dev->base_addr + FT1000_REG_MAG_UFDR); + pr_debug("Pseudo = 0x%8x\n", *(u32 *)&pseudo.buff[0]); + outl(*(u32 *)&pseudo.buff[2], + dev->base_addr + FT1000_REG_MAG_UFDR); + pr_debug("Pseudo = 0x%8x\n", *(u32 *)&pseudo.buff[2]); + outl(*(u32 *)&pseudo.buff[4], + dev->base_addr + FT1000_REG_MAG_UFDR); + pr_debug("Pseudo = 0x%8x\n", *(u32 *)&pseudo.buff[4]); + outl(*(u32 *)&pseudo.buff[6], + dev->base_addr + FT1000_REG_MAG_UFDR); + pr_debug("Pseudo = 0x%8x\n", *(u32 *)&pseudo.buff[6]); + + plong = (u32 *)packet; /* Write PPP type + IP Packet into Downlink FIFO */ for (i = 0; i < (len >> 2); i++) { outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR); @@ -1905,9 +1841,7 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) /* Check for odd alignment */ if (len & 0x0003) { - DEBUG(1, - "ft1000_hw:ft1000_copy_down_pkt:data = 0x%8x\n", - *plong); + pr_debug("data = 0x%8x\n", *plong); outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR); } outl(1, dev->base_addr + FT1000_REG_MAG_UFER); @@ -1928,19 +1862,14 @@ static struct net_device_stats *ft1000_stats(struct net_device *dev) static int ft1000_open(struct net_device *dev) { - - DEBUG(0, "ft1000_hw: ft1000_open is called\n"); - ft1000_reset_card(dev); - DEBUG(0, "ft1000_hw: ft1000_open is ended\n"); /* schedule ft1000_hbchk to perform periodic heartbeat checks on DSP and ASIC */ init_timer(&poll_timer); poll_timer.expires = jiffies + (2 * HZ); - poll_timer.data = (u_long) dev; + poll_timer.data = (u_long)dev; add_timer(&poll_timer); - DEBUG(0, "ft1000_hw: ft1000_open is ended2\n"); return 0; } @@ -1948,13 +1877,11 @@ static int ft1000_close(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); - DEBUG(0, "ft1000_hw: ft1000_close()\n"); - info->CardReady = 0; del_timer(&poll_timer); if (ft1000_card_present == 1) { - DEBUG(0, "Media is down\n"); + pr_debug("Media is down\n"); netif_stop_queue(dev); ft1000_disable_interrupts(dev); @@ -1971,31 +1898,28 @@ static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev) struct ft1000_info *info = netdev_priv(dev); u8 *pdata; - DEBUG(1, "ft1000_hw: ft1000_start_xmit()\n"); if (skb == NULL) { - DEBUG(1, "ft1000_hw: ft1000_start_xmit:skb == NULL!!!\n"); + pr_debug("skb == NULL!!!\n"); return 0; } - DEBUG(1, "ft1000_hw: ft1000_start_xmit:length of packet = %d\n", - skb->len); + pr_debug("length of packet = %d\n", skb->len); - pdata = (u8 *) skb->data; + pdata = (u8 *)skb->data; if (info->mediastate == 0) { /* Drop packet is mediastate is down */ - DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:mediastate is down\n"); + pr_debug("mediastate is down\n"); return SUCCESS; } if ((skb->len < ENET_HEADER_SIZE) || (skb->len > ENET_MAX_SIZE)) { /* Drop packet which has invalid size */ - DEBUG(1, - "ft1000_hw:ft1000_copy_down_pkt:invalid ethernet length\n"); + pr_debug("invalid ethernet length\n"); return SUCCESS; } ft1000_copy_down_pkt(dev, (u16 *) (pdata + ENET_HEADER_SIZE - 2), - skb->len - ENET_HEADER_SIZE + 2); + skb->len - ENET_HEADER_SIZE + 2); dev_kfree_skb(skb); @@ -2004,14 +1928,12 @@ static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev) static irqreturn_t ft1000_interrupt(int irq, void *dev_id) { - struct net_device *dev = (struct net_device *)dev_id; + struct net_device *dev = dev_id; struct ft1000_info *info = netdev_priv(dev); u16 tempword; u16 inttype; int cnt; - DEBUG(1, "ft1000_hw: ft1000_interrupt()\n"); - if (info->CardReady == 0) { ft1000_disable_interrupts(dev); return IRQ_HANDLED; @@ -2033,19 +1955,19 @@ static irqreturn_t ft1000_interrupt(int irq, void *dev_id) ft1000_parse_dpram_msg(dev); if (inttype & ISR_RCV) { - DEBUG(1, "Data in FIFO\n"); + pr_debug("Data in FIFO\n"); cnt = 0; do { /* Check if we have packets in the Downlink FIFO */ if (info->AsicID == ELECTRABUZZ_ID) { tempword = - ft1000_read_reg(dev, - FT1000_REG_DFIFO_STAT); + ft1000_read_reg(dev, + FT1000_REG_DFIFO_STAT); } else { tempword = - ft1000_read_reg(dev, - FT1000_REG_MAG_DFSR); + ft1000_read_reg(dev, + FT1000_REG_MAG_DFSR); } if (tempword & 0x1f) { ft1000_copy_up_pkt(dev); @@ -2058,12 +1980,13 @@ static irqreturn_t ft1000_interrupt(int irq, void *dev_id) } /* clear interrupts */ tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR); - DEBUG(1, "ft1000_hw: interrupt status register = 0x%x\n", tempword); + pr_debug("interrupt status register = 0x%x\n", tempword); ft1000_write_reg(dev, FT1000_REG_SUP_ISR, tempword); /* Read interrupt type */ - inttype = ft1000_read_reg (dev, FT1000_REG_SUP_ISR); - DEBUG(1, "ft1000_hw: interrupt status register after clear = 0x%x\n", inttype); + inttype = ft1000_read_reg(dev, FT1000_REG_SUP_ISR); + pr_debug("interrupt status register after clear = 0x%x\n", + inttype); } ft1000_enable_interrupts(dev); return IRQ_HANDLED; @@ -2075,8 +1998,6 @@ void stop_ft1000_card(struct net_device *dev) struct prov_record *ptr; /* int cnt; */ - DEBUG(0, "ft1000_hw: stop_ft1000_card()\n"); - info->CardReady = 0; ft1000_card_present = 0; netif_stop_queue(dev); @@ -2105,7 +2026,7 @@ void stop_ft1000_card(struct net_device *dev) } static void ft1000_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) + struct ethtool_drvinfo *info) { struct ft1000_info *ft_info; ft_info = netdev_priv(dev); @@ -2121,6 +2042,7 @@ static void ft1000_get_drvinfo(struct net_device *dev, static u32 ft1000_get_link(struct net_device *dev) { struct ft1000_info *info; + info = netdev_priv(dev); return info->mediastate; } @@ -2131,37 +2053,36 @@ static const struct ethtool_ops ops = { }; struct net_device *init_ft1000_card(struct pcmcia_device *link, - void *ft1000_reset) + void *ft1000_reset) { struct ft1000_info *info; struct ft1000_pcmcia *pcmcia; struct net_device *dev; static const struct net_device_ops ft1000ops = /* Slavius 21.10.2009 due to kernel changes */ - { - .ndo_open = &ft1000_open, - .ndo_stop = &ft1000_close, - .ndo_start_xmit = &ft1000_start_xmit, - .ndo_get_stats = &ft1000_stats, - }; + { + .ndo_open = &ft1000_open, + .ndo_stop = &ft1000_close, + .ndo_start_xmit = &ft1000_start_xmit, + .ndo_get_stats = &ft1000_stats, + }; - DEBUG(1, "ft1000_hw: init_ft1000_card()\n"); - DEBUG(1, "ft1000_hw: irq = %d\n", link->irq); - DEBUG(1, "ft1000_hw: port = 0x%04x\n", link->resource[0]->start); + pr_debug("irq = %d, port = 0x%04llx\n", + link->irq, (unsigned long long)link->resource[0]->start); flarion_ft1000_cnt++; if (flarion_ft1000_cnt > 1) { flarion_ft1000_cnt--; - printk(KERN_INFO - "ft1000: This driver can not support more than one instance\n"); + dev_info(&link->dev, + "This driver can not support more than one instance\n"); return NULL; } dev = alloc_etherdev(sizeof(struct ft1000_info)); if (!dev) { - printk(KERN_ERR "ft1000: failed to allocate etherdev\n"); + dev_err(&link->dev, "Failed to allocate etherdev\n"); return NULL; } @@ -2170,9 +2091,9 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link, memset(info, 0, sizeof(struct ft1000_info)); - DEBUG(1, "address of dev = 0x%8x\n", (u32) dev); - DEBUG(1, "address of dev info = 0x%8x\n", (u32) info); - DEBUG(0, "device name = %s\n", dev->name); + pr_debug("address of dev = 0x%p\n", dev); + pr_debug("address of dev info = 0x%p\n", info); + pr_debug("device name = %s\n", dev->name); memset(&info->stats, 0, sizeof(struct net_device_stats)); @@ -2204,41 +2125,41 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link, dev->netdev_ops = &ft1000ops; /* Slavius 21.10.2009 due to kernel changes */ - DEBUG(0, "device name = %s\n", dev->name); + pr_debug("device name = %s\n", dev->name); dev->irq = link->irq; dev->base_addr = link->resource[0]->start; if (pcmcia_get_mac_from_cis(link, dev)) { - printk(KERN_ERR "ft1000: Could not read mac address\n"); + netdev_err(dev, "Could not read mac address\n"); goto err_dev; } if (request_irq(dev->irq, ft1000_interrupt, IRQF_SHARED, dev->name, dev)) { - printk(KERN_ERR "ft1000: Could not request_irq\n"); + netdev_err(dev, "Could not request_irq\n"); goto err_dev; } if (request_region(dev->base_addr, 256, dev->name) == NULL) { - printk(KERN_ERR "ft1000: Could not request_region\n"); + netdev_err(dev, "Could not request_region\n"); goto err_irq; } if (register_netdev(dev) != 0) { - DEBUG(0, "ft1000: Could not register netdev"); + pr_debug("Could not register netdev\n"); goto err_reg; } info->AsicID = ft1000_read_reg(dev, FT1000_REG_ASIC_ID); if (info->AsicID == ELECTRABUZZ_ID) { - DEBUG(0, "ft1000_hw: ELECTRABUZZ ASIC\n"); + pr_debug("ELECTRABUZZ ASIC\n"); if (request_firmware(&fw_entry, "ft1000.img", &link->dev) != 0) { - printk(KERN_INFO "ft1000: Could not open ft1000.img\n"); + pr_info("Could not open ft1000.img\n"); goto err_unreg; } } else { - DEBUG(0, "ft1000_hw: MAGNEMITE ASIC\n"); + pr_debug("MAGNEMITE ASIC\n"); if (request_firmware(&fw_entry, "ft2000.img", &link->dev) != 0) { - printk(KERN_INFO "ft1000: Could not open ft2000.img\n"); + pr_info("Could not open ft2000.img\n"); goto err_unreg; } } @@ -2247,8 +2168,8 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link, ft1000_card_present = 1; dev->ethtool_ops = &ops; - printk(KERN_INFO "ft1000: %s: addr 0x%04lx irq %d, MAC addr %pM\n", - dev->name, dev->base_addr, dev->irq, dev->dev_addr); + pr_info("%s: addr 0x%04lx irq %d, MAC addr %pM\n", + dev->name, dev->base_addr, dev->irq, dev->dev_addr); return dev; err_unreg: diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c index 0f347ab0d300..c8d278229940 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c @@ -1,31 +1,34 @@ /* -*--------------------------------------------------------------------------- -* FT1000 driver for Flarion Flash OFDM NIC Device -* -* Copyright (C) 2006 Flarion Technologies, All rights reserved. -* -* This program is free software; you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by the Free -* Software Foundation; either version 2 of the License, or (at your option) any -* later version. This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. You should have received a copy of the GNU General Public -* License along with this program; if not, write to the -* Free Software Foundation, Inc., 59 Temple Place - -* Suite 330, Boston, MA 02111-1307, USA. -*--------------------------------------------------------------------------- -* -* File: ft1000_chdev.c -* -* Description: Custom character device dispatch routines. -* -* History: -* 8/29/02 Whc Ported to Linux. -* 6/05/06 Whc Porting to Linux 2.6.9 -* -*--------------------------------------------------------------------------- -*/ + *--------------------------------------------------------------------------- + * FT1000 driver for Flarion Flash OFDM NIC Device + * + * Copyright (C) 2006 Flarion Technologies, All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) any + * later version. This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - + * Suite 330, Boston, MA 02111-1307, USA. + *--------------------------------------------------------------------------- + * + * File: ft1000_chdev.c + * + * Description: Custom character device dispatch routines. + * + * History: + * 8/29/02 Whc Ported to Linux. + * 6/05/06 Whc Porting to Linux 2.6.9 + * + *--------------------------------------------------------------------------- + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> @@ -38,12 +41,12 @@ #include <linux/debugfs.h> #include "ft1000_usb.h" -static int ft1000_flarion_cnt = 0; +static int ft1000_flarion_cnt; static int ft1000_open(struct inode *inode, struct file *file); static unsigned int ft1000_poll_dev(struct file *file, poll_table *wait); static long ft1000_ioctl(struct file *file, unsigned int command, - unsigned long argument); + unsigned long argument); static int ft1000_release(struct inode *inode, struct file *file); /* List to free receive command buffer pool */ @@ -55,8 +58,8 @@ spinlock_t free_buff_lock; int numofmsgbuf = 0; /* -* Table of entry-point routines for char device -*/ + * Table of entry-point routines for char device + */ static const struct file_operations ft1000fops = { .unlocked_ioctl = ft1000_ioctl, .poll = ft1000_poll_dev, @@ -66,104 +69,104 @@ static const struct file_operations ft1000fops = { }; /* ---------------------------------------------------------------------------- -* Function: ft1000_get_buffer -* -* Parameters: -* -* Returns: -* -* Description: -* -* Notes: -* -*--------------------------------------------------------------------------- -*/ + --------------------------------------------------------------------------- + * Function: ft1000_get_buffer + * + * Parameters: + * + * Returns: + * + * Description: + * + * Notes: + * + *--------------------------------------------------------------------------- + */ struct dpram_blk *ft1000_get_buffer(struct list_head *bufflist) { - unsigned long flags; + unsigned long flags; struct dpram_blk *ptr; - spin_lock_irqsave(&free_buff_lock, flags); - /* Check if buffer is available */ - if (list_empty(bufflist)) { - DEBUG("ft1000_get_buffer: No more buffer - %d\n", numofmsgbuf); - ptr = NULL; - } else { - numofmsgbuf--; - ptr = list_entry(bufflist->next, struct dpram_blk, list); - list_del(&ptr->list); - /* DEBUG("ft1000_get_buffer: number of free msg buffers = %d\n", numofmsgbuf); */ - } - spin_unlock_irqrestore(&free_buff_lock, flags); - - return ptr; + spin_lock_irqsave(&free_buff_lock, flags); + /* Check if buffer is available */ + if (list_empty(bufflist)) { + pr_debug("No more buffer - %d\n", numofmsgbuf); + ptr = NULL; + } else { + numofmsgbuf--; + ptr = list_entry(bufflist->next, struct dpram_blk, list); + list_del(&ptr->list); + /* pr_debug("number of free msg buffers = %d\n", numofmsgbuf); */ + } + spin_unlock_irqrestore(&free_buff_lock, flags); + + return ptr; } /* -*--------------------------------------------------------------------------- -* Function: ft1000_free_buffer -* -* Parameters: -* -* Returns: -* -* Description: -* -* Notes: -* -*--------------------------------------------------------------------------- -*/ + *--------------------------------------------------------------------------- + * Function: ft1000_free_buffer + * + * Parameters: + * + * Returns: + * + * Description: + * + * Notes: + * + *--------------------------------------------------------------------------- + */ void ft1000_free_buffer(struct dpram_blk *pdpram_blk, struct list_head *plist) { - unsigned long flags; - - spin_lock_irqsave(&free_buff_lock, flags); - /* Put memory back to list */ - list_add_tail(&pdpram_blk->list, plist); - numofmsgbuf++; - /*DEBUG("ft1000_free_buffer: number of free msg buffers = %d\n", numofmsgbuf); */ - spin_unlock_irqrestore(&free_buff_lock, flags); + unsigned long flags; + + spin_lock_irqsave(&free_buff_lock, flags); + /* Put memory back to list */ + list_add_tail(&pdpram_blk->list, plist); + numofmsgbuf++; + /*pr_debug("number of free msg buffers = %d\n", numofmsgbuf); */ + spin_unlock_irqrestore(&free_buff_lock, flags); } /* -*--------------------------------------------------------------------------- -* Function: ft1000_CreateDevice -* -* Parameters: dev - pointer to adapter object -* -* Returns: 0 if successful -* -* Description: Creates a private char device. -* -* Notes: Only called by init_module(). -* -*--------------------------------------------------------------------------- -*/ + *--------------------------------------------------------------------------- + * Function: ft1000_CreateDevice + * + * Parameters: dev - pointer to adapter object + * + * Returns: 0 if successful + * + * Description: Creates a private char device. + * + * Notes: Only called by init_module(). + * + *--------------------------------------------------------------------------- + */ int ft1000_create_dev(struct ft1000_usb *dev) { - int result; - int i; + int result; + int i; struct dentry *dir, *file; struct ft1000_debug_dirs *tmp; - /* make a new device name */ - sprintf(dev->DeviceName, "%s%d", "FT1000_", dev->CardNumber); + /* make a new device name */ + sprintf(dev->DeviceName, "%s%d", "FT1000_", dev->CardNumber); - DEBUG("%s: number of instance = %d\n", __func__, ft1000_flarion_cnt); - DEBUG("DeviceCreated = %x\n", dev->DeviceCreated); + pr_debug("number of instance = %d\n", ft1000_flarion_cnt); + pr_debug("DeviceCreated = %x\n", dev->DeviceCreated); - if (dev->DeviceCreated) { - DEBUG("%s: \"%s\" already registered\n", __func__, dev->DeviceName); - return -EIO; - } + if (dev->DeviceCreated) { + pr_debug("\"%s\" already registered\n", dev->DeviceName); + return -EIO; + } - /* register the device */ - DEBUG("%s: \"%s\" debugfs device registration\n", __func__, dev->DeviceName); + /* register the device */ + pr_debug("\"%s\" debugfs device registration\n", dev->DeviceName); tmp = kmalloc(sizeof(struct ft1000_debug_dirs), GFP_KERNEL); if (tmp == NULL) { @@ -178,7 +181,7 @@ int ft1000_create_dev(struct ft1000_usb *dev) } file = debugfs_create_file("device", S_IRUGO | S_IWUSR, dir, - dev, &ft1000fops); + dev, &ft1000fops); if (IS_ERR(file)) { result = PTR_ERR(file); goto debug_file_fail; @@ -189,25 +192,25 @@ int ft1000_create_dev(struct ft1000_usb *dev) tmp->int_number = dev->CardNumber; list_add(&(tmp->list), &(dev->nodes.list)); - DEBUG("%s: registered debugfs directory \"%s\"\n", __func__, dev->DeviceName); - - /* initialize application information */ - dev->appcnt = 0; - for (i=0; i<MAX_NUM_APP; i++) { - dev->app_info[i].nTxMsg = 0; - dev->app_info[i].nRxMsg = 0; - dev->app_info[i].nTxMsgReject = 0; - dev->app_info[i].nRxMsgMiss = 0; - dev->app_info[i].fileobject = NULL; - dev->app_info[i].app_id = i+1; - dev->app_info[i].DspBCMsgFlag = 0; - dev->app_info[i].NumOfMsg = 0; - init_waitqueue_head(&dev->app_info[i].wait_dpram_msg); - INIT_LIST_HEAD(&dev->app_info[i].app_sqlist); - } - - dev->DeviceCreated = TRUE; - ft1000_flarion_cnt++; + pr_debug("registered debugfs directory \"%s\"\n", dev->DeviceName); + + /* initialize application information */ + dev->appcnt = 0; + for (i = 0; i < MAX_NUM_APP; i++) { + dev->app_info[i].nTxMsg = 0; + dev->app_info[i].nRxMsg = 0; + dev->app_info[i].nTxMsgReject = 0; + dev->app_info[i].nRxMsgMiss = 0; + dev->app_info[i].fileobject = NULL; + dev->app_info[i].app_id = i+1; + dev->app_info[i].DspBCMsgFlag = 0; + dev->app_info[i].NumOfMsg = 0; + init_waitqueue_head(&dev->app_info[i].wait_dpram_msg); + INIT_LIST_HEAD(&dev->app_info[i].app_sqlist); + } + + dev->DeviceCreated = TRUE; + ft1000_flarion_cnt++; return 0; @@ -220,33 +223,29 @@ fail: } /* -*--------------------------------------------------------------------------- -* Function: ft1000_DestroyDeviceDEBUG -* -* Parameters: dev - pointer to adapter object -* -* Description: Destroys a private char device. -* -* Notes: Only called by cleanup_module(). -* -*--------------------------------------------------------------------------- -*/ + *--------------------------------------------------------------------------- + * Function: ft1000_DestroyDeviceDEBUG + * + * Parameters: dev - pointer to adapter object + * + * Description: Destroys a private char device. + * + * Notes: Only called by cleanup_module(). + * + *--------------------------------------------------------------------------- + */ void ft1000_destroy_dev(struct net_device *netdev) { struct ft1000_info *info = netdev_priv(netdev); struct ft1000_usb *dev = info->priv; - int i; + int i; struct dpram_blk *pdpram_blk; struct dpram_blk *ptr; struct list_head *pos, *q; struct ft1000_debug_dirs *dir; - DEBUG("%s called\n", __func__); - - - - if (dev->DeviceCreated) { - ft1000_flarion_cnt--; + if (dev->DeviceCreated) { + ft1000_flarion_cnt--; list_for_each_safe(pos, q, &dev->nodes.list) { dir = list_entry(pos, struct ft1000_debug_dirs, list); if (dir->int_number == dev->CardNumber) { @@ -256,29 +255,28 @@ void ft1000_destroy_dev(struct net_device *netdev) kfree(dir); } } - DEBUG("%s: unregistered device \"%s\"\n", __func__, - dev->DeviceName); - - /* Make sure we free any memory reserve for slow Queue */ - for (i=0; i<MAX_NUM_APP; i++) { - while (list_empty(&dev->app_info[i].app_sqlist) == 0) { - pdpram_blk = list_entry(dev->app_info[i].app_sqlist.next, struct dpram_blk, list); - list_del(&pdpram_blk->list); - ft1000_free_buffer(pdpram_blk, &freercvpool); - - } - wake_up_interruptible(&dev->app_info[i].wait_dpram_msg); - } - - /* Remove buffer allocated for receive command data */ - if (ft1000_flarion_cnt == 0) { - while (list_empty(&freercvpool) == 0) { - ptr = list_entry(freercvpool.next, struct dpram_blk, list); - list_del(&ptr->list); - kfree(ptr->pbuffer); - kfree(ptr); - } - } + pr_debug("unregistered device \"%s\"\n", dev->DeviceName); + + /* Make sure we free any memory reserve for slow Queue */ + for (i = 0; i < MAX_NUM_APP; i++) { + while (list_empty(&dev->app_info[i].app_sqlist) == 0) { + pdpram_blk = list_entry(dev->app_info[i].app_sqlist.next, struct dpram_blk, list); + list_del(&pdpram_blk->list); + ft1000_free_buffer(pdpram_blk, &freercvpool); + + } + wake_up_interruptible(&dev->app_info[i].wait_dpram_msg); + } + + /* Remove buffer allocated for receive command data */ + if (ft1000_flarion_cnt == 0) { + while (list_empty(&freercvpool) == 0) { + ptr = list_entry(freercvpool.next, struct dpram_blk, list); + list_del(&ptr->list); + kfree(ptr->pbuffer); + kfree(ptr); + } + } dev->DeviceCreated = FALSE; } @@ -286,507 +284,499 @@ void ft1000_destroy_dev(struct net_device *netdev) } /* -*--------------------------------------------------------------------------- -* Function: ft1000_open -* -* Parameters: -* -* Description: -* -* Notes: -* -*--------------------------------------------------------------------------- -*/ + *--------------------------------------------------------------------------- + * Function: ft1000_open + * + * Parameters: + * + * Description: + * + * Notes: + * + *--------------------------------------------------------------------------- + */ static int ft1000_open(struct inode *inode, struct file *file) { struct ft1000_info *info; struct ft1000_usb *dev = (struct ft1000_usb *)inode->i_private; - int i,num; + int i, num; - DEBUG("%s called\n", __func__); - num = (MINOR(inode->i_rdev) & 0xf); - DEBUG("ft1000_open: minor number=%d\n", num); + num = (MINOR(inode->i_rdev) & 0xf); + pr_debug("minor number=%d\n", num); info = file->private_data = netdev_priv(dev->net); - DEBUG("f_owner = %p number of application = %d\n", (&file->f_owner), dev->appcnt); - - /* Check if maximum number of application exceeded */ - if (dev->appcnt > MAX_NUM_APP) { - DEBUG("Maximum number of application exceeded\n"); - return -EACCES; - } - - /* Search for available application info block */ - for (i=0; i<MAX_NUM_APP; i++) { - if ((dev->app_info[i].fileobject == NULL)) { - break; - } - } - - /* Fail due to lack of application info block */ - if (i == MAX_NUM_APP) { - DEBUG("Could not find an application info block\n"); - return -EACCES; - } - - dev->appcnt++; - dev->app_info[i].fileobject = &file->f_owner; - dev->app_info[i].nTxMsg = 0; - dev->app_info[i].nRxMsg = 0; - dev->app_info[i].nTxMsgReject = 0; - dev->app_info[i].nRxMsgMiss = 0; + pr_debug("f_owner = %p number of application = %d\n", + &file->f_owner, dev->appcnt); + + /* Check if maximum number of application exceeded */ + if (dev->appcnt > MAX_NUM_APP) { + pr_debug("Maximum number of application exceeded\n"); + return -EACCES; + } + + /* Search for available application info block */ + for (i = 0; i < MAX_NUM_APP; i++) { + if ((dev->app_info[i].fileobject == NULL)) { + break; + } + } + + /* Fail due to lack of application info block */ + if (i == MAX_NUM_APP) { + pr_debug("Could not find an application info block\n"); + return -EACCES; + } + + dev->appcnt++; + dev->app_info[i].fileobject = &file->f_owner; + dev->app_info[i].nTxMsg = 0; + dev->app_info[i].nRxMsg = 0; + dev->app_info[i].nTxMsgReject = 0; + dev->app_info[i].nRxMsgMiss = 0; nonseekable_open(inode, file); - return 0; + return 0; } /* -*--------------------------------------------------------------------------- -* Function: ft1000_poll_dev -* -* Parameters: -* -* Description: -* -* Notes: -* -*--------------------------------------------------------------------------- -*/ + *--------------------------------------------------------------------------- + * Function: ft1000_poll_dev + * + * Parameters: + * + * Description: + * + * Notes: + * + *--------------------------------------------------------------------------- + */ static unsigned int ft1000_poll_dev(struct file *file, poll_table *wait) { - struct net_device *netdev = file->private_data; + struct net_device *netdev = file->private_data; struct ft1000_info *info = netdev_priv(netdev); struct ft1000_usb *dev = info->priv; - int i; - - /* DEBUG("ft1000_poll_dev called\n"); */ - if (ft1000_flarion_cnt == 0) { - DEBUG("FT1000:ft1000_poll_dev called when ft1000_flarion_cnt is zero\n"); - return (-EBADF); - } - - /* Search for matching file object */ - for (i=0; i<MAX_NUM_APP; i++) { - if (dev->app_info[i].fileobject == &file->f_owner) { - /* DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", dev->app_info[i].app_id); */ - break; - } - } - - /* Could not find application info block */ - if (i == MAX_NUM_APP) { - DEBUG("FT1000:ft1000_ioctl:Could not find application info block\n"); - return (-EACCES); - } - - if (list_empty(&dev->app_info[i].app_sqlist) == 0) { - DEBUG("FT1000:ft1000_poll_dev:Message detected in slow queue\n"); - return(POLLIN | POLLRDNORM | POLLPRI); - } - - poll_wait(file, &dev->app_info[i].wait_dpram_msg, wait); - /* DEBUG("FT1000:ft1000_poll_dev:Polling for data from DSP\n"); */ + int i; + + if (ft1000_flarion_cnt == 0) { + pr_debug("called with ft1000_flarion_cnt value zero\n"); + return -EBADF; + } + + /* Search for matching file object */ + for (i = 0; i < MAX_NUM_APP; i++) { + if (dev->app_info[i].fileobject == &file->f_owner) { + /* pr_debug("Message is for AppId = %d\n", dev->app_info[i].app_id); */ + break; + } + } + + /* Could not find application info block */ + if (i == MAX_NUM_APP) { + pr_debug("Could not find application info block\n"); + return -EACCES; + } + + if (list_empty(&dev->app_info[i].app_sqlist) == 0) { + pr_debug("Message detected in slow queue\n"); + return(POLLIN | POLLRDNORM | POLLPRI); + } + + poll_wait(file, &dev->app_info[i].wait_dpram_msg, wait); + /* pr_debug("Polling for data from DSP\n"); */ return 0; } /* -*--------------------------------------------------------------------------- -* Function: ft1000_ioctl -* -* Parameters: -* -* Description: -* -* Notes: -* -*--------------------------------------------------------------------------- -*/ + *--------------------------------------------------------------------------- + * Function: ft1000_ioctl + * + * Parameters: + * + * Description: + * + * Notes: + * + *--------------------------------------------------------------------------- + */ static long ft1000_ioctl(struct file *file, unsigned int command, - unsigned long argument) + unsigned long argument) { - void __user *argp = (void __user *)argument; + void __user *argp = (void __user *)argument; struct ft1000_info *info; - struct ft1000_usb *ft1000dev; - int result=0; - int cmd; - int i; - u16 tempword; - unsigned long flags; - struct timeval tv; + struct ft1000_usb *ft1000dev; + int result = 0; + int cmd; + int i; + u16 tempword; + unsigned long flags; + struct timeval tv; struct IOCTL_GET_VER get_ver_data; struct IOCTL_GET_DSP_STAT get_stat_data; - u8 ConnectionMsg[] = {0x00,0x44,0x10,0x20,0x80,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x93,0x64, - 0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0a, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x02,0x37,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x01,0x00,0x01,0x7f,0x00, - 0x00,0x01,0x00,0x00}; + u8 ConnectionMsg[] = {0x00, 0x44, 0x10, 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x93, 0x64, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x37, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x7f, 0x00, + 0x00, 0x01, 0x00, 0x00}; + + unsigned short ledStat = 0; + unsigned short conStat = 0; + + if (ft1000_flarion_cnt == 0) { + pr_debug("called with ft1000_flarion_cnt of zero\n"); + return -EBADF; + } - unsigned short ledStat=0; - unsigned short conStat=0; + /* pr_debug("command = 0x%x argument = 0x%8x\n", command, (u32)argument); */ - /* DEBUG("ft1000_ioctl called\n"); */ + info = file->private_data; + ft1000dev = info->priv; + cmd = _IOC_NR(command); + /* pr_debug("cmd = 0x%x\n", cmd); */ + + /* process the command */ + switch (cmd) { + case IOCTL_REGISTER_CMD: + pr_debug("IOCTL_FT1000_REGISTER called\n"); + result = get_user(tempword, (__u16 __user *)argp); + if (result) { + pr_debug("result = %d failed to get_user\n", result); + break; + } + if (tempword == DSPBCMSGID) { + /* Search for matching file object */ + for (i = 0; i < MAX_NUM_APP; i++) { + if (ft1000dev->app_info[i].fileobject == &file->f_owner) { + ft1000dev->app_info[i].DspBCMsgFlag = 1; + pr_debug("Registered for broadcast messages\n"); + break; + } + } + } + break; - if (ft1000_flarion_cnt == 0) { - DEBUG("FT1000:ft1000_ioctl called when ft1000_flarion_cnt is zero\n"); - return (-EBADF); - } + case IOCTL_GET_VER_CMD: + pr_debug("IOCTL_FT1000_GET_VER called\n"); - /* DEBUG("FT1000:ft1000_ioctl:command = 0x%x argument = 0x%8x\n", command, (u32)argument); */ + get_ver_data.drv_ver = FT1000_DRV_VER; - info = file->private_data; - ft1000dev = info->priv; - cmd = _IOC_NR(command); - /* DEBUG("FT1000:ft1000_ioctl:cmd = 0x%x\n", cmd); */ - - /* process the command */ - switch (cmd) { - case IOCTL_REGISTER_CMD: - DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_REGISTER called\n"); - result = get_user(tempword, (__u16 __user*)argp); - if (result) { - DEBUG("result = %d failed to get_user\n", result); - break; - } - if (tempword == DSPBCMSGID) { - /* Search for matching file object */ - for (i=0; i<MAX_NUM_APP; i++) { - if (ft1000dev->app_info[i].fileobject == &file->f_owner) { - ft1000dev->app_info[i].DspBCMsgFlag = 1; - DEBUG("FT1000:ft1000_ioctl:Registered for broadcast messages\n"); - break; - } - } - } - break; - - case IOCTL_GET_VER_CMD: - DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_VER called\n"); - - get_ver_data.drv_ver = FT1000_DRV_VER; - - if (copy_to_user(argp, &get_ver_data, sizeof(get_ver_data))) { - DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n"); - result = -EFAULT; - break; - } - - DEBUG("FT1000:ft1000_ioctl:driver version = 0x%x\n",(unsigned int)get_ver_data.drv_ver); - - break; - case IOCTL_CONNECT: - /* Connect Message */ - DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_CONNECT\n"); - ConnectionMsg[79] = 0xfc; - result = card_send_command(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c); - - break; - case IOCTL_DISCONNECT: - /* Disconnect Message */ - DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_DISCONNECT\n"); - ConnectionMsg[79] = 0xfd; - result = card_send_command(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c); - break; - case IOCTL_GET_DSP_STAT_CMD: - /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DSP_STAT called\n"); */ - memset(&get_stat_data, 0, sizeof(get_stat_data)); - memcpy(get_stat_data.DspVer, info->DspVer, DSPVERSZ); - memcpy(get_stat_data.HwSerNum, info->HwSerNum, HWSERNUMSZ); - memcpy(get_stat_data.Sku, info->Sku, SKUSZ); - memcpy(get_stat_data.eui64, info->eui64, EUISZ); - - if (info->ProgConStat != 0xFF) { - ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_LED, (u8 *)&ledStat, FT1000_MAG_DSP_LED_INDX); - get_stat_data.LedStat = ntohs(ledStat); - DEBUG("FT1000:ft1000_ioctl: LedStat = 0x%x\n", get_stat_data.LedStat); - ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_CON_STATE, (u8 *)&conStat, FT1000_MAG_DSP_CON_STATE_INDX); - get_stat_data.ConStat = ntohs(conStat); - DEBUG("FT1000:ft1000_ioctl: ConStat = 0x%x\n", get_stat_data.ConStat); - } else { - get_stat_data.ConStat = 0x0f; - } - - - get_stat_data.nTxPkts = info->stats.tx_packets; - get_stat_data.nRxPkts = info->stats.rx_packets; - get_stat_data.nTxBytes = info->stats.tx_bytes; - get_stat_data.nRxBytes = info->stats.rx_bytes; - do_gettimeofday(&tv); - get_stat_data.ConTm = (u32)(tv.tv_sec - info->ConTm); - DEBUG("Connection Time = %d\n", (int)get_stat_data.ConTm); - if (copy_to_user(argp, &get_stat_data, sizeof(get_stat_data))) { - DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n"); - result = -EFAULT; - break; - } - DEBUG("ft1000_chioctl: GET_DSP_STAT succeed\n"); - break; - case IOCTL_SET_DPRAM_CMD: - { + if (copy_to_user(argp, &get_ver_data, sizeof(get_ver_data))) { + pr_debug("copy fault occurred\n"); + result = -EFAULT; + break; + } + + pr_debug("driver version = 0x%x\n", + (unsigned int)get_ver_data.drv_ver); + + break; + case IOCTL_CONNECT: + /* Connect Message */ + pr_debug("IOCTL_FT1000_CONNECT\n"); + ConnectionMsg[79] = 0xfc; + result = card_send_command(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c); + + break; + case IOCTL_DISCONNECT: + /* Disconnect Message */ + pr_debug("IOCTL_FT1000_DISCONNECT\n"); + ConnectionMsg[79] = 0xfd; + result = card_send_command(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c); + break; + case IOCTL_GET_DSP_STAT_CMD: + /* pr_debug("IOCTL_FT1000_GET_DSP_STAT\n"); */ + memset(&get_stat_data, 0, sizeof(get_stat_data)); + memcpy(get_stat_data.DspVer, info->DspVer, DSPVERSZ); + memcpy(get_stat_data.HwSerNum, info->HwSerNum, HWSERNUMSZ); + memcpy(get_stat_data.Sku, info->Sku, SKUSZ); + memcpy(get_stat_data.eui64, info->eui64, EUISZ); + + if (info->ProgConStat != 0xFF) { + ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_LED, (u8 *)&ledStat, FT1000_MAG_DSP_LED_INDX); + get_stat_data.LedStat = ntohs(ledStat); + pr_debug("LedStat = 0x%x\n", get_stat_data.LedStat); + ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_CON_STATE, (u8 *)&conStat, FT1000_MAG_DSP_CON_STATE_INDX); + get_stat_data.ConStat = ntohs(conStat); + pr_debug("ConStat = 0x%x\n", get_stat_data.ConStat); + } else { + get_stat_data.ConStat = 0x0f; + } + + + get_stat_data.nTxPkts = info->stats.tx_packets; + get_stat_data.nRxPkts = info->stats.rx_packets; + get_stat_data.nTxBytes = info->stats.tx_bytes; + get_stat_data.nRxBytes = info->stats.rx_bytes; + do_gettimeofday(&tv); + get_stat_data.ConTm = (u32)(tv.tv_sec - info->ConTm); + pr_debug("Connection Time = %d\n", (int)get_stat_data.ConTm); + if (copy_to_user(argp, &get_stat_data, sizeof(get_stat_data))) { + pr_debug("copy fault occurred\n"); + result = -EFAULT; + break; + } + pr_debug("GET_DSP_STAT succeed\n"); + break; + case IOCTL_SET_DPRAM_CMD: + { struct IOCTL_DPRAM_BLK *dpram_data = NULL; /* struct IOCTL_DPRAM_COMMAND dpram_command; */ - u16 qtype; - u16 msgsz; + u16 qtype; + u16 msgsz; struct pseudo_hdr *ppseudo_hdr; - u16 *pmsg; - u16 total_len; - u16 app_index; - u16 status; + u16 *pmsg; + u16 total_len; + u16 app_index; + u16 status; - /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_SET_DPRAM called\n");*/ + /* pr_debug("IOCTL_FT1000_SET_DPRAM called\n");*/ - if (ft1000_flarion_cnt == 0) { - return (-EBADF); - } + if (ft1000_flarion_cnt == 0) + return -EBADF; - if (ft1000dev->DrvMsgPend) { - return (-ENOTTY); - } + if (ft1000dev->DrvMsgPend) + return -ENOTTY; - if (ft1000dev->fProvComplete == 0) { - return (-EACCES); - } + if (ft1000dev->fProvComplete == 0) + return -EACCES; - ft1000dev->fAppMsgPend = 1; + ft1000dev->fAppMsgPend = 1; - if (info->CardReady) { + if (info->CardReady) { - /* DEBUG("FT1000:ft1000_ioctl: try to SET_DPRAM \n"); */ + /* pr_debug("try to SET_DPRAM\n"); */ - /* Get the length field to see how many bytes to copy */ - result = get_user(msgsz, (__u16 __user *)argp); - if (result) - break; - msgsz = ntohs(msgsz); - /* DEBUG("FT1000:ft1000_ioctl: length of message = %d\n", msgsz); */ - - if (msgsz > MAX_CMD_SQSIZE) { - DEBUG("FT1000:ft1000_ioctl: bad message length = %d\n", msgsz); - result = -EINVAL; - break; - } - - result = -ENOMEM; - dpram_data = kmalloc(msgsz + 2, GFP_KERNEL); - if (!dpram_data) - break; + /* Get the length field to see how many bytes to copy */ + result = get_user(msgsz, (__u16 __user *)argp); + if (result) + break; + msgsz = ntohs(msgsz); + /* pr_debug("length of message = %d\n", msgsz); */ + + if (msgsz > MAX_CMD_SQSIZE) { + pr_debug("bad message length = %d\n", msgsz); + result = -EINVAL; + break; + } - if (copy_from_user(dpram_data, argp, msgsz+2)) { - DEBUG("FT1000:ft1000_ChIoctl: copy fault occurred\n"); - result = -EFAULT; - } else { - /* Check if this message came from a registered application */ - for (i=0; i<MAX_NUM_APP; i++) { - if (ft1000dev->app_info[i].fileobject == &file->f_owner) { - break; - } - } - if (i==MAX_NUM_APP) { - DEBUG("FT1000:No matching application fileobject\n"); - result = -EINVAL; - kfree(dpram_data); - break; - } - app_index = i; - - /* Check message qtype type which is the lower byte within qos_class */ - qtype = ntohs(dpram_data->pseudohdr.qos_class) & 0xff; - /* DEBUG("FT1000_ft1000_ioctl: qtype = %d\n", qtype); */ - if (qtype) { - } else { - /* Put message into Slow Queue */ - /* Only put a message into the DPRAM if msg doorbell is available */ - status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); - /* DEBUG("FT1000_ft1000_ioctl: READ REGISTER tempword=%x\n", tempword); */ - if (tempword & FT1000_DB_DPRAM_TX) { - /* Suspend for 2ms and try again due to DSP doorbell busy */ - mdelay(2); - status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) { - /* Suspend for 1ms and try again due to DSP doorbell busy */ - mdelay(1); - status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) { - status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) { - /* Suspend for 3ms and try again due to DSP doorbell busy */ - mdelay(3); - status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) { - DEBUG("FT1000:ft1000_ioctl:Doorbell not available\n"); - result = -ENOTTY; - kfree(dpram_data); - break; - } - } - } - } - } - - /*DEBUG("FT1000_ft1000_ioctl: finished reading register\n"); */ - - /* Make sure we are within the limits of the slow queue memory limitation */ - if ((msgsz < MAX_CMD_SQSIZE) && (msgsz > PSEUDOSZ)) { - /* Need to put sequence number plus new checksum for message */ - pmsg = (u16 *)&dpram_data->pseudohdr; - ppseudo_hdr = (struct pseudo_hdr *)pmsg; - total_len = msgsz+2; - if (total_len & 0x1) { - total_len++; - } - - /* Insert slow queue sequence number */ - ppseudo_hdr->seq_num = info->squeseqnum++; - ppseudo_hdr->portsrc = ft1000dev->app_info[app_index].app_id; - /* Calculate new checksum */ - ppseudo_hdr->checksum = *pmsg++; - /* DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum); */ - for (i=1; i<7; i++) { - ppseudo_hdr->checksum ^= *pmsg++; - /* DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum); */ - } - pmsg++; - ppseudo_hdr = (struct pseudo_hdr *)pmsg; - result = card_send_command(ft1000dev,(unsigned short*)dpram_data,total_len+2); - - - ft1000dev->app_info[app_index].nTxMsg++; - } else { - result = -EINVAL; - } - } - } - } else { - DEBUG("FT1000:ft1000_ioctl: Card not ready take messages\n"); - result = -EACCES; - } - kfree(dpram_data); - - } - break; - case IOCTL_GET_DPRAM_CMD: - { + result = -ENOMEM; + dpram_data = kmalloc(msgsz + 2, GFP_KERNEL); + if (!dpram_data) + break; + + if (copy_from_user(dpram_data, argp, msgsz+2)) { + pr_debug("copy fault occurred\n"); + result = -EFAULT; + } else { + /* Check if this message came from a registered application */ + for (i = 0; i < MAX_NUM_APP; i++) { + if (ft1000dev->app_info[i].fileobject == &file->f_owner) { + break; + } + } + if (i == MAX_NUM_APP) { + pr_debug("No matching application fileobject\n"); + result = -EINVAL; + kfree(dpram_data); + break; + } + app_index = i; + + /* Check message qtype type which is the lower byte within qos_class */ + qtype = ntohs(dpram_data->pseudohdr.qos_class) & 0xff; + /* pr_debug("qtype = %d\n", qtype); */ + if (qtype) { + } else { + /* Put message into Slow Queue */ + /* Only put a message into the DPRAM if msg doorbell is available */ + status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); + /* pr_debug("READ REGISTER tempword=%x\n", tempword); */ + if (tempword & FT1000_DB_DPRAM_TX) { + /* Suspend for 2ms and try again due to DSP doorbell busy */ + mdelay(2); + status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) { + /* Suspend for 1ms and try again due to DSP doorbell busy */ + mdelay(1); + status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) { + status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) { + /* Suspend for 3ms and try again due to DSP doorbell busy */ + mdelay(3); + status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) { + pr_debug("Doorbell not available\n"); + result = -ENOTTY; + kfree(dpram_data); + break; + } + } + } + } + } + + /*pr_debug("finished reading register\n"); */ + + /* Make sure we are within the limits of the slow queue memory limitation */ + if ((msgsz < MAX_CMD_SQSIZE) && (msgsz > PSEUDOSZ)) { + /* Need to put sequence number plus new checksum for message */ + pmsg = (u16 *)&dpram_data->pseudohdr; + ppseudo_hdr = (struct pseudo_hdr *)pmsg; + total_len = msgsz+2; + if (total_len & 0x1) { + total_len++; + } + + /* Insert slow queue sequence number */ + ppseudo_hdr->seq_num = info->squeseqnum++; + ppseudo_hdr->portsrc = ft1000dev->app_info[app_index].app_id; + /* Calculate new checksum */ + ppseudo_hdr->checksum = *pmsg++; + /* pr_debug("checksum = 0x%x\n", ppseudo_hdr->checksum); */ + for (i = 1; i < 7; i++) { + ppseudo_hdr->checksum ^= *pmsg++; + /* pr_debug("checksum = 0x%x\n", ppseudo_hdr->checksum); */ + } + pmsg++; + ppseudo_hdr = (struct pseudo_hdr *)pmsg; + result = card_send_command(ft1000dev, (unsigned short *)dpram_data, total_len+2); + + + ft1000dev->app_info[app_index].nTxMsg++; + } else { + result = -EINVAL; + } + } + } + } else { + pr_debug("Card not ready take messages\n"); + result = -EACCES; + } + kfree(dpram_data); + + } + break; + case IOCTL_GET_DPRAM_CMD: + { struct dpram_blk *pdpram_blk; struct IOCTL_DPRAM_BLK __user *pioctl_dpram; - int msglen; - - /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DPRAM called\n"); */ - - if (ft1000_flarion_cnt == 0) { - return (-EBADF); - } - - /* Search for matching file object */ - for (i=0; i<MAX_NUM_APP; i++) { - if (ft1000dev->app_info[i].fileobject == &file->f_owner) { - /*DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", ft1000dev->app_info[i].app_id); */ - break; - } - } - - /* Could not find application info block */ - if (i == MAX_NUM_APP) { - DEBUG("FT1000:ft1000_ioctl:Could not find application info block\n"); - result = -EBADF; - break; - } - - result = 0; - pioctl_dpram = argp; - if (list_empty(&ft1000dev->app_info[i].app_sqlist) == 0) { - /* DEBUG("FT1000:ft1000_ioctl:Message detected in slow queue\n"); */ - spin_lock_irqsave(&free_buff_lock, flags); - pdpram_blk = list_entry(ft1000dev->app_info[i].app_sqlist.next, struct dpram_blk, list); - list_del(&pdpram_blk->list); - ft1000dev->app_info[i].NumOfMsg--; - /* DEBUG("FT1000:ft1000_ioctl:NumOfMsg for app %d = %d\n", i, ft1000dev->app_info[i].NumOfMsg); */ - spin_unlock_irqrestore(&free_buff_lock, flags); - msglen = ntohs(*(u16 *)pdpram_blk->pbuffer) + PSEUDOSZ; - result = get_user(msglen, &pioctl_dpram->total_len); - if (result) - break; - msglen = htons(msglen); - /* DEBUG("FT1000:ft1000_ioctl:msg length = %x\n", msglen); */ - if (copy_to_user (&pioctl_dpram->pseudohdr, pdpram_blk->pbuffer, msglen)) { - DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n"); - result = -EFAULT; + int msglen; + + /* pr_debug("IOCTL_FT1000_GET_DPRAM called\n"); */ + + if (ft1000_flarion_cnt == 0) + return -EBADF; + + /* Search for matching file object */ + for (i = 0; i < MAX_NUM_APP; i++) { + if (ft1000dev->app_info[i].fileobject == &file->f_owner) { + /*pr_debug("Message is for AppId = %d\n", ft1000dev->app_info[i].app_id); */ + break; + } + } + + /* Could not find application info block */ + if (i == MAX_NUM_APP) { + pr_debug("Could not find application info block\n"); + result = -EBADF; break; - } + } + + result = 0; + pioctl_dpram = argp; + if (list_empty(&ft1000dev->app_info[i].app_sqlist) == 0) { + /* pr_debug("Message detected in slow queue\n"); */ + spin_lock_irqsave(&free_buff_lock, flags); + pdpram_blk = list_entry(ft1000dev->app_info[i].app_sqlist.next, struct dpram_blk, list); + list_del(&pdpram_blk->list); + ft1000dev->app_info[i].NumOfMsg--; + /* pr_debug("NumOfMsg for app %d = %d\n", i, ft1000dev->app_info[i].NumOfMsg); */ + spin_unlock_irqrestore(&free_buff_lock, flags); + msglen = ntohs(*(u16 *)pdpram_blk->pbuffer) + PSEUDOSZ; + result = get_user(msglen, &pioctl_dpram->total_len); + if (result) + break; + msglen = htons(msglen); + /* pr_debug("msg length = %x\n", msglen); */ + if (copy_to_user(&pioctl_dpram->pseudohdr, pdpram_blk->pbuffer, msglen)) { + pr_debug("copy fault occurred\n"); + result = -EFAULT; + break; + } + + ft1000_free_buffer(pdpram_blk, &freercvpool); + result = msglen; + } + /* pr_debug("IOCTL_FT1000_GET_DPRAM no message\n"); */ + } + break; - ft1000_free_buffer(pdpram_blk, &freercvpool); - result = msglen; - } - /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DPRAM no message\n"); */ - } - break; - - default: - DEBUG("FT1000:ft1000_ioctl:unknown command: 0x%x\n", command); - result = -ENOTTY; - break; - } - ft1000dev->fAppMsgPend = 0; - return result; + default: + pr_debug("unknown command: 0x%x\n", command); + result = -ENOTTY; + break; + } + ft1000dev->fAppMsgPend = 0; + return result; } /* -*--------------------------------------------------------------------------- -* Function: ft1000_release -* -* Parameters: -* -* Description: -* -* Notes: -* -*--------------------------------------------------------------------------- -*/ + *--------------------------------------------------------------------------- + * Function: ft1000_release + * + * Parameters: + * + * Description: + * + * Notes: + * + *--------------------------------------------------------------------------- + */ static int ft1000_release(struct inode *inode, struct file *file) { struct ft1000_info *info; - struct net_device *dev; - struct ft1000_usb *ft1000dev; - int i; + struct net_device *dev; + struct ft1000_usb *ft1000dev; + int i; struct dpram_blk *pdpram_blk; - DEBUG("ft1000_release called\n"); - - dev = file->private_data; + dev = file->private_data; info = netdev_priv(dev); ft1000dev = info->priv; - if (ft1000_flarion_cnt == 0) { - ft1000dev->appcnt--; - return (-EBADF); - } - - /* Search for matching file object */ - for (i=0; i<MAX_NUM_APP; i++) { - if (ft1000dev->app_info[i].fileobject == &file->f_owner) { - /* DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", ft1000dev->app_info[i].app_id); */ - break; - } - } - - if (i==MAX_NUM_APP) - return 0; - - while (list_empty(&ft1000dev->app_info[i].app_sqlist) == 0) { - DEBUG("Remove and free memory queue up on slow queue\n"); - pdpram_blk = list_entry(ft1000dev->app_info[i].app_sqlist.next, struct dpram_blk, list); - list_del(&pdpram_blk->list); - ft1000_free_buffer(pdpram_blk, &freercvpool); - } - - /* initialize application information */ - ft1000dev->appcnt--; - DEBUG("ft1000_chdev:%s:appcnt = %d\n", __func__, ft1000dev->appcnt); - ft1000dev->app_info[i].fileobject = NULL; - - return 0; + if (ft1000_flarion_cnt == 0) { + ft1000dev->appcnt--; + return -EBADF; + } + + /* Search for matching file object */ + for (i = 0; i < MAX_NUM_APP; i++) { + if (ft1000dev->app_info[i].fileobject == &file->f_owner) { + /* pr_debug("Message is for AppId = %d\n", ft1000dev->app_info[i].app_id); */ + break; + } + } + + if (i == MAX_NUM_APP) + return 0; + + while (list_empty(&ft1000dev->app_info[i].app_sqlist) == 0) { + pr_debug("Remove and free memory queue up on slow queue\n"); + pdpram_blk = list_entry(ft1000dev->app_info[i].app_sqlist.next, struct dpram_blk, list); + list_del(&pdpram_blk->list); + ft1000_free_buffer(pdpram_blk, &freercvpool); + } + + /* initialize application information */ + ft1000dev->appcnt--; + pr_debug("appcnt = %d\n", ft1000dev->appcnt); + ft1000dev->app_info[i].fileobject = NULL; + + return 0; } diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 37707da09e9c..e8126325877b 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -1,8 +1,10 @@ /* -* CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved. -* -* This file is part of Express Card USB Driver -*/ + * CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved. + * + * This file is part of Express Card USB Driver + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/kernel.h> #include <linux/module.h> @@ -117,17 +119,16 @@ static int check_usb_db(struct ft1000_usb *ft1000dev) while (loopcnt < 10) { status = ft1000_read_register(ft1000dev, &temp, - FT1000_REG_DOORBELL); - DEBUG("check_usb_db: read FT1000_REG_DOORBELL value is %x\n", - temp); + FT1000_REG_DOORBELL); + pr_debug("read FT1000_REG_DOORBELL value is %x\n", temp); if (temp & 0x0080) { - DEBUG("FT1000:Got checkusb doorbell\n"); + pr_debug("Got checkusb doorbell\n"); status = ft1000_write_register(ft1000dev, 0x0080, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); status = ft1000_write_register(ft1000dev, 0x0100, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); status = ft1000_write_register(ft1000dev, 0x8000, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); break; } loopcnt++; @@ -138,13 +139,13 @@ static int check_usb_db(struct ft1000_usb *ft1000dev) loopcnt = 0; while (loopcnt < 20) { status = ft1000_read_register(ft1000dev, &temp, - FT1000_REG_DOORBELL); - DEBUG("FT1000:check_usb_db:Doorbell = 0x%x\n", temp); + FT1000_REG_DOORBELL); + pr_debug("Doorbell = 0x%x\n", temp); if (temp & 0x8000) { loopcnt++; msleep(10); } else { - DEBUG("check_usb_db: door bell is cleared, return 0\n"); + pr_debug("door bell is cleared, return 0\n"); return 0; } } @@ -164,23 +165,22 @@ static u16 get_handshake(struct ft1000_usb *ft1000dev, u16 expected_value) while (loopcnt < 100) { /* Need to clear downloader doorbell if Hartley ASIC */ status = ft1000_write_register(ft1000dev, FT1000_DB_DNLD_RX, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); if (ft1000dev->fcodeldr) { - DEBUG(" get_handshake: fcodeldr is %d\n", - ft1000dev->fcodeldr); + pr_debug("fcodeldr is %d\n", ft1000dev->fcodeldr); ft1000dev->fcodeldr = 0; status = check_usb_db(ft1000dev); if (status != 0) { - DEBUG("get_handshake: check_usb_db failed\n"); + pr_debug("check_usb_db failed\n"); break; } status = ft1000_write_register(ft1000dev, - FT1000_DB_DNLD_RX, - FT1000_REG_DOORBELL); + FT1000_DB_DNLD_RX, + FT1000_REG_DOORBELL); } status = ft1000_read_dpram16(ft1000dev, - DWNLD_MAG1_HANDSHAKE_LOC, (u8 *)&handshake, 1); + DWNLD_MAG1_HANDSHAKE_LOC, (u8 *)&handshake, 1); handshake = ntohs(handshake); if (status) @@ -209,12 +209,12 @@ static void put_handshake(struct ft1000_usb *ft1000dev, u16 handshake_value) tempword = (u16)(tempx & 0xffff); status = ft1000_write_dpram16(ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, - tempword, 0); + tempword, 0); tempword = (u16)(tempx >> 16); status = ft1000_write_dpram16(ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, - tempword, 1); + tempword, 1); status = ft1000_write_register(ft1000dev, FT1000_DB_DNLD_TX, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); } static u16 get_handshake_usb(struct ft1000_usb *ft1000dev, u16 expected_value) @@ -230,27 +230,27 @@ static u16 get_handshake_usb(struct ft1000_usb *ft1000dev, u16 expected_value) while (loopcnt < 100) { if (ft1000dev->usbboot == 2) { status = ft1000_read_dpram32(ft1000dev, 0, - (u8 *)&(ft1000dev->tempbuf[0]), 64); + (u8 *)&(ft1000dev->tempbuf[0]), 64); for (temp = 0; temp < 16; temp++) { - DEBUG("tempbuf %d = 0x%x\n", temp, - ft1000dev->tempbuf[temp]); + pr_debug("tempbuf %d = 0x%x\n", + temp, ft1000dev->tempbuf[temp]); } status = ft1000_read_dpram16(ft1000dev, - DWNLD_MAG1_HANDSHAKE_LOC, - (u8 *)&handshake, 1); - DEBUG("handshake from read_dpram16 = 0x%x\n", - handshake); + DWNLD_MAG1_HANDSHAKE_LOC, + (u8 *)&handshake, 1); + pr_debug("handshake from read_dpram16 = 0x%x\n", + handshake); if (ft1000dev->dspalive == ft1000dev->tempbuf[6]) { handshake = 0; } else { handshake = ft1000dev->tempbuf[1]; ft1000dev->dspalive = - ft1000dev->tempbuf[6]; + ft1000dev->tempbuf[6]; } } else { status = ft1000_read_dpram16(ft1000dev, - DWNLD_MAG1_HANDSHAKE_LOC, - (u8 *)&handshake, 1); + DWNLD_MAG1_HANDSHAKE_LOC, + (u8 *)&handshake, 1); } loopcnt++; @@ -281,12 +281,12 @@ static u16 get_request_type(struct ft1000_usb *ft1000dev) if (ft1000dev->bootmode == 1) { status = fix_ft1000_read_dpram32(ft1000dev, - DWNLD_MAG1_TYPE_LOC, (u8 *)&tempx); + DWNLD_MAG1_TYPE_LOC, (u8 *)&tempx); tempx = ntohl(tempx); } else { tempx = 0; status = ft1000_read_dpram16(ft1000dev, - DWNLD_MAG1_TYPE_LOC, (u8 *)&tempword, 1); + DWNLD_MAG1_TYPE_LOC, (u8 *)&tempword, 1); tempx |= (tempword << 16); tempx = ntohl(tempx); } @@ -304,7 +304,7 @@ static u16 get_request_type_usb(struct ft1000_usb *ft1000dev) if (ft1000dev->bootmode == 1) { status = fix_ft1000_read_dpram32(ft1000dev, - DWNLD_MAG1_TYPE_LOC, (u8 *)&tempx); + DWNLD_MAG1_TYPE_LOC, (u8 *)&tempx); tempx = ntohl(tempx); } else { if (ft1000dev->usbboot == 2) { @@ -313,8 +313,8 @@ static u16 get_request_type_usb(struct ft1000_usb *ft1000dev) } else { tempx = 0; status = ft1000_read_dpram16(ft1000dev, - DWNLD_MAG1_TYPE_LOC, - (u8 *)&tempword, 1); + DWNLD_MAG1_TYPE_LOC, + (u8 *)&tempword, 1); } tempx |= (tempword << 16); tempx = ntohl(tempx); @@ -332,14 +332,14 @@ static long get_request_value(struct ft1000_usb *ft1000dev) if (ft1000dev->bootmode == 1) { status = fix_ft1000_read_dpram32(ft1000dev, - DWNLD_MAG1_SIZE_LOC, (u8 *)&value); + DWNLD_MAG1_SIZE_LOC, (u8 *)&value); value = ntohl(value); } else { status = ft1000_read_dpram16(ft1000dev, - DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 0); + DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 0); value = tempword; status = ft1000_read_dpram16(ft1000dev, - DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 1); + DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 1); value |= (tempword << 16); value = ntohl(value); } @@ -369,7 +369,7 @@ static u16 hdr_checksum(struct pseudo_hdr *pHdr) chksum = ((((((usPtr[0] ^ usPtr[1]) ^ usPtr[2]) ^ usPtr[3]) ^ - usPtr[4]) ^ usPtr[5]) ^ usPtr[6]); + usPtr[4]) ^ usPtr[5]) ^ usPtr[6]); return chksum; } @@ -387,7 +387,7 @@ static int check_buffers(u16 *buff_w, u16 *buff_r, int len, int offset) } static int write_dpram32_and_check(struct ft1000_usb *ft1000dev, - u16 tempbuffer[], u16 dpram) + u16 tempbuffer[], u16 dpram) { int status; u16 resultbuffer[64]; @@ -395,38 +395,38 @@ static int write_dpram32_and_check(struct ft1000_usb *ft1000dev, for (i = 0; i < 10; i++) { status = ft1000_write_dpram32(ft1000dev, dpram, - (u8 *)&tempbuffer[0], 64); + (u8 *)&tempbuffer[0], 64); if (status == 0) { /* Work around for ASIC bit stuffing problem. */ if ((tempbuffer[31] & 0xfe00) == 0xfe00) { status = ft1000_write_dpram32(ft1000dev, - dpram+12, (u8 *)&tempbuffer[24], - 64); + dpram+12, (u8 *)&tempbuffer[24], + 64); } /* Let's check the data written */ status = ft1000_read_dpram32(ft1000dev, dpram, - (u8 *)&resultbuffer[0], 64); + (u8 *)&resultbuffer[0], 64); if ((tempbuffer[31] & 0xfe00) == 0xfe00) { if (check_buffers(tempbuffer, resultbuffer, 28, - 0)) { - DEBUG("FT1000:download:DPRAM write failed 1 during bootloading\n"); + 0)) { + pr_debug("DPRAM write failed 1 during bootloading\n"); usleep_range(9000, 11000); break; } status = ft1000_read_dpram32(ft1000dev, - dpram+12, - (u8 *)&resultbuffer[0], 64); + dpram+12, + (u8 *)&resultbuffer[0], 64); if (check_buffers(tempbuffer, resultbuffer, 16, - 24)) { - DEBUG("FT1000:download:DPRAM write failed 2 during bootloading\n"); + 24)) { + pr_debug("DPRAM write failed 2 during bootloading\n"); usleep_range(9000, 11000); break; } } else { if (check_buffers(tempbuffer, resultbuffer, 32, - 0)) { - DEBUG("FT1000:download:DPRAM write failed 3 during bootloading\n"); + 0)) { + pr_debug("DPRAM write failed 3 during bootloading\n"); usleep_range(9000, 11000); break; } @@ -445,7 +445,7 @@ static int write_dpram32_and_check(struct ft1000_usb *ft1000dev, * long word_length - length of the buffer to be written to DPRAM */ static int write_blk(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile, - long word_length) + long word_length) { int status = 0; u16 dpram; @@ -453,7 +453,7 @@ static int write_blk(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile, u16 tempword; u16 tempbuffer[64]; - /*DEBUG("FT1000:download:start word_length = %d\n",(int)word_length); */ + /*pr_debug("start word_length = %d\n",(int)word_length); */ dpram = (u16)DWNLD_MAG1_PS_HDR_LOC; tempword = *(*pUsFile); (*pUsFile)++; @@ -483,21 +483,22 @@ static int write_blk(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile, } } - /*DEBUG("write_blk: loopcnt is %d\n", loopcnt); */ - /*DEBUG("write_blk: bootmode = %d\n", bootmode); */ - /*DEBUG("write_blk: dpram = %x\n", dpram); */ + /*pr_debug("loopcnt is %d\n", loopcnt); */ + /*pr_debug("write_blk: bootmode = %d\n", bootmode); */ + /*pr_debug("write_blk: dpram = %x\n", dpram); */ if (ft1000dev->bootmode == 0) { if (dpram >= 0x3F4) status = ft1000_write_dpram32(ft1000dev, dpram, - (u8 *)&tempbuffer[0], 8); + (u8 *)&tempbuffer[0], 8); else status = ft1000_write_dpram32(ft1000dev, dpram, - (u8 *)&tempbuffer[0], 64); + (u8 *)&tempbuffer[0], 64); } else { status = write_dpram32_and_check(ft1000dev, tempbuffer, - dpram); + dpram); if (status != 0) { - DEBUG("FT1000:download:Write failed tempbuffer[31] = 0x%x\n", tempbuffer[31]); + pr_debug("Write failed tempbuffer[31] = 0x%x\n", + tempbuffer[31]); break; } } @@ -508,7 +509,7 @@ static int write_blk(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile, static void usb_dnld_complete(struct urb *urb) { - /* DEBUG("****** usb_dnld_complete\n"); */ + /* pr_debug("****** usb_dnld_complete\n"); */ } /* writes a block of DSP image to DPRAM @@ -548,22 +549,21 @@ static int write_blk_fifo(struct ft1000_usb *ft1000dev, u16 **pUsFile, } static int scram_start_dwnld(struct ft1000_usb *ft1000dev, u16 *hshake, - u32 *state) + u32 *state) { int status = 0; - DEBUG("FT1000:STATE_START_DWNLD\n"); if (ft1000dev->usbboot) *hshake = get_handshake_usb(ft1000dev, HANDSHAKE_DSP_BL_READY); else *hshake = get_handshake(ft1000dev, HANDSHAKE_DSP_BL_READY); if (*hshake == HANDSHAKE_DSP_BL_READY) { - DEBUG("scram_dnldr: handshake is HANDSHAKE_DSP_BL_READY, call put_handshake(HANDSHAKE_DRIVER_READY)\n"); + pr_debug("handshake is HANDSHAKE_DSP_BL_READY, call put_handshake(HANDSHAKE_DRIVER_READY)\n"); put_handshake(ft1000dev, HANDSHAKE_DRIVER_READY); } else if (*hshake == HANDSHAKE_TIMEOUT_VALUE) { status = -ETIMEDOUT; } else { - DEBUG("FT1000:download:Download error: Handshake failed\n"); + pr_debug("Download error: Handshake failed\n"); status = -ENETRESET; } *state = STATE_BOOT_DWNLD; @@ -571,22 +571,22 @@ static int scram_start_dwnld(struct ft1000_usb *ft1000dev, u16 *hshake, } static int request_code_segment(struct ft1000_usb *ft1000dev, u16 **s_file, - u8 **c_file, const u8 *endpoint, bool boot_case) + u8 **c_file, const u8 *endpoint, bool boot_case) { long word_length; int status = 0; - /*DEBUG("FT1000:REQUEST_CODE_SEGMENT\n");i*/ word_length = get_request_value(ft1000dev); - /*DEBUG("FT1000:word_length = 0x%x\n", (int)word_length); */ + /*pr_debug("word_length = 0x%x\n", (int)word_length); */ /*NdisMSleep (100); */ if (word_length > MAX_LENGTH) { - DEBUG("FT1000:download:Download error: Max length exceeded\n"); + pr_debug("Download error: Max length exceeded\n"); return -1; } if ((word_length * 2 + (long)c_file) > (long)endpoint) { /* Error, beyond boot code range.*/ - DEBUG("FT1000:download:Download error: Requested len=%d exceeds BOOT code boundary.\n", (int)word_length); + pr_debug("Download error: Requested len=%d exceeds BOOT code boundary\n", + (int)word_length); return -1; } if (word_length & 0x1) @@ -595,14 +595,14 @@ static int request_code_segment(struct ft1000_usb *ft1000dev, u16 **s_file, if (boot_case) { status = write_blk(ft1000dev, s_file, c_file, word_length); - /*DEBUG("write_blk returned %d\n", status); */ + /*pr_debug("write_blk returned %d\n", status); */ } else { status = write_blk_fifo(ft1000dev, s_file, c_file, word_length); if (ft1000dev->usbboot == 0) ft1000dev->usbboot++; if (ft1000dev->usbboot == 1) status |= ft1000_write_dpram16(ft1000dev, - DWNLD_MAG1_PS_HDR_LOC, 0, 0); + DWNLD_MAG1_PS_HDR_LOC, 0, 0); } return status; } @@ -641,8 +641,6 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, struct prov_record *pprov_record; struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); - DEBUG("Entered scram_dnldr...\n"); - ft1000dev->fcodeldr = 0; ft1000dev->usbboot = 0; ft1000dev->dspalive = 0xffff; @@ -653,7 +651,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, state = STATE_START_DWNLD; - file_hdr = (struct dsp_file_hdr *)pFileStart; + file_hdr = pFileStart; ft1000_write_register(ft1000dev, 0x800, FT1000_REG_MAG_WATERMARK); @@ -674,7 +672,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, break; case STATE_BOOT_DWNLD: - DEBUG("FT1000:STATE_BOOT_DWNLD\n"); + pr_debug("STATE_BOOT_DWNLD\n"); ft1000dev->bootmode = 1; handshake = get_handshake(ft1000dev, HANDSHAKE_REQUEST); if (handshake == HANDSHAKE_REQUEST) { @@ -684,35 +682,34 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, request = get_request_type(ft1000dev); switch (request) { case REQUEST_RUN_ADDRESS: - DEBUG("FT1000:REQUEST_RUN_ADDRESS\n"); + pr_debug("REQUEST_RUN_ADDRESS\n"); put_request_value(ft1000dev, loader_code_address); break; case REQUEST_CODE_LENGTH: - DEBUG("FT1000:REQUEST_CODE_LENGTH\n"); + pr_debug("REQUEST_CODE_LENGTH\n"); put_request_value(ft1000dev, loader_code_size); break; case REQUEST_DONE_BL: - DEBUG("FT1000:REQUEST_DONE_BL\n"); + pr_debug("REQUEST_DONE_BL\n"); /* Reposition ptrs to beginning of code section */ s_file = (u16 *) (boot_end); c_file = (u8 *) (boot_end); - /* DEBUG("FT1000:download:s_file = 0x%8x\n", (int)s_file); */ - /* DEBUG("FT1000:download:c_file = 0x%8x\n", (int)c_file); */ + /* pr_debug("download:s_file = 0x%8x\n", (int)s_file); */ + /* pr_debug("FT1000:download:c_file = 0x%8x\n", (int)c_file); */ state = STATE_CODE_DWNLD; ft1000dev->fcodeldr = 1; break; case REQUEST_CODE_SEGMENT: status = request_code_segment(ft1000dev, - &s_file, &c_file, - (const u8 *)boot_end, - true); - break; + &s_file, &c_file, + (const u8 *)boot_end, + true); + break; default: - DEBUG - ("FT1000:download:Download error: Bad request type=%d in BOOT download state.\n", - request); + pr_debug("Download error: Bad request type=%d in BOOT download state\n", + request); status = -1; break; } @@ -723,68 +720,60 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, put_handshake(ft1000dev, HANDSHAKE_RESPONSE); } else { - DEBUG - ("FT1000:download:Download error: Handshake failed\n"); + pr_debug("Download error: Handshake failed\n"); status = -1; } break; case STATE_CODE_DWNLD: - /* DEBUG("FT1000:STATE_CODE_DWNLD\n"); */ + /* pr_debug("STATE_CODE_DWNLD\n"); */ ft1000dev->bootmode = 0; if (ft1000dev->usbboot) handshake = - get_handshake_usb(ft1000dev, - HANDSHAKE_REQUEST); + get_handshake_usb(ft1000dev, + HANDSHAKE_REQUEST); else handshake = - get_handshake(ft1000dev, HANDSHAKE_REQUEST); + get_handshake(ft1000dev, HANDSHAKE_REQUEST); if (handshake == HANDSHAKE_REQUEST) { /* * Get type associated with the request. */ if (ft1000dev->usbboot) request = - get_request_type_usb(ft1000dev); + get_request_type_usb(ft1000dev); else request = get_request_type(ft1000dev); switch (request) { case REQUEST_FILE_CHECKSUM: - DEBUG - ("FT1000:download:image_chksum = 0x%8x\n", - image_chksum); + pr_debug("image_chksum = 0x%8x\n", + image_chksum); put_request_value(ft1000dev, image_chksum); break; case REQUEST_RUN_ADDRESS: - DEBUG - ("FT1000:download: REQUEST_RUN_ADDRESS\n"); + pr_debug("REQUEST_RUN_ADDRESS\n"); if (correct_version) { - DEBUG - ("FT1000:download:run_address = 0x%8x\n", - (int)run_address); + pr_debug("run_address = 0x%8x\n", + (int)run_address); put_request_value(ft1000dev, run_address); } else { - DEBUG - ("FT1000:download:Download error: Got Run address request before image offset request.\n"); + pr_debug("Download error: Got Run address request before image offset request\n"); status = -1; break; } break; case REQUEST_CODE_LENGTH: - DEBUG - ("FT1000:download:REQUEST_CODE_LENGTH\n"); + pr_debug("REQUEST_CODE_LENGTH\n"); if (correct_version) { - DEBUG - ("FT1000:download:run_size = 0x%8x\n", - (int)run_size); + pr_debug("run_size = 0x%8x\n", + (int)run_size); put_request_value(ft1000dev, run_size); } else { - DEBUG - ("FT1000:download:Download error: Got Size request before image offset request.\n"); + pr_debug("Download error: Got Size request before image offset request\n"); status = -1; break; } @@ -793,69 +782,66 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, ft1000dev->usbboot = 3; /* Reposition ptrs to beginning of provisioning section */ s_file = - (u16 *) (pFileStart + - file_hdr->commands_offset); + (u16 *) (pFileStart + + file_hdr->commands_offset); c_file = - (u8 *) (pFileStart + - file_hdr->commands_offset); + (u8 *) (pFileStart + + file_hdr->commands_offset); state = STATE_DONE_DWNLD; break; case REQUEST_CODE_SEGMENT: - /* DEBUG("FT1000:download: REQUEST_CODE_SEGMENT - CODELOADER\n"); */ + /* pr_debug("REQUEST_CODE_SEGMENT - CODELOADER\n"); */ if (!correct_version) { - DEBUG - ("FT1000:download:Download error: Got Code Segment request before image offset request.\n"); + pr_debug("Download error: Got Code Segment request before image offset request\n"); status = -1; break; } status = request_code_segment(ft1000dev, - &s_file, &c_file, - (const u8 *)code_end, - false); + &s_file, &c_file, + (const u8 *)code_end, + false); break; case REQUEST_MAILBOX_DATA: - DEBUG - ("FT1000:download: REQUEST_MAILBOX_DATA\n"); + pr_debug("REQUEST_MAILBOX_DATA\n"); /* Convert length from byte count to word count. Make sure we round up. */ word_length = - (long)(pft1000info->DSPInfoBlklen + - 1) / 2; + (long)(pft1000info->DSPInfoBlklen + + 1) / 2; put_request_value(ft1000dev, word_length); mailbox_data = - (struct drv_msg *)&(pft1000info-> - DSPInfoBlk[0]); + (struct drv_msg *)&(pft1000info-> + DSPInfoBlk[0]); /* * Position ASIC DPRAM auto-increment pointer. */ - data = (u16 *) &mailbox_data->data[0]; - dpram = (u16) DWNLD_MAG1_PS_HDR_LOC; + data = (u16 *)&mailbox_data->data[0]; + dpram = (u16)DWNLD_MAG1_PS_HDR_LOC; if (word_length & 0x1) word_length++; - word_length = (word_length / 2); + word_length = word_length / 2; for (; word_length > 0; word_length--) { /* In words */ templong = *data++; templong |= (*data++ << 16); status = - fix_ft1000_write_dpram32 - (ft1000dev, dpram++, - (u8 *) &templong); + fix_ft1000_write_dpram32 + (ft1000dev, dpram++, + (u8 *)&templong); } break; case REQUEST_VERSION_INFO: - DEBUG - ("FT1000:download:REQUEST_VERSION_INFO\n"); + pr_debug("REQUEST_VERSION_INFO\n"); word_length = - file_hdr->version_data_size; + file_hdr->version_data_size; put_request_value(ft1000dev, word_length); /* @@ -863,15 +849,15 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, */ s_file = - (u16 *) (pFileStart + - file_hdr-> - version_data_offset); + (u16 *) (pFileStart + + file_hdr-> + version_data_offset); - dpram = (u16) DWNLD_MAG1_PS_HDR_LOC; + dpram = (u16)DWNLD_MAG1_PS_HDR_LOC; if (word_length & 0x1) word_length++; - word_length = (word_length / 2); + word_length = word_length / 2; for (; word_length > 0; word_length--) { /* In words */ @@ -879,26 +865,25 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, temp = ntohs(*s_file++); templong |= (temp << 16); status = - fix_ft1000_write_dpram32 - (ft1000dev, dpram++, - (u8 *) &templong); + fix_ft1000_write_dpram32 + (ft1000dev, dpram++, + (u8 *)&templong); } break; case REQUEST_CODE_BY_VERSION: - DEBUG - ("FT1000:download:REQUEST_CODE_BY_VERSION\n"); + pr_debug("REQUEST_CODE_BY_VERSION\n"); correct_version = false; requested_version = - get_request_value(ft1000dev); + get_request_value(ft1000dev); dsp_img_info = - (struct dsp_image_info *)(pFileStart - + - sizeof - (struct - dsp_file_hdr)); + (struct dsp_image_info *)(pFileStart + + + sizeof + (struct + dsp_file_hdr)); for (image = 0; image < file_hdr->nDspImages; @@ -907,30 +892,29 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, if (dsp_img_info->version == requested_version) { correct_version = true; - DEBUG - ("FT1000:download: correct_version is TRUE\n"); + pr_debug("correct_version is TRUE\n"); s_file = - (u16 *) (pFileStart - + - dsp_img_info-> - begin_offset); + (u16 *) (pFileStart + + + dsp_img_info-> + begin_offset); c_file = - (u8 *) (pFileStart + - dsp_img_info-> - begin_offset); + (u8 *) (pFileStart + + dsp_img_info-> + begin_offset); code_end = - (u8 *) (pFileStart + - dsp_img_info-> - end_offset); + (u8 *) (pFileStart + + dsp_img_info-> + end_offset); run_address = - dsp_img_info-> - run_address; + dsp_img_info-> + run_address; run_size = - dsp_img_info-> - image_size; + dsp_img_info-> + image_size; image_chksum = - (u32) dsp_img_info-> - checksum; + (u32)dsp_img_info-> + checksum; break; } dsp_img_info++; @@ -941,18 +925,16 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, /* * Error, beyond boot code range. */ - DEBUG - ("FT1000:download:Download error: Bad Version Request = 0x%x.\n", - (int)requested_version); + pr_debug("Download error: Bad Version Request = 0x%x.\n", + (int)requested_version); status = -1; break; } break; default: - DEBUG - ("FT1000:download:Download error: Bad request type=%d in CODE download state.\n", - request); + pr_debug("Download error: Bad request type=%d in CODE download state.\n", + request); status = -1; break; } @@ -963,20 +945,19 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, put_handshake(ft1000dev, HANDSHAKE_RESPONSE); } else { - DEBUG - ("FT1000:download:Download error: Handshake failed\n"); + pr_debug("Download error: Handshake failed\n"); status = -1; } break; case STATE_DONE_DWNLD: - DEBUG("FT1000:download:Code loader is done...\n"); + pr_debug("Code loader is done...\n"); state = STATE_SECTION_PROV; break; case STATE_SECTION_PROV: - DEBUG("FT1000:download:STATE_SECTION_PROV\n"); + pr_debug("STATE_SECTION_PROV\n"); pseudo_header = (struct pseudo_hdr *)c_file; if (pseudo_header->checksum == @@ -990,9 +971,9 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, /* Get buffer for provisioning data */ pbuffer = - kmalloc((pseudo_header_len + - sizeof(struct pseudo_hdr)), - GFP_ATOMIC); + kmalloc((pseudo_header_len + + sizeof(struct pseudo_hdr)), + GFP_ATOMIC); if (pbuffer) { memcpy(pbuffer, (void *)c_file, (u32) (pseudo_header_len + @@ -1000,20 +981,20 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, pseudo_hdr))); /* link provisioning data */ pprov_record = - kmalloc(sizeof(struct prov_record), - GFP_ATOMIC); + kmalloc(sizeof(struct prov_record), + GFP_ATOMIC); if (pprov_record) { pprov_record->pprov_data = - pbuffer; + pbuffer; list_add_tail(&pprov_record-> list, &pft1000info-> prov_list); /* Move to next entry if available */ c_file = - (u8 *) ((unsigned long) - c_file + - (u32) ((pseudo_header_len + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr)); + (u8 *) ((unsigned long) + c_file + + (u32) ((pseudo_header_len + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr)); if ((unsigned long)(c_file) - (unsigned long)(pFileStart) >= @@ -1031,13 +1012,12 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, /* Checksum did not compute */ status = -1; } - DEBUG - ("ft1000:download: after STATE_SECTION_PROV, state = %d, status= %d\n", - state, status); + pr_debug("after STATE_SECTION_PROV, state = %d, status= %d\n", + state, status); break; case STATE_DONE_PROV: - DEBUG("FT1000:download:STATE_DONE_PROV\n"); + pr_debug("STATE_DONE_PROV\n"); state = STATE_DONE_FILE; break; @@ -1050,21 +1030,21 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, break; /**** - // Check if Card is present - status = Harley_Read_Register(&temp, FT1000_REG_SUP_IMASK); - if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0x0000) ) { - break; - } - - status = Harley_Read_Register(&temp, FT1000_REG_ASIC_ID); - if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0xffff) ) { - break; - } + // Check if Card is present + status = Harley_Read_Register(&temp, FT1000_REG_SUP_IMASK); + if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0x0000) ) { + break; + } + + status = Harley_Read_Register(&temp, FT1000_REG_ASIC_ID); + if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0xffff) ) { + break; + } ****/ } /* End while */ - DEBUG("Download exiting with status = 0x%8x\n", status); + pr_debug("Download exiting with status = 0x%8x\n", status); ft1000_write_register(ft1000dev, FT1000_DB_DNLD_TX, FT1000_REG_DOORBELL); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 2e13e7b7ec10..d12cfc9aa32a 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -1,8 +1,10 @@ /* CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved. -* -* -* This file is part of Express Card USB Driver -*/ + * + * + * This file is part of Express Card USB Driver + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/kernel.h> #include <linux/module.h> @@ -35,16 +37,16 @@ static u8 tempbuffer[1600]; #define MAX_RCV_LOOP 100 /* send a control message via USB interface synchronously -* Parameters: ft1000_usb - device structure -* pipe - usb control message pipe -* request - control request -* requesttype - control message request type -* value - value to be written or 0 -* index - register index -* data - data buffer to hold the read/write values -* size - data size -* timeout - control message time out value -*/ + * Parameters: ft1000_usb - device structure + * pipe - usb control message pipe + * request - control request + * requesttype - control message request type + * value - value to be written or 0 + * index - register index + * data - data buffer to hold the read/write values + * size - data size + * timeout - control message time out value + */ static int ft1000_control(struct ft1000_usb *ft1000dev, unsigned int pipe, u8 request, u8 requesttype, u16 value, u16 index, void *data, u16 size, int timeout) @@ -52,7 +54,7 @@ static int ft1000_control(struct ft1000_usb *ft1000dev, unsigned int pipe, int ret; if ((ft1000dev == NULL) || (ft1000dev->dev == NULL)) { - DEBUG("ft1000dev or ft1000dev->dev == NULL, failure\n"); + pr_debug("ft1000dev or ft1000dev->dev == NULL, failure\n"); return -ENODEV; } @@ -171,7 +173,7 @@ int ft1000_read_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer, /* write into DPRAM a number of bytes */ int ft1000_write_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u16 value, - u8 highlow) + u8 highlow) { int ret = 0; u8 request; @@ -212,7 +214,7 @@ int fix_ft1000_read_dpram32(struct ft1000_usb *ft1000dev, u16 indx, *buffer++ = buf[pos++]; *buffer++ = buf[pos++]; } else { - DEBUG("fix_ft1000_read_dpram32: DPRAM32 Read failed\n"); + pr_debug("DPRAM32 Read failed\n"); *buffer++ = 0; *buffer++ = 0; *buffer++ = 0; @@ -246,7 +248,7 @@ int fix_ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer) buf[pos2++] = *buffer++; ret = ft1000_write_dpram32(ft1000dev, pos1, buf, 16); } else { - DEBUG("fix_ft1000_write_dpram32: DPRAM32 Read failed\n"); + pr_debug("DPRAM32 Read failed\n"); return ret; } @@ -270,8 +272,7 @@ int fix_ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer) for (i = 0; i < 16; i++) { if (tempbuffer[i] != resultbuffer[i]) { ret = -1; - DEBUG("%s Failed to write\n", - __func__); + pr_debug("Failed to write\n"); } } } @@ -287,19 +288,19 @@ static void card_reset_dsp(struct ft1000_usb *ft1000dev, bool value) u16 tempword; status = ft1000_write_register(ft1000dev, HOST_INTF_BE, - FT1000_REG_SUP_CTRL); + FT1000_REG_SUP_CTRL); status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_SUP_CTRL); if (value) { - DEBUG("Reset DSP\n"); + pr_debug("Reset DSP\n"); status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_RESET); tempword |= DSP_RESET_BIT; status = ft1000_write_register(ft1000dev, tempword, FT1000_REG_RESET); } else { - DEBUG("Activate DSP\n"); + pr_debug("Activate DSP\n"); status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_RESET); tempword |= DSP_ENCRYPTED; @@ -318,18 +319,18 @@ static void card_reset_dsp(struct ft1000_usb *ft1000dev, bool value) } /* send a command to ASIC -* Parameters: ft1000_usb - device structure -* ptempbuffer - command buffer -* size - command buffer size -*/ + * Parameters: ft1000_usb - device structure + * ptempbuffer - command buffer + * size - command buffer size + */ int card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer, - int size) + int size) { int ret; unsigned short temp; unsigned char *commandbuf; - DEBUG("card_send_command: enter card_send_command... size=%d\n", size); + pr_debug("enter card_send_command... size=%d\n", size); commandbuf = kmalloc(size + 2, GFP_KERNEL); if (!commandbuf) @@ -355,7 +356,7 @@ int card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer, return ret; usleep_range(900, 1100); ret = ft1000_write_register(ft1000dev, FT1000_DB_DPRAM_TX, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); if (ret) return ret; usleep_range(900, 1100); @@ -364,7 +365,7 @@ int card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer, #if 0 if ((temp & 0x0100) == 0) - DEBUG("card_send_command: Message sent\n"); + pr_debug("Message sent\n"); #endif return ret; } @@ -390,7 +391,7 @@ int dsp_reload(struct ft1000_usb *ft1000dev) status = ft1000_write_register(ft1000dev, tempword, FT1000_REG_RESET); msleep(1000); status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_RESET); - DEBUG("Reset Register = 0x%x\n", tempword); + pr_debug("Reset Register = 0x%x\n", tempword); /* Toggle DSP reset */ card_reset_dsp(ft1000dev, 1); @@ -399,13 +400,13 @@ int dsp_reload(struct ft1000_usb *ft1000dev) msleep(1000); status = - ft1000_write_register(ft1000dev, HOST_INTF_BE, FT1000_REG_SUP_CTRL); + ft1000_write_register(ft1000dev, HOST_INTF_BE, FT1000_REG_SUP_CTRL); /* Let's check for FEFE */ status = - ft1000_read_dpram32(ft1000dev, FT1000_MAG_DPRAM_FEFE_INDX, - (u8 *) &templong, 4); - DEBUG("templong (fefe) = 0x%8x\n", templong); + ft1000_read_dpram32(ft1000dev, FT1000_MAG_DPRAM_FEFE_INDX, + (u8 *)&templong, 4); + pr_debug("templong (fefe) = 0x%8x\n", templong); /* call codeloader */ status = scram_dnldr(ft1000dev, pFileStart, FileLength); @@ -415,8 +416,6 @@ int dsp_reload(struct ft1000_usb *ft1000dev) msleep(1000); - DEBUG("dsp_reload returned\n"); - return 0; } @@ -427,8 +426,6 @@ static void ft1000_reset_asic(struct net_device *dev) struct ft1000_usb *ft1000dev = info->priv; u16 tempword; - DEBUG("ft1000_hw:ft1000_reset_asic called\n"); - /* Let's use the register provided by the Magnemite ASIC to reset the * ASIC and DSP. */ @@ -442,10 +439,10 @@ static void ft1000_reset_asic(struct net_device *dev) /* clear interrupts */ ft1000_read_register(ft1000dev, &tempword, FT1000_REG_SUP_ISR); - DEBUG("ft1000_hw: interrupt status register = 0x%x\n", tempword); + pr_debug("interrupt status register = 0x%x\n", tempword); ft1000_write_register(ft1000dev, tempword, FT1000_REG_SUP_ISR); ft1000_read_register(ft1000dev, &tempword, FT1000_REG_SUP_ISR); - DEBUG("ft1000_hw: interrupt status register = 0x%x\n", tempword); + pr_debug("interrupt status register = 0x%x\n", tempword); } static int ft1000_reset_card(struct net_device *dev) @@ -455,38 +452,36 @@ static int ft1000_reset_card(struct net_device *dev) u16 tempword; struct prov_record *ptr; - DEBUG("ft1000_hw:ft1000_reset_card called.....\n"); - ft1000dev->fCondResetPend = true; info->CardReady = 0; ft1000dev->fProvComplete = false; /* Make sure we free any memory reserve for provisioning */ while (list_empty(&info->prov_list) == 0) { - DEBUG("ft1000_reset_card:deleting provisioning record\n"); + pr_debug("deleting provisioning record\n"); ptr = - list_entry(info->prov_list.next, struct prov_record, list); + list_entry(info->prov_list.next, struct prov_record, list); list_del(&ptr->list); kfree(ptr->pprov_data); kfree(ptr); } - DEBUG("ft1000_hw:ft1000_reset_card: reset asic\n"); + pr_debug("reset asic\n"); ft1000_reset_asic(dev); - DEBUG("ft1000_hw:ft1000_reset_card: call dsp_reload\n"); + pr_debug("call dsp_reload\n"); dsp_reload(ft1000dev); - DEBUG("dsp reload successful\n"); + pr_debug("dsp reload successful\n"); mdelay(10); /* Initialize DSP heartbeat area */ ft1000_write_dpram16(ft1000dev, FT1000_MAG_HI_HO, ho_mag, FT1000_MAG_HI_HO_INDX); - ft1000_read_dpram16(ft1000dev, FT1000_MAG_HI_HO, (u8 *) &tempword, + ft1000_read_dpram16(ft1000dev, FT1000_MAG_HI_HO, (u8 *)&tempword, FT1000_MAG_HI_HO_INDX); - DEBUG("ft1000_hw:ft1000_reset_card:hi_ho value = 0x%x\n", tempword); + pr_debug("hi_ho value = 0x%x\n", tempword); info->CardReady = 1; @@ -508,8 +503,8 @@ static void ft1000_usb_transmit_complete(struct urb *urb) } /* take an ethernet packet and convert it to a Flarion -* packet prior to sending it to the ASIC Downlink FIFO. -*/ + * packet prior to sending it to the ASIC Downlink FIFO. + */ static int ft1000_copy_down_pkt(struct net_device *netdev, u8 *packet, u16 len) { struct ft1000_info *pInfo = netdev_priv(netdev); @@ -520,14 +515,13 @@ static int ft1000_copy_down_pkt(struct net_device *netdev, u8 *packet, u16 len) struct pseudo_hdr hdr; if (!pInfo->CardReady) { - DEBUG("ft1000_copy_down_pkt::Card Not Ready\n"); + pr_debug("Card Not Ready\n"); return -ENODEV; } count = sizeof(struct pseudo_hdr) + len; if (count > MAX_BUF_SIZE) { - DEBUG("Error:ft1000_copy_down_pkt:Message Size Overflow!\n"); - DEBUG("size = %d\n", count); + pr_debug("Message Size Overflow! size = %d\n", count); return -EINVAL; } @@ -545,7 +539,7 @@ static int ft1000_copy_down_pkt(struct net_device *netdev, u8 *packet, u16 len) hdr.control = 0x00; hdr.checksum = hdr.length ^ hdr.source ^ hdr.destination ^ - hdr.portdest ^ hdr.portsrc ^ hdr.sh_str_id ^ hdr.control; + hdr.portdest ^ hdr.portsrc ^ hdr.sh_str_id ^ hdr.control; memcpy(&pFt1000Dev->tx_buf[0], &hdr, sizeof(hdr)); memcpy(&(pFt1000Dev->tx_buf[sizeof(struct pseudo_hdr)]), packet, len); @@ -559,12 +553,12 @@ static int ft1000_copy_down_pkt(struct net_device *netdev, u8 *packet, u16 len) pFt1000Dev->tx_buf, count, ft1000_usb_transmit_complete, (void *)pFt1000Dev); - t = (u8 *) pFt1000Dev->tx_urb->transfer_buffer; + t = (u8 *)pFt1000Dev->tx_urb->transfer_buffer; ret = usb_submit_urb(pFt1000Dev->tx_urb, GFP_ATOMIC); if (ret) { - DEBUG("ft1000 failed tx_urb %d\n", ret); + pr_debug("failed tx_urb %d\n", ret); return ret; } pInfo->stats.tx_packets++; @@ -574,9 +568,9 @@ static int ft1000_copy_down_pkt(struct net_device *netdev, u8 *packet, u16 len) } /* transmit an ethernet packet -* Parameters: skb - socket buffer to be sent -* dev - network device -*/ + * Parameters: skb - socket buffer to be sent + * dev - network device + */ static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ft1000_info *pInfo = netdev_priv(dev); @@ -585,30 +579,30 @@ static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev) int maxlen, pipe; if (skb == NULL) { - DEBUG("ft1000_hw: ft1000_start_xmit:skb == NULL!!!\n"); + pr_debug("skb == NULL!!!\n"); return NETDEV_TX_OK; } if (pFt1000Dev->status & FT1000_STATUS_CLOSING) { - DEBUG("network driver is closed, return\n"); + pr_debug("network driver is closed, return\n"); goto err; } pipe = - usb_sndbulkpipe(pFt1000Dev->dev, pFt1000Dev->bulk_out_endpointAddr); + usb_sndbulkpipe(pFt1000Dev->dev, pFt1000Dev->bulk_out_endpointAddr); maxlen = usb_maxpacket(pFt1000Dev->dev, pipe, usb_pipeout(pipe)); - pdata = (u8 *) skb->data; + pdata = (u8 *)skb->data; if (pInfo->mediastate == 0) { /* Drop packet is mediastate is down */ - DEBUG("ft1000_hw:ft1000_start_xmit:mediastate is down\n"); + pr_debug("mediastate is down\n"); goto err; } if ((skb->len < ENET_HEADER_SIZE) || (skb->len > ENET_MAX_SIZE)) { /* Drop packet which has invalid size */ - DEBUG("ft1000_hw:ft1000_start_xmit:invalid ethernet length\n"); + pr_debug("invalid ethernet length\n"); goto err; } @@ -628,7 +622,7 @@ static int ft1000_open(struct net_device *dev) struct ft1000_usb *pFt1000Dev = pInfo->priv; struct timeval tv; - DEBUG("ft1000_open is called for card %d\n", pFt1000Dev->CardNumber); + pr_debug("ft1000_open is called for card %d\n", pFt1000Dev->CardNumber); pInfo->stats.rx_bytes = 0; pInfo->stats.tx_bytes = 0; @@ -676,11 +670,9 @@ int init_ft1000_netdev(struct ft1000_usb *ft1000dev) char card_nr[2]; u8 gCardIndex = 0; - DEBUG("Enter init_ft1000_netdev...\n"); - netdev = alloc_etherdev(sizeof(struct ft1000_info)); if (!netdev) { - DEBUG("init_ft1000_netdev: can not allocate network device\n"); + pr_debug("can not allocate network device\n"); return -ENOMEM; } @@ -690,7 +682,7 @@ int init_ft1000_netdev(struct ft1000_usb *ft1000dev) dev_alloc_name(netdev, netdev->name); - DEBUG("init_ft1000_netdev: network device name is %s\n", netdev->name); + pr_debug("network device name is %s\n", netdev->name); if (strncmp(netdev->name, "eth", 3) == 0) { card_nr[0] = netdev->name[3]; @@ -702,7 +694,7 @@ int init_ft1000_netdev(struct ft1000_usb *ft1000dev) } ft1000dev->CardNumber = gCardIndex; - DEBUG("card number = %d\n", ft1000dev->CardNumber); + pr_debug("card number = %d\n", ft1000dev->CardNumber); } else { netdev_err(ft1000dev->net, "ft1000: Invalid device name\n"); ret_val = -ENXIO; @@ -738,7 +730,7 @@ int init_ft1000_netdev(struct ft1000_usb *ft1000dev) ft1000dev->net = netdev; - DEBUG("Initialize free_buff_lock and freercvpool\n"); + pr_debug("Initialize free_buff_lock and freercvpool\n"); spin_lock_init(&free_buff_lock); /* initialize a list of buffers to be use for queuing @@ -790,7 +782,6 @@ int reg_ft1000_netdev(struct ft1000_usb *ft1000dev, netdev = ft1000dev->net; pInfo = netdev_priv(ft1000dev->net); - DEBUG("Enter reg_ft1000_netdev...\n"); ft1000_read_register(ft1000dev, &pInfo->AsicID, FT1000_REG_ASIC_ID); @@ -799,23 +790,21 @@ int reg_ft1000_netdev(struct ft1000_usb *ft1000dev, rc = register_netdev(netdev); if (rc) { - DEBUG("reg_ft1000_netdev: could not register network device\n"); + pr_debug("could not register network device\n"); free_netdev(netdev); return rc; } ft1000_create_dev(ft1000dev); - DEBUG("reg_ft1000_netdev returned\n"); - pInfo->CardReady = 1; return 0; } /* take a packet from the FIFO up link and -* convert it into an ethernet packet and deliver it to the IP stack -*/ + * convert it into an ethernet packet and deliver it to the IP stack + */ static int ft1000_copy_up_pkt(struct urb *urb) { struct ft1000_info *info = urb->context; @@ -832,14 +821,14 @@ static int ft1000_copy_up_pkt(struct urb *urb) u16 *chksum; if (ft1000dev->status & FT1000_STATUS_CLOSING) { - DEBUG("network driver is closed, return\n"); + pr_debug("network driver is closed, return\n"); return 0; } /* Read length */ len = urb->transfer_buffer_length; lena = urb->actual_length; - chksum = (u16 *) ft1000dev->rx_buf; + chksum = (u16 *)ft1000dev->rx_buf; tempword = *chksum++; for (i = 1; i < 7; i++) @@ -854,13 +843,13 @@ static int ft1000_copy_up_pkt(struct urb *urb) skb = dev_alloc_skb(len + 12 + 2); if (skb == NULL) { - DEBUG("ft1000_copy_up_pkt: No Network buffers available\n"); + pr_debug("No Network buffers available\n"); info->stats.rx_errors++; ft1000_submit_rx_urb(info); return -1; } - pbuffer = (u8 *) skb_put(skb, len + 12); + pbuffer = (u8 *)skb_put(skb, len + 12); /* subtract the number of bytes read already */ ptemp = pbuffer; @@ -905,7 +894,7 @@ static int ft1000_submit_rx_urb(struct ft1000_info *info) struct ft1000_usb *pFt1000Dev = info->priv; if (pFt1000Dev->status & FT1000_STATUS_CLOSING) { - DEBUG("network driver is closed, return\n"); + pr_debug("network driver is closed, return\n"); return -ENODEV; } @@ -914,13 +903,12 @@ static int ft1000_submit_rx_urb(struct ft1000_info *info) usb_rcvbulkpipe(pFt1000Dev->dev, pFt1000Dev->bulk_in_endpointAddr), pFt1000Dev->rx_buf, MAX_BUF_SIZE, - (usb_complete_t) ft1000_copy_up_pkt, info); + (usb_complete_t)ft1000_copy_up_pkt, info); result = usb_submit_urb(pFt1000Dev->rx_urb, GFP_ATOMIC); if (result) { - pr_err("ft1000_submit_rx_urb: submitting rx_urb %d failed\n", - result); + pr_err("submitting rx_urb %d failed\n", result); return result; } @@ -935,7 +923,7 @@ int ft1000_close(struct net_device *net) ft1000dev->status |= FT1000_STATUS_CLOSING; - DEBUG("ft1000_close: pInfo=%p, ft1000dev=%p\n", pInfo, ft1000dev); + pr_debug("pInfo=%p, ft1000dev=%p\n", pInfo, ft1000dev); netif_carrier_off(net); netif_stop_queue(net); ft1000dev->status &= ~FT1000_STATUS_CLOSING; @@ -952,7 +940,7 @@ static int ft1000_chkcard(struct ft1000_usb *dev) int status; if (dev->fCondResetPend) { - DEBUG("ft1000_hw:ft1000_chkcard:Card is being reset, return FALSE\n"); + pr_debug("Card is being reset, return FALSE\n"); return TRUE; } /* Mask register is used to check for device presence since it is never @@ -960,7 +948,7 @@ static int ft1000_chkcard(struct ft1000_usb *dev) */ status = ft1000_read_register(dev, &tempword, FT1000_REG_SUP_IMASK); if (tempword == 0) { - DEBUG("ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n"); + pr_debug("IMASK = 0 Card not detected\n"); return FALSE; } /* The system will return the value of 0xffff for the version register @@ -969,17 +957,17 @@ static int ft1000_chkcard(struct ft1000_usb *dev) status = ft1000_read_register(dev, &tempword, FT1000_REG_ASIC_ID); if (tempword != 0x1b01) { dev->status |= FT1000_STATUS_CLOSING; - DEBUG("ft1000_hw:ft1000_chkcard: Version = 0xffff Card not detected\n"); + pr_debug("Version = 0xffff Card not detected\n"); return FALSE; } return TRUE; } /* read a message from the dpram area. -* Input: -* dev - network device structure -* pbuffer - caller supply address to buffer -*/ + * Input: + * dev - network device structure + * pbuffer - caller supply address to buffer + */ static bool ft1000_receive_cmd(struct ft1000_usb *dev, u16 *pbuffer, int maxsz) { @@ -990,46 +978,45 @@ static bool ft1000_receive_cmd(struct ft1000_usb *dev, u16 *pbuffer, u16 tempword; ret = - ft1000_read_dpram16(dev, FT1000_MAG_PH_LEN, (u8 *) &size, - FT1000_MAG_PH_LEN_INDX); + ft1000_read_dpram16(dev, FT1000_MAG_PH_LEN, (u8 *)&size, + FT1000_MAG_PH_LEN_INDX); size = ntohs(size) + PSEUDOSZ; if (size > maxsz) { - DEBUG("FT1000:ft1000_receive_cmd:Invalid command length = %d\n", - size); + pr_debug("Invalid command length = %d\n", size); return FALSE; } - ppseudohdr = (u16 *) pbuffer; + ppseudohdr = (u16 *)pbuffer; ft1000_write_register(dev, FT1000_DPRAM_MAG_RX_BASE, FT1000_REG_DPRAM_ADDR); ret = - ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAH); + ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAH); pbuffer++; ft1000_write_register(dev, FT1000_DPRAM_MAG_RX_BASE + 1, FT1000_REG_DPRAM_ADDR); for (i = 0; i <= (size >> 2); i++) { ret = - ft1000_read_register(dev, pbuffer, - FT1000_REG_MAG_DPDATAL); + ft1000_read_register(dev, pbuffer, + FT1000_REG_MAG_DPDATAL); pbuffer++; ret = - ft1000_read_register(dev, pbuffer, - FT1000_REG_MAG_DPDATAH); + ft1000_read_register(dev, pbuffer, + FT1000_REG_MAG_DPDATAH); pbuffer++; } /* copy odd aligned word */ ret = - ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAL); + ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAL); pbuffer++; ret = - ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAH); + ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAH); pbuffer++; if (size & 0x0001) { /* copy odd byte from fifo */ ret = - ft1000_read_register(dev, &tempword, - FT1000_REG_DPRAM_DATA); + ft1000_read_register(dev, &tempword, + FT1000_REG_DPRAM_DATA); *pbuffer = ntohs(tempword); } /* Check if pseudo header checksum is good @@ -1058,17 +1045,15 @@ static int ft1000_dsp_prov(void *arg) int status; u16 TempShortBuf[256]; - DEBUG("*** DspProv Entered\n"); - while (list_empty(&info->prov_list) == 0) { - DEBUG("DSP Provisioning List Entry\n"); + pr_debug("DSP Provisioning List Entry\n"); /* Check if doorbell is available */ - DEBUG("check if doorbell is cleared\n"); + pr_debug("check if doorbell is cleared\n"); status = - ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL); + ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL); if (status) { - DEBUG("ft1000_dsp_prov::ft1000_read_register error\n"); + pr_debug("ft1000_read_register error\n"); break; } @@ -1076,7 +1061,7 @@ static int ft1000_dsp_prov(void *arg) mdelay(10); i++; if (i == 10) { - DEBUG("FT1000:ft1000_dsp_prov:message drop\n"); + pr_debug("message drop\n"); return -1; } ft1000_read_register(dev, &tempword, @@ -1084,17 +1069,17 @@ static int ft1000_dsp_prov(void *arg) } if (!(tempword & FT1000_DB_DPRAM_TX)) { - DEBUG("*** Provision Data Sent to DSP\n"); + pr_debug("*** Provision Data Sent to DSP\n"); /* Send provisioning data */ ptr = - list_entry(info->prov_list.next, struct prov_record, - list); - len = *(u16 *) ptr->pprov_data; + list_entry(info->prov_list.next, struct prov_record, + list); + len = *(u16 *)ptr->pprov_data; len = htons(len); len += PSEUDOSZ; - pmsg = (u16 *) ptr->pprov_data; + pmsg = (u16 *)ptr->pprov_data; ppseudo_hdr = (struct pseudo_hdr *)pmsg; /* Insert slow queue sequence number */ ppseudo_hdr->seq_num = info->squeseqnum++; @@ -1109,12 +1094,12 @@ static int ft1000_dsp_prov(void *arg) memcpy(&TempShortBuf[2], ppseudo_hdr, len); status = - ft1000_write_dpram32(dev, 0, - (u8 *) &TempShortBuf[0], - (unsigned short)(len + 2)); + ft1000_write_dpram32(dev, 0, + (u8 *)&TempShortBuf[0], + (unsigned short)(len + 2)); status = - ft1000_write_register(dev, FT1000_DB_DPRAM_TX, - FT1000_REG_DOORBELL); + ft1000_write_register(dev, FT1000_DB_DPRAM_TX, + FT1000_REG_DOORBELL); list_del(&ptr->list); kfree(ptr->pprov_data); @@ -1123,7 +1108,7 @@ static int ft1000_dsp_prov(void *arg) usleep_range(9000, 11000); } - DEBUG("DSP Provisioning List Entry finished\n"); + pr_debug("DSP Provisioning List Entry finished\n"); msleep(100); @@ -1158,37 +1143,26 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) status = ft1000_read_dpram32(dev, 0x200, cmdbuffer, size); #ifdef JDEBUG - DEBUG("ft1000_proc_drvmsg:cmdbuffer\n"); - for (i = 0; i < size; i += 5) { - if ((i + 5) < size) - DEBUG("0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", cmdbuffer[i], - cmdbuffer[i + 1], cmdbuffer[i + 2], - cmdbuffer[i + 3], cmdbuffer[i + 4]); - else { - for (j = i; j < size; j++) - DEBUG("0x%x ", cmdbuffer[j]); - DEBUG("\n"); - break; - } - } + print_hex_dump_debug("cmdbuffer: ", HEX_DUMP_OFFSET, 16, 1, + cmdbuffer, size, true); #endif pdrvmsg = (struct drv_msg *)&cmdbuffer[2]; msgtype = ntohs(pdrvmsg->type); - DEBUG("ft1000_proc_drvmsg:Command message type = 0x%x\n", msgtype); + pr_debug("Command message type = 0x%x\n", msgtype); switch (msgtype) { case MEDIA_STATE:{ - DEBUG("ft1000_proc_drvmsg:Command message type = MEDIA_STATE"); + pr_debug("Command message type = MEDIA_STATE\n"); pmediamsg = (struct media_msg *)&cmdbuffer[0]; if (info->ProgConStat != 0xFF) { if (pmediamsg->state) { - DEBUG("Media is up\n"); + pr_debug("Media is up\n"); if (info->mediastate == 0) { if (dev->NetDevRegDone) netif_wake_queue(dev->net); info->mediastate = 1; } } else { - DEBUG("Media is down\n"); + pr_debug("Media is down\n"); if (info->mediastate == 1) { info->mediastate = 0; if (dev->NetDevRegDone) @@ -1196,7 +1170,7 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) } } } else { - DEBUG("Media is down\n"); + pr_debug("Media is down\n"); if (info->mediastate == 1) { info->mediastate = 0; info->ConTm = 0; @@ -1205,20 +1179,20 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) break; } case DSP_INIT_MSG:{ - DEBUG("ft1000_proc_drvmsg:Command message type = DSP_INIT_MSG"); + pr_debug("Command message type = DSP_INIT_MSG\n"); pdspinitmsg = (struct dsp_init_msg *)&cmdbuffer[2]; memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ); - DEBUG("DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n", - info->DspVer[0], info->DspVer[1], info->DspVer[2], - info->DspVer[3]); + pr_debug("DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n", + info->DspVer[0], info->DspVer[1], info->DspVer[2], + info->DspVer[3]); memcpy(info->HwSerNum, pdspinitmsg->HwSerNum, HWSERNUMSZ); memcpy(info->Sku, pdspinitmsg->Sku, SKUSZ); memcpy(info->eui64, pdspinitmsg->eui64, EUISZ); - DEBUG("EUI64=%2x.%2x.%2x.%2x.%2x.%2x.%2x.%2x\n", - info->eui64[0], info->eui64[1], info->eui64[2], - info->eui64[3], info->eui64[4], info->eui64[5], - info->eui64[6], info->eui64[7]); + pr_debug("EUI64=%2x.%2x.%2x.%2x.%2x.%2x.%2x.%2x\n", + info->eui64[0], info->eui64[1], info->eui64[2], + info->eui64[3], info->eui64[4], info->eui64[5], + info->eui64[6], info->eui64[7]); dev->net->dev_addr[0] = info->eui64[0]; dev->net->dev_addr[1] = info->eui64[1]; dev->net->dev_addr[2] = info->eui64[2]; @@ -1229,17 +1203,17 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) if (ntohs(pdspinitmsg->length) == (sizeof(struct dsp_init_msg) - 20)) { memcpy(info->ProductMode, pdspinitmsg->ProductMode, - MODESZ); + MODESZ); memcpy(info->RfCalVer, pdspinitmsg->RfCalVer, CALVERSZ); memcpy(info->RfCalDate, pdspinitmsg->RfCalDate, CALDATESZ); - DEBUG("RFCalVer = 0x%2x 0x%2x\n", info->RfCalVer[0], - info->RfCalVer[1]); + pr_debug("RFCalVer = 0x%2x 0x%2x\n", + info->RfCalVer[0], info->RfCalVer[1]); } break; } case DSP_PROVISION:{ - DEBUG("ft1000_proc_drvmsg:Command message type = DSP_PROVISION\n"); + pr_debug("Command message type = DSP_PROVISION\n"); /* kick off dspprov routine to start provisioning * Send provisioning data to DSP @@ -1252,21 +1226,20 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) } else { dev->fProvComplete = true; status = ft1000_write_register(dev, FT1000_DB_HB, - FT1000_REG_DOORBELL); - DEBUG("FT1000:drivermsg:No more DSP provisioning data in dsp image\n"); + FT1000_REG_DOORBELL); + pr_debug("No more DSP provisioning data in dsp image\n"); } - DEBUG("ft1000_proc_drvmsg:DSP PROVISION is done\n"); + pr_debug("DSP PROVISION is done\n"); break; } case DSP_STORE_INFO:{ - DEBUG("ft1000_proc_drvmsg:Command message type = DSP_STORE_INFO"); - DEBUG("FT1000:drivermsg:Got DSP_STORE_INFO\n"); + pr_debug("Command message type = DSP_STORE_INFO"); tempword = ntohs(pdrvmsg->length); info->DSPInfoBlklen = tempword; if (tempword < (MAX_DSP_SESS_REC - 4)) { - pmsg = (u16 *) &pdrvmsg->data[0]; + pmsg = (u16 *)&pdrvmsg->data[0]; for (i = 0; i < ((tempword + 1) / 2); i++) { - DEBUG("FT1000:drivermsg:dsp info data = 0x%x\n", *pmsg); + pr_debug("dsp info data = 0x%x\n", *pmsg); info->DSPInfoBlk[i + 10] = *pmsg++; } } else { @@ -1275,33 +1248,33 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) break; } case DSP_GET_INFO:{ - DEBUG("FT1000:drivermsg:Got DSP_GET_INFO\n"); + pr_debug("Got DSP_GET_INFO\n"); /* copy dsp info block to dsp */ dev->DrvMsgPend = 1; /* allow any outstanding ioctl to finish */ mdelay(10); status = ft1000_read_register(dev, &tempword, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); if (tempword & FT1000_DB_DPRAM_TX) { mdelay(10); status = ft1000_read_register(dev, &tempword, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); if (tempword & FT1000_DB_DPRAM_TX) { mdelay(10); status = ft1000_read_register(dev, &tempword, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); if (tempword & FT1000_DB_DPRAM_TX) break; } } /* Put message into Slow Queue Form Pseudo header */ - pmsg = (u16 *) info->DSPInfoBlk; + pmsg = (u16 *)info->DSPInfoBlk; *pmsg++ = 0; *pmsg++ = htons(info->DSPInfoBlklen + 20 + info->DSPInfoBlklen); ppseudo_hdr = - (struct pseudo_hdr *)(u16 *) &info->DSPInfoBlk[2]; + (struct pseudo_hdr *)(u16 *)&info->DSPInfoBlk[2]; ppseudo_hdr->length = htons(info->DSPInfoBlklen + 4 - + info->DSPInfoBlklen); + + info->DSPInfoBlklen); ppseudo_hdr->source = 0x10; ppseudo_hdr->destination = 0x20; ppseudo_hdr->portdest = 0; @@ -1323,31 +1296,31 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) info->DSPInfoBlk[10] = 0x7200; info->DSPInfoBlk[11] = htons(info->DSPInfoBlklen); status = ft1000_write_dpram32(dev, 0, - (u8 *)&info->DSPInfoBlk[0], - (unsigned short)(info->DSPInfoBlklen + 22)); + (u8 *)&info->DSPInfoBlk[0], + (unsigned short)(info->DSPInfoBlklen + 22)); status = ft1000_write_register(dev, FT1000_DB_DPRAM_TX, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); dev->DrvMsgPend = 0; break; } case GET_DRV_ERR_RPT_MSG:{ - DEBUG("FT1000:drivermsg:Got GET_DRV_ERR_RPT_MSG\n"); + pr_debug("Got GET_DRV_ERR_RPT_MSG\n"); /* copy driver error message to dsp */ dev->DrvMsgPend = 1; /* allow any outstanding ioctl to finish */ mdelay(10); status = ft1000_read_register(dev, &tempword, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); if (tempword & FT1000_DB_DPRAM_TX) { mdelay(10); status = ft1000_read_register(dev, &tempword, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); if (tempword & FT1000_DB_DPRAM_TX) mdelay(10); } if ((tempword & FT1000_DB_DPRAM_TX) == 0) { /* Put message into Slow Queue Form Pseudo header */ - pmsg = (u16 *) &tempbuffer[0]; + pmsg = (u16 *)&tempbuffer[0]; ppseudo_hdr = (struct pseudo_hdr *)pmsg; ppseudo_hdr->length = htons(0x0012); ppseudo_hdr->source = 0x10; @@ -1368,7 +1341,7 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) for (i = 1; i < 7; i++) ppseudo_hdr->checksum ^= *pmsg++; - pmsg = (u16 *) &tempbuffer[16]; + pmsg = (u16 *)&tempbuffer[16]; *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG); *pmsg++ = htons(0x000e); *pmsg++ = htons(info->DSP_TIME[0]); @@ -1384,7 +1357,7 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) *pmsg++ = htons(info->DrvErrNum); status = card_send_command(dev, (unsigned char *)&tempbuffer[0], - (u16)(0x0012 + PSEUDOSZ)); + (u16)(0x0012 + PSEUDOSZ)); if (status) goto out; info->DrvErrNum = 0; @@ -1399,7 +1372,6 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) status = 0; out: kfree(cmdbuffer); - DEBUG("return from ft1000_proc_drvmsg\n"); return status; } @@ -1412,32 +1384,32 @@ static int dsp_broadcast_msg_id(struct ft1000_usb *dev) for (i = 0; i < MAX_NUM_APP; i++) { if ((dev->app_info[i].DspBCMsgFlag) - && (dev->app_info[i].fileobject) - && (dev->app_info[i].NumOfMsg - < MAX_MSG_LIMIT)) { + && (dev->app_info[i].fileobject) + && (dev->app_info[i].NumOfMsg + < MAX_MSG_LIMIT)) { pdpram_blk = ft1000_get_buffer(&freercvpool); if (pdpram_blk == NULL) { - DEBUG("Out of memory in free receive command pool\n"); + pr_debug("Out of memory in free receive command pool\n"); dev->app_info[i].nRxMsgMiss++; return -1; } if (ft1000_receive_cmd(dev, pdpram_blk->pbuffer, - MAX_CMD_SQSIZE)) { + MAX_CMD_SQSIZE)) { /* Put message into the * appropriate application block */ dev->app_info[i].nRxMsg++; spin_lock_irqsave(&free_buff_lock, flags); list_add_tail(&pdpram_blk->list, - &dev->app_info[i] .app_sqlist); + &dev->app_info[i] .app_sqlist); dev->app_info[i].NumOfMsg++; spin_unlock_irqrestore(&free_buff_lock, flags); wake_up_interruptible(&dev->app_info[i] - .wait_dpram_msg); + .wait_dpram_msg); } else { dev->app_info[i].nRxMsgMiss++; ft1000_free_buffer(pdpram_blk, &freercvpool); - DEBUG("pdpram_blk::ft1000_get_buffer NULL\n"); + pr_debug("ft1000_get_buffer NULL\n"); return -1; } } @@ -1452,7 +1424,7 @@ static int handle_misc_portid(struct ft1000_usb *dev) pdpram_blk = ft1000_get_buffer(&freercvpool); if (pdpram_blk == NULL) { - DEBUG("Out of memory in free receive command pool\n"); + pr_debug("Out of memory in free receive command pool\n"); return -1; } if (!ft1000_receive_cmd(dev, pdpram_blk->pbuffer, MAX_CMD_SQSIZE)) @@ -1461,11 +1433,12 @@ static int handle_misc_portid(struct ft1000_usb *dev) /* Search for correct application block */ for (i = 0; i < MAX_NUM_APP; i++) { if (dev->app_info[i].app_id == ((struct pseudo_hdr *) - pdpram_blk->pbuffer)->portdest) + pdpram_blk->pbuffer)->portdest) break; } if (i == MAX_NUM_APP) { - DEBUG("FT1000:ft1000_parse_dpram_msg: No application matching id = %d\n", ((struct pseudo_hdr *)pdpram_blk->pbuffer)->portdest); + pr_debug("No application matching id = %d\n", + ((struct pseudo_hdr *)pdpram_blk->pbuffer)->portdest); goto exit_failure; } else if (dev->app_info[i].NumOfMsg > MAX_MSG_LIMIT) { goto exit_failure; @@ -1495,26 +1468,26 @@ int ft1000_poll(void *dev_id) u16 portid; if (ft1000_chkcard(dev) == FALSE) { - DEBUG("ft1000_poll::ft1000_chkcard: failed\n"); + pr_debug("failed\n"); return -1; } status = ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL); if (!status) { if (tempword & FT1000_DB_DPRAM_RX) { status = ft1000_read_dpram16(dev, - 0x200, (u8 *)&data, 0); + 0x200, (u8 *)&data, 0); size = ntohs(data) + 16 + 2; if (size % 4) { modulo = 4 - (size % 4); size = size + modulo; } status = ft1000_read_dpram16(dev, 0x201, - (u8 *)&portid, 1); + (u8 *)&portid, 1); portid &= 0xff; if (size < MAX_CMD_SQSIZE) { switch (portid) { case DRIVERID: - DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_DPRAM_RX : portid DRIVERID\n"); + pr_debug("FT1000_REG_DOORBELL message type: FT1000_DB_DPRAM_RX : portid DRIVERID\n"); status = ft1000_proc_drvmsg(dev, size); if (status != 0) return status; @@ -1527,87 +1500,88 @@ int ft1000_poll(void *dev_id) break; } } else - DEBUG("FT1000:dpc:Invalid total length for SlowQ = %d\n", size); + pr_debug("Invalid total length for SlowQ = %d\n", + size); status = ft1000_write_register(dev, - FT1000_DB_DPRAM_RX, - FT1000_REG_DOORBELL); + FT1000_DB_DPRAM_RX, + FT1000_REG_DOORBELL); } else if (tempword & FT1000_DSP_ASIC_RESET) { /* Let's reset the ASIC from the Host side as well */ status = ft1000_write_register(dev, ASIC_RESET_BIT, - FT1000_REG_RESET); + FT1000_REG_RESET); status = ft1000_read_register(dev, &tempword, - FT1000_REG_RESET); + FT1000_REG_RESET); i = 0; while (tempword & ASIC_RESET_BIT) { status = ft1000_read_register(dev, &tempword, - FT1000_REG_RESET); + FT1000_REG_RESET); usleep_range(9000, 11000); i++; if (i == 100) break; } if (i == 100) { - DEBUG("Unable to reset ASIC\n"); + pr_debug("Unable to reset ASIC\n"); return 0; } usleep_range(9000, 11000); /* Program WMARK register */ status = ft1000_write_register(dev, 0x600, - FT1000_REG_MAG_WATERMARK); + FT1000_REG_MAG_WATERMARK); /* clear ASIC reset doorbell */ status = ft1000_write_register(dev, - FT1000_DSP_ASIC_RESET, - FT1000_REG_DOORBELL); + FT1000_DSP_ASIC_RESET, + FT1000_REG_DOORBELL); usleep_range(9000, 11000); } else if (tempword & FT1000_ASIC_RESET_REQ) { - DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_ASIC_RESET_REQ\n"); + pr_debug("FT1000_REG_DOORBELL message type: FT1000_ASIC_RESET_REQ\n"); /* clear ASIC reset request from DSP */ status = ft1000_write_register(dev, - FT1000_ASIC_RESET_REQ, - FT1000_REG_DOORBELL); + FT1000_ASIC_RESET_REQ, + FT1000_REG_DOORBELL); status = ft1000_write_register(dev, HOST_INTF_BE, - FT1000_REG_SUP_CTRL); + FT1000_REG_SUP_CTRL); /* copy dsp session record from Adapter block */ status = ft1000_write_dpram32(dev, 0, - (u8 *)&info->DSPSess.Rec[0], 1024); + (u8 *)&info->DSPSess.Rec[0], 1024); status = ft1000_write_register(dev, 0x600, - FT1000_REG_MAG_WATERMARK); + FT1000_REG_MAG_WATERMARK); /* ring doorbell to tell DSP that * ASIC is out of reset * */ status = ft1000_write_register(dev, - FT1000_ASIC_RESET_DSP, - FT1000_REG_DOORBELL); + FT1000_ASIC_RESET_DSP, + FT1000_REG_DOORBELL); } else if (tempword & FT1000_DB_COND_RESET) { - DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_COND_RESET\n"); + pr_debug("FT1000_REG_DOORBELL message type: FT1000_DB_COND_RESET\n"); if (!dev->fAppMsgPend) { /* Reset ASIC and DSP */ status = ft1000_read_dpram16(dev, - FT1000_MAG_DSP_TIMER0, - (u8 *)&(info->DSP_TIME[0]), - FT1000_MAG_DSP_TIMER0_INDX); + FT1000_MAG_DSP_TIMER0, + (u8 *)&(info->DSP_TIME[0]), + FT1000_MAG_DSP_TIMER0_INDX); status = ft1000_read_dpram16(dev, - FT1000_MAG_DSP_TIMER1, - (u8 *)&(info->DSP_TIME[1]), - FT1000_MAG_DSP_TIMER1_INDX); + FT1000_MAG_DSP_TIMER1, + (u8 *)&(info->DSP_TIME[1]), + FT1000_MAG_DSP_TIMER1_INDX); status = ft1000_read_dpram16(dev, - FT1000_MAG_DSP_TIMER2, - (u8 *)&(info->DSP_TIME[2]), - FT1000_MAG_DSP_TIMER2_INDX); + FT1000_MAG_DSP_TIMER2, + (u8 *)&(info->DSP_TIME[2]), + FT1000_MAG_DSP_TIMER2_INDX); status = ft1000_read_dpram16(dev, - FT1000_MAG_DSP_TIMER3, - (u8 *)&(info->DSP_TIME[3]), - FT1000_MAG_DSP_TIMER3_INDX); + FT1000_MAG_DSP_TIMER3, + (u8 *)&(info->DSP_TIME[3]), + FT1000_MAG_DSP_TIMER3_INDX); info->CardReady = 0; info->DrvErrNum = DSP_CONDRESET_INFO; - DEBUG("ft1000_hw:DSP conditional reset requested\n"); + pr_debug("DSP conditional reset requested\n"); info->ft1000_reset(dev->net); } else { dev->fProvComplete = false; dev->fCondResetPend = true; } ft1000_write_register(dev, FT1000_DB_COND_RESET, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); } } return 0; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_ioctl.h b/drivers/staging/ft1000/ft1000-usb/ft1000_ioctl.h index cb644a58d9f3..e9472bebda0b 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_ioctl.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_ioctl.h @@ -1,30 +1,30 @@ /* -*--------------------------------------------------------------------------- -* FT1000 driver for Flarion Flash OFDM NIC Device -* -* Copyright (C) 2002 Flarion Technologies, All rights reserved. -* -* This program is free software; you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by the Free -* Software Foundation; either version 2 of the License, or (at your option) any -* later version. This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. You should have received a copy of the GNU General Public -* License along with this program; if not, write to the -* Free Software Foundation, Inc., 59 Temple Place - -* Suite 330, Boston, MA 02111-1307, USA. -*--------------------------------------------------------------------------- -* -* File: ft1000_ioctl.h -* -* Description: Common structures and defines relating to IOCTL -* -* History: -* 11/5/02 Whc Created. -* -*--------------------------------------------------------------------------- -*/ + *--------------------------------------------------------------------------- + * FT1000 driver for Flarion Flash OFDM NIC Device + * + * Copyright (C) 2002 Flarion Technologies, All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) any + * later version. This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - + * Suite 330, Boston, MA 02111-1307, USA. + *--------------------------------------------------------------------------- + * + * File: ft1000_ioctl.h + * + * Description: Common structures and defines relating to IOCTL + * + * History: + * 11/5/02 Whc Created. + * + *--------------------------------------------------------------------------- + */ #ifndef _FT1000IOCTLH_ #define _FT1000IOCTLH_ @@ -94,8 +94,8 @@ struct IOCTL_DPRAM_COMMAND { } __packed; /* -* Custom IOCTL command codes -*/ + * Custom IOCTL command codes + */ #define FT1000_MAGIC_CODE 'F' #define IOCTL_REGISTER_CMD 0 @@ -106,8 +106,8 @@ struct IOCTL_DPRAM_COMMAND { #define IOCTL_CONNECT 10 #define IOCTL_DISCONNECT 11 -#define IOCTL_FT1000_GET_DSP_STAT _IOR(FT1000_MAGIC_CODE, \ - IOCTL_GET_DSP_STAT_CMD, \ +#define IOCTL_FT1000_GET_DSP_STAT _IOR(FT1000_MAGIC_CODE, \ + IOCTL_GET_DSP_STAT_CMD, \ struct IOCTL_GET_DSP_STAT) #define IOCTL_FT1000_GET_VER _IOR(FT1000_MAGIC_CODE, IOCTL_GET_VER_CMD, \ struct IOCTL_GET_VER) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c index 39be30c0eedf..a6b55f42c07c 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c @@ -7,6 +7,9 @@ * $Id: *==================================================== */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/kernel.h> #include <linux/module.h> #include <linux/usb.h> @@ -45,7 +48,7 @@ static int ft1000_poll_thread(void *arg) if (!gPollingfailed) { ret = ft1000_poll(arg); if (ret != 0) { - DEBUG("ft1000_poll_thread: polling failed\n"); + pr_debug("polling failed\n"); gPollingfailed = true; } } @@ -71,9 +74,8 @@ static int ft1000_probe(struct usb_interface *interface, return -ENOMEM; dev = interface_to_usbdev(interface); - DEBUG("ft1000_probe: usb device descriptor info:\n"); - DEBUG("ft1000_probe: number of configuration is %d\n", - dev->descriptor.bNumConfigurations); + pr_debug("usb device descriptor info - number of configuration is %d\n", + dev->descriptor.bNumConfigurations); ft1000dev->dev = dev; ft1000dev->status = 0; @@ -85,60 +87,56 @@ static int ft1000_probe(struct usb_interface *interface, goto err_fw; } - DEBUG("ft1000_probe is called\n"); numaltsetting = interface->num_altsetting; - DEBUG("ft1000_probe: number of alt settings is :%d\n", numaltsetting); + pr_debug("number of alt settings is: %d\n", numaltsetting); iface_desc = interface->cur_altsetting; - DEBUG("ft1000_probe: number of endpoints is %d\n", - iface_desc->desc.bNumEndpoints); - DEBUG("ft1000_probe: descriptor type is %d\n", - iface_desc->desc.bDescriptorType); - DEBUG("ft1000_probe: interface number is %d\n", - iface_desc->desc.bInterfaceNumber); - DEBUG("ft1000_probe: alternatesetting is %d\n", - iface_desc->desc.bAlternateSetting); - DEBUG("ft1000_probe: interface class is %d\n", - iface_desc->desc.bInterfaceClass); - DEBUG("ft1000_probe: control endpoint info:\n"); - DEBUG("ft1000_probe: descriptor0 type -- %d\n", - iface_desc->endpoint[0].desc.bmAttributes); - DEBUG("ft1000_probe: descriptor1 type -- %d\n", - iface_desc->endpoint[1].desc.bmAttributes); - DEBUG("ft1000_probe: descriptor2 type -- %d\n", - iface_desc->endpoint[2].desc.bmAttributes); + pr_debug("number of endpoints is: %d\n", + iface_desc->desc.bNumEndpoints); + pr_debug("descriptor type is: %d\n", iface_desc->desc.bDescriptorType); + pr_debug("interface number is: %d\n", + iface_desc->desc.bInterfaceNumber); + pr_debug("alternatesetting is: %d\n", + iface_desc->desc.bAlternateSetting); + pr_debug("interface class is: %d\n", iface_desc->desc.bInterfaceClass); + pr_debug("control endpoint info:\n"); + pr_debug("descriptor0 type -- %d\n", + iface_desc->endpoint[0].desc.bmAttributes); + pr_debug("descriptor1 type -- %d\n", + iface_desc->endpoint[1].desc.bmAttributes); + pr_debug("descriptor2 type -- %d\n", + iface_desc->endpoint[2].desc.bmAttributes); for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { endpoint = - (struct usb_endpoint_descriptor *)&iface_desc-> - endpoint[i].desc; - DEBUG("endpoint %d\n", i); - DEBUG("bEndpointAddress=%x, bmAttributes=%x\n", - endpoint->bEndpointAddress, endpoint->bmAttributes); + (struct usb_endpoint_descriptor *)&iface_desc-> + endpoint[i].desc; + pr_debug("endpoint %d\n", i); + pr_debug("bEndpointAddress=%x, bmAttributes=%x\n", + endpoint->bEndpointAddress, endpoint->bmAttributes); if ((endpoint->bEndpointAddress & USB_DIR_IN) && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) { ft1000dev->bulk_in_endpointAddr = - endpoint->bEndpointAddress; - DEBUG("ft1000_probe: in: %d\n", - endpoint->bEndpointAddress); + endpoint->bEndpointAddress; + pr_debug("in: %d\n", endpoint->bEndpointAddress); } if (!(endpoint->bEndpointAddress & USB_DIR_IN) && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) { ft1000dev->bulk_out_endpointAddr = - endpoint->bEndpointAddress; - DEBUG("ft1000_probe: out: %d\n", - endpoint->bEndpointAddress); + endpoint->bEndpointAddress; + pr_debug("out: %d\n", endpoint->bEndpointAddress); } } - DEBUG("bulk_in=%d, bulk_out=%d\n", ft1000dev->bulk_in_endpointAddr, - ft1000dev->bulk_out_endpointAddr); + pr_debug("bulk_in=%d, bulk_out=%d\n", + ft1000dev->bulk_in_endpointAddr, + ft1000dev->bulk_out_endpointAddr); ret = request_firmware(&dsp_fw, "ft3000.img", &dev->dev); if (ret < 0) { - pr_err("Error request_firmware().\n"); + pr_err("Error request_firmware()\n"); goto err_fw; } @@ -155,7 +153,7 @@ static int ft1000_probe(struct usb_interface *interface, FileLength = dsp_fw->size; release_firmware(dsp_fw); - DEBUG("ft1000_probe: start downloading dsp image...\n"); + pr_debug("start downloading dsp image...\n"); ret = init_ft1000_netdev(ft1000dev); if (ret) @@ -163,7 +161,7 @@ static int ft1000_probe(struct usb_interface *interface, pft1000info = netdev_priv(ft1000dev->net); - DEBUG("In probe: pft1000info=%p\n", pft1000info); + pr_debug("pft1000info=%p\n", pft1000info); ret = dsp_reload(ft1000dev); if (ret) { pr_err("Problem with DSP image loading\n"); @@ -172,7 +170,7 @@ static int ft1000_probe(struct usb_interface *interface, gPollingfailed = false; ft1000dev->pPollThread = - kthread_run(ft1000_poll_thread, ft1000dev, "ft1000_poll"); + kthread_run(ft1000_poll_thread, ft1000dev, "ft1000_poll"); if (IS_ERR(ft1000dev->pPollThread)) { ret = PTR_ERR(ft1000dev->pPollThread); @@ -187,10 +185,10 @@ static int ft1000_probe(struct usb_interface *interface, goto err_thread; } msleep(100); - DEBUG("ft1000_probe::Waiting for Card Ready\n"); + pr_debug("Waiting for Card Ready\n"); } - DEBUG("ft1000_probe::Card Ready!!!! Registering network device\n"); + pr_debug("Card Ready!!!! Registering network device\n"); ret = reg_ft1000_netdev(ft1000dev, interface); if (ret) @@ -216,24 +214,21 @@ static void ft1000_disconnect(struct usb_interface *interface) struct ft1000_info *pft1000info; struct ft1000_usb *ft1000dev; - DEBUG("ft1000_disconnect is called\n"); - - pft1000info = (struct ft1000_info *) usb_get_intfdata(interface); - DEBUG("In disconnect pft1000info=%p\n", pft1000info); + pft1000info = (struct ft1000_info *)usb_get_intfdata(interface); + pr_debug("In disconnect pft1000info=%p\n", pft1000info); if (pft1000info) { ft1000dev = pft1000info->priv; if (ft1000dev->pPollThread) kthread_stop(ft1000dev->pPollThread); - DEBUG("ft1000_disconnect: threads are terminated\n"); + pr_debug("threads are terminated\n"); if (ft1000dev->net) { - DEBUG("ft1000_disconnect: destroy char driver\n"); + pr_debug("destroy char driver\n"); ft1000_destroy_dev(ft1000dev->net); unregister_netdev(ft1000dev->net); - DEBUG - ("ft1000_disconnect: network device unregistered\n"); + pr_debug("network device unregistered\n"); free_netdev(ft1000dev->net); } @@ -241,7 +236,7 @@ static void ft1000_disconnect(struct usb_interface *interface) usb_free_urb(ft1000dev->rx_urb); usb_free_urb(ft1000dev->tx_urb); - DEBUG("ft1000_disconnect: urb freed\n"); + pr_debug("urb freed\n"); kfree(ft1000dev); } diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index 8f7ccae57f31..fea60d5651a7 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -28,8 +28,6 @@ struct app_info_block { */ } __packed; -#define DEBUG(args...) pr_info(args) - #define FALSE 0 #define TRUE 1 @@ -137,7 +135,7 @@ extern spinlock_t free_buff_lock; int ft1000_create_dev(struct ft1000_usb *dev); void ft1000_destroy_dev(struct net_device *dev); extern int card_send_command(struct ft1000_usb *ft1000dev, - void *ptempbuffer, int size); + void *ptempbuffer, int size); struct dpram_blk *ft1000_get_buffer(struct list_head *bufflist); void ft1000_free_buffer(struct dpram_blk *pdpram_blk, struct list_head *plist); diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index af0c3878358c..73deae3cd9eb 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c @@ -278,7 +278,6 @@ static void fwtty_send_txn_async(struct fwtty_peer *peer, len, fwtty_common_callback, txn); } - static void __fwtty_restart_tx(struct fwtty_port *port) { int len, avail; @@ -508,7 +507,6 @@ static void fwtty_do_hangup(struct work_struct *work) tty_kref_put(tty); } - static void fwtty_emit_breaks(struct work_struct *work) { struct fwtty_port *port = to_port(to_delayed_work(work), emit_breaks); @@ -1622,7 +1620,6 @@ static inline int mgmt_pkt_expected_len(__be16 code) case FWSC_VIRT_CABLE_PLUG_RSP: /* | FWSC_RSP_OK */ return sizeof(pkt.hdr) + sizeof(pkt.plug_rsp); - case FWSC_VIRT_CABLE_UNPLUG: case FWSC_VIRT_CABLE_UNPLUG_RSP: case FWSC_VIRT_CABLE_PLUG_RSP | FWSC_RSP_NACK: diff --git a/drivers/staging/gdm724x/gdm_lte.c b/drivers/staging/gdm724x/gdm_lte.c index c657639f884b..73eede163820 100644 --- a/drivers/staging/gdm724x/gdm_lte.c +++ b/drivers/staging/gdm724x/gdm_lte.c @@ -626,7 +626,7 @@ static void gdm_lte_netif_rx(struct net_device *dev, char *buf, void *addr = buf + sizeof(struct iphdr) + sizeof(struct udphdr) + offsetof(struct dhcp_packet, chaddr); - memcpy(nic->dest_mac_addr, addr, ETH_ALEN); + ether_addr_copy(nic->dest_mac_addr, addr); } } @@ -639,7 +639,7 @@ static void gdm_lte_netif_rx(struct net_device *dev, char *buf, } /* Format the data so that it can be put to skb */ - memcpy(mac_header_data, nic->dest_mac_addr, ETH_ALEN); + ether_addr_copy(mac_header_data, nic->dest_mac_addr); memcpy(mac_header_data + ETH_ALEN, nic->src_mac_addr, ETH_ALEN); vlan_eth.h_vlan_TCI = htons(nic->vlan_id); @@ -842,9 +842,9 @@ static void form_mac_address(u8 *dev_addr, u8 *nic_src, u8 *nic_dest, { /* Form the dev_addr */ if (!mac_address) - memcpy(dev_addr, gdm_lte_macaddr, ETH_ALEN); + ether_addr_copy(dev_addr, gdm_lte_macaddr); else - memcpy(dev_addr, mac_address, ETH_ALEN); + ether_addr_copy(dev_addr, mac_address); /* The last byte of the mac address * should be less than or equal to 0xFC @@ -858,7 +858,7 @@ static void form_mac_address(u8 *dev_addr, u8 *nic_src, u8 *nic_dest, memcpy(nic_src, dev_addr, 3); /* Copy the nic_dest from dev_addr*/ - memcpy(nic_dest, dev_addr, ETH_ALEN); + ether_addr_copy(nic_dest, dev_addr); } static void validate_mac_address(u8 *mac_address) diff --git a/drivers/staging/gdm724x/gdm_mux.h b/drivers/staging/gdm724x/gdm_mux.h index 0163b243d3e0..3d50383c6ced 100644 --- a/drivers/staging/gdm724x/gdm_mux.h +++ b/drivers/staging/gdm724x/gdm_mux.h @@ -35,10 +35,10 @@ #define RETRY_TIMER 30 /* msec */ struct mux_pkt_header { - unsigned int start_flag; - unsigned int seq_num; - unsigned int payload_size; - unsigned short packet_type; + __le32 start_flag; + __le32 seq_num; + __le32 payload_size; + __le16 packet_type; unsigned char data[0]; }; diff --git a/drivers/staging/gdm72xx/Kconfig b/drivers/staging/gdm72xx/Kconfig index 5836503caa7b..bf11a7fbfc51 100644 --- a/drivers/staging/gdm72xx/Kconfig +++ b/drivers/staging/gdm72xx/Kconfig @@ -53,7 +53,7 @@ if WIMAX_GDM72XX_USB config WIMAX_GDM72XX_USB_PM bool "Enable power management support" - depends on PM_RUNTIME + depends on PM help Enable USB power management in order to reduce power consumption while the interface is not in use. diff --git a/drivers/staging/gdm72xx/gdm_wimax.c b/drivers/staging/gdm72xx/gdm_wimax.c index f5a3378c3951..9cab54bfa6f4 100644 --- a/drivers/staging/gdm72xx/gdm_wimax.c +++ b/drivers/staging/gdm72xx/gdm_wimax.c @@ -115,7 +115,7 @@ static void gdm_wimax_event_rcv(struct net_device *dev, u16 type, void *msg, { struct nic *nic = netdev_priv(dev); - u8 *buf = (u8 *)msg; + u8 *buf = msg; u16 hci_cmd = (buf[0]<<8) | buf[1]; u16 hci_len = (buf[2]<<8) | buf[3]; @@ -605,10 +605,8 @@ static void gdm_wimax_netif_rx(struct net_device *dev, char *buf, int len) int ret; skb = dev_alloc_skb(len + 2); - if (!skb) { - netdev_err(dev, "%s: dev_alloc_skb failed!\n", __func__); + if (!skb) return; - } skb_reserve(skb, 2); dev->stats.rx_packets++; diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c index 6aa9d7c30139..6da72858d28c 100644 --- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c +++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c @@ -46,27 +46,6 @@ static char *file = "xlinx_fpga_firmware.bit"; module_param(file, charp, S_IRUGO); MODULE_PARM_DESC(file, "Xilinx FPGA firmware file."); -#ifdef DEBUG_FPGA -static void datadump(char *msg, void *m, int n) -{ - int i; - unsigned char *c; - - pr_info("=== %s ===\n", msg); - - c = m; - - for (i = 0; i < n; i++) { - if ((i&0xf) == 0) - pr_info(KERN_INFO "\n 0x%4x: ", i); - - pr_info("%02X ", c[i]); - } - - pr_info("\n"); -} -#endif /* DEBUG_FPGA */ - static void read_bitstream(char *bitdata, char *buf, int *offset, int rdsize) { memcpy(buf, bitdata + *offset, rdsize); @@ -157,12 +136,10 @@ static void gs_print_header(struct fpgaimage *fimage) static void gs_read_bitstream(struct fpgaimage *fimage) { char *bitdata; - int size; int offset; offset = 0; bitdata = (char *)fimage->fw_entry->data; - size = fimage->fw_entry->size; readmagic_bitstream(bitdata, &offset); readinfo_bitstream(bitdata, fimage->filename, &offset); @@ -195,15 +172,15 @@ static int gs_read_image(struct fpgaimage *fimage) return 0; } -static int gs_load_image(struct fpgaimage *fimage, char *file) +static int gs_load_image(struct fpgaimage *fimage, char *fw_file) { int err; - pr_info("load fpgaimage %s\n", file); + pr_info("load fpgaimage %s\n", fw_file); - err = request_firmware(&fimage->fw_entry, file, &firmware_pdev->dev); + err = request_firmware(&fimage->fw_entry, fw_file, &firmware_pdev->dev); if (err != 0) { - pr_err("firmware %s is missing, cannot continue.\n", file); + pr_err("firmware %s is missing, cannot continue.\n", fw_file); return err; } @@ -220,9 +197,9 @@ static int gs_download_image(struct fpgaimage *fimage, enum wbus bus_bytes) size = fimage->lendata; #ifdef DEBUG_FPGA - datadump("bitfile sample", bitdata, 0x100); + print_hex_dump_bytes("bitfile sample: ", DUMP_PREFIX_OFFSET, + bitdata, 0x100); #endif /* DEBUG_FPGA */ - if (!xl_supported_prog_bus_width(bus_bytes)) { pr_err("unsupported program bus width %d\n", bus_bytes); @@ -316,10 +293,8 @@ static int gs_fpgaboot(void) struct fpgaimage *fimage; fimage = kmalloc(sizeof(struct fpgaimage), GFP_KERNEL); - if (fimage == NULL) { - pr_err("No memory is available\n"); - goto err_out; - } + if (!fimage) + return -ENOMEM; err = gs_load_image(fimage, file); if (err) { @@ -361,50 +336,44 @@ err_out2: err_out1: kfree(fimage); -err_out: return -1; } static int __init gs_fpgaboot_init(void) { - int err, r; - - r = -1; + int err; pr_info("FPGA DOWNLOAD --->\n"); pr_info("FPGA image file name: %s\n", file); err = init_driver(); - if (err != 0) { + if (err) { pr_err("FPGA DRIVER INIT FAIL!!\n"); - return r; + return err; } err = xl_init_io(); if (err) { pr_err("GPIO INIT FAIL!!\n"); - r = -1; goto errout; } err = gs_fpgaboot(); if (err) { pr_err("FPGA DOWNLOAD FAIL!!\n"); - r = -1; goto errout; } pr_info("FPGA DOWNLOAD DONE <---\n"); - r = 0; - return r; + return 0; errout: finish_driver(); - return r; + return err; } static void __exit gs_fpgaboot_exit(void) diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/drivers/staging/iio/Documentation/generic_buffer.c index 044ea196aa6f..de4647e2495e 100644 --- a/drivers/staging/iio/Documentation/generic_buffer.c +++ b/drivers/staging/iio/Documentation/generic_buffer.c @@ -47,6 +47,7 @@ int size_from_channelarray(struct iio_channel_info *channels, int num_channels) { int bytes = 0; int i = 0; + while (i < num_channels) { if (bytes % channels[i].bytes == 0) channels[i].location = bytes; @@ -74,12 +75,14 @@ void print2byte(int input, struct iio_channel_info *info) input = input >> info->shift; if (info->is_signed) { int16_t val = input; + val &= (1 << info->bits_used) - 1; val = (int16_t)(val << (16 - info->bits_used)) >> (16 - info->bits_used); printf("%05f ", ((float)val + info->offset)*info->scale); } else { uint16_t val = input; + val &= (1 << info->bits_used) - 1; printf("%05f ", ((float)val + info->offset)*info->scale); } @@ -97,6 +100,7 @@ void process_scan(char *data, int num_channels) { int k; + for (k = 0; k < num_channels; k++) switch (channels[k].bytes) { /* only a few cases implemented so far */ @@ -158,11 +162,12 @@ int main(int argc, char **argv) char *buffer_access; int scan_size; int noevents = 0; + int notrigger = 0; char *dummy; struct iio_channel_info *channels; - while ((c = getopt(argc, argv, "l:w:c:et:n:")) != -1) { + while ((c = getopt(argc, argv, "l:w:c:et:n:g")) != -1) { switch (c) { case 'n': device_name = optarg; @@ -183,6 +188,9 @@ int main(int argc, char **argv) case 'l': buf_len = strtoul(optarg, &dummy, 10); break; + case 'g': + notrigger = 1; + break; case '?': return -1; } @@ -201,28 +209,32 @@ int main(int argc, char **argv) printf("iio device number being used is %d\n", dev_num); asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num); - if (trigger_name == NULL) { - /* - * Build the trigger name. If it is device associated its - * name is <device_name>_dev[n] where n matches the device - * number found above - */ - ret = asprintf(&trigger_name, - "%s-dev%d", device_name, dev_num); - if (ret < 0) { - ret = -ENOMEM; - goto error_ret; + + if (!notrigger) { + if (trigger_name == NULL) { + /* + * Build the trigger name. If it is device associated + * its name is <device_name>_dev[n] where n matches + * the device number found above. + */ + ret = asprintf(&trigger_name, + "%s-dev%d", device_name, dev_num); + if (ret < 0) { + ret = -ENOMEM; + goto error_ret; + } } - } - /* Verify the trigger exists */ - trig_num = find_type_by_name(trigger_name, "trigger"); - if (trig_num < 0) { - printf("Failed to find the trigger %s\n", trigger_name); - ret = -ENODEV; - goto error_free_triggername; - } - printf("iio trigger number being used is %d\n", trig_num); + /* Verify the trigger exists */ + trig_num = find_type_by_name(trigger_name, "trigger"); + if (trig_num < 0) { + printf("Failed to find the trigger %s\n", trigger_name); + ret = -ENODEV; + goto error_free_triggername; + } + printf("iio trigger number being used is %d\n", trig_num); + } else + printf("trigger-less mode selected\n"); /* * Parse the files in scan_elements to identify what channels are @@ -246,14 +258,18 @@ int main(int argc, char **argv) ret = -ENOMEM; goto error_free_triggername; } - printf("%s %s\n", dev_dir_name, trigger_name); - /* Set the device trigger to be the data ready trigger found above */ - ret = write_sysfs_string_and_verify("trigger/current_trigger", - dev_dir_name, - trigger_name); - if (ret < 0) { - printf("Failed to write current_trigger file\n"); - goto error_free_buf_dir_name; + + if (!notrigger) { + printf("%s %s\n", dev_dir_name, trigger_name); + /* Set the device trigger to be the data ready trigger found + * above */ + ret = write_sysfs_string_and_verify("trigger/current_trigger", + dev_dir_name, + trigger_name); + if (ret < 0) { + printf("Failed to write current_trigger file\n"); + goto error_free_buf_dir_name; + } } /* Setup ring buffer parameters */ @@ -323,9 +339,10 @@ int main(int argc, char **argv) if (ret < 0) goto error_close_buffer_access; - /* Disconnect the trigger - just write a dummy name. */ - write_sysfs_string("trigger/current_trigger", - dev_dir_name, "NULL"); + if (!notrigger) + /* Disconnect the trigger - just write a dummy name. */ + write_sysfs_string("trigger/current_trigger", + dev_dir_name, "NULL"); error_close_buffer_access: close(fp); diff --git a/drivers/staging/iio/Documentation/iio_event_monitor.c b/drivers/staging/iio/Documentation/iio_event_monitor.c index 569d6f8face5..940ed2399e73 100644 --- a/drivers/staging/iio/Documentation/iio_event_monitor.c +++ b/drivers/staging/iio/Documentation/iio_event_monitor.c @@ -69,16 +69,29 @@ static const char * const iio_modifier_names[] = { [IIO_MOD_X] = "x", [IIO_MOD_Y] = "y", [IIO_MOD_Z] = "z", + [IIO_MOD_X_AND_Y] = "x&y", + [IIO_MOD_X_AND_Z] = "x&z", + [IIO_MOD_Y_AND_Z] = "y&z", + [IIO_MOD_X_AND_Y_AND_Z] = "x&y&z", + [IIO_MOD_X_OR_Y] = "x|y", + [IIO_MOD_X_OR_Z] = "x|z", + [IIO_MOD_Y_OR_Z] = "y|z", + [IIO_MOD_X_OR_Y_OR_Z] = "x|y|z", [IIO_MOD_LIGHT_BOTH] = "both", [IIO_MOD_LIGHT_IR] = "ir", [IIO_MOD_ROOT_SUM_SQUARED_X_Y] = "sqrt(x^2+y^2)", [IIO_MOD_SUM_SQUARED_X_Y_Z] = "x^2+y^2+z^2", - [IIO_MOD_LIGHT_BOTH] = "both", - [IIO_MOD_LIGHT_IR] = "ir", [IIO_MOD_LIGHT_CLEAR] = "clear", [IIO_MOD_LIGHT_RED] = "red", [IIO_MOD_LIGHT_GREEN] = "green", [IIO_MOD_LIGHT_BLUE] = "blue", + [IIO_MOD_QUATERNION] = "quaternion", + [IIO_MOD_TEMP_AMBIENT] = "ambient", + [IIO_MOD_TEMP_OBJECT] = "object", + [IIO_MOD_NORTH_MAGN] = "from_north_magnetic", + [IIO_MOD_NORTH_TRUE] = "from_north_true", + [IIO_MOD_NORTH_MAGN_TILT_COMP] = "from_north_magnetic_tilt_comp", + [IIO_MOD_NORTH_TRUE_TILT_COMP] = "from_north_true_tilt_comp", }; static bool event_is_known(struct iio_event_data *event) @@ -118,6 +131,14 @@ static bool event_is_known(struct iio_event_data *event) case IIO_MOD_X: case IIO_MOD_Y: case IIO_MOD_Z: + case IIO_MOD_X_AND_Y: + case IIO_MOD_X_AND_Z: + case IIO_MOD_Y_AND_Z: + case IIO_MOD_X_AND_Y_AND_Z: + case IIO_MOD_X_OR_Y: + case IIO_MOD_X_OR_Z: + case IIO_MOD_Y_OR_Z: + case IIO_MOD_X_OR_Y_OR_Z: case IIO_MOD_LIGHT_BOTH: case IIO_MOD_LIGHT_IR: case IIO_MOD_ROOT_SUM_SQUARED_X_Y: @@ -126,6 +147,13 @@ static bool event_is_known(struct iio_event_data *event) case IIO_MOD_LIGHT_RED: case IIO_MOD_LIGHT_GREEN: case IIO_MOD_LIGHT_BLUE: + case IIO_MOD_QUATERNION: + case IIO_MOD_TEMP_AMBIENT: + case IIO_MOD_TEMP_OBJECT: + case IIO_MOD_NORTH_MAGN: + case IIO_MOD_NORTH_TRUE: + case IIO_MOD_NORTH_MAGN_TILT_COMP: + case IIO_MOD_NORTH_TRUE_TILT_COMP: break; default: return false; diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index 0973a092224a..568eff06f803 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -34,6 +34,7 @@ inline int iioutils_break_up_name(const char *full_name, char *current; char *w, *r; char *working; + current = strdup(full_name); working = strtok(current, "_\0"); w = working; @@ -335,6 +336,7 @@ inline int build_channel_array(const char *device_dir, if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"), "_en") == 0) { int current_enabled = 0; + current = &(*ci_array)[count++]; ret = asprintf(&filename, "%s/%s", scan_el_dir, ent->d_name); @@ -506,6 +508,7 @@ inline int _write_sysfs_int(char *filename, char *basedir, int val, int verify) FILE *sysfsfp; int test; char *temp = malloc(strlen(basedir) + strlen(filename) + 2); + if (temp == NULL) return -ENOMEM; sprintf(temp, "%s/%s", basedir, filename); @@ -554,6 +557,7 @@ int _write_sysfs_string(char *filename, char *basedir, char *val, int verify) int ret = 0; FILE *sysfsfp; char *temp = malloc(strlen(basedir) + strlen(filename) + 2); + if (temp == NULL) { printf("Memory allocation failed\n"); return -ENOMEM; @@ -614,6 +618,7 @@ int read_sysfs_posint(char *filename, char *basedir) int ret; FILE *sysfsfp; char *temp = malloc(strlen(basedir) + strlen(filename) + 2); + if (temp == NULL) { printf("Memory allocation failed"); return -ENOMEM; @@ -636,6 +641,7 @@ int read_sysfs_float(char *filename, char *basedir, float *val) int ret = 0; FILE *sysfsfp; char *temp = malloc(strlen(basedir) + strlen(filename) + 2); + if (temp == NULL) { printf("Memory allocation failed"); return -ENOMEM; @@ -658,6 +664,7 @@ int read_sysfs_string(const char *filename, const char *basedir, char *str) int ret = 0; FILE *sysfsfp; char *temp = malloc(strlen(basedir) + strlen(filename) + 2); + if (temp == NULL) { printf("Memory allocation failed"); return -ENOMEM; diff --git a/drivers/staging/iio/Documentation/lsiio.c b/drivers/staging/iio/Documentation/lsiio.c index 24ae9694eb41..98a0de098130 100644 --- a/drivers/staging/iio/Documentation/lsiio.c +++ b/drivers/staging/iio/Documentation/lsiio.c @@ -46,6 +46,7 @@ static int dump_channels(const char *dev_dir_name) { DIR *dp; const struct dirent *ent; + dp = opendir(dev_dir_name); if (dp == NULL) return -errno; @@ -62,17 +63,17 @@ static int dump_one_device(const char *dev_dir_name) { char name[IIO_MAX_NAME_LENGTH]; int dev_idx; + int retval; - sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_device), + retval = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_device), "%i", &dev_idx); + if (retval != 1) + return -EINVAL; read_sysfs_string("name", dev_dir_name, name); printf("Device %03d: %s\n", dev_idx, name); - if (verblevel >= VERBLEVEL_SENSORS) { - int ret = dump_channels(dev_dir_name); - if (ret) - return ret; - } + if (verblevel >= VERBLEVEL_SENSORS) + return dump_channels(dev_dir_name); return 0; } @@ -80,9 +81,12 @@ static int dump_one_trigger(const char *dev_dir_name) { char name[IIO_MAX_NAME_LENGTH]; int dev_idx; + int retval; - sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_trigger), + retval = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_trigger), "%i", &dev_idx); + if (retval != 1) + return -EINVAL; read_sysfs_string("name", dev_dir_name, name); printf("Trigger %03d: %s\n", dev_idx, name); return 0; @@ -107,6 +111,7 @@ static void dump_devices(void) while (ent = readdir(dp), ent != NULL) { if (check_prefix(ent->d_name, type_device)) { char *dev_dir_name; + asprintf(&dev_dir_name, "%s%s", iio_dir, ent->d_name); dump_one_device(dev_dir_name); free(dev_dir_name); @@ -118,6 +123,7 @@ static void dump_devices(void) while (ent = readdir(dp), ent != NULL) { if (check_prefix(ent->d_name, type_trigger)) { char *dev_dir_name; + asprintf(&dev_dir_name, "%s%s", iio_dir, ent->d_name); dump_one_trigger(dev_dir_name); free(dev_dir_name); diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig index ad45dfbdf417..07b7ffa00ab5 100644 --- a/drivers/staging/iio/accel/Kconfig +++ b/drivers/staging/iio/accel/Kconfig @@ -9,53 +9,71 @@ config ADIS16201 select IIO_ADIS_LIB select IIO_ADIS_LIB_BUFFER if IIO_BUFFER help - Say yes here to build support for Analog Devices adis16201 dual-axis + Say Y here to build support for Analog Devices adis16201 dual-axis digital inclinometer and accelerometer. + To compile this driver as a module, say M here: the module will + be called adis16201. + config ADIS16203 tristate "Analog Devices ADIS16203 Programmable 360 Degrees Inclinometer" depends on SPI select IIO_ADIS_LIB select IIO_ADIS_LIB_BUFFER if IIO_BUFFER help - Say yes here to build support for Analog Devices adis16203 Programmable + Say Y here to build support for Analog Devices adis16203 Programmable 360 Degrees Inclinometer. + To compile this driver as a module, say M here: the module will be + called adis16203. + config ADIS16204 tristate "Analog Devices ADIS16204 Programmable High-g Digital Impact Sensor and Recorder" depends on SPI select IIO_ADIS_LIB select IIO_ADIS_LIB_BUFFER if IIO_BUFFER help - Say yes here to build support for Analog Devices adis16204 Programmable + Say Y here to build support for Analog Devices adis16204 Programmable High-g Digital Impact Sensor and Recorder. + To compile this driver as a module, say M here: the module will be + called adis16204. + config ADIS16209 tristate "Analog Devices ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer" depends on SPI select IIO_ADIS_LIB select IIO_ADIS_LIB_BUFFER if IIO_BUFFER help - Say yes here to build support for Analog Devices adis16209 dual-axis digital inclinometer + Say Y here to build support for Analog Devices adis16209 dual-axis digital inclinometer and accelerometer. + To compile this driver as a module, say M here: the module will be + called adis16209. + config ADIS16220 tristate "Analog Devices ADIS16220 Programmable Digital Vibration Sensor" depends on SPI select IIO_ADIS_LIB help - Say yes here to build support for Analog Devices adis16220 programmable + Say Y here to build support for Analog Devices adis16220 programmable digital vibration sensor. + To compile this driver as a module, say M here: the module will be + called adis16220. + config ADIS16240 tristate "Analog Devices ADIS16240 Programmable Impact Sensor and Recorder" depends on SPI select IIO_ADIS_LIB select IIO_ADIS_LIB_BUFFER if IIO_BUFFER help - Say yes here to build support for Analog Devices adis16240 programmable + Say Y here to build support for Analog Devices adis16240 programmable impact Sensor and recorder. + To compile this driver as a module, say M here: the module will be + called adis16240. + config LIS3L02DQ tristate "ST Microelectronics LIS3L02DQ Accelerometer Driver" depends on SPI @@ -63,16 +81,21 @@ config LIS3L02DQ depends on !IIO_BUFFER || IIO_KFIFO_BUF depends on GPIOLIB help - Say yes here to build SPI support for the ST microelectronics + Say Y here to build SPI support for the ST microelectronics accelerometer. The driver supplies direct access via sysfs files and an event interface via a character device. + To compile this driver as a module, say M here: the module will be + called lis3l02dq. + config SCA3000 depends on IIO_BUFFER depends on SPI tristate "VTI SCA3000 series accelerometers" help - Say yes here to build support for the VTI SCA3000 series of SPI + Say Y here to build support for the VTI SCA3000 series of SPI accelerometers. These devices use a hardware ring buffer. + To compile this driver as a module, say M here: the module will be + called sca3000. endmenu diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 61f94221b8b7..9efc77b0ebdd 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -35,6 +35,7 @@ irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private) iio_trigger_poll(st->trig); return IRQ_HANDLED; } + return IRQ_WAKE_THREAD; } diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index c110a255d4e8..f6526aa22e8a 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -223,7 +223,8 @@ static int ad7192_setup(struct ad7192_state *st, id &= AD7192_ID_MASK; if (id != st->devid) - dev_warn(&st->sd.spi->dev, "device ID query failed (0x%X)\n", id); + dev_warn(&st->sd.spi->dev, "device ID query failed (0x%X)\n", + id); switch (pdata->clock_source_sel) { case AD7192_CLK_EXT_MCLK1_2: diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c index d215edf66af2..4d4870787eed 100644 --- a/drivers/staging/iio/adc/ad7280a.c +++ b/drivers/staging/iio/adc/ad7280a.c @@ -188,7 +188,7 @@ static void ad7280_delay(struct ad7280_state *st) if (st->readback_delay_us < 50) udelay(st->readback_delay_us); else - msleep(1); + usleep_range(250, 500); } static int __ad7280_read32(struct ad7280_state *st, unsigned *val) diff --git a/drivers/staging/iio/adc/ad7606_spi.c b/drivers/staging/iio/adc/ad7606_spi.c index 6a8ecd73a1a7..7303983e64a7 100644 --- a/drivers/staging/iio/adc/ad7606_spi.c +++ b/drivers/staging/iio/adc/ad7606_spi.c @@ -23,7 +23,7 @@ static int ad7606_spi_read_block(struct device *dev, int i, ret; unsigned short *data = buf; - ret = spi_read(spi, (u8 *)buf, count * 2); + ret = spi_read(spi, buf, count * 2); if (ret < 0) { dev_err(&spi->dev, "SPI read error\n"); return ret; diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c index 734a7e4886a0..48b1c3740030 100644 --- a/drivers/staging/iio/adc/ad7816.c +++ b/drivers/staging/iio/adc/ad7816.c @@ -152,7 +152,8 @@ static ssize_t ad7816_show_available_modes(struct device *dev, return sprintf(buf, "full\npower-save\n"); } -static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7816_show_available_modes, NULL, 0); +static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7816_show_available_modes, + NULL, 0); static ssize_t ad7816_show_channel(struct device *dev, struct device_attribute *attr, diff --git a/drivers/staging/iio/adc/lpc32xx_adc.c b/drivers/staging/iio/adc/lpc32xx_adc.c index 4708e9a41633..5331c442fcfc 100644 --- a/drivers/staging/iio/adc/lpc32xx_adc.c +++ b/drivers/staging/iio/adc/lpc32xx_adc.c @@ -116,7 +116,7 @@ static const struct iio_chan_spec lpc32xx_adc_iio_channels[] = { static irqreturn_t lpc32xx_adc_isr(int irq, void *dev_id) { - struct lpc32xx_adc_info *info = (struct lpc32xx_adc_info *) dev_id; + struct lpc32xx_adc_info *info = dev_id; /* Read value and clear irq */ info->value = __raw_readl(LPC32XX_ADC_VALUE(info->adc_base)) & diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index 51931045bedd..f053535385bf 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -455,7 +455,8 @@ static void mxs_lradc_setup_ts_channel(struct mxs_lradc *lradc, unsigned ch) * SoC's delay unit and start the conversion later * and automatically. */ - mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(0) | /* don't trigger ADC */ + mxs_lradc_reg_wrt(lradc, + LRADC_DELAY_TRIGGER(0) | /* don't trigger ADC */ LRADC_DELAY_TRIGGER_DELAYS(1 << 3) | /* trigger DELAY unit#3 */ LRADC_DELAY_KICK | LRADC_DELAY_DELAY(lradc->settling_delay), @@ -513,7 +514,8 @@ static void mxs_lradc_setup_ts_pressure(struct mxs_lradc *lradc, unsigned ch1, * SoC's delay unit and start the conversion later * and automatically. */ - mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(0) | /* don't trigger ADC */ + mxs_lradc_reg_wrt(lradc, + LRADC_DELAY_TRIGGER(0) | /* don't trigger ADC */ LRADC_DELAY_TRIGGER_DELAYS(1 << 3) | /* trigger DELAY unit#3 */ LRADC_DELAY_KICK | LRADC_DELAY_DELAY(lradc->settling_delay), LRADC_DELAY(2)); diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c index 750697832b96..8ad71691fc09 100644 --- a/drivers/staging/iio/adc/spear_adc.c +++ b/drivers/staging/iio/adc/spear_adc.c @@ -98,7 +98,7 @@ static void spear_adc_set_clk(struct spear_adc_state *st, u32 val) u32 clk_high, clk_low, count; u32 apb_clk = clk_get_rate(st->clk); - count = (apb_clk + val - 1) / val; + count = DIV_ROUND_UP(apb_clk, val); clk_low = count / 2; clk_high = count - clk_low; st->current_clk = apb_clk / count; @@ -226,7 +226,7 @@ static const struct iio_chan_spec spear_adc_iio_channels[] = { static irqreturn_t spear_adc_isr(int irq, void *dev_id) { - struct spear_adc_state *st = (struct spear_adc_state *)dev_id; + struct spear_adc_state *st = dev_id; /* Read value to clear IRQ */ st->value = spear_adc_get_average(st); diff --git a/drivers/staging/iio/addac/Kconfig b/drivers/staging/iio/addac/Kconfig index e6795e0bed1d..0ed7e13e2283 100644 --- a/drivers/staging/iio/addac/Kconfig +++ b/drivers/staging/iio/addac/Kconfig @@ -10,6 +10,9 @@ config ADT7316 Say yes here to build support for Analog Devices ADT7316, ADT7317, ADT7318 and ADT7516, ADT7517, ADT7519 temperature sensors, ADC and DAC. + To compile this driver as a module, choose M here: the module will + be called adt7316. + config ADT7316_SPI tristate "support SPI bus connection" depends on SPI && ADT7316 @@ -18,6 +21,9 @@ config ADT7316_SPI Say yes here to build SPI bus support for Analog Devices ADT7316/7/8 and ADT7516/7/9. + To compile this driver as a module, choose M here: the module will + be called adt7316_spi. + config ADT7316_I2C tristate "support I2C bus connection" depends on I2C && ADT7316 @@ -25,4 +31,7 @@ config ADT7316_I2C Say yes here to build I2C bus support for Analog Devices ADT7316/7/8 and ADT7516/7/9. + To compile this driver as a module, choose M here: the module will + be called adt7316_i2c. + endmenu diff --git a/drivers/staging/iio/addac/adt7316.h b/drivers/staging/iio/addac/adt7316.h index ec50bf34628d..ec40fbb698a6 100644 --- a/drivers/staging/iio/addac/adt7316.h +++ b/drivers/staging/iio/addac/adt7316.h @@ -30,6 +30,7 @@ extern const struct dev_pm_ops adt7316_pm_ops; #else #define ADT7316_PM_OPS NULL #endif -int adt7316_probe(struct device *dev, struct adt7316_bus *bus, const char *name); +int adt7316_probe(struct device *dev, struct adt7316_bus *bus, + const char *name); #endif diff --git a/drivers/staging/iio/gyro/Kconfig b/drivers/staging/iio/gyro/Kconfig index 88b199bb2926..f62f68fd6f3f 100644 --- a/drivers/staging/iio/gyro/Kconfig +++ b/drivers/staging/iio/gyro/Kconfig @@ -7,7 +7,10 @@ config ADIS16060 tristate "Analog Devices ADIS16060 Yaw Rate Gyroscope with SPI driver" depends on SPI help - Say yes here to build support for Analog Devices adis16060 wide bandwidth + Say Y (yes) here to build support for Analog Devices adis16060 wide bandwidth yaw rate gyroscope with SPI. + To compile this driver as a module, say M here: the module will be + called adis16060. If unsure, say N. + endmenu diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c index e0d88fa2a5b5..423f96bdf595 100644 --- a/drivers/staging/iio/light/tsl2x7x_core.c +++ b/drivers/staging/iio/light/tsl2x7x_core.c @@ -1040,8 +1040,8 @@ static ssize_t tsl2x7x_als_persistence_show(struct device *dev, y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1; z = y * TSL2X7X_MIN_ITIME; filter_delay = z * (chip->tsl2x7x_settings.persistence & 0x0F); - y = (filter_delay / 1000); - z = (filter_delay % 1000); + y = filter_delay / 1000; + z = filter_delay % 1000; return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z); } @@ -1086,8 +1086,8 @@ static ssize_t tsl2x7x_prox_persistence_show(struct device *dev, y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.prx_time) + 1; z = y * TSL2X7X_MIN_ITIME; filter_delay = z * ((chip->tsl2x7x_settings.persistence & 0xF0) >> 4); - y = (filter_delay / 1000); - z = (filter_delay % 1000); + y = filter_delay / 1000; + z = filter_delay % 1000; return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z); } @@ -1573,8 +1573,7 @@ static struct attribute *tsl2x7x_ALS_device_attrs[] = { &dev_attr_power_state.attr, &dev_attr_in_illuminance0_calibscale_available.attr, &dev_attr_in_illuminance0_integration_time.attr, - &iio_const_attr_in_illuminance0_integration_time_available\ - .dev_attr.attr, + &iio_const_attr_in_illuminance0_integration_time_available.dev_attr.attr, &dev_attr_in_illuminance0_target_input.attr, &dev_attr_in_illuminance0_calibrate.attr, &dev_attr_in_illuminance0_lux_table.attr, @@ -1591,8 +1590,7 @@ static struct attribute *tsl2x7x_ALSPRX_device_attrs[] = { &dev_attr_power_state.attr, &dev_attr_in_illuminance0_calibscale_available.attr, &dev_attr_in_illuminance0_integration_time.attr, - &iio_const_attr_in_illuminance0_integration_time_available\ - .dev_attr.attr, + &iio_const_attr_in_illuminance0_integration_time_available.dev_attr.attr, &dev_attr_in_illuminance0_target_input.attr, &dev_attr_in_illuminance0_calibrate.attr, &dev_attr_in_illuminance0_lux_table.attr, @@ -1611,8 +1609,7 @@ static struct attribute *tsl2x7x_ALSPRX2_device_attrs[] = { &dev_attr_power_state.attr, &dev_attr_in_illuminance0_calibscale_available.attr, &dev_attr_in_illuminance0_integration_time.attr, - &iio_const_attr_in_illuminance0_integration_time_available\ - .dev_attr.attr, + &iio_const_attr_in_illuminance0_integration_time_available.dev_attr.attr, &dev_attr_in_illuminance0_target_input.attr, &dev_attr_in_illuminance0_calibrate.attr, &dev_attr_in_illuminance0_lux_table.attr, diff --git a/drivers/staging/iio/meter/Kconfig b/drivers/staging/iio/meter/Kconfig index e53274b64ae1..64cd3704ec6e 100644 --- a/drivers/staging/iio/meter/Kconfig +++ b/drivers/staging/iio/meter/Kconfig @@ -10,6 +10,9 @@ config ADE7753 Say yes here to build support for Analog Devices ADE7753 Single-Phase Multifunction Metering IC with di/dt Sensor Interface. + To compile this driver as a module, choose M here: the + module will be called ade7753. + config ADE7754 tristate "Analog Devices ADE7754 Polyphase Multifunction Energy Metering IC Driver" depends on SPI @@ -17,6 +20,9 @@ config ADE7754 Say yes here to build support for Analog Devices ADE7754 Polyphase Multifunction Energy Metering IC Driver. + To compile this driver as a module, choose M here: the + module will be called ade7754. + config ADE7758 tristate "Analog Devices ADE7758 Poly Phase Multifunction Energy Metering IC Driver" depends on SPI @@ -26,6 +32,9 @@ config ADE7758 Say yes here to build support for Analog Devices ADE7758 Polyphase Multifunction Energy Metering IC with Per Phase Information Driver. + To compile this driver as a module, choose M here: the + module will be called ade7758. + config ADE7759 tristate "Analog Devices ADE7759 Active Energy Metering IC Driver" depends on SPI @@ -33,6 +42,9 @@ config ADE7759 Say yes here to build support for Analog Devices ADE7758 Active Energy Metering IC with di/dt Sensor Interface. + To compile this driver as a module, choose M here: the + module will be called ade7759. + config ADE7854 tristate "Analog Devices ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver" depends on SPI || I2C @@ -40,6 +52,9 @@ config ADE7854 Say yes here to build support for Analog Devices ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver. + To compile this driver as a module, choose M here: the + module will be called ade7854. + config ADE7854_I2C tristate "support I2C bus connection" depends on ADE7854 && I2C diff --git a/drivers/staging/iio/trigger/Kconfig b/drivers/staging/iio/trigger/Kconfig index 2fd18c60323d..710a2f3e787e 100644 --- a/drivers/staging/iio/trigger/Kconfig +++ b/drivers/staging/iio/trigger/Kconfig @@ -1,4 +1,4 @@ -# + # # Industrial I/O standalone triggers # comment "Triggers - standalone" @@ -12,6 +12,9 @@ config IIO_PERIODIC_RTC_TRIGGER Provides support for using periodic capable real time clocks as IIO triggers. + To compile this driver as a module, choose M here: the + module will be called iio-trig-periodic-rtc. + config IIO_BFIN_TMR_TRIGGER tristate "Blackfin TIMER trigger" depends on BLACKFIN diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c index 82c2e6d3f5a7..a24caf73ae0b 100644 --- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c +++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c @@ -72,7 +72,8 @@ static ssize_t iio_trig_periodic_write_freq(struct device *dev, if (val > 0) { ret = rtc_irq_set_freq(trig_info->rtc, &trig_info->task, val); if (ret == 0 && trig_info->state && trig_info->frequency == 0) - ret = rtc_irq_set_state(trig_info->rtc, &trig_info->task, 1); + ret = rtc_irq_set_state(trig_info->rtc, + &trig_info->task, 1); } else if (val == 0) { ret = rtc_irq_set_state(trig_info->rtc, &trig_info->task, 0); } else diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h index 8888b2756174..2e5a9e5965b1 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h @@ -242,18 +242,6 @@ do { \ #define LCONSOLE_EMERG(format, ...) CDEBUG(D_CONSOLE | D_EMERG, format, ## __VA_ARGS__) -void libcfs_log_goto(struct libcfs_debug_msg_data *, const char *, long_ptr_t); -#define GOTO(label, rc) \ -do { \ - if (cfs_cdebug_show(D_TRACE, DEBUG_SUBSYSTEM)) { \ - LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_TRACE, NULL); \ - libcfs_log_goto(&msgdata, #label, (long_ptr_t)(rc)); \ - } else { \ - (void)(rc); \ - } \ - goto label; \ -} while (0) - int libcfs_debug_msg(struct libcfs_debug_msg_data *msgdata, const char *format1, ...) __attribute__ ((format (printf, 2, 3))); diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 8f5cdd584f85..62b575deac3a 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -930,8 +930,7 @@ kiblnd_close_peer_conns_locked (kib_peer_t *peer, int why) list_for_each_safe (ctmp, cnxt, &peer->ibp_conns) { conn = list_entry(ctmp, kib_conn_t, ibc_list); - CDEBUG(D_NET, "Closing conn -> %s, " - "version: %x, reason: %d\n", + CDEBUG(D_NET, "Closing conn -> %s, version: %x, reason: %d\n", libcfs_nid2str(peer->ibp_nid), conn->ibc_version, why); @@ -958,8 +957,7 @@ kiblnd_close_stale_conns_locked (kib_peer_t *peer, conn->ibc_incarnation == incarnation) continue; - CDEBUG(D_NET, "Closing stale conn -> %s version: %x, " - "incarnation:%#llx(%x, %#llx)\n", + CDEBUG(D_NET, "Closing stale conn -> %s version: %x, incarnation:%#llx(%x, %#llx)\n", libcfs_nid2str(peer->ibp_nid), conn->ibc_version, conn->ibc_incarnation, version, incarnation); @@ -1599,8 +1597,7 @@ kiblnd_fmr_pool_map(kib_fmr_poolset_t *fps, __u64 *pages, int npages, if (fps->fps_increasing) { spin_unlock(&fps->fps_lock); - CDEBUG(D_NET, "Another thread is allocating new " - "FMR pool, waiting for her to complete\n"); + CDEBUG(D_NET, "Another thread is allocating new FMR pool, waiting for her to complete\n"); schedule(); goto again; @@ -1801,8 +1798,7 @@ kiblnd_pool_alloc_node(kib_poolset_t *ps) if (ps->ps_increasing) { /* another thread is allocating a new pool */ spin_unlock(&ps->ps_lock); - CDEBUG(D_NET, "Another thread is allocating new " - "%s pool, waiting for her to complete\n", + CDEBUG(D_NET, "Another thread is allocating new %s pool, waiting for her to complete\n", ps->ps_name); schedule(); goto again; @@ -2411,7 +2407,7 @@ kiblnd_hdev_setup_mrs(kib_hca_dev_t *hdev) goto out; } - mr_size = (1ULL << hdev->ibh_mr_shift); + mr_size = 1ULL << hdev->ibh_mr_shift; mm_size = (unsigned long)high_memory - PAGE_OFFSET; hdev->ibh_nmrs = (int)((mm_size + mr_size - 1) >> hdev->ibh_mr_shift); @@ -3081,7 +3077,7 @@ kiblnd_startup (lnet_ni_t *ni) LIBCFS_ALLOC(net, sizeof(*net)); ni->ni_data = net; if (net == NULL) - goto failed; + goto net_failed; do_gettimeofday(&tv); net->ibn_incarnation = (((__u64)tv.tv_sec) * 1000000) + tv.tv_usec; @@ -3147,6 +3143,7 @@ failed: if (net->ibn_dev == NULL && ibdev != NULL) kiblnd_destroy_dev(ibdev); +net_failed: kiblnd_shutdown(ni); CDEBUG(D_NET, "kiblnd_startup failed\n"); diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index 14c9c8d18d02..b48d7edf5669 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -1116,8 +1116,7 @@ kiblnd_init_rdma (kib_conn_t *conn, kib_tx_t *tx, int type, } if (tx->tx_nwrq == IBLND_RDMA_FRAGS(conn->ibc_version)) { - CERROR("RDMA too fragmented for %s (%d): " - "%d/%d src %d/%d dst frags\n", + CERROR("RDMA too fragmented for %s (%d): %d/%d src %d/%d dst frags\n", libcfs_nid2str(conn->ibc_peer->ibp_nid), IBLND_RDMA_FRAGS(conn->ibc_version), srcidx, srcrd->rd_nfrags, @@ -2254,8 +2253,8 @@ kiblnd_passive_connect (struct rdma_cm_id *cmid, void *priv, int priv_nob) if (ni == NULL || /* no matching net */ ni->ni_nid != reqmsg->ibm_dstnid || /* right NET, wrong NID! */ net->ibn_dev != ibdev) { /* wrong device */ - CERROR("Can't accept %s on %s (%s:%d:%pI4h): " - "bad dst nid %s\n", libcfs_nid2str(nid), + CERROR("Can't accept %s on %s (%s:%d:%pI4h): bad dst nid %s\n", + libcfs_nid2str(nid), ni == NULL ? "NA" : libcfs_nid2str(ni->ni_nid), ibdev->ibd_ifname, ibdev->ibd_nnets, &ibdev->ibd_ifip, @@ -2295,8 +2294,7 @@ kiblnd_passive_connect (struct rdma_cm_id *cmid, void *priv, int priv_nob) if (reqmsg->ibm_u.connparams.ibcp_max_frags != IBLND_RDMA_FRAGS(version)) { - CERROR("Can't accept %s(version %x): " - "incompatible max_frags %d (%d wanted)\n", + CERROR("Can't accept %s(version %x): incompatible max_frags %d (%d wanted)\n", libcfs_nid2str(nid), version, reqmsg->ibm_u.connparams.ibcp_max_frags, IBLND_RDMA_FRAGS(version)); @@ -2502,8 +2500,7 @@ kiblnd_reconnect (kib_conn_t *conn, int version, break; } - CNETERR("%s: retrying (%s), %x, %x, " - "queue_dep: %d, max_frag: %d, msg_size: %d\n", + CNETERR("%s: retrying (%s), %x, %x, queue_dep: %d, max_frag: %d, msg_size: %d\n", libcfs_nid2str(peer->ibp_nid), reason, IBLND_MSG_VERSION, version, cp != NULL? cp->ibcp_queue_depth :IBLND_MSG_QUEUE_SIZE(version), @@ -2679,8 +2676,7 @@ kiblnd_check_connreply (kib_conn_t *conn, void *priv, int priv_nob) } if (ver != msg->ibm_version) { - CERROR("%s replied version %x is different with " - "requested version %x\n", + CERROR("%s replied version %x is different with requested version %x\n", libcfs_nid2str(peer->ibp_nid), msg->ibm_version, ver); rc = -EPROTO; goto failed; @@ -2724,8 +2720,7 @@ kiblnd_check_connreply (kib_conn_t *conn, void *priv, int priv_nob) read_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags); if (rc != 0) { - CERROR("Bad connection reply from %s, rc = %d, " - "version: %x max_frags: %d\n", + CERROR("Bad connection reply from %s, rc = %d, version: %x max_frags: %d\n", libcfs_nid2str(peer->ibp_nid), rc, msg->ibm_version, msg->ibm_u.connparams.ibcp_max_frags); goto failed; @@ -3060,8 +3055,7 @@ kiblnd_check_conns (int idx) } if (timedout) { - CERROR("Timed out RDMA with %s (%lu): " - "c: %u, oc: %u, rc: %u\n", + CERROR("Timed out RDMA with %s (%lu): c: %u, oc: %u, rc: %u\n", libcfs_nid2str(peer->ibp_nid), cfs_duration_sec(cfs_time_current() - peer->ibp_last_alive), @@ -3334,10 +3328,8 @@ kiblnd_scheduler(void *arg) rc = cfs_cpt_bind(lnet_cpt_table(), sched->ibs_cpt); if (rc != 0) { - CWARN("Failed to bind on CPT %d, please verify whether " - "all CPUs are healthy and reload modules if necessary, " - "otherwise your system might under risk of low " - "performance\n", sched->ibs_cpt); + CWARN("Failed to bind on CPT %d, please verify whether all CPUs are healthy and reload modules if necessary, otherwise your system might under risk of low performance\n", + sched->ibs_cpt); } spin_lock_irqsave(&sched->ibs_lock, flags); @@ -3369,8 +3361,7 @@ kiblnd_scheduler(void *arg) rc = ib_req_notify_cq(conn->ibc_cq, IB_CQ_NEXT_COMP); if (rc < 0) { - CWARN("%s: ib_req_notify_cq failed: %d, " - "closing connection\n", + CWARN("%s: ib_req_notify_cq failed: %d, closing connection\n", libcfs_nid2str(conn->ibc_peer->ibp_nid), rc); kiblnd_close_conn(conn, -EIO); kiblnd_conn_decref(conn); @@ -3383,8 +3374,7 @@ kiblnd_scheduler(void *arg) } if (rc < 0) { - CWARN("%s: ib_poll_cq failed: %d, " - "closing connection\n", + CWARN("%s: ib_poll_cq failed: %d, closing connection\n", libcfs_nid2str(conn->ibc_peer->ibp_nid), rc); kiblnd_close_conn(conn, -EIO); diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c index cefdfb6b1bec..8b4a8e9a29b4 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c @@ -222,8 +222,7 @@ kiblnd_tunables_init (void) *kiblnd_tunables.kib_concurrent_sends = *kiblnd_tunables.kib_peertxcredits / 2; if (*kiblnd_tunables.kib_concurrent_sends < *kiblnd_tunables.kib_peertxcredits) { - CWARN("Concurrent sends %d is lower than message queue size: %d, " - "performance may drop slightly.\n", + CWARN("Concurrent sends %d is lower than message queue size: %d, performance may drop slightly.\n", *kiblnd_tunables.kib_concurrent_sends, *kiblnd_tunables.kib_peertxcredits); } diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 038854e8302f..9188b34e6948 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -337,8 +337,7 @@ ksocknal_associate_route_conn_locked(ksock_route_t *route, ksock_conn_t *conn) &route->ksnr_ipaddr, &conn->ksnc_myipaddr); } else { - CDEBUG(D_NET, "Rebinding %s %pI4h from " - "%pI4h to %pI4h\n", + CDEBUG(D_NET, "Rebinding %s %pI4h from %pI4h to %pI4h\n", libcfs_id2str(peer->ksnp_id), &route->ksnr_ipaddr, &route->ksnr_myipaddr, @@ -974,8 +973,7 @@ ksocknal_accept (lnet_ni_t *ni, struct socket *sock) LIBCFS_ALLOC(cr, sizeof(*cr)); if (cr == NULL) { - LCONSOLE_ERROR_MSG(0x12f, "Dropping connection request from " - "%pI4h: memory exhausted\n", + LCONSOLE_ERROR_MSG(0x12f, "Dropping connection request from %pI4h: memory exhausted\n", &peer_ip); return -ENOMEM; } @@ -1288,8 +1286,7 @@ ksocknal_create_conn (lnet_ni_t *ni, ksock_route_t *route, * socket callbacks. */ - CDEBUG(D_NET, "New conn %s p %d.x %pI4h -> %pI4h/%d" - " incarnation:%lld sched[%d:%d]\n", + CDEBUG(D_NET, "New conn %s p %d.x %pI4h -> %pI4h/%d incarnation:%lld sched[%d:%d]\n", libcfs_id2str(peerid), conn->ksnc_proto->pro_version, &conn->ksnc_myipaddr, &conn->ksnc_ipaddr, conn->ksnc_port, incarnation, cpt, @@ -1638,37 +1635,32 @@ ksocknal_destroy_conn (ksock_conn_t *conn) case SOCKNAL_RX_LNET_PAYLOAD: last_rcv = conn->ksnc_rx_deadline - cfs_time_seconds(*ksocknal_tunables.ksnd_timeout); - CERROR("Completing partial receive from %s[%d]" - ", ip %pI4h:%d, with error, wanted: %d, left: %d, " - "last alive is %ld secs ago\n", + CERROR("Completing partial receive from %s[%d], ip %pI4h:%d, with error, wanted: %d, left: %d, last alive is %ld secs ago\n", libcfs_id2str(conn->ksnc_peer->ksnp_id), conn->ksnc_type, &conn->ksnc_ipaddr, conn->ksnc_port, conn->ksnc_rx_nob_wanted, conn->ksnc_rx_nob_left, cfs_duration_sec(cfs_time_sub(cfs_time_current(), - last_rcv))); + last_rcv))); lnet_finalize (conn->ksnc_peer->ksnp_ni, conn->ksnc_cookie, -EIO); break; case SOCKNAL_RX_LNET_HEADER: if (conn->ksnc_rx_started) - CERROR("Incomplete receive of lnet header from %s" - ", ip %pI4h:%d, with error, protocol: %d.x.\n", + CERROR("Incomplete receive of lnet header from %s, ip %pI4h:%d, with error, protocol: %d.x.\n", libcfs_id2str(conn->ksnc_peer->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port, conn->ksnc_proto->pro_version); break; case SOCKNAL_RX_KSM_HEADER: if (conn->ksnc_rx_started) - CERROR("Incomplete receive of ksock message from %s" - ", ip %pI4h:%d, with error, protocol: %d.x.\n", + CERROR("Incomplete receive of ksock message from %s, ip %pI4h:%d, with error, protocol: %d.x.\n", libcfs_id2str(conn->ksnc_peer->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port, conn->ksnc_proto->pro_version); break; case SOCKNAL_RX_SLOP: if (conn->ksnc_rx_started) - CERROR("Incomplete receive of slops from %s" - ", ip %pI4h:%d, with error\n", + CERROR("Incomplete receive of slops from %s, ip %pI4h:%d, with error\n", libcfs_id2str(conn->ksnc_peer->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port); break; @@ -2348,16 +2340,11 @@ ksocknal_base_shutdown(void) static __u64 ksocknal_new_incarnation (void) { - struct timeval tv; /* The incarnation number is the time this module loaded and it - * identifies this particular instance of the socknal. Hopefully - * we won't be able to reboot more frequently than 1MHz for the - * foreseeable future :) */ - - do_gettimeofday(&tv); - - return (((__u64)tv.tv_sec) * 1000000) + tv.tv_usec; + * identifies this particular instance of the socknal. + */ + return ktime_get_ns(); } static int @@ -2516,22 +2503,21 @@ ksocknal_debug_peerhash (lnet_ni_t *ni) ksock_route_t *route; ksock_conn_t *conn; - CWARN ("Active peer on shutdown: %s, ref %d, scnt %d, " - "closing %d, accepting %d, err %d, zcookie %llu, " - "txq %d, zc_req %d\n", libcfs_id2str(peer->ksnp_id), - atomic_read(&peer->ksnp_refcount), - peer->ksnp_sharecount, peer->ksnp_closing, - peer->ksnp_accepting, peer->ksnp_error, - peer->ksnp_zc_next_cookie, - !list_empty(&peer->ksnp_tx_queue), - !list_empty(&peer->ksnp_zc_req_list)); + CWARN("Active peer on shutdown: %s, ref %d, scnt %d, closing %d, accepting %d, err %d, zcookie %llu, txq %d, zc_req %d\n", + libcfs_id2str(peer->ksnp_id), + atomic_read(&peer->ksnp_refcount), + peer->ksnp_sharecount, peer->ksnp_closing, + peer->ksnp_accepting, peer->ksnp_error, + peer->ksnp_zc_next_cookie, + !list_empty(&peer->ksnp_tx_queue), + !list_empty(&peer->ksnp_zc_req_list)); list_for_each (tmp, &peer->ksnp_routes) { route = list_entry(tmp, ksock_route_t, ksnr_list); - CWARN ("Route: ref %d, schd %d, conn %d, cnted %d, " - "del %d\n", atomic_read(&route->ksnr_refcount), - route->ksnr_scheduled, route->ksnr_connecting, - route->ksnr_connected, route->ksnr_deleted); + CWARN("Route: ref %d, schd %d, conn %d, cnted %d, del %d\n", + atomic_read(&route->ksnr_refcount), + route->ksnr_scheduled, route->ksnr_connecting, + route->ksnr_connected, route->ksnr_deleted); } list_for_each (tmp, &peer->ksnp_conns) { diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c index d29f5f134b89..e6c1d3647952 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c @@ -551,19 +551,16 @@ ksocknal_process_transmit (ksock_conn_t *conn, ksock_tx_t *tx) if (!conn->ksnc_closing) { switch (rc) { case -ECONNRESET: - LCONSOLE_WARN("Host %pI4h reset our connection " - "while we were sending data; it may have " - "rebooted.\n", + LCONSOLE_WARN("Host %pI4h reset our connection while we were sending data; it may have rebooted.\n", &conn->ksnc_ipaddr); break; default: - LCONSOLE_WARN("There was an unexpected network error " - "while writing to %pI4h: %d.\n", + LCONSOLE_WARN("There was an unexpected network error while writing to %pI4h: %d.\n", &conn->ksnc_ipaddr, rc); break; } - CDEBUG(D_NET, "[%p] Error %d on write to %s" - " ip %pI4h:%d\n", conn, rc, + CDEBUG(D_NET, "[%p] Error %d on write to %s ip %pI4h:%d\n", + conn, rc, libcfs_id2str(conn->ksnc_peer->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port); @@ -799,8 +796,7 @@ ksocknal_find_connectable_route_locked (ksock_peer_t *peer) if (!(route->ksnr_retry_interval == 0 || /* first attempt */ cfs_time_aftereq(now, route->ksnr_timeout))) { CDEBUG(D_NET, - "Too soon to retry route %pI4h " - "(cnted %d, interval %ld, %ld secs later)\n", + "Too soon to retry route %pI4h (cnted %d, interval %ld, %ld secs later)\n", &route->ksnr_ipaddr, route->ksnr_connected, route->ksnr_retry_interval, @@ -874,8 +870,8 @@ ksocknal_launch_packet (lnet_ni_t *ni, ksock_tx_t *tx, lnet_process_id_t id) write_unlock_bh(g_lock); if ((id.pid & LNET_PID_USERFLAG) != 0) { - CERROR("Refusing to create a connection to " - "userspace process %s\n", libcfs_id2str(id)); + CERROR("Refusing to create a connection to userspace process %s\n", + libcfs_id2str(id)); return -EHOSTUNREACH; } @@ -1132,18 +1128,17 @@ ksocknal_process_receive (ksock_conn_t *conn) LASSERT (rc != -EAGAIN); if (rc == 0) - CDEBUG(D_NET, "[%p] EOF from %s" - " ip %pI4h:%d\n", conn, - libcfs_id2str(conn->ksnc_peer->ksnp_id), - &conn->ksnc_ipaddr, - conn->ksnc_port); + CDEBUG(D_NET, "[%p] EOF from %s ip %pI4h:%d\n", + conn, + libcfs_id2str(conn->ksnc_peer->ksnp_id), + &conn->ksnc_ipaddr, + conn->ksnc_port); else if (!conn->ksnc_closing) - CERROR("[%p] Error %d on read from %s" - " ip %pI4h:%d\n", - conn, rc, - libcfs_id2str(conn->ksnc_peer->ksnp_id), - &conn->ksnc_ipaddr, - conn->ksnc_port); + CERROR("[%p] Error %d on read from %s ip %pI4h:%d\n", + conn, rc, + libcfs_id2str(conn->ksnc_peer->ksnp_id), + &conn->ksnc_ipaddr, + conn->ksnc_port); /* it's not an error if conn is being closed */ ksocknal_close_conn_and_siblings (conn, @@ -1724,10 +1719,10 @@ ksocknal_recv_hello (lnet_ni_t *ni, ksock_conn_t *conn, hello->kshm_magic != __swab32(LNET_PROTO_MAGIC) && hello->kshm_magic != le32_to_cpu (LNET_PROTO_TCP_MAGIC)) { /* Unexpected magic! */ - CERROR("Bad magic(1) %#08x (%#08x expected) from " - "%pI4h\n", __cpu_to_le32 (hello->kshm_magic), - LNET_PROTO_TCP_MAGIC, - &conn->ksnc_ipaddr); + CERROR("Bad magic(1) %#08x (%#08x expected) from %pI4h\n", + __cpu_to_le32 (hello->kshm_magic), + LNET_PROTO_TCP_MAGIC, + &conn->ksnc_ipaddr); return -EPROTO; } @@ -1755,10 +1750,9 @@ ksocknal_recv_hello (lnet_ni_t *ni, ksock_conn_t *conn, ksocknal_send_hello(ni, conn, ni->ni_nid, hello); } - CERROR("Unknown protocol version (%d.x expected)" - " from %pI4h\n", - conn->ksnc_proto->pro_version, - &conn->ksnc_ipaddr); + CERROR("Unknown protocol version (%d.x expected) from %pI4h\n", + conn->ksnc_proto->pro_version, + &conn->ksnc_ipaddr); return -EPROTO; } @@ -1778,8 +1772,8 @@ ksocknal_recv_hello (lnet_ni_t *ni, ksock_conn_t *conn, *incarnation = hello->kshm_src_incarnation; if (hello->kshm_src_nid == LNET_NID_ANY) { - CERROR("Expecting a HELLO hdr with a NID, but got LNET_NID_ANY" - "from %pI4h\n", &conn->ksnc_ipaddr); + CERROR("Expecting a HELLO hdr with a NID, but got LNET_NID_ANY from %pI4h\n", + &conn->ksnc_ipaddr); return -EPROTO; } @@ -1810,10 +1804,7 @@ ksocknal_recv_hello (lnet_ni_t *ni, ksock_conn_t *conn, if (peerid->pid != recv_id.pid || peerid->nid != recv_id.nid) { - LCONSOLE_ERROR_MSG(0x130, "Connected successfully to %s on host" - " %pI4h, but they claimed they were " - "%s; please check your Lustre " - "configuration.\n", + LCONSOLE_ERROR_MSG(0x130, "Connected successfully to %s on host %pI4h, but they claimed they were %s; please check your Lustre configuration.\n", libcfs_id2str(*peerid), &conn->ksnc_ipaddr, libcfs_id2str(recv_id)); @@ -2199,8 +2190,7 @@ ksocknal_connd (void *arg) if (ksocknal_connect(route)) { /* consecutive retry */ if (cons_retry++ > SOCKNAL_INSANITY_RECONN) { - CWARN("massive consecutive " - "re-connecting to %pI4h\n", + CWARN("massive consecutive re-connecting to %pI4h\n", &route->ksnr_ipaddr); cons_retry = 0; } @@ -2264,25 +2254,20 @@ ksocknal_find_timed_out_conn (ksock_peer_t *peer) switch (error) { case ECONNRESET: - CNETERR("A connection with %s " - "(%pI4h:%d) was reset; " - "it may have rebooted.\n", + CNETERR("A connection with %s (%pI4h:%d) was reset; it may have rebooted.\n", libcfs_id2str(peer->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port); break; case ETIMEDOUT: - CNETERR("A connection with %s " - "(%pI4h:%d) timed out; the " - "network or node may be down.\n", + CNETERR("A connection with %s (%pI4h:%d) timed out; the network or node may be down.\n", libcfs_id2str(peer->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port); break; default: - CNETERR("An unexpected network error %d " - "occurred with %s " - "(%pI4h:%d\n", error, + CNETERR("An unexpected network error %d occurred with %s (%pI4h:%d\n", + error, libcfs_id2str(peer->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port); @@ -2297,8 +2282,7 @@ ksocknal_find_timed_out_conn (ksock_peer_t *peer) conn->ksnc_rx_deadline)) { /* Timed out incomplete incoming message */ ksocknal_conn_addref(conn); - CNETERR("Timeout receiving from %s (%pI4h:%d), " - "state %d wanted %d left %d\n", + CNETERR("Timeout receiving from %s (%pI4h:%d), state %d wanted %d left %d\n", libcfs_id2str(peer->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port, @@ -2315,8 +2299,7 @@ ksocknal_find_timed_out_conn (ksock_peer_t *peer) /* Timed out messages queued for sending or * buffered in the socket's send buffer */ ksocknal_conn_addref(conn); - CNETERR("Timeout sending data to %s (%pI4h:%d) " - "the network or that node may be down.\n", + CNETERR("Timeout sending data to %s (%pI4h:%d) the network or that node may be down.\n", libcfs_id2str(peer->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port); @@ -2500,9 +2483,7 @@ ksocknal_check_peer_timeouts (int idx) spin_unlock(&peer->ksnp_lock); read_unlock(&ksocknal_data.ksnd_global_lock); - CERROR("Total %d stale ZC_REQs for peer %s detected; the " - "oldest(%p) timed out %ld secs ago, " - "resid: %d, wmem: %d\n", + CERROR("Total %d stale ZC_REQs for peer %s detected; the oldest(%p) timed out %ld secs ago, resid: %d, wmem: %d\n", n, libcfs_nid2str(peer->ksnp_id.nid), tx, cfs_duration_sec(cfs_time_current() - deadline), resid, conn->ksnc_sock->sk->sk_wmem_queued); diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c index 9dde548070af..ea9d80f40cab 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c @@ -515,8 +515,8 @@ ksocknal_send_hello_v1 (ksock_conn_t *conn, ksock_hello_msg_t *hello) hello->kshm_nips * sizeof(__u32), lnet_acceptor_timeout()); if (rc != 0) { - CNETERR("Error %d sending HELLO payload (%d)" - " to %pI4h/%d\n", rc, hello->kshm_nips, + CNETERR("Error %d sending HELLO payload (%d) to %pI4h/%d\n", + rc, hello->kshm_nips, &conn->ksnc_ipaddr, conn->ksnc_port); } out: @@ -560,8 +560,8 @@ ksocknal_send_hello_v2 (ksock_conn_t *conn, ksock_hello_msg_t *hello) hello->kshm_nips * sizeof(__u32), lnet_acceptor_timeout()); if (rc != 0) { - CNETERR("Error %d sending HELLO payload (%d)" - " to %pI4h/%d\n", rc, hello->kshm_nips, + CNETERR("Error %d sending HELLO payload (%d) to %pI4h/%d\n", + rc, hello->kshm_nips, &conn->ksnc_ipaddr, conn->ksnc_port); } @@ -595,10 +595,9 @@ ksocknal_recv_hello_v1(ksock_conn_t *conn, ksock_hello_msg_t *hello, /* ...and check we got what we expected */ if (hdr->type != cpu_to_le32 (LNET_MSG_HELLO)) { - CERROR("Expecting a HELLO hdr," - " but got type %d from %pI4h\n", - le32_to_cpu (hdr->type), - &conn->ksnc_ipaddr); + CERROR("Expecting a HELLO hdr, but got type %d from %pI4h\n", + le32_to_cpu(hdr->type), + &conn->ksnc_ipaddr); rc = -EPROTO; goto out; } diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 60bc2ae4fdf1..faceb9505d84 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -37,6 +37,7 @@ #define DEBUG_SUBSYSTEM S_LNET #include "../../include/linux/lnet/lib-lnet.h" #include <linux/log2.h> +#include <linux/ktime.h> #define D_LNI D_CONSOLE @@ -276,7 +277,7 @@ lnet_find_lnd_by_type(int type) struct list_head *tmp; /* holding lnd mutex */ - list_for_each (tmp, &the_lnet.ln_lnds) { + list_for_each(tmp, &the_lnet.ln_lnds) { lnd = list_entry(tmp, lnd_t, lnd_list); if ((int)lnd->lnd_type == type) @@ -417,17 +418,9 @@ static __u64 lnet_create_interface_cookie(void) { /* NB the interface cookie in wire handles guards against delayed - * replies and ACKs appearing valid after reboot. Initialisation time, - * even if it's only implemented to millisecond resolution is probably - * easily good enough. */ - struct timeval tv; - __u64 cookie; - - do_gettimeofday(&tv); - cookie = tv.tv_sec; - cookie *= 1000000; - cookie += tv.tv_usec; - return cookie; + * replies and ACKs appearing valid after reboot. + */ + return ktime_get_ns(); } static char * @@ -1652,7 +1645,6 @@ lnet_destroy_ping_info(void) offsetof(lnet_ping_info_t, pi_ni[the_lnet.ln_ping_info->pi_nnis])); the_lnet.ln_ping_info = NULL; - return; } int diff --git a/drivers/staging/lustre/lnet/lnet/lib-md.c b/drivers/staging/lustre/lnet/lnet/lib-md.c index e4d906a65635..3225c069637d 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-md.c +++ b/drivers/staging/lustre/lnet/lnet/lib-md.c @@ -218,7 +218,7 @@ lnet_md_deconstruct(lnet_libmd_t *lmd, lnet_md_t *umd) lnet_eq2handle(&umd->eq_handle, lmd->md_eq); } -int +static int lnet_md_validate(lnet_md_t *umd) { if (umd->start == NULL && umd->length != 0) { diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 4b9567d67f33..c8c1ed84fe5c 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -561,7 +561,7 @@ lnet_extract_kiov(int dst_niov, lnet_kiov_t *dst, } EXPORT_SYMBOL(lnet_extract_kiov); -void +static void lnet_ni_recv(lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed, unsigned int offset, unsigned int mlen, unsigned int rlen) { @@ -599,7 +599,7 @@ lnet_ni_recv(lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed, lnet_finalize(ni, msg, rc); } -void +static void lnet_setpayloadbuffer(lnet_msg_t *msg) { lnet_libmd_t *md = msg->msg_md; @@ -639,7 +639,7 @@ lnet_prep_send(lnet_msg_t *msg, int type, lnet_process_id_t target, msg->msg_hdr.payload_length = cpu_to_le32(len); } -void +static void lnet_ni_send(lnet_ni_t *ni, lnet_msg_t *msg) { void *priv = msg->msg_private; @@ -654,7 +654,7 @@ lnet_ni_send(lnet_ni_t *ni, lnet_msg_t *msg) lnet_finalize(ni, msg, rc); } -int +static int lnet_ni_eager_recv(lnet_ni_t *ni, lnet_msg_t *msg) { int rc; @@ -668,8 +668,7 @@ lnet_ni_eager_recv(lnet_ni_t *ni, lnet_msg_t *msg) rc = (ni->ni_lnd->lnd_eager_recv)(ni, msg->msg_private, msg, &msg->msg_private); if (rc != 0) { - CERROR("recv from %s / send to %s aborted: " - "eager_recv failed %d\n", + CERROR("recv from %s / send to %s aborted: eager_recv failed %d\n", libcfs_nid2str(msg->msg_rxpeer->lp_nid), libcfs_id2str(msg->msg_target), rc); LASSERT(rc < 0); /* required by my callers */ @@ -679,7 +678,7 @@ lnet_ni_eager_recv(lnet_ni_t *ni, lnet_msg_t *msg) } /* NB: caller shall hold a ref on 'lp' as I'd drop lnet_net_lock */ -void +static void lnet_ni_query_locked(lnet_ni_t *ni, lnet_peer_t *lp) { unsigned long last_alive = 0; @@ -731,7 +730,7 @@ lnet_peer_is_alive(lnet_peer_t *lp, unsigned long now) /* NB: returns 1 when alive, 0 when dead, negative when error; * may drop the lnet_net_lock */ -int +static int lnet_peer_alive_locked(lnet_peer_t *lp) { unsigned long now = cfs_time_current(); @@ -753,8 +752,7 @@ lnet_peer_alive_locked(lnet_peer_t *lp) if (time_before(now, next_query)) { if (lp->lp_alive) - CWARN("Unexpected aliveness of peer %s: " - "%d < %d (%d/%d)\n", + CWARN("Unexpected aliveness of peer %s: %d < %d (%d/%d)\n", libcfs_nid2str(lp->lp_nid), (int)now, (int)next_query, lnet_queryinterval, @@ -817,8 +815,7 @@ lnet_post_send_locked(lnet_msg_t *msg, int do_send) (msg->msg_md->md_flags & LNET_MD_FLAG_ABORTED) != 0) { lnet_net_unlock(cpt); - CNETERR("Aborting message for %s: LNetM[DE]Unlink() already " - "called on the MD/ME.\n", + CNETERR("Aborting message for %s: LNetM[DE]Unlink() already called on the MD/ME.\n", libcfs_id2str(msg->msg_target)); if (do_send) lnet_finalize(ni, msg, -ECANCELED); @@ -871,7 +868,7 @@ lnet_post_send_locked(lnet_msg_t *msg, int do_send) } -lnet_rtrbufpool_t * +static lnet_rtrbufpool_t * lnet_msg2bufpool(lnet_msg_t *msg) { lnet_rtrbufpool_t *rbp; @@ -891,7 +888,7 @@ lnet_msg2bufpool(lnet_msg_t *msg) return rbp; } -int +static int lnet_post_routed_recv_locked(lnet_msg_t *msg, int do_recv) { /* lnet_parse is going to lnet_net_unlock immediately after this, so it @@ -1220,8 +1217,8 @@ lnet_send(lnet_nid_t src_nid, lnet_msg_t *msg, lnet_nid_t rtr_nid) src_ni = lnet_nid2ni_locked(src_nid, cpt); if (src_ni == NULL) { lnet_net_unlock(cpt); - LCONSOLE_WARN("Can't send to %s: src %s is not a " - "local nid\n", libcfs_nid2str(dst_nid), + LCONSOLE_WARN("Can't send to %s: src %s is not a local nid\n", + libcfs_nid2str(dst_nid), libcfs_nid2str(src_nid)); return -EINVAL; } @@ -1283,8 +1280,7 @@ lnet_send(lnet_nid_t src_nid, lnet_msg_t *msg, lnet_nid_t rtr_nid) lnet_ni_decref_locked(src_ni, cpt); lnet_net_unlock(cpt); - LCONSOLE_WARN("No route to %s via %s " - "(all routers down)\n", + LCONSOLE_WARN("No route to %s via %s (all routers down)\n", libcfs_id2str(msg->msg_target), libcfs_nid2str(src_nid)); return -EHOSTUNREACH; @@ -1676,8 +1672,7 @@ lnet_print_hdr(lnet_hdr_t *hdr) break; case LNET_MSG_PUT: - CWARN(" Ptl index %d, ack md %#llx.%#llx, " - "match bits %llu\n", + CWARN(" Ptl index %d, ack md %#llx.%#llx, match bits %llu\n", hdr->msg.put.ptl_index, hdr->msg.put.ack_wmd.wh_interface_cookie, hdr->msg.put.ack_wmd.wh_object_cookie, @@ -1688,8 +1683,8 @@ lnet_print_hdr(lnet_hdr_t *hdr) break; case LNET_MSG_GET: - CWARN(" Ptl index %d, return md %#llx.%#llx, " - "match bits %llu\n", hdr->msg.get.ptl_index, + CWARN(" Ptl index %d, return md %#llx.%#llx, match bits %llu\n", + hdr->msg.get.ptl_index, hdr->msg.get.return_wmd.wh_interface_cookie, hdr->msg.get.return_wmd.wh_object_cookie, hdr->msg.get.match_bits); @@ -1699,16 +1694,14 @@ lnet_print_hdr(lnet_hdr_t *hdr) break; case LNET_MSG_ACK: - CWARN(" dst md %#llx.%#llx, " - "manipulated length %d\n", + CWARN(" dst md %#llx.%#llx, manipulated length %d\n", hdr->msg.ack.dst_wmd.wh_interface_cookie, hdr->msg.ack.dst_wmd.wh_object_cookie, hdr->msg.ack.mlength); break; case LNET_MSG_REPLY: - CWARN(" dst md %#llx.%#llx, " - "length %d\n", + CWARN(" dst md %#llx.%#llx, length %d\n", hdr->msg.reply.dst_wmd.wh_interface_cookie, hdr->msg.reply.dst_wmd.wh_object_cookie, hdr->payload_length); @@ -1757,8 +1750,7 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid, case LNET_MSG_REPLY: if (payload_length > (__u32)(for_me ? LNET_MAX_PAYLOAD : LNET_MTU)) { - CERROR("%s, src %s: bad %s payload %d " - "(%d max expected)\n", + CERROR("%s, src %s: bad %s payload %d (%d max expected)\n", libcfs_nid2str(from_nid), libcfs_nid2str(src_nid), lnet_msgtyp2str(type), @@ -1794,40 +1786,36 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid, if (!for_me) { if (LNET_NIDNET(dest_nid) == LNET_NIDNET(ni->ni_nid)) { /* should have gone direct */ - CERROR("%s, src %s: Bad dest nid %s " - "(should have been sent direct)\n", - libcfs_nid2str(from_nid), - libcfs_nid2str(src_nid), - libcfs_nid2str(dest_nid)); + CERROR("%s, src %s: Bad dest nid %s (should have been sent direct)\n", + libcfs_nid2str(from_nid), + libcfs_nid2str(src_nid), + libcfs_nid2str(dest_nid)); return -EPROTO; } if (lnet_islocalnid(dest_nid)) { /* dest is another local NI; sender should have used * this node's NID on its own network */ - CERROR("%s, src %s: Bad dest nid %s " - "(it's my nid but on a different network)\n", - libcfs_nid2str(from_nid), - libcfs_nid2str(src_nid), - libcfs_nid2str(dest_nid)); + CERROR("%s, src %s: Bad dest nid %s (it's my nid but on a different network)\n", + libcfs_nid2str(from_nid), + libcfs_nid2str(src_nid), + libcfs_nid2str(dest_nid)); return -EPROTO; } if (rdma_req && type == LNET_MSG_GET) { - CERROR("%s, src %s: Bad optimized GET for %s " - "(final destination must be me)\n", - libcfs_nid2str(from_nid), - libcfs_nid2str(src_nid), - libcfs_nid2str(dest_nid)); + CERROR("%s, src %s: Bad optimized GET for %s (final destination must be me)\n", + libcfs_nid2str(from_nid), + libcfs_nid2str(src_nid), + libcfs_nid2str(dest_nid)); return -EPROTO; } if (!the_lnet.ln_routing) { - CERROR("%s, src %s: Dropping message for %s " - "(routing not enabled)\n", - libcfs_nid2str(from_nid), - libcfs_nid2str(src_nid), - libcfs_nid2str(dest_nid)); + CERROR("%s, src %s: Dropping message for %s (routing not enabled)\n", + libcfs_nid2str(from_nid), + libcfs_nid2str(src_nid), + libcfs_nid2str(dest_nid)); goto drop; } } @@ -1882,8 +1870,7 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid, rc = lnet_nid2peer_locked(&msg->msg_rxpeer, from_nid, cpt); if (rc != 0) { lnet_net_unlock(cpt); - CERROR("%s, src %s: Dropping %s " - "(error %d looking up sender)\n", + CERROR("%s, src %s: Dropping %s (error %d looking up sender)\n", libcfs_nid2str(from_nid), libcfs_nid2str(src_nid), lnet_msgtyp2str(type), rc); lnet_msg_free(msg); @@ -2003,12 +1990,11 @@ lnet_recv_delayed_msg_list(struct list_head *head) LASSERT(msg->msg_rxpeer != NULL); LASSERT(msg->msg_hdr.type == LNET_MSG_PUT); - CDEBUG(D_NET, "Resuming delayed PUT from %s portal %d " - "match %llu offset %d length %d.\n", - libcfs_id2str(id), msg->msg_hdr.msg.put.ptl_index, - msg->msg_hdr.msg.put.match_bits, - msg->msg_hdr.msg.put.offset, - msg->msg_hdr.payload_length); + CDEBUG(D_NET, "Resuming delayed PUT from %s portal %d match %llu offset %d length %d.\n", + libcfs_id2str(id), msg->msg_hdr.msg.put.ptl_index, + msg->msg_hdr.msg.put.match_bits, + msg->msg_hdr.msg.put.offset, + msg->msg_hdr.payload_length); lnet_recv_put(msg->msg_rxpeer->lp_ni, msg); } diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c index 720c73be4d3c..19ed696344fe 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c @@ -192,8 +192,7 @@ lnet_try_match_md(lnet_libmd_t *md, } /* Commit to this ME/MD */ - CDEBUG(D_NET, "Incoming %s index %x from %s of " - "length %d/%d into md %#llx [%d] + %d\n", + CDEBUG(D_NET, "Incoming %s index %x from %s of length %d/%d into md %#llx [%d] + %d\n", (info->mi_opc == LNET_MD_OP_PUT) ? "put" : "get", info->mi_portal, libcfs_id2str(info->mi_id), mlength, info->mi_rlength, md->md_lh.lh_cookie, md->md_niov, offset); diff --git a/drivers/staging/lustre/lnet/lnet/lo.c b/drivers/staging/lustre/lnet/lnet/lo.c index be31dfc5fa4b..17e1643fd675 100644 --- a/drivers/staging/lustre/lnet/lnet/lo.c +++ b/drivers/staging/lustre/lnet/lnet/lo.c @@ -35,7 +35,7 @@ #define DEBUG_SUBSYSTEM S_LNET #include "../../include/linux/lnet/lib-lnet.h" -int +static int lolnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg) { LASSERT(!lntmsg->msg_routing); @@ -44,7 +44,7 @@ lolnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg) return lnet_parse(ni, &lntmsg->msg_hdr, ni->ni_nid, lntmsg, 0); } -int +static int lolnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, int delayed, unsigned int niov, struct iovec *iov, lnet_kiov_t *kiov, @@ -86,7 +86,7 @@ lolnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, static int lolnd_instanced; -void +static void lolnd_shutdown(lnet_ni_t *ni) { CDEBUG(D_NET, "shutdown\n"); @@ -95,7 +95,7 @@ lolnd_shutdown(lnet_ni_t *ni) lolnd_instanced = 0; } -int +static int lolnd_startup(lnet_ni_t *ni) { LASSERT(ni->ni_lnd == &the_lolnd); diff --git a/drivers/staging/lustre/lnet/lnet/module.c b/drivers/staging/lustre/lnet/lnet/module.c index e84d59d23ae0..3c23677bc280 100644 --- a/drivers/staging/lustre/lnet/lnet/module.c +++ b/drivers/staging/lustre/lnet/lnet/module.c @@ -43,7 +43,7 @@ MODULE_PARM_DESC(config_on_load, "configure network at module load"); static struct mutex lnet_config_mutex; -int +static int lnet_configure(void *arg) { /* 'arg' only there so I can be passed to cfs_create_thread() */ @@ -63,7 +63,7 @@ lnet_configure(void *arg) return rc; } -int +static int lnet_unconfigure(void) { int refcount; @@ -83,7 +83,7 @@ lnet_unconfigure(void) return (refcount == 0) ? 0 : -EBUSY; } -int +static int lnet_ioctl(unsigned int cmd, struct libcfs_ioctl_data *data) { int rc; @@ -110,7 +110,7 @@ lnet_ioctl(unsigned int cmd, struct libcfs_ioctl_data *data) DECLARE_IOCTL_HANDLER(lnet_ioctl_handler, lnet_ioctl); -int +static int __init init_lnet(void) { int rc; @@ -135,7 +135,7 @@ init_lnet(void) return 0; } -void +static void __exit fini_lnet(void) { int rc; diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index b5b8fb576bfb..c667b5b76761 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -457,8 +457,7 @@ lnet_check_routes(void) lnet_net_unlock(cpt); - CERROR("Routes to %s via %s and %s not " - "supported\n", + CERROR("Routes to %s via %s and %s not supported\n", libcfs_net2str(net), libcfs_nid2str(nid1), libcfs_nid2str(nid2)); @@ -752,7 +751,7 @@ lnet_router_checker_event(lnet_event_t *event) lnet_net_unlock(lp->lp_cpt); } -void +static void lnet_wait_known_routerstate(void) { lnet_peer_t *rtr; @@ -784,7 +783,7 @@ lnet_wait_known_routerstate(void) } } -void +static void lnet_update_ni_status_locked(void) { lnet_ni_t *ni; @@ -824,7 +823,7 @@ lnet_update_ni_status_locked(void) } } -void +static void lnet_destroy_rc_data(lnet_rc_data_t *rcd) { LASSERT(list_empty(&rcd->rcd_list)); @@ -845,7 +844,7 @@ lnet_destroy_rc_data(lnet_rc_data_t *rcd) LIBCFS_FREE(rcd, sizeof(*rcd)); } -lnet_rc_data_t * +static lnet_rc_data_t * lnet_create_rc_data_locked(lnet_peer_t *gateway) { lnet_rc_data_t *rcd = NULL; @@ -959,8 +958,7 @@ lnet_ping_router_locked (lnet_peer_t *rtr) secs = lnet_router_check_interval(rtr); CDEBUG(D_NET, - "rtr %s %d: deadline %lu ping_notsent %d alive %d " - "alive_count %d lp_ping_timestamp %lu\n", + "rtr %s %d: deadline %lu ping_notsent %d alive %d alive_count %d lp_ping_timestamp %lu\n", libcfs_nid2str(rtr->lp_nid), secs, rtr->lp_ping_deadline, rtr->lp_ping_notsent, rtr->lp_alive, rtr->lp_alive_count, rtr->lp_ping_timestamp); @@ -1010,9 +1008,7 @@ lnet_router_checker_start(void) if (check_routers_before_use && dead_router_check_interval <= 0) { - LCONSOLE_ERROR_MSG(0x10a, "'dead_router_check_interval' must be" - " set if 'check_routers_before_use' is set" - "\n"); + LCONSOLE_ERROR_MSG(0x10a, "'dead_router_check_interval' must be set if 'check_routers_before_use' is set\n"); return -EINVAL; } @@ -1224,7 +1220,7 @@ rescan: return 0; } -void +static void lnet_destroy_rtrbuf(lnet_rtrbuf_t *rb, int npages) { int sz = offsetof(lnet_rtrbuf_t, rb_kiov[npages]); @@ -1235,7 +1231,7 @@ lnet_destroy_rtrbuf(lnet_rtrbuf_t *rb, int npages) LIBCFS_FREE(rb, sz); } -lnet_rtrbuf_t * +static lnet_rtrbuf_t * lnet_new_rtrbuf(lnet_rtrbufpool_t *rbp, int cpt) { int npages = rbp->rbp_npages; @@ -1270,7 +1266,7 @@ lnet_new_rtrbuf(lnet_rtrbufpool_t *rbp, int cpt) return rb; } -void +static void lnet_rtrpool_free_bufs(lnet_rtrbufpool_t *rbp) { int npages = rbp->rbp_npages; @@ -1299,7 +1295,7 @@ lnet_rtrpool_free_bufs(lnet_rtrbufpool_t *rbp) rbp->rbp_nbuffers = rbp->rbp_credits = 0; } -int +static int lnet_rtrpool_alloc_bufs(lnet_rtrbufpool_t *rbp, int nbufs, int cpt) { lnet_rtrbuf_t *rb; @@ -1333,7 +1329,7 @@ lnet_rtrpool_alloc_bufs(lnet_rtrbufpool_t *rbp, int nbufs, int cpt) return 0; } -void +static void lnet_rtrpool_init(lnet_rtrbufpool_t *rbp, int npages) { INIT_LIST_HEAD(&rbp->rbp_msgs); @@ -1370,8 +1366,8 @@ lnet_nrb_tiny_calculate(int npages) if (tiny_router_buffers < 0) { LCONSOLE_ERROR_MSG(0x10c, - "tiny_router_buffers=%d invalid when " - "routing enabled\n", tiny_router_buffers); + "tiny_router_buffers=%d invalid when routing enabled\n", + tiny_router_buffers); return -1; } @@ -1389,8 +1385,8 @@ lnet_nrb_small_calculate(int npages) if (small_router_buffers < 0) { LCONSOLE_ERROR_MSG(0x10c, - "small_router_buffers=%d invalid when " - "routing enabled\n", small_router_buffers); + "small_router_buffers=%d invalid when routing enabled\n", + small_router_buffers); return -1; } @@ -1408,8 +1404,8 @@ lnet_nrb_large_calculate(int npages) if (large_router_buffers < 0) { LCONSOLE_ERROR_MSG(0x10c, - "large_router_buffers=%d invalid when " - "routing enabled\n", large_router_buffers); + "large_router_buffers=%d invalid when routing enabled\n", + large_router_buffers); return -1; } @@ -1442,8 +1438,7 @@ lnet_rtrpools_alloc(int im_a_router) } else if (!strcmp(forwarding, "enabled")) { /* explicitly enabled */ } else { - LCONSOLE_ERROR_MSG(0x10b, "'forwarding' not set to either " - "'enabled' or 'disabled'\n"); + LCONSOLE_ERROR_MSG(0x10b, "'forwarding' not set to either 'enabled' or 'disabled'\n"); return -EINVAL; } @@ -1520,11 +1515,10 @@ lnet_notify(lnet_ni_t *ni, lnet_nid_t nid, int alive, unsigned long when) /* can't do predictions... */ if (cfs_time_after(when, now)) { - CWARN ("Ignoring prediction from %s of %s %s " - "%ld seconds in the future\n", - (ni == NULL) ? "userspace" : libcfs_nid2str(ni->ni_nid), - libcfs_nid2str(nid), alive ? "up" : "down", - cfs_duration_sec(cfs_time_sub(when, now))); + CWARN("Ignoring prediction from %s of %s %s %ld seconds in the future\n", + (ni == NULL) ? "userspace" : libcfs_nid2str(ni->ni_nid), + libcfs_nid2str(nid), alive ? "up" : "down", + cfs_duration_sec(cfs_time_sub(when, now))); return -EINVAL; } diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c index 6e8f7e2bbcfc..46cde7036f1d 100644 --- a/drivers/staging/lustre/lnet/lnet/router_proc.c +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c @@ -164,8 +164,8 @@ static int proc_lnet_stats(struct ctl_table *table, int write, __proc_lnet_stats); } -int proc_lnet_routes(struct ctl_table *table, int write, void __user *buffer, - size_t *lenp, loff_t *ppos) +static int proc_lnet_routes(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) { const int tmpsiz = 256; char *tmpstr; @@ -290,8 +290,8 @@ int proc_lnet_routes(struct ctl_table *table, int write, void __user *buffer, return rc; } -int proc_lnet_routers(struct ctl_table *table, int write, void __user *buffer, - size_t *lenp, loff_t *ppos) +static int proc_lnet_routers(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) { int rc = 0; char *tmpstr; @@ -425,8 +425,8 @@ int proc_lnet_routers(struct ctl_table *table, int write, void __user *buffer, return rc; } -int proc_lnet_peers(struct ctl_table *table, int write, void __user *buffer, - size_t *lenp, loff_t *ppos) +static int proc_lnet_peers(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) { const int tmpsiz = 256; struct lnet_peer_table *ptable; @@ -657,8 +657,8 @@ static int proc_lnet_buffers(struct ctl_table *table, int write, __proc_lnet_buffers); } -int proc_lnet_nis(struct ctl_table *table, int write, void __user *buffer, - size_t *lenp, loff_t *ppos) +static int proc_lnet_nis(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) { int tmpsiz = 128 * LNET_CPT_NUMBER; int rc = 0; @@ -791,20 +791,17 @@ static struct lnet_portal_rotors portal_rotors[] = { { .pr_value = LNET_PTL_ROTOR_ON, .pr_name = "ON", - .pr_desc = "round-robin dispatch all PUT messages for " - "wildcard portals" + .pr_desc = "round-robin dispatch all PUT messages for wildcard portals" }, { .pr_value = LNET_PTL_ROTOR_RR_RT, .pr_name = "RR_RT", - .pr_desc = "round-robin dispatch routed PUT message for " - "wildcard portals" + .pr_desc = "round-robin dispatch routed PUT message for wildcard portals" }, { .pr_value = LNET_PTL_ROTOR_HASH_RT, .pr_name = "HASH_RT", - .pr_desc = "dispatch routed PUT message by hashing source " - "NID for wildcard portals" + .pr_desc = "dispatch routed PUT message by hashing source NID for wildcard portals" }, { .pr_value = -1, diff --git a/drivers/staging/lustre/lnet/selftest/brw_test.c b/drivers/staging/lustre/lnet/selftest/brw_test.c index a94f336d578c..463da076fa70 100644 --- a/drivers/staging/lustre/lnet/selftest/brw_test.c +++ b/drivers/staging/lustre/lnet/selftest/brw_test.c @@ -233,7 +233,7 @@ brw_fill_bulk(srpc_bulk_t *bk, int pattern, __u64 magic) } } -int +static int brw_check_bulk(srpc_bulk_t *bk, int pattern, __u64 magic) { int i; @@ -358,7 +358,7 @@ out: return; } -void +static void brw_server_rpc_done(srpc_server_rpc_t *rpc) { srpc_bulk_t *blk = rpc->srpc_bulk; @@ -378,7 +378,7 @@ brw_server_rpc_done(srpc_server_rpc_t *rpc) sfw_free_pages(rpc); } -int +static int brw_bulk_ready(srpc_server_rpc_t *rpc, int status) { __u64 magic = BRW_MAGIC; @@ -414,7 +414,7 @@ brw_bulk_ready(srpc_server_rpc_t *rpc, int status) return 0; } -int +static int brw_server_handle(struct srpc_server_rpc *rpc) { struct srpc_service *sv = rpc->srpc_scd->scd_svc; diff --git a/drivers/staging/lustre/lnet/selftest/conctl.c b/drivers/staging/lustre/lnet/selftest/conctl.c index ae7b0fcd818d..5bc615309e72 100644 --- a/drivers/staging/lustre/lnet/selftest/conctl.c +++ b/drivers/staging/lustre/lnet/selftest/conctl.c @@ -45,7 +45,7 @@ #include "../../include/linux/lnet/lnetst.h" #include "console.h" -int +static int lst_session_new_ioctl(lstio_session_new_args_t *args) { char *name; @@ -82,7 +82,7 @@ lst_session_new_ioctl(lstio_session_new_args_t *args) return rc; } -int +static int lst_session_end_ioctl(lstio_session_end_args_t *args) { if (args->lstio_ses_key != console_session.ses_key) @@ -91,7 +91,7 @@ lst_session_end_ioctl(lstio_session_end_args_t *args) return lstcon_session_end(); } -int +static int lst_session_info_ioctl(lstio_session_info_args_t *args) { /* no checking of key */ @@ -113,7 +113,7 @@ lst_session_info_ioctl(lstio_session_info_args_t *args) args->lstio_ses_nmlen); } -int +static int lst_debug_ioctl(lstio_debug_args_t *args) { char *name = NULL; @@ -194,7 +194,7 @@ out: return rc; } -int +static int lst_group_add_ioctl(lstio_group_add_args_t *args) { char *name; @@ -228,7 +228,7 @@ lst_group_add_ioctl(lstio_group_add_args_t *args) return rc; } -int +static int lst_group_del_ioctl(lstio_group_del_args_t *args) { int rc; @@ -262,7 +262,7 @@ lst_group_del_ioctl(lstio_group_del_args_t *args) return rc; } -int +static int lst_group_update_ioctl(lstio_group_update_args_t *args) { int rc; @@ -320,7 +320,7 @@ lst_group_update_ioctl(lstio_group_update_args_t *args) return rc; } -int +static int lst_nodes_add_ioctl(lstio_group_nodes_args_t *args) { unsigned feats; @@ -365,7 +365,7 @@ lst_nodes_add_ioctl(lstio_group_nodes_args_t *args) return rc; } -int +static int lst_group_list_ioctl(lstio_group_list_args_t *args) { if (args->lstio_grp_key != console_session.ses_key) @@ -382,7 +382,7 @@ lst_group_list_ioctl(lstio_group_list_args_t *args) args->lstio_grp_namep); } -int +static int lst_group_info_ioctl(lstio_group_info_args_t *args) { char *name; @@ -446,7 +446,7 @@ lst_group_info_ioctl(lstio_group_info_args_t *args) return 0; } -int +static int lst_batch_add_ioctl(lstio_batch_add_args_t *args) { int rc; @@ -480,7 +480,7 @@ lst_batch_add_ioctl(lstio_batch_add_args_t *args) return rc; } -int +static int lst_batch_run_ioctl(lstio_batch_run_args_t *args) { int rc; @@ -515,7 +515,7 @@ lst_batch_run_ioctl(lstio_batch_run_args_t *args) return rc; } -int +static int lst_batch_stop_ioctl(lstio_batch_stop_args_t *args) { int rc; @@ -551,7 +551,7 @@ lst_batch_stop_ioctl(lstio_batch_stop_args_t *args) return rc; } -int +static int lst_batch_query_ioctl(lstio_batch_query_args_t *args) { char *name; @@ -593,7 +593,7 @@ lst_batch_query_ioctl(lstio_batch_query_args_t *args) return rc; } -int +static int lst_batch_list_ioctl(lstio_batch_list_args_t *args) { if (args->lstio_bat_key != console_session.ses_key) @@ -610,7 +610,7 @@ lst_batch_list_ioctl(lstio_batch_list_args_t *args) args->lstio_bat_namep); } -int +static int lst_batch_info_ioctl(lstio_batch_info_args_t *args) { char *name; @@ -675,7 +675,7 @@ lst_batch_info_ioctl(lstio_batch_info_args_t *args) return rc; } -int +static int lst_stat_query_ioctl(lstio_stat_args_t *args) { int rc; diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c index a3a60d6e9081..9999b0dc03e4 100644 --- a/drivers/staging/lustre/lnet/selftest/conrpc.c +++ b/drivers/staging/lustre/lnet/selftest/conrpc.c @@ -88,7 +88,7 @@ lstcon_rpc_done(srpc_client_rpc_t *rpc) spin_unlock(&rpc->crpc_lock); } -int +static int lstcon_rpc_init(lstcon_node_t *nd, int service, unsigned feats, int bulk_npg, int bulk_len, int embedded, lstcon_rpc_t *crpc) { @@ -113,7 +113,7 @@ lstcon_rpc_init(lstcon_node_t *nd, int service, unsigned feats, return 0; } -int +static int lstcon_rpc_prep(lstcon_node_t *nd, int service, unsigned feats, int bulk_npg, int bulk_len, lstcon_rpc_t **crpcpp) { @@ -182,7 +182,7 @@ lstcon_rpc_put(lstcon_rpc_t *crpc) atomic_dec(&console_session.ses_rpc_counter); } -void +static void lstcon_rpc_post(lstcon_rpc_t *crpc) { lstcon_rpc_trans_t *trans = crpc->crp_trans; @@ -383,7 +383,7 @@ lstcon_rpc_trans_postwait(lstcon_rpc_trans_t *trans, int timeout) return rc; } -int +static int lstcon_rpc_get_reply(lstcon_rpc_t *crpc, srpc_msg_t **msgpp) { lstcon_node_t *nd = crpc->crp_node; @@ -718,7 +718,7 @@ lstcon_next_id(int idx, int nkiov, lnet_kiov_t *kiov) return &pid[idx % SFW_ID_PER_PAGE]; } -int +static int lstcon_dstnodes_prep(lstcon_group_t *grp, int idx, int dist, int span, int nkiov, lnet_kiov_t *kiov) { @@ -772,7 +772,7 @@ lstcon_dstnodes_prep(lstcon_group_t *grp, int idx, return 0; } -int +static int lstcon_pingrpc_prep(lst_test_ping_param_t *param, srpc_test_reqst_t *req) { test_ping_req_t *prq = &req->tsr_u.ping; @@ -783,7 +783,7 @@ lstcon_pingrpc_prep(lst_test_ping_param_t *param, srpc_test_reqst_t *req) return 0; } -int +static int lstcon_bulkrpc_v0_prep(lst_test_bulk_param_t *param, srpc_test_reqst_t *req) { test_bulk_req_t *brq = &req->tsr_u.bulk_v0; @@ -795,7 +795,7 @@ lstcon_bulkrpc_v0_prep(lst_test_bulk_param_t *param, srpc_test_reqst_t *req) return 0; } -int +static int lstcon_bulkrpc_v1_prep(lst_test_bulk_param_t *param, srpc_test_reqst_t *req) { test_bulk_req_v1_t *brq = &req->tsr_u.bulk_v1; @@ -915,7 +915,7 @@ lstcon_testrpc_prep(lstcon_node_t *nd, int transop, unsigned feats, return rc; } -int +static int lstcon_sesnew_stat_reply(lstcon_rpc_trans_t *trans, lstcon_node_t *nd, srpc_msg_t *reply) { @@ -1162,7 +1162,7 @@ lstcon_rpc_trans_ndlist(struct list_head *ndlist, return rc; } -void +static void lstcon_rpc_pinger(void *arg) { stt_timer_t *ptimer = (stt_timer_t *)arg; diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c index 5dad9f1f9462..49cb6543d538 100644 --- a/drivers/staging/lustre/lnet/selftest/console.c +++ b/drivers/staging/lustre/lnet/selftest/console.c @@ -1208,8 +1208,7 @@ again: lstcon_rpc_trans_destroy(trans); /* return if any error */ - CDEBUG(D_NET, "Failed to add test %s, " - "RPC error %d, framework error %d\n", + CDEBUG(D_NET, "Failed to add test %s, RPC error %d, framework error %d\n", transop == LST_TRANS_TSBCLIADD ? "client" : "server", lstcon_trans_stat()->trs_rpc_errno, lstcon_trans_stat()->trs_fwk_errno); @@ -1885,8 +1884,7 @@ lstcon_session_feats_check(unsigned feats) spin_unlock(&console_session.ses_rpc_lock); if (rc != 0) { - CERROR("remote features %x do not match with " - "session features %x of console\n", + CERROR("remote features %x do not match with session features %x of console\n", feats, console_session.ses_features); } diff --git a/drivers/staging/lustre/lnet/selftest/framework.c b/drivers/staging/lustre/lnet/selftest/framework.c index df04ab7de835..cc9d1826ae66 100644 --- a/drivers/staging/lustre/lnet/selftest/framework.c +++ b/drivers/staging/lustre/lnet/selftest/framework.c @@ -156,7 +156,7 @@ sfw_register_test (srpc_service_t *service, sfw_test_client_ops_t *cliops) return 0; } -void +static void sfw_add_session_timer (void) { sfw_session_t *sn = sfw_data.fw_session; @@ -176,7 +176,7 @@ sfw_add_session_timer (void) return; } -int +static int sfw_del_session_timer (void) { sfw_session_t *sn = sfw_data.fw_session; @@ -238,7 +238,7 @@ sfw_deactivate_session (void) } -void +static void sfw_session_expired (void *data) { sfw_session_t *sn = data; @@ -284,15 +284,14 @@ sfw_init_session(sfw_session_t *sn, lst_sid_t sid, } /* completion handler for incoming framework RPCs */ -void +static void sfw_server_rpc_done(struct srpc_server_rpc *rpc) { struct srpc_service *sv = rpc->srpc_scd->scd_svc; int status = rpc->srpc_status; CDEBUG (D_NET, - "Incoming framework RPC done: " - "service %s, peer %s, status %s:%d\n", + "Incoming framework RPC done: service %s, peer %s, status %s:%d\n", sv->sv_name, libcfs_id2str(rpc->srpc_peer), swi_state2str(rpc->srpc_wi.swi_state), status); @@ -302,7 +301,7 @@ sfw_server_rpc_done(struct srpc_server_rpc *rpc) return; } -void +static void sfw_client_rpc_fini (srpc_client_rpc_t *rpc) { LASSERT (rpc->crpc_bulk.bk_niov == 0); @@ -310,8 +309,7 @@ sfw_client_rpc_fini (srpc_client_rpc_t *rpc) LASSERT (atomic_read(&rpc->crpc_refcount) == 0); CDEBUG (D_NET, - "Outgoing framework RPC done: " - "service %d, peer %s, status %s:%d:%d\n", + "Outgoing framework RPC done: service %d, peer %s, status %s:%d:%d\n", rpc->crpc_service, libcfs_id2str(rpc->crpc_dest), swi_state2str(rpc->crpc_wi.swi_state), rpc->crpc_aborted, rpc->crpc_status); @@ -325,7 +323,7 @@ sfw_client_rpc_fini (srpc_client_rpc_t *rpc) spin_unlock(&sfw_data.fw_lock); } -sfw_batch_t * +static sfw_batch_t * sfw_find_batch (lst_bid_t bid) { sfw_session_t *sn = sfw_data.fw_session; @@ -341,7 +339,7 @@ sfw_find_batch (lst_bid_t bid) return NULL; } -sfw_batch_t * +static sfw_batch_t * sfw_bid2batch (lst_bid_t bid) { sfw_session_t *sn = sfw_data.fw_session; @@ -367,7 +365,7 @@ sfw_bid2batch (lst_bid_t bid) return bat; } -int +static int sfw_get_stats (srpc_stat_reqst_t *request, srpc_stat_reply_t *reply) { sfw_session_t *sn = sfw_data.fw_session; @@ -479,7 +477,7 @@ sfw_make_session(srpc_mksn_reqst_t *request, srpc_mksn_reply_t *reply) return 0; } -int +static int sfw_remove_session (srpc_rmsn_reqst_t *request, srpc_rmsn_reply_t *reply) { sfw_session_t *sn = sfw_data.fw_session; @@ -511,7 +509,7 @@ sfw_remove_session (srpc_rmsn_reqst_t *request, srpc_rmsn_reply_t *reply) return 0; } -int +static int sfw_debug_session (srpc_debug_reqst_t *request, srpc_debug_reply_t *reply) { sfw_session_t *sn = sfw_data.fw_session; @@ -532,7 +530,7 @@ sfw_debug_session (srpc_debug_reqst_t *request, srpc_debug_reply_t *reply) return 0; } -void +static void sfw_test_rpc_fini (srpc_client_rpc_t *rpc) { sfw_test_unit_t *tsu = rpc->crpc_priv; @@ -554,7 +552,7 @@ sfw_test_buffers(sfw_test_instance_t *tsi) return max(SFW_TEST_WI_MIN, nbuf + SFW_TEST_WI_EXTRA); } -int +static int sfw_load_test(struct sfw_test_instance *tsi) { struct sfw_test_case *tsc; @@ -575,8 +573,8 @@ sfw_load_test(struct sfw_test_instance *tsi) rc = srpc_service_add_buffers(svc, nbuf); if (rc != 0) { - CWARN("Failed to reserve enough buffers: " - "service %s, %d needed: %d\n", svc->sv_name, nbuf, rc); + CWARN("Failed to reserve enough buffers: service %s, %d needed: %d\n", + svc->sv_name, nbuf, rc); /* NB: this error handler is not strictly correct, because * it may release more buffers than already allocated, * but it doesn't matter because request portal should @@ -591,7 +589,7 @@ sfw_load_test(struct sfw_test_instance *tsi) return 0; } -void +static void sfw_unload_test(struct sfw_test_instance *tsi) { struct sfw_test_case *tsc = sfw_find_test_case(tsi->tsi_service); @@ -609,7 +607,7 @@ sfw_unload_test(struct sfw_test_instance *tsi) return; } -void +static void sfw_destroy_test_instance (sfw_test_instance_t *tsi) { srpc_client_rpc_t *rpc; @@ -643,7 +641,7 @@ clean: return; } -void +static void sfw_destroy_batch (sfw_batch_t *tsb) { sfw_test_instance_t *tsi; @@ -682,7 +680,7 @@ sfw_destroy_session (sfw_session_t *sn) return; } -void +static void sfw_unpack_addtest_req(srpc_msg_t *msg) { srpc_test_reqst_t *req = &msg->msg_body.tes_reqst; @@ -727,7 +725,7 @@ sfw_unpack_addtest_req(srpc_msg_t *msg) return; } -int +static int sfw_add_test_instance (sfw_batch_t *tsb, srpc_server_rpc_t *rpc) { srpc_msg_t *msg = &rpc->srpc_reqstbuf->buf_msg; @@ -865,7 +863,7 @@ sfw_test_unit_done (sfw_test_unit_t *tsu) return; } -void +static void sfw_test_rpc_done (srpc_client_rpc_t *rpc) { sfw_test_unit_t *tsu = rpc->crpc_priv; @@ -944,7 +942,7 @@ sfw_create_test_rpc(sfw_test_unit_t *tsu, lnet_process_id_t peer, return 0; } -int +static int sfw_run_test (swi_workitem_t *wi) { sfw_test_unit_t *tsu = wi->swi_workitem.wi_data; @@ -994,7 +992,7 @@ test_done: return 1; } -int +static int sfw_run_batch (sfw_batch_t *tsb) { swi_workitem_t *wi; @@ -1072,7 +1070,7 @@ sfw_stop_batch (sfw_batch_t *tsb, int force) return 0; } -int +static int sfw_query_batch (sfw_batch_t *tsb, int testidx, srpc_batch_reply_t *reply) { sfw_test_instance_t *tsi; @@ -1117,7 +1115,7 @@ sfw_alloc_pages(struct srpc_server_rpc *rpc, int cpt, int npages, int len, return 0; } -int +static int sfw_add_test (srpc_server_rpc_t *rpc) { sfw_session_t *sn = sfw_data.fw_session; @@ -1187,7 +1185,7 @@ sfw_add_test (srpc_server_rpc_t *rpc) return 0; } -int +static int sfw_control_batch (srpc_batch_reqst_t *request, srpc_batch_reply_t *reply) { sfw_session_t *sn = sfw_data.fw_session; @@ -1228,7 +1226,7 @@ sfw_control_batch (srpc_batch_reqst_t *request, srpc_batch_reply_t *reply) return 0; } -int +static int sfw_handle_server_rpc(struct srpc_server_rpc *rpc) { struct srpc_service *sv = rpc->srpc_scd->scd_svc; @@ -1270,8 +1268,7 @@ sfw_handle_server_rpc(struct srpc_server_rpc *rpc) if (sn != NULL && sn->sn_features != request->msg_ses_feats) { - CNETERR("Features of framework RPC don't match " - "features of current session: %x/%x\n", + CNETERR("Features of framework RPC don't match features of current session: %x/%x\n", request->msg_ses_feats, sn->sn_features); reply->msg_body.reply.status = EPROTO; reply->msg_body.reply.sid = sn->sn_id; @@ -1334,7 +1331,7 @@ sfw_handle_server_rpc(struct srpc_server_rpc *rpc) return rc; } -int +static int sfw_bulk_ready(struct srpc_server_rpc *rpc, int status) { struct srpc_service *sv = rpc->srpc_scd->scd_svc; @@ -1348,8 +1345,7 @@ sfw_bulk_ready(struct srpc_server_rpc *rpc, int status) spin_lock(&sfw_data.fw_lock); if (status != 0) { - CERROR("Bulk transfer failed for RPC: " - "service %s, peer %s, status %d\n", + CERROR("Bulk transfer failed for RPC: service %s, peer %s, status %d\n", sv->sv_name, libcfs_id2str(rpc->srpc_peer), status); spin_unlock(&sfw_data.fw_lock); return -EIO; @@ -1664,12 +1660,10 @@ sfw_startup (void) } if (session_timeout == 0) - CWARN ("Zero session_timeout specified " - "- test sessions never expire.\n"); + CWARN("Zero session_timeout specified - test sessions never expire.\n"); if (rpc_timeout == 0) - CWARN ("Zero rpc_timeout specified " - "- test RPC never expire.\n"); + CWARN("Zero rpc_timeout specified - test RPC never expire.\n"); memset(&sfw_data, 0, sizeof(struct smoketest_framework)); @@ -1727,8 +1721,7 @@ sfw_startup (void) rc = srpc_service_add_buffers(sv, sv->sv_wi_total); if (rc != 0) { - CWARN("Failed to reserve enough buffers: " - "service %s, %d needed: %d\n", + CWARN("Failed to reserve enough buffers: service %s, %d needed: %d\n", sv->sv_name, sv->sv_wi_total, rc); error = -ENOMEM; } diff --git a/drivers/staging/lustre/lnet/selftest/module.c b/drivers/staging/lustre/lnet/selftest/module.c index 6dd4309dc5ea..c6ef5b0d8de1 100644 --- a/drivers/staging/lustre/lnet/selftest/module.c +++ b/drivers/staging/lustre/lnet/selftest/module.c @@ -55,7 +55,7 @@ static int lst_init_step = LST_INIT_NONE; struct cfs_wi_sched *lst_sched_serial; struct cfs_wi_sched **lst_sched_test; -void +static void lnet_selftest_fini(void) { int i; @@ -90,18 +90,7 @@ lnet_selftest_fini(void) return; } -void -lnet_selftest_structure_assertion(void) -{ - CLASSERT(sizeof(srpc_msg_t) == 160); - CLASSERT(sizeof(srpc_test_reqst_t) == 70); - CLASSERT(offsetof(srpc_msg_t, msg_body.tes_reqst.tsr_concur) == 72); - CLASSERT(offsetof(srpc_msg_t, msg_body.tes_reqst.tsr_ndest) == 78); - CLASSERT(sizeof(srpc_stat_reply_t) == 136); - CLASSERT(sizeof(srpc_stat_reqst_t) == 28); -} - -int +static int lnet_selftest_init(void) { int nscheds; @@ -130,8 +119,8 @@ lnet_selftest_init(void) rc = cfs_wi_sched_create("lst_t", lnet_cpt_table(), i, nthrs, &lst_sched_test[i]); if (rc != 0) { - CERROR("Failed to create CPT affinity WI scheduler " - "%d for LST\n", i); + CERROR("Failed to create CPT affinity WI scheduler %d for LST\n", + i); goto error; } } diff --git a/drivers/staging/lustre/lnet/selftest/ping_test.c b/drivers/staging/lustre/lnet/selftest/ping_test.c index 750cac4afbb2..d8c0df6e6852 100644 --- a/drivers/staging/lustre/lnet/selftest/ping_test.c +++ b/drivers/staging/lustre/lnet/selftest/ping_test.c @@ -44,7 +44,7 @@ #define LST_PING_TEST_MAGIC 0xbabeface -int ping_srv_workitems = SFW_TEST_WI_MAX; +static int ping_srv_workitems = SFW_TEST_WI_MAX; module_param(ping_srv_workitems, int, 0644); MODULE_PARM_DESC(ping_srv_workitems, "# PING server workitems"); diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c index a9f29d8833a9..f753add7bfb3 100644 --- a/drivers/staging/lustre/lnet/selftest/rpc.c +++ b/drivers/staging/lustre/lnet/selftest/rpc.c @@ -87,7 +87,7 @@ void srpc_set_counters (const srpc_counters_t *cnt) spin_unlock(&srpc_data.rpc_glock); } -int +static int srpc_add_bulk_page(srpc_bulk_t *bk, struct page *pg, int i, int nob) { nob = min(nob, (int)PAGE_CACHE_SIZE); @@ -170,7 +170,7 @@ srpc_next_id (void) return id; } -void +static void srpc_init_server_rpc(struct srpc_server_rpc *rpc, struct srpc_service_cd *scd, struct srpc_buffer *buffer) @@ -351,7 +351,7 @@ srpc_remove_service (srpc_service_t *sv) return 0; } -int +static int srpc_post_passive_rdma(int portal, int local, __u64 matchbits, void *buf, int len, int options, lnet_process_id_t peer, lnet_handle_md_t *mdh, srpc_event_t *ev) @@ -391,7 +391,7 @@ srpc_post_passive_rdma(int portal, int local, __u64 matchbits, void *buf, return 0; } -int +static int srpc_post_active_rdma(int portal, __u64 matchbits, void *buf, int len, int options, lnet_process_id_t peer, lnet_nid_t self, lnet_handle_md_t *mdh, srpc_event_t *ev) @@ -443,7 +443,7 @@ srpc_post_active_rdma(int portal, __u64 matchbits, void *buf, int len, return 0; } -int +static int srpc_post_active_rqtbuf(lnet_process_id_t peer, int service, void *buf, int len, lnet_handle_md_t *mdh, srpc_event_t *ev) { @@ -452,7 +452,7 @@ srpc_post_active_rqtbuf(lnet_process_id_t peer, int service, void *buf, LNET_NID_ANY, mdh, ev); } -int +static int srpc_post_passive_rqtbuf(int service, int local, void *buf, int len, lnet_handle_md_t *mdh, srpc_event_t *ev) { @@ -466,7 +466,7 @@ srpc_post_passive_rqtbuf(int service, int local, void *buf, int len, LNET_MD_OP_PUT, any, mdh, ev); } -int +static int srpc_service_post_buffer(struct srpc_service_cd *scd, struct srpc_buffer *buf) { struct srpc_service *sv = scd->scd_svc; @@ -678,9 +678,7 @@ srpc_finish_service(struct srpc_service *sv) rpc = list_entry(scd->scd_rpc_active.next, struct srpc_server_rpc, srpc_list); - CNETERR("Active RPC %p on shutdown: sv %s, peer %s, " - "wi %s scheduled %d running %d, " - "ev fired %d type %d status %d lnet %d\n", + CNETERR("Active RPC %p on shutdown: sv %s, peer %s, wi %s scheduled %d running %d, ev fired %d type %d status %d lnet %d\n", rpc, sv->sv_name, libcfs_id2str(rpc->srpc_peer), swi_state2str(rpc->srpc_wi.swi_state), rpc->srpc_wi.swi_workitem.wi_scheduled, @@ -697,7 +695,7 @@ srpc_finish_service(struct srpc_service *sv) } /* called with sv->sv_lock held */ -void +static void srpc_service_recycle_buffer(struct srpc_service_cd *scd, srpc_buffer_t *buf) { if (!scd->scd_svc->sv_shuttingdown && scd->scd_buf_adjust >= 0) { @@ -787,7 +785,7 @@ srpc_shutdown_service(srpc_service_t *sv) } } -int +static int srpc_send_request (srpc_client_rpc_t *rpc) { srpc_event_t *ev = &rpc->crpc_reqstev; @@ -807,7 +805,7 @@ srpc_send_request (srpc_client_rpc_t *rpc) return rc; } -int +static int srpc_prepare_reply (srpc_client_rpc_t *rpc) { srpc_event_t *ev = &rpc->crpc_replyev; @@ -831,7 +829,7 @@ srpc_prepare_reply (srpc_client_rpc_t *rpc) return rc; } -int +static int srpc_prepare_bulk (srpc_client_rpc_t *rpc) { srpc_bulk_t *bk = &rpc->crpc_bulk; @@ -863,7 +861,7 @@ srpc_prepare_bulk (srpc_client_rpc_t *rpc) return rc; } -int +static int srpc_do_bulk (srpc_server_rpc_t *rpc) { srpc_event_t *ev = &rpc->srpc_ev; @@ -891,7 +889,7 @@ srpc_do_bulk (srpc_server_rpc_t *rpc) } /* only called from srpc_handle_rpc */ -void +static void srpc_server_rpc_done(srpc_server_rpc_t *rpc, int status) { struct srpc_service_cd *scd = rpc->srpc_scd; @@ -1066,7 +1064,7 @@ srpc_handle_rpc(swi_workitem_t *wi) return 0; } -void +static void srpc_client_rpc_expired (void *data) { srpc_client_rpc_t *rpc = data; @@ -1108,7 +1106,7 @@ srpc_add_client_rpc_timer (srpc_client_rpc_t *rpc) * * Upon exit the RPC expiry timer is not queued and the handler is not * running on any CPU. */ -void +static void srpc_del_client_rpc_timer (srpc_client_rpc_t *rpc) { /* timer not planted or already exploded */ @@ -1129,7 +1127,7 @@ srpc_del_client_rpc_timer (srpc_client_rpc_t *rpc) } } -void +static void srpc_client_rpc_done (srpc_client_rpc_t *rpc, int status) { swi_workitem_t *wi = &rpc->crpc_wi; @@ -1236,20 +1234,18 @@ srpc_send_rpc (swi_workitem_t *wi) if (reply->msg_type != type || (reply->msg_magic != SRPC_MSG_MAGIC && reply->msg_magic != __swab32(SRPC_MSG_MAGIC))) { - CWARN ("Bad message from %s: type %u (%d expected)," - " magic %u (%d expected).\n", - libcfs_id2str(rpc->crpc_dest), - reply->msg_type, type, - reply->msg_magic, SRPC_MSG_MAGIC); + CWARN("Bad message from %s: type %u (%d expected), magic %u (%d expected).\n", + libcfs_id2str(rpc->crpc_dest), + reply->msg_type, type, + reply->msg_magic, SRPC_MSG_MAGIC); rc = -EBADMSG; break; } if (do_bulk && reply->msg_body.reply.status != 0) { - CWARN ("Remote error %d at %s, unlink bulk buffer in " - "case peer didn't initiate bulk transfer\n", - reply->msg_body.reply.status, - libcfs_id2str(rpc->crpc_dest)); + CWARN("Remote error %d at %s, unlink bulk buffer in case peer didn't initiate bulk transfer\n", + reply->msg_body.reply.status, + libcfs_id2str(rpc->crpc_dest)); LNetMDUnlink(rpc->crpc_bulk.bk_mdh); } @@ -1393,7 +1389,7 @@ srpc_send_reply(struct srpc_server_rpc *rpc) } /* when in kernel always called with LNET_LOCK() held, and in thread context */ -void +static void srpc_lnet_ev_handler(lnet_event_t *ev) { struct srpc_service_cd *scd; @@ -1504,11 +1500,10 @@ srpc_lnet_ev_handler(lnet_event_t *ev) msg->msg_type != __swab32(type)) || (msg->msg_magic != SRPC_MSG_MAGIC && msg->msg_magic != __swab32(SRPC_MSG_MAGIC))) { - CERROR ("Dropping RPC (%s) from %s: " - "status %d mlength %d type %u magic %u.\n", - sv->sv_name, libcfs_id2str(ev->initiator), - ev->status, ev->mlength, - msg->msg_type, msg->msg_magic); + CERROR("Dropping RPC (%s) from %s: status %d mlength %d type %u magic %u.\n", + sv->sv_name, libcfs_id2str(ev->initiator), + ev->status, ev->mlength, + msg->msg_type, msg->msg_magic); /* NB can't call srpc_service_recycle_buffer here since * it may call LNetM[DE]Attach. The invalid magic tells diff --git a/drivers/staging/lustre/lnet/selftest/timer.c b/drivers/staging/lustre/lnet/selftest/timer.c index 91d4caa4edb0..f8352c2a7d37 100644 --- a/drivers/staging/lustre/lnet/selftest/timer.c +++ b/drivers/staging/lustre/lnet/selftest/timer.c @@ -121,7 +121,7 @@ stt_del_timer(stt_timer_t *timer) } /* called with stt_data.stt_lock held */ -int +static int stt_expire_list(struct list_head *slot, unsigned long now) { int expired = 0; @@ -145,7 +145,7 @@ stt_expire_list(struct list_head *slot, unsigned long now) return expired; } -int +static int stt_check_timers(unsigned long *last) { int expired = 0; @@ -168,7 +168,7 @@ stt_check_timers(unsigned long *last) } -int +static int stt_timer_main(void *arg) { cfs_block_allsigs(); @@ -187,7 +187,7 @@ stt_timer_main(void *arg) return 0; } -int +static int stt_start_timer_thread(void) { struct task_struct *task; diff --git a/drivers/staging/lustre/lustre/Kconfig b/drivers/staging/lustre/lustre/Kconfig index 4f65ba1158bf..6725467ef4d0 100644 --- a/drivers/staging/lustre/lustre/Kconfig +++ b/drivers/staging/lustre/lustre/Kconfig @@ -57,5 +57,5 @@ config LUSTRE_TRANSLATE_ERRNOS config LUSTRE_LLITE_LLOOP tristate "Lustre virtual block device" depends on LUSTRE_FS && BLOCK - depends on !PPC_64K_PAGES && !ARM64_64K_PAGES + depends on !PPC_64K_PAGES && !ARM64_64K_PAGES && !MICROBLAZE_64K_PAGES && !PAGE_SIZE_64KB && !IA64_PAGE_SIZE_64KB && !PARISC_PAGE_SIZE_64KB default m diff --git a/drivers/staging/lustre/lustre/include/dt_object.h b/drivers/staging/lustre/lustre/include/dt_object.h index 212ebaea8555..be4c7d95e788 100644 --- a/drivers/staging/lustre/lustre/include/dt_object.h +++ b/drivers/staging/lustre/lustre/include/dt_object.h @@ -617,7 +617,7 @@ struct dt_index_operations { int (*load)(const struct lu_env *env, const struct dt_it *di, __u64 hash); int (*key_rec)(const struct lu_env *env, - const struct dt_it *di, void* key_rec); + const struct dt_it *di, void *key_rec); } dio_it; }; @@ -667,7 +667,7 @@ static inline int lu_device_is_dt(const struct lu_device *d) return ergo(d != NULL, d->ld_type->ldt_tags & LU_DEVICE_DT); } -static inline struct dt_device * lu2dt_dev(struct lu_device *l) +static inline struct dt_device *lu2dt_dev(struct lu_device *l) { LASSERT(lu_device_is_dt(l)); return container_of0(l, struct dt_device, dd_lu_dev); diff --git a/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h b/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h index e94ab343ab25..3925db160650 100644 --- a/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h +++ b/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h @@ -42,28 +42,6 @@ #include "lustre_patchless_compat.h" -# define LOCK_FS_STRUCT(fs) spin_lock(&(fs)->lock) -# define UNLOCK_FS_STRUCT(fs) spin_unlock(&(fs)->lock) - -static inline void ll_set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt, - struct dentry *dentry) -{ - struct path path; - struct path old_pwd; - - path.mnt = mnt; - path.dentry = dentry; - LOCK_FS_STRUCT(fs); - old_pwd = fs->pwd; - path_get(&path); - fs->pwd = path; - UNLOCK_FS_STRUCT(fs); - - if (old_pwd.dentry) - path_put(&old_pwd); -} - - /* * set ATTR_BLOCKS to a high value to avoid any risk of collision with other * ATTR_* attributes (see bug 13828) @@ -91,8 +69,6 @@ static inline void ll_set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt, # define inode_dio_read(i) atomic_inc(&(i)->i_dio_count) /* inode_dio_done(i) use as-is for read unlock */ -#define TREE_READ_LOCK_IRQ(mapping) spin_lock_irq(&(mapping)->tree_lock) -#define TREE_READ_UNLOCK_IRQ(mapping) spin_unlock_irq(&(mapping)->tree_lock) #ifndef FS_HAS_FIEMAP #define FS_HAS_FIEMAP (0) @@ -112,8 +88,6 @@ static inline void ll_set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt, #define cfs_bio_io_error(a, b) bio_io_error((a)) #define cfs_bio_endio(a, b, c) bio_endio((a), (c)) -#define cfs_fs_pwd(fs) ((fs)->pwd.dentry) -#define cfs_fs_mnt(fs) ((fs)->pwd.mnt) #define cfs_path_put(nd) path_put(&(nd)->path) @@ -139,8 +113,7 @@ ll_quota_on(struct super_block *sb, int off, int ver, char *name, int remount) ); path_put(&path); return rc; - } - else + } else return -ENOSYS; } @@ -149,8 +122,7 @@ static inline int ll_quota_off(struct super_block *sb, int off, int remount) if (sb->s_qcop->quota_off) { return sb->s_qcop->quota_off(sb, off ); - } - else + } else return -ENOSYS; } diff --git a/drivers/staging/lustre/lustre/include/linux/obd.h b/drivers/staging/lustre/lustre/include/linux/obd.h index 9d7e28ace42d..9cd8683573ce 100644 --- a/drivers/staging/lustre/lustre/include/linux/obd.h +++ b/drivers/staging/lustre/lustre/include/linux/obd.h @@ -87,8 +87,7 @@ static inline void __client_obd_list_lock(client_obd_lock_t *lock, if (task == NULL) continue; - LCONSOLE_WARN("%s:%d: lock %p was acquired" - " by <%s:%d:%s:%d> for %lu seconds.\n", + LCONSOLE_WARN("%s:%d: lock %p was acquired by <%s:%d:%s:%d> for %lu seconds.\n", current->comm, current->pid, lock, task->comm, task->pid, lock->func, lock->line, diff --git a/drivers/staging/lustre/lustre/include/lprocfs_status.h b/drivers/staging/lustre/lustre/include/lprocfs_status.h index ccb6cd42a67d..cfe503b7df62 100644 --- a/drivers/staging/lustre/lustre/include/lprocfs_status.h +++ b/drivers/staging/lustre/lustre/include/lprocfs_status.h @@ -374,8 +374,8 @@ static inline void s2dhms(struct dhms *ts, time_t secs) #define JOBSTATS_PROCNAME_UID "procname_uid" #define JOBSTATS_NODELOCAL "nodelocal" -extern int lprocfs_write_frac_helper(const char *buffer, unsigned long count, - int *val, int mult); +extern int lprocfs_write_frac_helper(const char __user *buffer, + unsigned long count, int *val, int mult); extern int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val, int mult); #if defined (CONFIG_PROC_FS) @@ -557,7 +557,7 @@ extern void lprocfs_free_obd_stats(struct obd_device *obddev); extern void lprocfs_free_md_stats(struct obd_device *obddev); struct obd_export; struct nid_stat; -extern int lprocfs_add_clear_entry(struct obd_device * obd, +extern int lprocfs_add_clear_entry(struct obd_device *obd, struct proc_dir_entry *entry); extern int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *peer_nid, int *newnid); @@ -647,7 +647,7 @@ extern int lprocfs_rd_kbytesavail(struct seq_file *m, void *data); extern int lprocfs_rd_filestotal(struct seq_file *m, void *data); extern int lprocfs_rd_filesfree(struct seq_file *m, void *data); -extern int lprocfs_write_helper(const char *buffer, unsigned long count, +extern int lprocfs_write_helper(const char __user *buffer, unsigned long count, int *val); extern int lprocfs_seq_read_frac_helper(struct seq_file *m, long val, int mult); extern int lprocfs_write_u64_helper(const char *buffer, unsigned long count, diff --git a/drivers/staging/lustre/lustre/include/lu_object.h b/drivers/staging/lustre/lustre/include/lu_object.h index 6015ee5c4b64..2ddb2b054d8d 100644 --- a/drivers/staging/lustre/lustre/include/lu_object.h +++ b/drivers/staging/lustre/lustre/include/lu_object.h @@ -1120,7 +1120,7 @@ struct lu_context_key { }; #define LU_KEY_INIT(mod, type) \ - static void* mod##_key_init(const struct lu_context *ctx, \ + static void *mod##_key_init(const struct lu_context *ctx, \ struct lu_context_key *key) \ { \ type *value; \ @@ -1137,7 +1137,7 @@ struct lu_context_key { #define LU_KEY_FINI(mod, type) \ static void mod##_key_fini(const struct lu_context *ctx, \ - struct lu_context_key *key, void* data) \ + struct lu_context_key *key, void *data) \ { \ type *info = data; \ \ diff --git a/drivers/staging/lustre/lustre/include/lustre_capa.h b/drivers/staging/lustre/lustre/include/lustre_capa.h index ab6b9ea98a70..fe19534ebd8f 100644 --- a/drivers/staging/lustre/lustre/include/lustre_capa.h +++ b/drivers/staging/lustre/lustre/include/lustre_capa.h @@ -154,7 +154,7 @@ static inline __u32 capa_expiry(struct lustre_capa *capa) } void _debug_capa(struct lustre_capa *, struct libcfs_debug_msg_data *, - const char *fmt, ... ); + const char *fmt, ...); #define DEBUG_CAPA(level, capa, fmt, args...) \ do { \ if (((level) & D_CANTMASK) != 0 || \ diff --git a/drivers/staging/lustre/lustre/include/lustre_disk.h b/drivers/staging/lustre/lustre/include/lustre_disk.h index 515b835ce14d..9b2833131744 100644 --- a/drivers/staging/lustre/lustre/include/lustre_disk.h +++ b/drivers/staging/lustre/lustre/include/lustre_disk.h @@ -368,8 +368,7 @@ static inline void check_lcd(char *obd_name, int index, if (strnlen((char*)lcd->lcd_uuid, length) == length) { lcd->lcd_uuid[length - 1] = '\0'; - LCONSOLE_ERROR("the client UUID (%s) on %s for exports" - "stored in last_rcvd(index = %d) is bad!\n", + LCONSOLE_ERROR("the client UUID (%s) on %s for exports stored in last_rcvd(index = %d) is bad!\n", lcd->lcd_uuid, obd_name, index); } } diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm.h b/drivers/staging/lustre/lustre/include/lustre_dlm.h index 14ac46f45fd1..83bc0a9d7d4c 100644 --- a/drivers/staging/lustre/lustre/include/lustre_dlm.h +++ b/drivers/staging/lustre/lustre/include/lustre_dlm.h @@ -1446,7 +1446,7 @@ static inline void check_res_locked(struct ldlm_resource *res) assert_spin_locked(&res->lr_lock); } -struct ldlm_resource * lock_res_and_lock(struct ldlm_lock *lock); +struct ldlm_resource *lock_res_and_lock(struct ldlm_lock *lock); void unlock_res_and_lock(struct ldlm_lock *lock); /* ldlm_pool.c */ diff --git a/drivers/staging/lustre/lustre/include/lustre_eacl.h b/drivers/staging/lustre/lustre/include/lustre_eacl.h index b94f76a3301b..0f8f76c43ee1 100644 --- a/drivers/staging/lustre/lustre/include/lustre_eacl.h +++ b/drivers/staging/lustre/lustre/include/lustre_eacl.h @@ -74,7 +74,7 @@ typedef struct { extern ext_acl_xattr_header * lustre_posix_acl_xattr_2ext(posix_acl_xattr_header *header, int size); extern int -lustre_posix_acl_xattr_filter(posix_acl_xattr_header *header, int size, +lustre_posix_acl_xattr_filter(posix_acl_xattr_header *header, size_t size, posix_acl_xattr_header **out); extern void lustre_posix_acl_xattr_free(posix_acl_xattr_header *header, int size); diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h index 12c7590e61fa..bf135630c39a 100644 --- a/drivers/staging/lustre/lustre/include/lustre_lib.h +++ b/drivers/staging/lustre/lustre/include/lustre_lib.h @@ -85,7 +85,7 @@ void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id); /* client.c */ -int client_sanobd_setup(struct obd_device *obddev, struct lustre_cfg* lcfg); +int client_sanobd_setup(struct obd_device *obddev, struct lustre_cfg *lcfg); struct client_obd *client_conn2cli(struct lustre_handle *conn); struct md_open_data; diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h b/drivers/staging/lustre/lustre/include/lustre_net.h index 0a024d3cfeb7..36396d1c94dc 100644 --- a/drivers/staging/lustre/lustre/include/lustre_net.h +++ b/drivers/staging/lustre/lustre/include/lustre_net.h @@ -2627,12 +2627,7 @@ __u32 lustre_msg_get_timeout(struct lustre_msg *msg); __u32 lustre_msg_get_service_time(struct lustre_msg *msg); char *lustre_msg_get_jobid(struct lustre_msg *msg); __u32 lustre_msg_get_cksum(struct lustre_msg *msg); -#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0) -__u32 lustre_msg_calc_cksum(struct lustre_msg *msg, int compat18); -#else -# warning "remove checksum compatibility support for b1_8" __u32 lustre_msg_calc_cksum(struct lustre_msg *msg); -#endif void lustre_msg_set_handle(struct lustre_msg *msg, struct lustre_handle *handle); void lustre_msg_set_type(struct lustre_msg *msg, __u32 type); @@ -2951,7 +2946,7 @@ void ptlrpcd_decref(void); * procfs output related functions * @{ */ -const char* ll_opcode2str(__u32 opcode); +const char *ll_opcode2str(__u32 opcode); #if defined (CONFIG_PROC_FS) void ptlrpc_lprocfs_register_obd(struct obd_device *obd); void ptlrpc_lprocfs_unregister_obd(struct obd_device *obd); diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h index 882e40bd584c..4a29261c514d 100644 --- a/drivers/staging/lustre/lustre/include/obd_class.h +++ b/drivers/staging/lustre/lustre/include/obd_class.h @@ -414,7 +414,7 @@ do { \ #define EXP_MD_COUNTER_INCREMENT(exp, op) #endif -static inline int lprocfs_nid_ldlm_stats_init(struct nid_stat* tmp) +static inline int lprocfs_nid_ldlm_stats_init(struct nid_stat *tmp) { /* Always add in ldlm_stats */ tmp->nid_ldlm_stats = lprocfs_alloc_stats(LDLM_LAST_OPC - LDLM_FIRST_OPC diff --git a/drivers/staging/lustre/lustre/ldlm/interval_tree.c b/drivers/staging/lustre/lustre/ldlm/interval_tree.c index a3d7a7292417..eab2bd60241b 100644 --- a/drivers/staging/lustre/lustre/ldlm/interval_tree.c +++ b/drivers/staging/lustre/lustre/ldlm/interval_tree.c @@ -73,6 +73,7 @@ static inline int extent_compare(struct interval_node_extent *e1, struct interval_node_extent *e2) { int rc; + if (e1->start == e2->start) { if (e1->end < e2->end) rc = -1; @@ -321,6 +322,7 @@ static void interval_insert_color(struct interval_node *node, /* Parent is RED, so gparent must not be NULL */ if (node_is_left_child(parent)) { struct interval_node *uncle; + uncle = gparent->in_right; if (uncle && node_is_red(uncle)) { uncle->in_color = INTERVAL_BLACK; @@ -340,6 +342,7 @@ static void interval_insert_color(struct interval_node *node, __rotate_right(gparent, root); } else { struct interval_node *uncle; + uncle = gparent->in_left; if (uncle && node_is_red(uncle)) { uncle->in_color = INTERVAL_BLACK; @@ -427,6 +430,7 @@ static void interval_erase_color(struct interval_node *node, } else { if (node_is_black_or_0(tmp->in_right)) { struct interval_node *o_left; + o_left = tmp->in_left; if (o_left) o_left->in_color = INTERVAL_BLACK; @@ -458,6 +462,7 @@ static void interval_erase_color(struct interval_node *node, } else { if (node_is_black_or_0(tmp->in_left)) { struct interval_node *o_right; + o_right = tmp->in_right; if (o_right) o_right->in_color = INTERVAL_BLACK; diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c b/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c index 0c09b611f4a6..a89eebaedabf 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c @@ -182,7 +182,9 @@ void ldlm_extent_add_lock(struct ldlm_resource *res, root = &res->lr_itree[idx].lit_root; found = interval_insert(&node->li_node, root); if (found) { /* The policy group found. */ - struct ldlm_interval *tmp = ldlm_interval_detach(lock); + struct ldlm_interval *tmp; + + tmp = ldlm_interval_detach(lock); LASSERT(tmp != NULL); ldlm_interval_free(tmp); ldlm_interval_attach(to_ldlm_interval(found), lock); diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c index b798daa094bc..a4c252febfe4 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c @@ -260,7 +260,8 @@ ldlm_process_flock_lock(struct ldlm_lock *req, __u64 *flags, int first_enq, int splitted = 0; const struct ldlm_callback_suite null_cbs = { NULL }; - CDEBUG(D_DLMTRACE, "flags %#llx owner %llu pid %u mode %u start %llu end %llu\n", + CDEBUG(D_DLMTRACE, + "flags %#llx owner %llu pid %u mode %u start %llu end %llu\n", *flags, new->l_policy_data.l_flock.owner, new->l_policy_data.l_flock.pid, mode, req->l_policy_data.l_flock.start, @@ -291,6 +292,7 @@ reprocess: } } else { int reprocess_failed = 0; + lockmode_verify(mode); /* This loop determines if there are existing locks @@ -496,7 +498,8 @@ reprocess: new->l_policy_data.l_flock.end + 1; new2->l_conn_export = lock->l_conn_export; if (lock->l_export != NULL) { - new2->l_export = class_export_lock_get(lock->l_export, new2); + new2->l_export = class_export_lock_get(lock->l_export, + new2); if (new2->l_export->exp_lock_hash && hlist_unhashed(&new2->l_exp_hash)) cfs_hash_add(new2->l_export->exp_lock_hash, @@ -619,8 +622,7 @@ ldlm_flock_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data) return 0; } - LDLM_DEBUG(lock, "client-side enqueue returned a blocked lock, " - "sleeping"); + LDLM_DEBUG(lock, "client-side enqueue returned a blocked lock, sleeping"); fwd.fwd_lock = lock; obd = class_exp2obd(lock->l_conn_export); diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h index f997566ef11e..6c6c57ca91de 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h @@ -91,7 +91,8 @@ static inline int ldlm_ns_empty(struct ldlm_namespace *ns) } void ldlm_namespace_move_to_active_locked(struct ldlm_namespace *, ldlm_side_t); -void ldlm_namespace_move_to_inactive_locked(struct ldlm_namespace *, ldlm_side_t); +void ldlm_namespace_move_to_inactive_locked(struct ldlm_namespace *, + ldlm_side_t); struct ldlm_namespace *ldlm_namespace_first_locked(ldlm_side_t); /* ldlm_request.c */ @@ -214,6 +215,7 @@ static inline struct ldlm_extent * ldlm_interval_extent(struct ldlm_interval *node) { struct ldlm_lock *lock; + LASSERT(!list_empty(&node->li_group)); lock = list_entry(node->li_group.next, struct ldlm_lock, @@ -244,7 +246,7 @@ typedef enum ldlm_policy_res ldlm_policy_res_t; \ return lprocfs_rd_uint(m, &tmp); \ } \ - struct __##var##__dummy_read {;} /* semicolon catcher */ + struct __##var##__dummy_read {; } /* semicolon catcher */ #define LDLM_POOL_PROC_WRITER(var, type) \ static int lprocfs_wr_##var(struct file *file, const char *buffer, \ @@ -266,7 +268,7 @@ typedef enum ldlm_policy_res ldlm_policy_res_t; \ return rc; \ } \ - struct __##var##__dummy_write {;} /* semicolon catcher */ + struct __##var##__dummy_write {; } /* semicolon catcher */ static inline int is_granted_or_cancelled(struct ldlm_lock *lock) { diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c index c21e30a074b9..c5c86e73ca52 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c @@ -603,7 +603,8 @@ int client_disconnect_export(struct obd_export *exp) /* obd_force == local only */ ldlm_cli_cancel_unused(obd->obd_namespace, NULL, obd->obd_force ? LCF_LOCAL : 0, NULL); - ldlm_namespace_free_prior(obd->obd_namespace, imp, obd->obd_force); + ldlm_namespace_free_prior(obd->obd_namespace, imp, + obd->obd_force); } /* There's no need to hold sem while disconnecting an import, @@ -858,8 +859,8 @@ void ldlm_dump_export_locks(struct obd_export *exp) if (!list_empty(&exp->exp_locks_list)) { struct ldlm_lock *lock; - CERROR("dumping locks for export %p," - "ignore if the unmount doesn't hang\n", exp); + CERROR("dumping locks for export %p,ignore if the unmount doesn't hang\n", + exp); list_for_each_entry(lock, &exp->exp_locks_list, l_exp_refs_link) LDLM_ERROR(lock, "lock:"); diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c index 6140130b6056..8191005464b1 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c @@ -226,6 +226,7 @@ EXPORT_SYMBOL(ldlm_lock_put); int ldlm_lock_remove_from_lru_nolock(struct ldlm_lock *lock) { int rc = 0; + if (!list_empty(&lock->l_lru)) { struct ldlm_namespace *ns = ldlm_lock_to_ns(lock); @@ -575,7 +576,7 @@ struct ldlm_lock *__ldlm_handle2lock(const struct lustre_handle *handle, /* It's unlikely but possible that someone marked the lock as * destroyed after we did handle2object on it */ - if (flags == 0 && ((lock->l_flags & LDLM_FL_DESTROYED)== 0)) { + if (flags == 0 && ((lock->l_flags & LDLM_FL_DESTROYED) == 0)) { lu_ref_add(&lock->l_reference, "handle", current); return lock; } @@ -811,8 +812,7 @@ void ldlm_lock_decref_internal(struct ldlm_lock *lock, __u32 mode) /* If we received a blocked AST and this was the last reference, * run the callback. */ if ((lock->l_flags & LDLM_FL_NS_SRV) && lock->l_export) - CERROR("FL_CBPENDING set on non-local lock--just a " - "warning\n"); + CERROR("FL_CBPENDING set on non-local lock--just a warning\n"); LDLM_DEBUG(lock, "final decref done on cbpending lock"); @@ -859,6 +859,7 @@ void ldlm_lock_decref_internal(struct ldlm_lock *lock, __u32 mode) void ldlm_lock_decref(struct lustre_handle *lockh, __u32 mode) { struct ldlm_lock *lock = __ldlm_handle2lock(lockh, 0); + LASSERTF(lock != NULL, "Non-existing lock: %#llx\n", lockh->cookie); ldlm_lock_decref_internal(lock, mode); LDLM_LOCK_PUT(lock); @@ -981,7 +982,6 @@ static void search_granted_lock(struct list_head *queue, prev->res_link = queue->prev; prev->mode_link = &req->l_sl_mode; prev->policy_link = &req->l_sl_policy; - return; } /** @@ -1287,6 +1287,7 @@ ldlm_mode_t ldlm_lock_match(struct ldlm_namespace *ns, __u64 flags, __u64 wait_flags = LDLM_FL_LVB_READY | LDLM_FL_DESTROYED | LDLM_FL_FAIL_NOTIFIED; struct l_wait_info lwi; + if (lock->l_completion_ast) { int err = lock->l_completion_ast(lock, LDLM_FL_WAIT_NOREPROC, @@ -1340,9 +1341,10 @@ ldlm_mode_t ldlm_lock_match(struct ldlm_namespace *ns, __u64 flags, } else if (!(flags & LDLM_FL_TEST_LOCK)) {/*less verbose for test-only*/ LDLM_DEBUG_NOLOCK("not matched ns %p type %u mode %u res %llu/%llu (%llu %llu)", - ns, type, mode, res_id->name[0], res_id->name[1], + ns, type, mode, res_id->name[0], + res_id->name[1], (type == LDLM_PLAIN || type == LDLM_IBITS) ? - res_id->name[2] :policy->l_extent.start, + res_id->name[2] : policy->l_extent.start, (type == LDLM_PLAIN || type == LDLM_IBITS) ? res_id->name[3] : policy->l_extent.end); } @@ -1453,7 +1455,8 @@ int ldlm_fill_lvb(struct ldlm_lock *lock, struct req_capsule *pill, memcpy(data, lvb, size); } else { - LDLM_ERROR(lock, "Replied unexpected lquota LVB size %d", + LDLM_ERROR(lock, + "Replied unexpected lquota LVB size %d", size); return -EINVAL; } @@ -1641,8 +1644,7 @@ ldlm_error_t ldlm_lock_enqueue(struct ldlm_namespace *ns, ldlm_grant_lock(lock, NULL); goto out; } else { - CERROR("This is client-side-only module, cannot handle " - "LDLM_NAMESPACE_SERVER resource type lock.\n"); + CERROR("This is client-side-only module, cannot handle LDLM_NAMESPACE_SERVER resource type lock.\n"); LBUG(); } @@ -1820,24 +1822,24 @@ int ldlm_run_ast_work(struct ldlm_namespace *ns, struct list_head *rpc_list, arg->list = rpc_list; switch (ast_type) { - case LDLM_WORK_BL_AST: - arg->type = LDLM_BL_CALLBACK; - work_ast_lock = ldlm_work_bl_ast_lock; - break; - case LDLM_WORK_CP_AST: - arg->type = LDLM_CP_CALLBACK; - work_ast_lock = ldlm_work_cp_ast_lock; - break; - case LDLM_WORK_REVOKE_AST: - arg->type = LDLM_BL_CALLBACK; - work_ast_lock = ldlm_work_revoke_ast_lock; - break; - case LDLM_WORK_GL_AST: - arg->type = LDLM_GL_CALLBACK; - work_ast_lock = ldlm_work_gl_ast_lock; - break; - default: - LBUG(); + case LDLM_WORK_BL_AST: + arg->type = LDLM_BL_CALLBACK; + work_ast_lock = ldlm_work_bl_ast_lock; + break; + case LDLM_WORK_CP_AST: + arg->type = LDLM_CP_CALLBACK; + work_ast_lock = ldlm_work_cp_ast_lock; + break; + case LDLM_WORK_REVOKE_AST: + arg->type = LDLM_BL_CALLBACK; + work_ast_lock = ldlm_work_revoke_ast_lock; + break; + case LDLM_WORK_GL_AST: + arg->type = LDLM_GL_CALLBACK; + work_ast_lock = ldlm_work_gl_ast_lock; + break; + default: + LBUG(); } /* We create a ptlrpc request set with flow control extension. @@ -1904,8 +1906,7 @@ void ldlm_reprocess_all(struct ldlm_resource *res) LIST_HEAD(rpc_list); if (!ns_is_client(ldlm_res_to_ns(res))) { - CERROR("This is client-side-only module, cannot handle " - "LDLM_NAMESPACE_SERVER resource type lock.\n"); + CERROR("This is client-side-only module, cannot handle LDLM_NAMESPACE_SERVER resource type lock.\n"); LBUG(); } } @@ -2038,8 +2039,7 @@ int ldlm_cancel_locks_for_export_cb(struct cfs_hash *hs, struct cfs_hash_bd *bd, ecl->ecl_loop++; if ((ecl->ecl_loop & -ecl->ecl_loop) == ecl->ecl_loop) { CDEBUG(D_INFO, - "Cancel lock %p for export %p (loop %d), still have " - "%d locks left on hash table.\n", + "Cancel lock %p for export %p (loop %d), still have %d locks left on hash table.\n", lock, exp, ecl->ecl_loop, atomic_read(&hs->hs_count)); } @@ -2169,8 +2169,7 @@ struct ldlm_resource *ldlm_lock_convert(struct ldlm_lock *lock, int new_mode, lock->l_completion_ast(lock, 0, NULL); } } else { - CERROR("This is client-side-only module, cannot handle " - "LDLM_NAMESPACE_SERVER resource type lock.\n"); + CERROR("This is client-side-only module, cannot handle LDLM_NAMESPACE_SERVER resource type lock.\n"); LBUG(); } unlock_res_and_lock(lock); @@ -2224,23 +2223,21 @@ void _ldlm_lock_debug(struct ldlm_lock *lock, nid = libcfs_nid2str(exp->exp_connection->c_peer.nid); } else if (exp && exp->exp_obd != NULL) { struct obd_import *imp = exp->exp_obd->u.cli.cl_import; + nid = libcfs_nid2str(imp->imp_connection->c_peer.nid); } if (resource == NULL) { libcfs_debug_vmsg2(msgdata, fmt, args, - " ns: \?\? lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s " - "res: \?\? rrc=\?\? type: \?\?\? flags: %#llx nid: %s " - "remote: %#llx expref: %d pid: %u timeout: %lu " - "lvb_type: %d\n", - lock, - lock->l_handle.h_cookie, atomic_read(&lock->l_refc), - lock->l_readers, lock->l_writers, - ldlm_lockname[lock->l_granted_mode], - ldlm_lockname[lock->l_req_mode], - lock->l_flags, nid, lock->l_remote_handle.cookie, - exp ? atomic_read(&exp->exp_refcount) : -99, - lock->l_pid, lock->l_callback_timeout, lock->l_lvb_type); + " ns: \?\? lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s res: \?\? rrc=\?\? type: \?\?\? flags: %#llx nid: %s remote: %#llx expref: %d pid: %u timeout: %lu lvb_type: %d\n", + lock, + lock->l_handle.h_cookie, atomic_read(&lock->l_refc), + lock->l_readers, lock->l_writers, + ldlm_lockname[lock->l_granted_mode], + ldlm_lockname[lock->l_req_mode], + lock->l_flags, nid, lock->l_remote_handle.cookie, + exp ? atomic_read(&exp->exp_refcount) : -99, + lock->l_pid, lock->l_callback_timeout, lock->l_lvb_type); va_end(args); return; } @@ -2248,90 +2245,78 @@ void _ldlm_lock_debug(struct ldlm_lock *lock, switch (resource->lr_type) { case LDLM_EXTENT: libcfs_debug_vmsg2(msgdata, fmt, args, - " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s " - "res: "DLDLMRES" rrc: %d type: %s [%llu->%llu] " - "(req %llu->%llu) flags: %#llx nid: %s remote: " - "%#llx expref: %d pid: %u timeout: %lu lvb_type: %d\n", - ldlm_lock_to_ns_name(lock), lock, - lock->l_handle.h_cookie, atomic_read(&lock->l_refc), - lock->l_readers, lock->l_writers, - ldlm_lockname[lock->l_granted_mode], - ldlm_lockname[lock->l_req_mode], - PLDLMRES(resource), - atomic_read(&resource->lr_refcount), - ldlm_typename[resource->lr_type], - lock->l_policy_data.l_extent.start, - lock->l_policy_data.l_extent.end, - lock->l_req_extent.start, lock->l_req_extent.end, - lock->l_flags, nid, lock->l_remote_handle.cookie, - exp ? atomic_read(&exp->exp_refcount) : -99, - lock->l_pid, lock->l_callback_timeout, - lock->l_lvb_type); + " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s res: " DLDLMRES " rrc: %d type: %s [%llu->%llu] (req %llu->%llu) flags: %#llx nid: %s remote: %#llx expref: %d pid: %u timeout: %lu lvb_type: %d\n", + ldlm_lock_to_ns_name(lock), lock, + lock->l_handle.h_cookie, atomic_read(&lock->l_refc), + lock->l_readers, lock->l_writers, + ldlm_lockname[lock->l_granted_mode], + ldlm_lockname[lock->l_req_mode], + PLDLMRES(resource), + atomic_read(&resource->lr_refcount), + ldlm_typename[resource->lr_type], + lock->l_policy_data.l_extent.start, + lock->l_policy_data.l_extent.end, + lock->l_req_extent.start, lock->l_req_extent.end, + lock->l_flags, nid, lock->l_remote_handle.cookie, + exp ? atomic_read(&exp->exp_refcount) : -99, + lock->l_pid, lock->l_callback_timeout, + lock->l_lvb_type); break; case LDLM_FLOCK: libcfs_debug_vmsg2(msgdata, fmt, args, - " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s " - "res: "DLDLMRES" rrc: %d type: %s pid: %d " - "[%llu->%llu] flags: %#llx nid: %s " - "remote: %#llx expref: %d pid: %u timeout: %lu\n", - ldlm_lock_to_ns_name(lock), lock, - lock->l_handle.h_cookie, atomic_read(&lock->l_refc), - lock->l_readers, lock->l_writers, - ldlm_lockname[lock->l_granted_mode], - ldlm_lockname[lock->l_req_mode], - PLDLMRES(resource), - atomic_read(&resource->lr_refcount), - ldlm_typename[resource->lr_type], - lock->l_policy_data.l_flock.pid, - lock->l_policy_data.l_flock.start, - lock->l_policy_data.l_flock.end, - lock->l_flags, nid, lock->l_remote_handle.cookie, - exp ? atomic_read(&exp->exp_refcount) : -99, - lock->l_pid, lock->l_callback_timeout); + " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s res: " DLDLMRES " rrc: %d type: %s pid: %d [%llu->%llu] flags: %#llx nid: %s remote: %#llx expref: %d pid: %u timeout: %lu\n", + ldlm_lock_to_ns_name(lock), lock, + lock->l_handle.h_cookie, atomic_read(&lock->l_refc), + lock->l_readers, lock->l_writers, + ldlm_lockname[lock->l_granted_mode], + ldlm_lockname[lock->l_req_mode], + PLDLMRES(resource), + atomic_read(&resource->lr_refcount), + ldlm_typename[resource->lr_type], + lock->l_policy_data.l_flock.pid, + lock->l_policy_data.l_flock.start, + lock->l_policy_data.l_flock.end, + lock->l_flags, nid, lock->l_remote_handle.cookie, + exp ? atomic_read(&exp->exp_refcount) : -99, + lock->l_pid, lock->l_callback_timeout); break; case LDLM_IBITS: libcfs_debug_vmsg2(msgdata, fmt, args, - " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s " - "res: "DLDLMRES" bits %#llx rrc: %d type: %s " - "flags: %#llx nid: %s remote: %#llx expref: %d " - "pid: %u timeout: %lu lvb_type: %d\n", - ldlm_lock_to_ns_name(lock), - lock, lock->l_handle.h_cookie, - atomic_read(&lock->l_refc), - lock->l_readers, lock->l_writers, - ldlm_lockname[lock->l_granted_mode], - ldlm_lockname[lock->l_req_mode], - PLDLMRES(resource), - lock->l_policy_data.l_inodebits.bits, - atomic_read(&resource->lr_refcount), - ldlm_typename[resource->lr_type], - lock->l_flags, nid, lock->l_remote_handle.cookie, - exp ? atomic_read(&exp->exp_refcount) : -99, - lock->l_pid, lock->l_callback_timeout, - lock->l_lvb_type); + " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s res: " DLDLMRES " bits %#llx rrc: %d type: %s flags: %#llx nid: %s remote: %#llx expref: %d pid: %u timeout: %lu lvb_type: %d\n", + ldlm_lock_to_ns_name(lock), + lock, lock->l_handle.h_cookie, + atomic_read(&lock->l_refc), + lock->l_readers, lock->l_writers, + ldlm_lockname[lock->l_granted_mode], + ldlm_lockname[lock->l_req_mode], + PLDLMRES(resource), + lock->l_policy_data.l_inodebits.bits, + atomic_read(&resource->lr_refcount), + ldlm_typename[resource->lr_type], + lock->l_flags, nid, lock->l_remote_handle.cookie, + exp ? atomic_read(&exp->exp_refcount) : -99, + lock->l_pid, lock->l_callback_timeout, + lock->l_lvb_type); break; default: libcfs_debug_vmsg2(msgdata, fmt, args, - " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s " - "res: "DLDLMRES" rrc: %d type: %s flags: %#llx " - "nid: %s remote: %#llx expref: %d pid: %u " - "timeout: %lu lvb_type: %d\n", - ldlm_lock_to_ns_name(lock), - lock, lock->l_handle.h_cookie, - atomic_read(&lock->l_refc), - lock->l_readers, lock->l_writers, - ldlm_lockname[lock->l_granted_mode], - ldlm_lockname[lock->l_req_mode], - PLDLMRES(resource), - atomic_read(&resource->lr_refcount), - ldlm_typename[resource->lr_type], - lock->l_flags, nid, lock->l_remote_handle.cookie, - exp ? atomic_read(&exp->exp_refcount) : -99, - lock->l_pid, lock->l_callback_timeout, - lock->l_lvb_type); + " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s res: " DLDLMRES " rrc: %d type: %s flags: %#llx nid: %s remote: %#llx expref: %d pid: %u timeout: %lu lvb_type: %d\n", + ldlm_lock_to_ns_name(lock), + lock, lock->l_handle.h_cookie, + atomic_read(&lock->l_refc), + lock->l_readers, lock->l_writers, + ldlm_lockname[lock->l_granted_mode], + ldlm_lockname[lock->l_req_mode], + PLDLMRES(resource), + atomic_read(&resource->lr_refcount), + ldlm_typename[resource->lr_type], + lock->l_flags, nid, lock->l_remote_handle.cookie, + exp ? atomic_read(&exp->exp_refcount) : -99, + lock->l_pid, lock->l_callback_timeout, + lock->l_lvb_type); break; } va_end(args); diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c index 91cf7ebae114..98fbd3f7e751 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c @@ -158,13 +158,15 @@ void ldlm_handle_bl_callback(struct ldlm_namespace *ns, unlock_res_and_lock(lock); if (do_ast) { - CDEBUG(D_DLMTRACE, "Lock %p already unused, calling callback (%p)\n", - lock, lock->l_blocking_ast); + CDEBUG(D_DLMTRACE, + "Lock %p already unused, calling callback (%p)\n", lock, + lock->l_blocking_ast); if (lock->l_blocking_ast != NULL) lock->l_blocking_ast(lock, ld, lock->l_ast_data, LDLM_CB_BLOCKING); } else { - CDEBUG(D_DLMTRACE, "Lock %p is referenced, will be cancelled later\n", + CDEBUG(D_DLMTRACE, + "Lock %p is referenced, will be cancelled later\n", lock); } @@ -190,6 +192,7 @@ static void ldlm_handle_cp_callback(struct ptlrpc_request *req, if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_CANCEL_BL_CB_RACE)) { int to = cfs_time_seconds(1); + while (to > 0) { set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(to); @@ -210,9 +213,7 @@ static void ldlm_handle_cp_callback(struct ptlrpc_request *req, LASSERT(lock->l_lvb_data != NULL); if (unlikely(lock->l_lvb_len < lvb_len)) { - LDLM_ERROR(lock, "Replied LVB is larger than " - "expectation, expected = %d, " - "replied = %d", + LDLM_ERROR(lock, "Replied LVB is larger than expectation, expected = %d, replied = %d", lock->l_lvb_len, lvb_len); rc = -EINVAL; goto out; @@ -639,8 +640,8 @@ static int ldlm_callback_handler(struct ptlrpc_request *req) lock = ldlm_handle2lock_long(&dlm_req->lock_handle[0], 0); if (!lock) { - CDEBUG(D_DLMTRACE, "callback on lock %#llx - lock " - "disappeared\n", dlm_req->lock_handle[0].cookie); + CDEBUG(D_DLMTRACE, "callback on lock %#llx - lock disappeared\n", + dlm_req->lock_handle[0].cookie); rc = ldlm_callback_reply(req, -EINVAL); ldlm_callback_errmsg(req, "Operate with invalid parameter", rc, &dlm_req->lock_handle[0]); @@ -663,8 +664,7 @@ static int ldlm_callback_handler(struct ptlrpc_request *req) if (((lock->l_flags & LDLM_FL_CANCELING) && (lock->l_flags & LDLM_FL_BL_DONE)) || (lock->l_flags & LDLM_FL_FAILED)) { - LDLM_DEBUG(lock, "callback on lock " - "%#llx - lock disappeared\n", + LDLM_DEBUG(lock, "callback on lock %#llx - lock disappeared\n", dlm_req->lock_handle[0].cookie); unlock_res_and_lock(lock); LDLM_LOCK_RELEASE(lock); @@ -724,7 +724,7 @@ static int ldlm_callback_handler(struct ptlrpc_request *req) static struct ldlm_bl_work_item *ldlm_bl_get_work(struct ldlm_bl_pool *blp) { struct ldlm_bl_work_item *blwi = NULL; - static unsigned int num_bl = 0; + static unsigned int num_bl; spin_lock(&blp->blp_lock); /* process a request from the blp_list at least every blp_num_threads */ @@ -887,6 +887,7 @@ void ldlm_put_ref(void) mutex_lock(&ldlm_ref_mutex); if (ldlm_refcount == 1) { int rc = ldlm_cleanup(); + if (rc) CERROR("ldlm_cleanup failed: %d\n", rc); else @@ -969,6 +970,7 @@ static cfs_hash_ops_t ldlm_export_lock_ops = { int ldlm_init_export(struct obd_export *exp) { int rc; + exp->exp_lock_hash = cfs_hash_create(obd_uuid2str(&exp->exp_client_uuid), HASH_EXP_LOCK_CUR_BITS, @@ -1049,7 +1051,7 @@ static int ldlm_setup(void) .so_req_handler = ldlm_callback_handler, }, }; - ldlm_state->ldlm_cb_service = \ + ldlm_state->ldlm_cb_service = ptlrpc_register_service(&conf, ldlm_svc_proc_dir); if (IS_ERR(ldlm_state->ldlm_cb_service)) { CERROR("failed to start service\n"); @@ -1077,7 +1079,7 @@ static int ldlm_setup(void) blp->blp_min_threads = LDLM_NTHRS_INIT; blp->blp_max_threads = LDLM_NTHRS_MAX; } else { - blp->blp_min_threads = blp->blp_max_threads = \ + blp->blp_min_threads = blp->blp_max_threads = min_t(int, LDLM_NTHRS_MAX, max_t(int, LDLM_NTHRS_INIT, ldlm_num_threads)); } diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c index 6054eee848d3..4c838f615a64 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c @@ -54,10 +54,10 @@ * calculated as the number of locks in LRU * lock live time in seconds. If * CLV > SLV - lock is canceled. * - * Client has LVF, that is, lock volume factor which regulates how much sensitive - * client should be about last SLV from server. The higher LVF is the more locks - * will be canceled on client. Default value for it is 1. Setting LVF to 2 means - * that client will cancel locks 2 times faster. + * Client has LVF, that is, lock volume factor which regulates how much + * sensitive client should be about last SLV from server. The higher LVF is the + * more locks will be canceled on client. Default value for it is 1. Setting LVF + * to 2 means that client will cancel locks 2 times faster. * * Locks on a client will be canceled more intensively in these cases: * (1) if SLV is smaller, that is, load is higher on the server; @@ -70,11 +70,12 @@ * if flow is getting thinner, more and more particles become outside of it and * as particles are locks, they should be canceled. * - * General idea of this belongs to Vitaly Fertman (vitaly@clusterfs.com). Andreas - * Dilger (adilger@clusterfs.com) proposed few nice ideas like using LVF and many - * cleanups. Flow definition to allow more easy understanding of the logic belongs - * to Nikita Danilov (nikita@clusterfs.com) as well as many cleanups and fixes. - * And design and implementation are done by Yury Umanets (umka@clusterfs.com). + * General idea of this belongs to Vitaly Fertman (vitaly@clusterfs.com). + * Andreas Dilger (adilger@clusterfs.com) proposed few nice ideas like using + * LVF and many cleanups. Flow definition to allow more easy understanding of + * the logic belongs to Nikita Danilov (nikita@clusterfs.com) as well as many + * cleanups and fixes. And design and implementation are done by Yury Umanets + * (umka@clusterfs.com). * * Glossary for terms used: * @@ -265,16 +266,15 @@ static void ldlm_pool_recalc_slv(struct ldlm_pool *pl) * SLV. And the opposite, the more grant plan is over-consumed * (load time) the faster drops SLV. */ - slv_factor = (grant_usage << LDLM_POOL_SLV_SHIFT); + slv_factor = grant_usage << LDLM_POOL_SLV_SHIFT; do_div(slv_factor, limit); slv = slv * slv_factor; slv = dru(slv, LDLM_POOL_SLV_SHIFT, round_up); - if (slv > ldlm_pool_slv_max(limit)) { + if (slv > ldlm_pool_slv_max(limit)) slv = ldlm_pool_slv_max(limit); - } else if (slv < ldlm_pool_slv_min(limit)) { + else if (slv < ldlm_pool_slv_min(limit)) slv = ldlm_pool_slv_min(limit); - } pl->pl_server_lock_volume = slv; } @@ -614,8 +614,8 @@ int ldlm_pool_shrink(struct ldlm_pool *pl, int nr, lprocfs_counter_add(pl->pl_stats, LDLM_POOL_SHRINK_FREED_STAT, cancel); - CDEBUG(D_DLMTRACE, "%s: request to shrink %d locks, " - "shrunk %d\n", pl->pl_name, nr, cancel); + CDEBUG(D_DLMTRACE, "%s: request to shrink %d locks, shrunk %d\n", + pl->pl_name, nr, cancel); } } return cancel; @@ -636,7 +636,7 @@ int ldlm_pool_setup(struct ldlm_pool *pl, int limit) } EXPORT_SYMBOL(ldlm_pool_setup); -#if defined (CONFIG_PROC_FS) +#if defined(CONFIG_PROC_FS) static int lprocfs_pool_state_seq_show(struct seq_file *m, void *unused) { int granted, grant_rate, cancel_rate, grant_step; @@ -696,8 +696,9 @@ LPROC_SEQ_FOPS_RO(lprocfs_grant_plan); LDLM_POOL_PROC_READER_SEQ_SHOW(recalc_period, int); LDLM_POOL_PROC_WRITER(recalc_period, int); -static ssize_t lprocfs_recalc_period_seq_write(struct file *file, const char *buf, - size_t len, loff_t *off) +static ssize_t lprocfs_recalc_period_seq_write(struct file *file, + const char *buf, size_t len, + loff_t *off) { struct seq_file *seq = file->private_data; @@ -943,6 +944,7 @@ EXPORT_SYMBOL(ldlm_pool_del); __u64 ldlm_pool_get_slv(struct ldlm_pool *pl) { __u64 slv; + spin_lock(&pl->pl_lock); slv = pl->pl_server_lock_volume; spin_unlock(&pl->pl_lock); @@ -971,6 +973,7 @@ EXPORT_SYMBOL(ldlm_pool_set_slv); __u64 ldlm_pool_get_clv(struct ldlm_pool *pl) { __u64 slv; + spin_lock(&pl->pl_lock); slv = pl->pl_client_lock_volume; spin_unlock(&pl->pl_lock); @@ -1132,23 +1135,27 @@ static unsigned long ldlm_pools_scan(ldlm_side_t client, int nr, gfp_t gfp_mask) return (client == LDLM_NAMESPACE_SERVER) ? SHRINK_STOP : freed; } -static unsigned long ldlm_pools_srv_count(struct shrinker *s, struct shrink_control *sc) +static unsigned long ldlm_pools_srv_count(struct shrinker *s, + struct shrink_control *sc) { return ldlm_pools_count(LDLM_NAMESPACE_SERVER, sc->gfp_mask); } -static unsigned long ldlm_pools_srv_scan(struct shrinker *s, struct shrink_control *sc) +static unsigned long ldlm_pools_srv_scan(struct shrinker *s, + struct shrink_control *sc) { return ldlm_pools_scan(LDLM_NAMESPACE_SERVER, sc->nr_to_scan, sc->gfp_mask); } -static unsigned long ldlm_pools_cli_count(struct shrinker *s, struct shrink_control *sc) +static unsigned long ldlm_pools_cli_count(struct shrinker *s, + struct shrink_control *sc) { return ldlm_pools_count(LDLM_NAMESPACE_CLIENT, sc->gfp_mask); } -static unsigned long ldlm_pools_cli_scan(struct shrinker *s, struct shrink_control *sc) +static unsigned long ldlm_pools_cli_scan(struct shrinker *s, + struct shrink_control *sc) { return ldlm_pools_scan(LDLM_NAMESPACE_CLIENT, sc->nr_to_scan, sc->gfp_mask); @@ -1194,10 +1201,8 @@ int ldlm_pools_recalc(ldlm_side_t client) * of limit. */ if (nr_l >= 2 * (LDLM_POOL_HOST_L / 3)) { - CWARN("\"Modest\" pools eat out 2/3 of server locks " - "limit (%d of %lu). This means that you have too " - "many clients for this amount of server RAM. " - "Upgrade server!\n", nr_l, LDLM_POOL_HOST_L); + CWARN("\"Modest\" pools eat out 2/3 of server locks limit (%d of %lu). This means that you have too many clients for this amount of server RAM. Upgrade server!\n", + nr_l, LDLM_POOL_HOST_L); equal = 1; } @@ -1205,8 +1210,7 @@ int ldlm_pools_recalc(ldlm_side_t client) * The rest is given to greedy namespaces. */ list_for_each_entry(ns, ldlm_namespace_list(client), - ns_list_chain) - { + ns_list_chain) { if (!equal && ns->ns_appetite != LDLM_NAMESPACE_GREEDY) continue; @@ -1383,9 +1387,8 @@ static int ldlm_pools_thread_start(void) static void ldlm_pools_thread_stop(void) { - if (ldlm_pools_thread == NULL) { + if (ldlm_pools_thread == NULL) return; - } thread_set_flags(ldlm_pools_thread, SVC_STOPPING); wake_up(&ldlm_pools_thread->t_ctl_waitq); diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c index 9ce437b18793..287da325d928 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c @@ -95,16 +95,14 @@ int ldlm_expired_completion_wait(void *data) struct obd_device *obd; if (lock->l_conn_export == NULL) { - static unsigned long next_dump = 0, last_dump = 0; + static unsigned long next_dump, last_dump; LCONSOLE_WARN("lock timed out (enqueued at "CFS_TIME_T", " CFS_DURATION_T"s ago)\n", lock->l_last_activity, cfs_time_sub(get_seconds(), lock->l_last_activity)); - LDLM_DEBUG(lock, "lock timed out (enqueued at "CFS_TIME_T", " - CFS_DURATION_T"s ago); not entering recovery in " - "server code, just going back to sleep", + LDLM_DEBUG(lock, "lock timed out (enqueued at " CFS_TIME_T ", " CFS_DURATION_T "s ago); not entering recovery in server code, just going back to sleep", lock->l_last_activity, cfs_time_sub(get_seconds(), lock->l_last_activity)); @@ -137,6 +135,7 @@ EXPORT_SYMBOL(ldlm_expired_completion_wait); int ldlm_get_enq_timeout(struct ldlm_lock *lock) { int timeout = at_get(ldlm_lock_to_ns_at(lock)); + if (AT_OFF) return obd_timeout / 2; /* Since these are non-updating timeouts, we should be conservative. @@ -191,8 +190,7 @@ int ldlm_completion_ast_async(struct ldlm_lock *lock, __u64 flags, void *data) return ldlm_completion_tail(lock); } - LDLM_DEBUG(lock, "client-side enqueue returned a blocked lock, " - "going forward"); + LDLM_DEBUG(lock, "client-side enqueue returned a blocked lock, going forward"); ldlm_reprocess_all(lock->l_resource); return 0; } @@ -240,17 +238,15 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data) return 0; } - LDLM_DEBUG(lock, "client-side enqueue returned a blocked lock, " - "sleeping"); + LDLM_DEBUG(lock, "client-side enqueue returned a blocked lock, sleeping"); noreproc: obd = class_exp2obd(lock->l_conn_export); /* if this is a local lock, then there is no import */ - if (obd != NULL) { + if (obd != NULL) imp = obd->u.cli.cl_import; - } /* Wait a long time for enqueue - server may have to callback a lock from another client. Server will evict the other client if it @@ -324,8 +320,7 @@ int ldlm_blocking_ast_nocheck(struct ldlm_lock *lock) if (rc < 0) CERROR("ldlm_cli_cancel: %d\n", rc); } else { - LDLM_DEBUG(lock, "Lock still has references, will be " - "cancelled later"); + LDLM_DEBUG(lock, "Lock still has references, will be cancelled later"); } return 0; } @@ -483,8 +478,7 @@ static void failed_lock_cleanup(struct ldlm_namespace *ns, if (need_cancel) LDLM_DEBUG(lock, - "setting FL_LOCAL_ONLY | LDLM_FL_FAILED | " - "LDLM_FL_ATOMIC_CB | LDLM_FL_CBPENDING"); + "setting FL_LOCAL_ONLY | LDLM_FL_FAILED | LDLM_FL_ATOMIC_CB | LDLM_FL_CBPENDING"); else LDLM_DEBUG(lock, "lock was granted or failed in race"); @@ -557,8 +551,7 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req, rc = size; goto cleanup; } else if (unlikely(size > lvb_len)) { - LDLM_ERROR(lock, "Replied LVB is larger than " - "expectation, expected = %d, replied = %d", + LDLM_ERROR(lock, "Replied LVB is larger than expectation, expected = %d, replied = %d", lvb_len, size); rc = -EINVAL; goto cleanup; @@ -608,6 +601,7 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req, * again. */ if ((*flags) & LDLM_FL_LOCK_CHANGED) { int newmode = reply->lock_desc.l_req_mode; + LASSERT(!is_replay); if (newmode && newmode != lock->l_req_mode) { LDLM_DEBUG(lock, "server returned different mode %s", @@ -676,6 +670,7 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req, rc = ldlm_lock_enqueue(ns, &lock, NULL, flags); if (lock->l_completion_ast != NULL) { int err = lock->l_completion_ast(lock, *flags, NULL); + if (!rc) rc = err; if (rc) @@ -725,6 +720,7 @@ static inline int ldlm_capsule_handles_avail(struct req_capsule *pill, int off) { int size = req_capsule_msg_size(pill, loc); + return ldlm_req_handles_avail(size, off); } @@ -733,6 +729,7 @@ static inline int ldlm_format_handles_avail(struct obd_import *imp, enum req_location loc, int off) { int size = req_capsule_fmt_size(imp->imp_msg_magic, fmt, loc); + return ldlm_req_handles_avail(size, off); } @@ -1107,8 +1104,7 @@ static __u64 ldlm_cli_cancel_local(struct ldlm_lock *lock) unlock_res_and_lock(lock); if (local_only) { - CDEBUG(D_DLMTRACE, "not sending request (at caller's " - "instruction)\n"); + CDEBUG(D_DLMTRACE, "not sending request (at caller's instruction)\n"); rc = LDLM_FL_LOCAL_ONLY; } ldlm_lock_cancel(lock); @@ -1223,8 +1219,7 @@ int ldlm_cli_cancel_req(struct obd_export *exp, struct list_head *cancels, rc = ptlrpc_queue_wait(req); } if (rc == LUSTRE_ESTALE) { - CDEBUG(D_DLMTRACE, "client/server (nid %s) " - "out of sync -- not fatal\n", + CDEBUG(D_DLMTRACE, "client/server (nid %s) out of sync -- not fatal\n", libcfs_nid2str(req->rq_import-> imp_connection->c_peer.nid)); rc = 0; @@ -1235,8 +1230,8 @@ int ldlm_cli_cancel_req(struct obd_export *exp, struct list_head *cancels, } else if (rc != ELDLM_OK) { /* -ESHUTDOWN is common on umount */ CDEBUG_LIMIT(rc == -ESHUTDOWN ? D_DLMTRACE : D_ERROR, - "Got rc %d from cancel RPC: " - "canceling anyway\n", rc); + "Got rc %d from cancel RPC: canceling anyway\n", + rc); break; } sent = count; @@ -1279,7 +1274,8 @@ int ldlm_cli_update_pool(struct ptlrpc_request *req) * server-side namespace is not possible. */ if (lustre_msg_get_slv(req->rq_repmsg) == 0 || lustre_msg_get_limit(req->rq_repmsg) == 0) { - DEBUG_REQ(D_HA, req, "Zero SLV or Limit found (SLV: %llu, Limit: %u)", + DEBUG_REQ(D_HA, req, + "Zero SLV or Limit found (SLV: %llu, Limit: %u)", lustre_msg_get_slv(req->rq_repmsg), lustre_msg_get_limit(req->rq_repmsg)); return 0; @@ -1416,19 +1412,20 @@ static ldlm_policy_res_t ldlm_cancel_no_wait_policy(struct ldlm_namespace *ns, { ldlm_policy_res_t result = LDLM_POLICY_CANCEL_LOCK; ldlm_cancel_for_recovery cb = ns->ns_cancel_for_recovery; + lock_res_and_lock(lock); /* don't check added & count since we want to process all locks * from unused list */ switch (lock->l_resource->lr_type) { - case LDLM_EXTENT: - case LDLM_IBITS: - if (cb && cb(lock)) - break; - default: - result = LDLM_POLICY_SKIP_LOCK; - lock->l_flags |= LDLM_FL_SKIPPED; + case LDLM_EXTENT: + case LDLM_IBITS: + if (cb && cb(lock)) break; + default: + result = LDLM_POLICY_SKIP_LOCK; + lock->l_flags |= LDLM_FL_SKIPPED; + break; } unlock_res_and_lock(lock); @@ -1594,8 +1591,9 @@ ldlm_cancel_lru_policy(struct ldlm_namespace *ns, int flags) * sending any RPCs or waiting for any * outstanding RPC to complete. */ -static int ldlm_prepare_lru_list(struct ldlm_namespace *ns, struct list_head *cancels, - int count, int max, int flags) +static int ldlm_prepare_lru_list(struct ldlm_namespace *ns, + struct list_head *cancels, int count, int max, + int flags) { ldlm_cancel_lru_policy_t pf; struct ldlm_lock *lock, *next; @@ -1730,6 +1728,7 @@ int ldlm_cancel_lru_local(struct ldlm_namespace *ns, struct list_head *cancels, int flags) { int added; + added = ldlm_prepare_lru_list(ns, cancels, count, max, flags); if (added <= 0) return added; @@ -1918,7 +1917,8 @@ struct ldlm_cli_cancel_arg { void *lc_opaque; }; -static int ldlm_cli_hash_cancel_unused(struct cfs_hash *hs, struct cfs_hash_bd *bd, +static int ldlm_cli_hash_cancel_unused(struct cfs_hash *hs, + struct cfs_hash_bd *bd, struct hlist_node *hnode, void *arg) { struct ldlm_resource *res = cfs_hash_object(hs, hnode); @@ -2014,6 +2014,7 @@ struct iter_helper_data { static int ldlm_iter_helper(struct ldlm_lock *lock, void *closure) { struct iter_helper_data *helper = closure; + return helper->iter(lock, helper->closure); } @@ -2080,7 +2081,8 @@ static int ldlm_chain_lock_for_replay(struct ldlm_lock *lock, void *closure) /* we use l_pending_chain here, because it's unused on clients. */ LASSERTF(list_empty(&lock->l_pending_chain), "lock %p next %p prev %p\n", - lock, &lock->l_pending_chain.next,&lock->l_pending_chain.prev); + lock, &lock->l_pending_chain.next, + &lock->l_pending_chain.prev); /* bug 9573: don't replay locks left after eviction, or * bug 17614: locks being actively cancelled. Get a reference * on a lock so that it does not disappear under us (e.g. due to cancel) @@ -2114,8 +2116,7 @@ static int replay_lock_interpret(const struct lu_env *env, lock = ldlm_handle2lock(&aa->lock_handle); if (!lock) { - CERROR("received replay ack for unknown local cookie %#llx" - " remote cookie %#llx from server %s id %s\n", + CERROR("received replay ack for unknown local cookie %#llx remote cookie %#llx from server %s id %s\n", aa->lock_handle.cookie, reply->lock_handle.cookie, req->rq_export->exp_client_uuid.uuid, libcfs_id2str(req->rq_peer)); @@ -2243,9 +2244,8 @@ static void ldlm_cancel_unused_locks_for_replay(struct ldlm_namespace *ns) int canceled; LIST_HEAD(cancels); - CDEBUG(D_DLMTRACE, "Dropping as many unused locks as possible before" - "replay for namespace %s (%d)\n", - ldlm_ns_name(ns), ns->ns_nr_unused); + CDEBUG(D_DLMTRACE, "Dropping as many unused locks as possible before replay for namespace %s (%d)\n", + ldlm_ns_name(ns), ns->ns_nr_unused); /* We don't need to care whether or not LRU resize is enabled * because the LDLM_CANCEL_NO_WAIT policy doesn't use the diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c index a785b7a7d1b3..1f150e46f50e 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c @@ -71,7 +71,7 @@ extern unsigned int ldlm_cancel_unused_locks_before_replay; * DDOS. */ unsigned int ldlm_dump_granted_max = 256; -#if defined (CONFIG_PROC_FS) +#if defined(CONFIG_PROC_FS) static ssize_t lprocfs_wr_dump_ns(struct file *file, const char *buffer, size_t count, loff_t *off) { @@ -93,7 +93,7 @@ int ldlm_proc_setup(void) &ldlm_dump_granted_max }, { "cancel_unused_locks_before_replay", &ldlm_rw_uint_fops, &ldlm_cancel_unused_locks_before_replay }, - { NULL }}; + { NULL } }; LASSERT(ldlm_ns_proc_dir == NULL); ldlm_type_proc_dir = lprocfs_register(OBD_LDLM_DEVICENAME, @@ -215,8 +215,8 @@ static ssize_t lprocfs_lru_size_seq_write(struct file *file, LDLM_CANCEL_PASSED); if (canceled < unused) { CDEBUG(D_DLMTRACE, - "not all requested locks are canceled, " - "requested: %d, canceled: %d\n", unused, + "not all requested locks are canceled, requested: %d, canceled: %d\n", + unused, canceled); return -EINVAL; } @@ -385,8 +385,8 @@ int ldlm_namespace_proc_register(struct ldlm_namespace *ns) #undef MAX_STRING_SIZE #else /* CONFIG_PROC_FS */ -#define ldlm_namespace_proc_unregister(ns) ({;}) -#define ldlm_namespace_proc_register(ns) ({0;}) +#define ldlm_namespace_proc_unregister(ns) ({; }) +#define ldlm_namespace_proc_register(ns) ({0; }) #endif /* CONFIG_PROC_FS */ @@ -454,7 +454,8 @@ static void *ldlm_res_hop_object(struct hlist_node *hnode) return hlist_entry(hnode, struct ldlm_resource, lr_hash); } -static void ldlm_res_hop_get_locked(struct cfs_hash *hs, struct hlist_node *hnode) +static void ldlm_res_hop_get_locked(struct cfs_hash *hs, + struct hlist_node *hnode) { struct ldlm_resource *res; @@ -462,7 +463,8 @@ static void ldlm_res_hop_get_locked(struct cfs_hash *hs, struct hlist_node *hnod ldlm_resource_getref(res); } -static void ldlm_res_hop_put_locked(struct cfs_hash *hs, struct hlist_node *hnode) +static void ldlm_res_hop_put_locked(struct cfs_hash *hs, + struct hlist_node *hnode) { struct ldlm_resource *res; @@ -501,7 +503,7 @@ cfs_hash_ops_t ldlm_ns_fid_hash_ops = { .hs_put = ldlm_res_hop_put }; -typedef struct { +struct ldlm_ns_hash_def { ldlm_ns_type_t nsd_type; /** hash bucket bits */ unsigned nsd_bkt_bits; @@ -509,9 +511,9 @@ typedef struct { unsigned nsd_all_bits; /** hash operations */ cfs_hash_ops_t *nsd_hops; -} ldlm_ns_hash_def_t; +}; -ldlm_ns_hash_def_t ldlm_ns_hash_defs[] = { +struct ldlm_ns_hash_def ldlm_ns_hash_defs[] = { { .nsd_type = LDLM_NS_TYPE_MDC, .nsd_bkt_bits = 11, @@ -563,7 +565,7 @@ struct ldlm_namespace *ldlm_namespace_new(struct obd_device *obd, char *name, { struct ldlm_namespace *ns = NULL; struct ldlm_ns_bucket *nsb; - ldlm_ns_hash_def_t *nsd; + struct ldlm_ns_hash_def *nsd; struct cfs_hash_bd bd; int idx; int rc; @@ -576,7 +578,7 @@ struct ldlm_namespace *ldlm_namespace_new(struct obd_device *obd, char *name, return NULL; } - for (idx = 0;;idx++) { + for (idx = 0;; idx++) { nsd = &ldlm_ns_hash_defs[idx]; if (nsd->nsd_type == LDLM_NS_TYPE_UNKNOWN) { CERROR("Unknown type %d for ns %s\n", ns_type, name); @@ -735,8 +737,7 @@ static void cleanup_resource(struct ldlm_resource *res, struct list_head *q, } else { ldlm_resource_unlink_lock(lock); unlock_res(res); - LDLM_DEBUG(lock, "Freeing a lock still held by a " - "client node"); + LDLM_DEBUG(lock, "Freeing a lock still held by a client node"); ldlm_lock_destroy(lock); } LDLM_LOCK_RELEASE(lock); @@ -805,6 +806,7 @@ static int __ldlm_namespace_free(struct ldlm_namespace *ns, int force) if (atomic_read(&ns->ns_bref) > 0) { struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL); int rc; + CDEBUG(D_DLMTRACE, "dlm namespace %s free waiting on refcount %d\n", ldlm_ns_name(ns), atomic_read(&ns->ns_bref)); @@ -818,16 +820,14 @@ force_wait: /* Forced cleanups should be able to reclaim all references, * so it's safe to wait forever... we can't leak locks... */ if (force && rc == -ETIMEDOUT) { - LCONSOLE_ERROR("Forced cleanup waiting for %s " - "namespace with %d resources in use, " - "(rc=%d)\n", ldlm_ns_name(ns), + LCONSOLE_ERROR("Forced cleanup waiting for %s namespace with %d resources in use, (rc=%d)\n", + ldlm_ns_name(ns), atomic_read(&ns->ns_bref), rc); goto force_wait; } if (atomic_read(&ns->ns_bref)) { - LCONSOLE_ERROR("Cleanup waiting for %s namespace " - "with %d resources in use, (rc=%d)\n", + LCONSOLE_ERROR("Cleanup waiting for %s namespace with %d resources in use, (rc=%d)\n", ldlm_ns_name(ns), atomic_read(&ns->ns_bref), rc); return ELDLM_NAMESPACE_EXISTS; @@ -1335,6 +1335,7 @@ void ldlm_dump_all_namespaces(ldlm_side_t client, int level) list_for_each(tmp, ldlm_namespace_list(client)) { struct ldlm_namespace *ns; + ns = list_entry(tmp, struct ldlm_namespace, ns_list_chain); ldlm_namespace_dump(level, ns); } @@ -1404,8 +1405,8 @@ void ldlm_resource_dump(int level, struct ldlm_resource *res) LDLM_DEBUG_LIMIT(level, lock, "###"); if (!(level & D_CANTMASK) && ++granted > ldlm_dump_granted_max) { - CDEBUG(level, "only dump %d granted locks to " - "avoid DDOS.\n", granted); + CDEBUG(level, "only dump %d granted locks to avoid DDOS.\n", + granted); break; } } diff --git a/drivers/staging/lustre/lustre/libcfs/debug.c b/drivers/staging/lustre/lustre/libcfs/debug.c index ba43b3067fa3..a7a7ac626aaf 100644 --- a/drivers/staging/lustre/lustre/libcfs/debug.c +++ b/drivers/staging/lustre/lustre/libcfs/debug.c @@ -318,9 +318,7 @@ libcfs_debug_str2mask(int *mask, const char *str, int is_subsys) if (t >= 1 && matched == n) { /* don't print warning for lctl set_param debug=0 or -1 */ if (m != 0 && m != -1) - CWARN("You are trying to use a numerical value for the " - "mask - this will be deprecated in a future " - "release.\n"); + CWARN("You are trying to use a numerical value for the mask - this will be deprecated in a future release.\n"); *mask = m; return 0; } @@ -375,8 +373,8 @@ void libcfs_debug_dumplog(void) (void *)(long)current_pid(), "libcfs_debug_dumper"); if (IS_ERR(dumper)) - pr_err("LustreError: cannot start log dump thread:" - " %ld\n", PTR_ERR(dumper)); + pr_err("LustreError: cannot start log dump thread: %ld\n", + PTR_ERR(dumper)); else schedule(); @@ -412,7 +410,7 @@ int libcfs_debug_init(unsigned long bufsize) max = TCD_MAX_PAGES; } else { max = (max / num_possible_cpus()); - max = (max << (20 - PAGE_CACHE_SHIFT)); + max = max << (20 - PAGE_CACHE_SHIFT); } rc = cfs_tracefile_init(max); @@ -460,11 +458,3 @@ void libcfs_debug_set_level(unsigned int debug_level) } EXPORT_SYMBOL(libcfs_debug_set_level); - -void libcfs_log_goto(struct libcfs_debug_msg_data *msgdata, const char *label, - long_ptr_t rc) -{ - libcfs_debug_msg(msgdata, "Process leaving via %s (rc=%lu : %ld : %#lx)\n", - label, (ulong_ptr_t)rc, rc, rc); -} -EXPORT_SYMBOL(libcfs_log_goto); diff --git a/drivers/staging/lustre/lustre/libcfs/fail.c b/drivers/staging/lustre/lustre/libcfs/fail.c index e73ca3df9734..92444b0fe2a3 100644 --- a/drivers/staging/lustre/lustre/libcfs/fail.c +++ b/drivers/staging/lustre/lustre/libcfs/fail.c @@ -103,18 +103,18 @@ int __cfs_fail_check_set(__u32 id, __u32 value, int set) } switch (set) { - case CFS_FAIL_LOC_NOSET: - case CFS_FAIL_LOC_VALUE: - break; - case CFS_FAIL_LOC_ORSET: - cfs_fail_loc |= value & ~(CFS_FAILED | CFS_FAIL_ONCE); - break; - case CFS_FAIL_LOC_RESET: - cfs_fail_loc = value; - break; - default: - LASSERTF(0, "called with bad set %u\n", set); - break; + case CFS_FAIL_LOC_NOSET: + case CFS_FAIL_LOC_VALUE: + break; + case CFS_FAIL_LOC_ORSET: + cfs_fail_loc |= value & ~(CFS_FAILED | CFS_FAIL_ONCE); + break; + case CFS_FAIL_LOC_RESET: + cfs_fail_loc = value; + break; + default: + LASSERTF(0, "called with bad set %u\n", set); + break; } return 1; diff --git a/drivers/staging/lustre/lustre/libcfs/hash.c b/drivers/staging/lustre/lustre/libcfs/hash.c index 3b67b7b6428c..2d1e6729e996 100644 --- a/drivers/staging/lustre/lustre/libcfs/hash.c +++ b/drivers/staging/lustre/lustre/libcfs/hash.c @@ -1121,8 +1121,7 @@ cfs_hash_destroy(struct cfs_hash *hs) cfs_hash_bd_for_each_hlist(hs, &bd, hhead) { hlist_for_each_safe(hnode, pos, hhead) { LASSERTF(!cfs_hash_with_assert_empty(hs), - "hash %s bucket %u(%u) is not " - " empty: %u items left\n", + "hash %s bucket %u(%u) is not empty: %u items left\n", hs->hs_name, bd.bd_bucket->hsb_index, bd.bd_offset, bd.bd_bucket->hsb_count); /* can't assert key valicate, because we @@ -1371,8 +1370,7 @@ cfs_hash_lookup(struct cfs_hash *hs, const void *key) EXPORT_SYMBOL(cfs_hash_lookup); static void -cfs_hash_for_each_enter(struct cfs_hash *hs) -{ +cfs_hash_for_each_enter(struct cfs_hash *hs) { LASSERT(!cfs_hash_is_exiting(hs)); if (!cfs_hash_with_rehash(hs)) @@ -1397,8 +1395,7 @@ cfs_hash_for_each_enter(struct cfs_hash *hs) } static void -cfs_hash_for_each_exit(struct cfs_hash *hs) -{ +cfs_hash_for_each_exit(struct cfs_hash *hs) { int remained; int bits; @@ -1429,8 +1426,7 @@ cfs_hash_for_each_exit(struct cfs_hash *hs) */ static __u64 cfs_hash_for_each_tight(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, - void *data, int remove_safe) -{ + void *data, int remove_safe) { struct hlist_node *hnode; struct hlist_node *pos; struct cfs_hash_bd bd; @@ -1523,8 +1519,7 @@ EXPORT_SYMBOL(cfs_hash_for_each); void cfs_hash_for_each_safe(struct cfs_hash *hs, - cfs_hash_for_each_cb_t func, void *data) -{ + cfs_hash_for_each_cb_t func, void *data) { cfs_hash_for_each_tight(hs, func, data, 1); } EXPORT_SYMBOL(cfs_hash_for_each_safe); @@ -1572,8 +1567,8 @@ EXPORT_SYMBOL(cfs_hash_size_get); * two cases, so iteration has to be stopped on change. */ static int -cfs_hash_for_each_relax(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, void *data) -{ +cfs_hash_for_each_relax(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, + void *data) { struct hlist_node *hnode; struct hlist_node *tmp; struct cfs_hash_bd bd; @@ -1634,8 +1629,7 @@ cfs_hash_for_each_relax(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, void * int cfs_hash_for_each_nolock(struct cfs_hash *hs, - cfs_hash_for_each_cb_t func, void *data) -{ + cfs_hash_for_each_cb_t func, void *data) { if (cfs_hash_with_no_lock(hs) || cfs_hash_with_rehash_key(hs) || !cfs_hash_with_no_itemref(hs)) @@ -1667,8 +1661,7 @@ EXPORT_SYMBOL(cfs_hash_for_each_nolock); */ int cfs_hash_for_each_empty(struct cfs_hash *hs, - cfs_hash_for_each_cb_t func, void *data) -{ + cfs_hash_for_each_cb_t func, void *data) { unsigned i = 0; if (cfs_hash_with_no_lock(hs)) @@ -1726,8 +1719,7 @@ EXPORT_SYMBOL(cfs_hash_hlist_for_each); */ void cfs_hash_for_each_key(struct cfs_hash *hs, const void *key, - cfs_hash_for_each_cb_t func, void *data) -{ + cfs_hash_for_each_cb_t func, void *data) { struct hlist_node *hnode; struct cfs_hash_bd bds[2]; unsigned i; diff --git a/drivers/staging/lustre/lustre/libcfs/libcfs_cpu.c b/drivers/staging/lustre/lustre/libcfs/libcfs_cpu.c index dbb81b6cc200..31a558115a96 100644 --- a/drivers/staging/lustre/lustre/libcfs/libcfs_cpu.c +++ b/drivers/staging/lustre/lustre/libcfs/libcfs_cpu.c @@ -38,7 +38,7 @@ #include "../../include/linux/libcfs/libcfs.h" /** Global CPU partition table */ -struct cfs_cpt_table *cfs_cpt_table __read_mostly = NULL; +struct cfs_cpt_table *cfs_cpt_table __read_mostly; EXPORT_SYMBOL(cfs_cpt_table); #ifndef HAVE_LIBCFS_CPT diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c index 224c65b5ce4e..05f7595f18aa 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c @@ -333,8 +333,8 @@ cfs_cpt_unset_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu) /* caller doesn't know the partition ID */ cpt = cptab->ctb_cpu2cpt[cpu]; if (cpt < 0) { /* not set in this CPT-table */ - CDEBUG(D_INFO, "Try to unset cpu %d which is " - "not in CPT-table %p\n", cpt, cptab); + CDEBUG(D_INFO, "Try to unset cpu %d which is not in CPT-table %p\n", + cpt, cptab); return; } @@ -384,8 +384,8 @@ cfs_cpt_set_cpumask(struct cfs_cpt_table *cptab, int cpt, cpumask_t *mask) int i; if (cpus_weight(*mask) == 0 || any_online_cpu(*mask) == NR_CPUS) { - CDEBUG(D_INFO, "No online CPU is found in the CPU mask " - "for CPU partition %d\n", cpt); + CDEBUG(D_INFO, "No online CPU is found in the CPU mask for CPU partition %d\n", + cpt); return 0; } @@ -579,9 +579,8 @@ cfs_cpt_bind(struct cfs_cpt_table *cptab, int cpt) } if (any_online_cpu(*cpumask) == NR_CPUS) { - CERROR("No online CPU found in CPU partition %d, did someone " - "do CPU hotplug on system? You might need to reload " - "Lustre modules to keep system working well.\n", cpt); + CERROR("No online CPU found in CPU partition %d, did someone do CPU hotplug on system? You might need to reload Lustre modules to keep system working well.\n", + cpt); return -EINVAL; } @@ -737,16 +736,12 @@ cfs_cpt_table_create(int ncpt) ncpt = rc; if (ncpt > num_online_cpus() || ncpt > 4 * rc) { - CWARN("CPU partition number %d is larger than suggested " - "value (%d), your system may have performance" - "issue or run out of memory while under pressure\n", + CWARN("CPU partition number %d is larger than suggested value (%d), your system may have performance issue or run out of memory while under pressure\n", ncpt, rc); } if (num_online_cpus() % ncpt != 0) { - CERROR("CPU number %d is not multiple of cpu_npartition %d, " - "please try different cpu_npartitions value or" - "set pattern string by cpu_pattern=STRING\n", + CERROR("CPU number %d is not multiple of cpu_npartition %d, please try different cpu_npartitions value or set pattern string by cpu_pattern=STRING\n", (int)num_online_cpus(), ncpt); goto failed; } @@ -796,8 +791,7 @@ cfs_cpt_table_create(int ncpt) if (cpt != ncpt || num != cpus_weight(*cptab->ctb_parts[ncpt - 1].cpt_cpumask)) { - CERROR("Expect %d(%d) CPU partitions but got %d(%d), " - "CPU hotplug/unplug while setting?\n", + CERROR("Expect %d(%d) CPU partitions but got %d(%d), CPU hotplug/unplug while setting?\n", cptab->ctb_nparts, num, cpt, cpus_weight(*cptab->ctb_parts[ncpt - 1].cpt_cpumask)); goto failed; @@ -808,8 +802,7 @@ cfs_cpt_table_create(int ncpt) return cptab; failed: - CERROR("Failed to setup CPU-partition-table with %d " - "CPU-partitions, online HW nodes: %d, HW cpus: %d.\n", + CERROR("Failed to setup CPU-partition-table with %d CPU-partitions, online HW nodes: %d, HW cpus: %d.\n", ncpt, num_online_nodes(), num_online_cpus()); if (mask != NULL) @@ -975,9 +968,8 @@ cfs_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) warn = any_online_cpu(*cpt_data.cpt_cpumask) >= nr_cpu_ids; mutex_unlock(&cpt_data.cpt_mutex); CDEBUG(warn ? D_WARNING : D_INFO, - "Lustre: can't support CPU plug-out well now, " - "performance and stability could be impacted " - "[CPU %u action: %lx]\n", cpu, action); + "Lustre: can't support CPU plug-out well now, performance and stability could be impacted [CPU %u action: %lx]\n", + cpu, action); } return NOTIFY_OK; diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-debug.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-debug.c index 3298ddf6d3be..12005a71aa73 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-debug.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-debug.c @@ -87,8 +87,7 @@ void libcfs_run_debug_log_upcall(char *file) rc = call_usermodehelper(argv[0], argv, envp, 1); if (rc < 0 && rc != -ENOENT) { - CERROR("Error %d invoking LNET debug log upcall %s %s; " - "check /proc/sys/lnet/debug_log_upcall\n", + CERROR("Error %d invoking LNET debug log upcall %s %s; check /proc/sys/lnet/debug_log_upcall\n", rc, argv[0], argv[1]); } else { CDEBUG(D_HA, "Invoked LNET debug log upcall %s %s\n", @@ -114,8 +113,7 @@ void libcfs_run_upcall(char **argv) rc = call_usermodehelper(argv[0], argv, envp, 1); if (rc < 0 && rc != -ENOENT) { - CERROR("Error %d invoking LNET upcall %s %s%s%s%s%s%s%s%s; " - "check /proc/sys/lnet/upcall\n", + CERROR("Error %d invoking LNET upcall %s %s%s%s%s%s%s%s%s; check /proc/sys/lnet/upcall\n", rc, argv[0], argv[1], argc < 3 ? "" : ",", argc < 3 ? "" : argv[2], argc < 4 ? "" : ",", argc < 4 ? "" : argv[3], diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c index bbe2c68c18a6..83d3f08a37b2 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c @@ -365,8 +365,8 @@ static int __proc_cpt_table(void *data, int write, if (rc >= 0) break; - LIBCFS_FREE(buf, len); if (rc == -EFBIG) { + LIBCFS_FREE(buf, len); len <<= 1; continue; } diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c index 939b33dd6520..b91a1f95bbd0 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c @@ -279,8 +279,7 @@ libcfs_sock_write (struct socket *sock, void *buffer, int nob, int timeout) rc = kernel_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(tv)); if (rc != 0) { - CERROR("Can't set socket send timeout " - "%ld.%06d: %d\n", + CERROR("Can't set socket send timeout %ld.%06d: %d\n", (long)tv.tv_sec, (int)tv.tv_usec, rc); return rc; } diff --git a/drivers/staging/lustre/lustre/libcfs/tracefile.c b/drivers/staging/lustre/lustre/libcfs/tracefile.c index 7561030c96e6..5917c31c7ed6 100644 --- a/drivers/staging/lustre/lustre/libcfs/tracefile.c +++ b/drivers/staging/lustre/lustre/libcfs/tracefile.c @@ -196,8 +196,7 @@ static void cfs_tcd_shrink(struct cfs_trace_cpu_data *tcd) */ if (printk_ratelimit()) - printk(KERN_WARNING "debug daemon buffer overflowed; " - "discarding 10%% of pages (%d of %ld)\n", + printk(KERN_WARNING "debug daemon buffer overflowed; discarding 10%% of pages (%d of %ld)\n", pgcount + 1, tcd->tcd_cur_pages); INIT_LIST_HEAD(&pc.pc_pages); @@ -357,8 +356,8 @@ int libcfs_debug_vmsg2(struct libcfs_debug_msg_data *msgdata, } if (*(string_buf+needed-1) != '\n') - printk(KERN_INFO "format at %s:%d:%s doesn't end in " - "newline\n", file, msgdata->msg_line, msgdata->msg_fn); + printk(KERN_INFO "format at %s:%d:%s doesn't end in newline\n", + file, msgdata->msg_line, msgdata->msg_fn); header.ph_len = known_size + needed; debug_buf = (char *)page_address(tage->page) + tage->used; @@ -715,8 +714,8 @@ int cfs_tracefile_dump_all_pages(char *filename) kunmap(tage->page); if (rc != (int)tage->used) { - printk(KERN_WARNING "wanted to write %u but wrote " - "%d\n", tage->used, rc); + printk(KERN_WARNING "wanted to write %u but wrote %d\n", + tage->used, rc); put_pages_back(&pc); __LASSERT(list_empty(&pc.pc_pages)); break; @@ -875,8 +874,8 @@ int cfs_trace_daemon_command(char *str) strcpy(cfs_tracefile, str); printk(KERN_INFO - "Lustre: debug daemon will attempt to start writing " - "to %s (%lukB max)\n", cfs_tracefile, + "Lustre: debug daemon will attempt to start writing to %s (%lukB max)\n", + cfs_tracefile, (long)(cfs_tracefile_size >> 10)); cfs_trace_start_thread(); @@ -914,15 +913,15 @@ int cfs_trace_set_debug_mb(int mb) if (mb < num_possible_cpus()) { printk(KERN_WARNING - "Lustre: %d MB is too small for debug buffer size, " - "setting it to %d MB.\n", mb, num_possible_cpus()); + "Lustre: %d MB is too small for debug buffer size, setting it to %d MB.\n", + mb, num_possible_cpus()); mb = num_possible_cpus(); } if (mb > limit) { printk(KERN_WARNING - "Lustre: %d MB is too large for debug buffer size, " - "setting it to %d MB.\n", mb, limit); + "Lustre: %d MB is too large for debug buffer size, setting it to %d MB.\n", + mb, limit); mb = limit; } @@ -1004,8 +1003,8 @@ static int tracefiled(void *arg) if (IS_ERR(filp)) { rc = PTR_ERR(filp); filp = NULL; - printk(KERN_WARNING "couldn't open %s: " - "%d\n", cfs_tracefile, rc); + printk(KERN_WARNING "couldn't open %s: %d\n", + cfs_tracefile, rc); } } cfs_tracefile_read_unlock(); @@ -1034,8 +1033,8 @@ static int tracefiled(void *arg) kunmap(tage->page); if (rc != (int)tage->used) { - printk(KERN_WARNING "wanted to write %u " - "but wrote %d\n", tage->used, rc); + printk(KERN_WARNING "wanted to write %u but wrote %d\n", + tage->used, rc); put_pages_back(&pc); __LASSERT(list_empty(&pc.pc_pages)); } @@ -1047,8 +1046,7 @@ static int tracefiled(void *arg) if (!list_empty(&pc.pc_pages)) { int i; - printk(KERN_ALERT "Lustre: trace pages aren't " - " empty\n"); + printk(KERN_ALERT "Lustre: trace pages aren't empty\n"); printk(KERN_ERR "total cpus(%d): ", num_possible_cpus()); for (i = 0; i < num_possible_cpus(); i++) @@ -1061,8 +1059,8 @@ static int tracefiled(void *arg) i = 0; list_for_each_entry_safe(tage, tmp, &pc.pc_pages, linkage) - printk(KERN_ERR "page %d belongs to cpu " - "%d\n", ++i, tage->cpu); + printk(KERN_ERR "page %d belongs to cpu %d\n", + ++i, tage->cpu); printk(KERN_ERR "There are %d pages unwritten\n", i); } diff --git a/drivers/staging/lustre/lustre/llite/dcache.c b/drivers/staging/lustre/lustre/llite/dcache.c index f692261e9b5c..5bb9c85cec81 100644 --- a/drivers/staging/lustre/lustre/llite/dcache.c +++ b/drivers/staging/lustre/lustre/llite/dcache.c @@ -259,8 +259,8 @@ void ll_invalidate_aliases(struct inode *inode) ll_lock_dcache(inode); ll_d_hlist_for_each_entry(dentry, p, &inode->i_dentry, d_u.d_alias) { - CDEBUG(D_DENTRY, "dentry in drop %pd (%p) parent %p " - "inode %p flags %d\n", dentry, dentry, dentry->d_parent, + CDEBUG(D_DENTRY, "dentry in drop %pd (%p) parent %p inode %p flags %d\n", + dentry, dentry, dentry->d_parent, dentry->d_inode, dentry->d_flags); if (unlikely(dentry == dentry->d_sb->s_root)) { diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index a79fd65ec4c6..1ac7a702ce26 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -163,7 +163,7 @@ static int ll_dir_filler(void *_hash, struct page *page0) LASSERT(max_pages > 0 && max_pages <= MD_MAX_BRW_PAGES); - page_pool = kzalloc(sizeof(page) * max_pages, GFP_NOFS); + page_pool = kcalloc(max_pages, sizeof(page), GFP_NOFS); if (page_pool) { page_pool[0] = page0; } else { @@ -228,8 +228,8 @@ static int ll_dir_filler(void *_hash, struct page *page0) if (ll_pagevec_add(&lru_pvec, page) == 0) ll_pagevec_lru_add_file(&lru_pvec); } else { - CDEBUG(D_VFSTRACE, "page %lu add to page cache failed:" - " %d\n", offset, ret); + CDEBUG(D_VFSTRACE, "page %lu add to page cache failed: %d\n", + offset, ret); } page_cache_release(page); } @@ -275,14 +275,14 @@ static struct page *ll_dir_page_locate(struct inode *dir, __u64 *hash, struct page *page; int found; - TREE_READ_LOCK_IRQ(mapping); + spin_lock_irq(&mapping->tree_lock); found = radix_tree_gang_lookup(&mapping->page_tree, (void **)&page, offset, 1); if (found > 0) { struct lu_dirpage *dp; page_cache_get(page); - TREE_READ_UNLOCK_IRQ(mapping); + spin_unlock_irq(&mapping->tree_lock); /* * In contrast to find_lock_page() we are sure that directory * page cannot be truncated (while DLM lock is held) and, @@ -326,7 +326,7 @@ static struct page *ll_dir_page_locate(struct inode *dir, __u64 *hash, } } else { - TREE_READ_UNLOCK_IRQ(mapping); + spin_unlock_irq(&mapping->tree_lock); page = NULL; } return page; @@ -600,8 +600,8 @@ static int ll_readdir(struct file *filp, struct dir_context *ctx) int api32 = ll_need_32bit_api(sbi); int rc; - CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p) pos %lu/%llu " - " 32bit_api %d\n", inode->i_ino, inode->i_generation, + CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p) pos %lu/%llu 32bit_api %d\n", + inode->i_ino, inode->i_generation, inode, (unsigned long)lfd->lfd_pos, i_size_read(inode), api32); if (lfd->lfd_pos == MDS_DIR_END_OFF) { @@ -661,7 +661,7 @@ int ll_dir_setdirstripe(struct inode *dir, struct lmv_user_md *lump, int mode; int err; - mode = (0755 & (S_IRWXUGO|S_ISVTX) & ~current->fs->umask) | S_IFDIR; + mode = (0755 & ~current_umask()) | S_IFDIR; op_data = ll_prep_md_op_data(NULL, dir, NULL, filename, strlen(filename), mode, LUSTRE_OPC_MKDIR, lump); @@ -715,10 +715,9 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, break; } default: { - CDEBUG(D_IOCTL, "bad userland LOV MAGIC:" - " %#08x != %#08x nor %#08x\n", - lump->lmm_magic, LOV_USER_MAGIC_V1, - LOV_USER_MAGIC_V3); + CDEBUG(D_IOCTL, "bad userland LOV MAGIC: %#08x != %#08x nor %#08x\n", + lump->lmm_magic, LOV_USER_MAGIC_V1, + LOV_USER_MAGIC_V3); return -EINVAL; } } @@ -814,8 +813,8 @@ int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp, rc = md_getattr(sbi->ll_md_exp, op_data, &req); ll_finish_md_op_data(op_data); if (rc < 0) { - CDEBUG(D_INFO, "md_getattr failed on inode " - "%lu/%u: rc %d\n", inode->i_ino, + CDEBUG(D_INFO, "md_getattr failed on inode %lu/%u: rc %d\n", + inode->i_ino, inode->i_generation, rc); goto out; } @@ -1013,8 +1012,7 @@ static int ll_ioc_copy_end(struct super_block *sb, struct hsm_copy *copy) copy->hc_hai.hai_action == HSMA_ARCHIVE); iput(inode); if (rc) { - CDEBUG(D_HSM, "Could not read file data version. " - "Request could not be confirmed.\n"); + CDEBUG(D_HSM, "Could not read file data version. Request could not be confirmed.\n"); if (hpk.hpk_errval == 0) hpk.hpk_errval = -rc; goto progress; @@ -1028,8 +1026,7 @@ static int ll_ioc_copy_end(struct super_block *sb, struct hsm_copy *copy) * to check anyway. */ if ((copy->hc_hai.hai_action == HSMA_ARCHIVE) && (copy->hc_data_version != data_version)) { - CDEBUG(D_HSM, "File data version mismatched. " - "File content was changed during archiving. " + CDEBUG(D_HSM, "File data version mismatched. File content was changed during archiving. " DFID", start:%#llx current:%#llx\n", PFID(©->hc_hai.hai_fid), copy->hc_data_version, data_version); @@ -1384,7 +1381,7 @@ lmv_out_free: if (copy_from_user(lumv1, lumv1p, sizeof(*lumv1))) return -EFAULT; - if ((lumv1->lmm_magic == LOV_USER_MAGIC_V3) ) { + if (lumv1->lmm_magic == LOV_USER_MAGIC_V3) { if (copy_from_user(&lumv3, lumv3p, sizeof(lumv3))) return -EFAULT; } @@ -1509,8 +1506,7 @@ out_rmdir: cmd == LL_IOC_MDC_GETINFO)) { rc = 0; goto skip_lmm; - } - else + } else goto out_req; } @@ -1694,64 +1690,6 @@ out_poll: OBD_FREE_PTR(check); return rc; } -#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0) - case LL_IOC_QUOTACTL_18: { - /* copy the old 1.x quota struct for internal use, then copy - * back into old format struct. For 1.8 compatibility. */ - struct if_quotactl_18 *qctl_18; - struct if_quotactl *qctl_20; - - qctl_18 = kzalloc(sizeof(*qctl_18), GFP_NOFS); - if (!qctl_18) - return -ENOMEM; - - qctl_20 = kzalloc(sizeof(*qctl_20), GFP_NOFS); - if (!qctl_20) { - rc = -ENOMEM; - goto out_quotactl_18; - } - - if (copy_from_user(qctl_18, (void *)arg, sizeof(*qctl_18))) { - rc = -ENOMEM; - goto out_quotactl_20; - } - - QCTL_COPY(qctl_20, qctl_18); - qctl_20->qc_idx = 0; - - /* XXX: dqb_valid was borrowed as a flag to mark that - * only mds quota is wanted */ - if (qctl_18->qc_cmd == Q_GETQUOTA && - qctl_18->qc_dqblk.dqb_valid) { - qctl_20->qc_valid = QC_MDTIDX; - qctl_20->qc_dqblk.dqb_valid = 0; - } else if (qctl_18->obd_uuid.uuid[0] != '\0') { - qctl_20->qc_valid = QC_UUID; - qctl_20->obd_uuid = qctl_18->obd_uuid; - } else { - qctl_20->qc_valid = QC_GENERAL; - } - - rc = quotactl_ioctl(sbi, qctl_20); - - if (rc == 0) { - QCTL_COPY(qctl_18, qctl_20); - qctl_18->obd_uuid = qctl_20->obd_uuid; - - if (copy_to_user((void *)arg, qctl_18, - sizeof(*qctl_18))) - rc = -EFAULT; - } - -out_quotactl_20: - OBD_FREE_PTR(qctl_20); -out_quotactl_18: - OBD_FREE_PTR(qctl_18); - return rc; - } -#else -#warning "remove old LL_IOC_QUOTACTL_18 compatibility code" -#endif /* LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0) */ case LL_IOC_QUOTACTL: { struct if_quotactl *qctl; diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index a2ae9a68a9a0..35a2df01528c 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -170,8 +170,8 @@ static int ll_close_inode_openhandle(struct obd_export *md_exp, * OSTs and send setattr to back to MDS. */ rc = ll_som_update(inode, op_data); if (rc) { - CERROR("inode %lu mdc Size-on-MDS update failed: " - "rc = %d\n", inode->i_ino, rc); + CERROR("inode %lu mdc Size-on-MDS update failed: rc = %d\n", + inode->i_ino, rc); rc = 0; } } else if (rc) { @@ -247,7 +247,7 @@ int ll_md_real_close(struct inode *inode, fmode_t fmode) return 0; } - och=*och_p; + och = *och_p; *och_p = NULL; mutex_unlock(&lli->lli_och_mutex); @@ -358,7 +358,7 @@ int ll_file_release(struct inode *inode, struct file *file) fd = LUSTRE_FPRIVATE(file); LASSERT(fd != NULL); - /* The last ref on @file, maybe not the the owner pid of statahead. + /* The last ref on @file, maybe not the owner pid of statahead. * Different processes can open the same dir, "ll_opendir_key" means: * it is me that should stop the statahead thread. */ if (S_ISDIR(inode->i_mode) && lli->lli_opendir_key == fd && @@ -975,8 +975,8 @@ int ll_inode_getattr(struct inode *inode, struct obdo *obdo, struct ost_id *oi = lsm ? &lsm->lsm_oi : &obdo->o_oi; obdo_refresh_inode(inode, obdo, obdo->o_valid); - CDEBUG(D_INODE, "objid "DOSTID" size %llu, blocks %llu," - " blksize %lu\n", POSTID(oi), i_size_read(inode), + CDEBUG(D_INODE, "objid " DOSTID " size %llu, blocks %llu, blksize %lu\n", + POSTID(oi), i_size_read(inode), (unsigned long long)inode->i_blocks, 1UL << inode->i_blkbits); } @@ -1403,8 +1403,8 @@ int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename, rc = md_getattr_name(sbi->ll_md_exp, op_data, &req); ll_finish_md_op_data(op_data); if (rc < 0) { - CDEBUG(D_INFO, "md_getattr_name failed " - "on %s: rc %d\n", filename, rc); + CDEBUG(D_INFO, "md_getattr_name failed on %s: rc %d\n", + filename, rc); goto out; } @@ -2221,8 +2221,8 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (cmd == LL_IOC_SETFLAGS) { if ((flags & LL_FILE_IGNORE_LOCK) && !(file->f_flags & O_DIRECT)) { - CERROR("%s: unable to disable locking on " - "non-O_DIRECT file\n", current->comm); + CERROR("%s: unable to disable locking on non-O_DIRECT file\n", + current->comm); return -EINVAL; } @@ -2848,7 +2848,7 @@ ldlm_mode_t ll_take_md_lock(struct inode *inode, __u64 bits, struct lustre_handle *lockh, __u64 flags, ldlm_mode_t mode) { - ldlm_policy_data_t policy = { .l_inodebits = {bits}}; + ldlm_policy_data_t policy = { .l_inodebits = {bits} }; struct lu_fid *fid; ldlm_mode_t rc; diff --git a/drivers/staging/lustre/lustre/llite/llite_capa.c b/drivers/staging/lustre/lustre/llite/llite_capa.c index b1e39ee412cd..aec9a44120c0 100644 --- a/drivers/staging/lustre/lustre/llite/llite_capa.c +++ b/drivers/staging/lustre/lustre/llite/llite_capa.c @@ -540,8 +540,7 @@ static int ll_update_capa(struct obd_capa *ocapa, struct lustre_capa *capa) if (rc == -EIO && !capa_is_expired(ocapa)) { delay_capa_renew(ocapa, 120); DEBUG_CAPA(D_ERROR, &ocapa->c_capa, - "renewal failed: -EIO, " - "retry in 2 mins"); + "renewal failed: -EIO, retry in 2 mins"); ll_capa_renewal_retries++; goto retry; } else { diff --git a/drivers/staging/lustre/lustre/llite/llite_close.c b/drivers/staging/lustre/lustre/llite/llite_close.c index 84e0003f2daf..21b4a5026776 100644 --- a/drivers/staging/lustre/lustre/llite/llite_close.c +++ b/drivers/staging/lustre/lustre/llite/llite_close.c @@ -90,8 +90,7 @@ void ll_queue_done_writing(struct inode *inode, unsigned long flags) struct ll_close_queue *lcq = ll_i2sbi(inode)->ll_lcq; if (lli->lli_flags & LLIF_MDS_SIZE_LOCK) - CWARN("ino %lu/%u(flags %u) som valid it just after " - "recovery\n", + CWARN("ino %lu/%u(flags %u) som valid it just after recovery\n", inode->i_ino, inode->i_generation, lli->lli_flags); /* DONE_WRITING is allowed and inode has no dirty page. */ @@ -124,8 +123,8 @@ void ll_done_writing_attr(struct inode *inode, struct md_op_data *op_data) op_data->op_flags |= MF_SOM_CHANGE; /* Check if Size-on-MDS attributes are valid. */ if (lli->lli_flags & LLIF_MDS_SIZE_LOCK) - CERROR("ino %lu/%u(flags %u) som valid it just after " - "recovery\n", inode->i_ino, inode->i_generation, + CERROR("ino %lu/%u(flags %u) som valid it just after recovery\n", + inode->i_ino, inode->i_generation, lli->lli_flags); if (!cl_local_size(inode)) { @@ -218,8 +217,8 @@ int ll_som_update(struct inode *inode, struct md_op_data *op_data) LASSERT(op_data != NULL); if (lli->lli_flags & LLIF_MDS_SIZE_LOCK) - CERROR("ino %lu/%u(flags %u) som valid it just after " - "recovery\n", inode->i_ino, inode->i_generation, + CERROR("ino %lu/%u(flags %u) som valid it just after recovery\n", + inode->i_ino, inode->i_generation, lli->lli_flags); OBDO_ALLOC(oa); @@ -238,9 +237,8 @@ int ll_som_update(struct inode *inode, struct md_op_data *op_data) if (rc) { oa->o_valid = 0; if (rc != -ENOENT) - CERROR("inode_getattr failed (%d): unable to " - "send a Size-on-MDS attribute update " - "for inode %lu/%u\n", rc, inode->i_ino, + CERROR("inode_getattr failed (%d): unable to send a Size-on-MDS attribute update for inode %lu/%u\n", + rc, inode->i_ino, inode->i_generation); } else { CDEBUG(D_INODE, "Size-on-MDS update on "DFID"\n", diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 77d1c12704b4..37306e0c7aad 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -1435,8 +1435,8 @@ static inline void ll_set_lock_data(struct obd_export *exp, struct inode *inode, * case the dcache being cleared */ if (it->d.lustre.it_remote_lock_mode) { handle.cookie = it->d.lustre.it_remote_lock_handle; - CDEBUG(D_DLMTRACE, "setting l_data to inode %p" - "(%lu/%u) for remote lock %#llx\n", inode, + CDEBUG(D_DLMTRACE, "setting l_data to inode %p(%lu/%u) for remote lock %#llx\n", + inode, inode->i_ino, inode->i_generation, handle.cookie); md_set_lock_data(exp, &handle.cookie, inode, NULL); @@ -1444,8 +1444,8 @@ static inline void ll_set_lock_data(struct obd_export *exp, struct inode *inode, handle.cookie = it->d.lustre.it_lock_handle; - CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u)" - " for lock %#llx\n", inode, inode->i_ino, + CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u) for lock %#llx\n", + inode, inode->i_ino, inode->i_generation, handle.cookie); md_set_lock_data(exp, &handle.cookie, inode, @@ -1489,8 +1489,8 @@ static inline void __d_lustre_invalidate(struct dentry *dentry) */ static inline void d_lustre_invalidate(struct dentry *dentry, int nested) { - CDEBUG(D_DENTRY, "invalidate dentry %pd (%p) parent %p inode %p " - "refc %d\n", dentry, dentry, + CDEBUG(D_DENTRY, "invalidate dentry %pd (%p) parent %p inode %p refc %d\n", + dentry, dentry, dentry->d_parent, dentry->d_inode, d_count(dentry)); spin_lock_nested(&dentry->d_lock, @@ -1509,24 +1509,6 @@ static inline void d_lustre_revalidate(struct dentry *dentry) spin_unlock(&dentry->d_lock); } -#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0) -/* Compatibility for old (1.8) compiled userspace quota code */ -struct if_quotactl_18 { - __u32 qc_cmd; - __u32 qc_type; - __u32 qc_id; - __u32 qc_stat; - struct obd_dqinfo qc_dqinfo; - struct obd_dqblk qc_dqblk; - char obd_type[16]; - struct obd_uuid obd_uuid; -}; -#define LL_IOC_QUOTACTL_18 _IOWR('f', 162, struct if_quotactl_18 *) -/* End compatibility for old (1.8) compiled userspace quota code */ -#else -#warning "remove old LL_IOC_QUOTACTL_18 compatibility code" -#endif /* LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0) */ - enum { LL_LAYOUT_GEN_NONE = ((__u32)-2), /* layout lock was cancelled */ LL_LAYOUT_GEN_EMPTY = ((__u32)-1) /* for empty layout */ diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 7b6b9e2e0102..a3367bfb1456 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -250,12 +250,11 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, data->ocd_brw_size = MD_MAX_BRW_SIZE; - err = obd_connect(NULL, &sbi->ll_md_exp, obd, &sbi->ll_sb_uuid, data, NULL); + err = obd_connect(NULL, &sbi->ll_md_exp, obd, &sbi->ll_sb_uuid, + data, NULL); if (err == -EBUSY) { - LCONSOLE_ERROR_MSG(0x14f, "An MDT (md %s) is performing " - "recovery, of which this client is not a " - "part. Please wait for recovery to complete," - " abort, or time out.\n", md); + LCONSOLE_ERROR_MSG(0x14f, "An MDT (md %s) is performing recovery, of which this client is not a part. Please wait for recovery to complete, abort, or time out.\n", + md); goto out; } else if (err) { CERROR("cannot connect to %s: rc = %d\n", md, err); @@ -267,8 +266,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, err = obd_fid_init(sbi->ll_md_exp->exp_obd, sbi->ll_md_exp, LUSTRE_SEQ_METADATA); if (err) { - CERROR("%s: Can't init metadata layer FID infrastructure, " - "rc = %d\n", sbi->ll_md_exp->exp_obd->obd_name, err); + CERROR("%s: Can't init metadata layer FID infrastructure, rc = %d\n", + sbi->ll_md_exp->exp_obd->obd_name, err); goto out_md; } @@ -296,10 +295,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, buf = kzalloc(PAGE_CACHE_SIZE, GFP_KERNEL); obd_connect_flags2str(buf, PAGE_CACHE_SIZE, valid ^ CLIENT_CONNECT_MDT_REQD, ","); - LCONSOLE_ERROR_MSG(0x170, "Server %s does not support " - "feature(s) needed for correct operation " - "of this client (%s). Please upgrade " - "server or downgrade client.\n", + LCONSOLE_ERROR_MSG(0x170, "Server %s does not support feature(s) needed for correct operation of this client (%s). Please upgrade server or downgrade client.\n", sbi->ll_md_exp->exp_obd->obd_name, buf); OBD_FREE(buf, PAGE_CACHE_SIZE); err = -EPROTO; @@ -325,8 +321,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, if ((sbi->ll_flags & LL_SBI_USER_XATTR) && !(data->ocd_connect_flags & OBD_CONNECT_XATTR)) { - LCONSOLE_INFO("Disabling user_xattr feature because " - "it is not supported on the server\n"); + LCONSOLE_INFO("Disabling user_xattr feature because it is not supported on the server\n"); sbi->ll_flags &= ~LL_SBI_USER_XATTR; } @@ -351,8 +346,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, } else { if (sbi->ll_flags & LL_SBI_RMT_CLIENT) { sbi->ll_flags &= ~LL_SBI_RMT_CLIENT; - LCONSOLE_INFO("client claims to be remote, but server " - "rejected, forced to be local.\n"); + LCONSOLE_INFO("client claims to be remote, but server rejected, forced to be local.\n"); } } @@ -429,8 +423,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, if (sbi->ll_flags & LL_SBI_RMT_CLIENT) data->ocd_connect_flags |= OBD_CONNECT_RMT_CLIENT_FORCE; - CDEBUG(D_RPCTRACE, "ocd_connect_flags: %#llx ocd_version: %d " - "ocd_grant: %d\n", data->ocd_connect_flags, + CDEBUG(D_RPCTRACE, "ocd_connect_flags: %#llx ocd_version: %d ocd_grant: %d\n", + data->ocd_connect_flags, data->ocd_version, data->ocd_grant); obd->obd_upcall.onu_owner = &sbi->ll_lco; @@ -441,10 +435,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, err = obd_connect(NULL, &sbi->ll_dt_exp, obd, &sbi->ll_sb_uuid, data, NULL); if (err == -EBUSY) { - LCONSOLE_ERROR_MSG(0x150, "An OST (dt %s) is performing " - "recovery, of which this client is not a " - "part. Please wait for recovery to " - "complete, abort, or time out.\n", dt); + LCONSOLE_ERROR_MSG(0x150, "An OST (dt %s) is performing recovery, of which this client is not a part. Please wait for recovery to complete, abort, or time out.\n", + dt); goto out_md; } else if (err) { CERROR("%s: Cannot connect to %s: rc = %d\n", @@ -457,8 +449,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, err = obd_fid_init(sbi->ll_dt_exp->exp_obd, sbi->ll_dt_exp, LUSTRE_SEQ_METADATA); if (err) { - CERROR("%s: Can't init data layer FID infrastructure, " - "rc = %d\n", sbi->ll_dt_exp->exp_obd->obd_name, err); + CERROR("%s: Can't init data layer FID infrastructure, rc = %d\n", + sbi->ll_dt_exp->exp_obd->obd_name, err); goto out_dt; } @@ -698,9 +690,9 @@ void lustre_dump_dentry(struct dentry *dentry, int recur) list_for_each(tmp, &dentry->d_subdirs) subdirs++; - CERROR("dentry %p dump: name=%pd parent=%p, inode=%p, count=%u," - " flags=0x%x, fsdata=%p, %d subdirs\n", dentry, dentry, - dentry->d_parent, dentry->d_inode, d_count(dentry), + CERROR("dentry %p dump: name=%pd parent=%pd (%p), inode=%p, count=%u, flags=0x%x, fsdata=%p, %d subdirs\n", + dentry, dentry, dentry->d_parent, dentry->d_parent, + dentry->d_inode, d_count(dentry), dentry->d_flags, dentry->d_fsdata, subdirs); if (dentry->d_inode != NULL) ll_dump_inode(dentry->d_inode); @@ -710,6 +702,7 @@ void lustre_dump_dentry(struct dentry *dentry, int recur) list_for_each(tmp, &dentry->d_subdirs) { struct dentry *d = list_entry(tmp, struct dentry, d_child); + lustre_dump_dentry(d, recur - 1); } } @@ -754,9 +747,9 @@ void ll_kill_super(struct super_block *sb) return; sbi = ll_s2sbi(sb); - /* we need to restore s_dev from changed for clustered NFS before put_super - * because new kernels have cached s_dev and change sb->s_dev in - * put_super not affected real removing devices */ + /* we need to restore s_dev from changed for clustered NFS before + * put_super because new kernels have cached s_dev and change sb->s_dev + * in put_super not affected real removing devices */ if (sbi) { sb->s_dev = sbi->ll_sdev_orig; sbi->ll_umounting = 1; @@ -814,25 +807,6 @@ static int ll_options(char *options, int *flags) *flags &= ~tmp; goto next; } -#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 5, 50, 0) - tmp = ll_set_opt("acl", s1, LL_SBI_ACL); - if (tmp) { - /* Ignore deprecated mount option. The client will - * always try to mount with ACL support, whether this - * is used depends on whether server supports it. */ - LCONSOLE_ERROR_MSG(0x152, "Ignoring deprecated " - "mount option 'acl'.\n"); - goto next; - } - tmp = ll_set_opt("noacl", s1, LL_SBI_ACL); - if (tmp) { - LCONSOLE_ERROR_MSG(0x152, "Ignoring deprecated " - "mount option 'noacl'.\n"); - goto next; - } -#else -#warning "{no}acl options have been deprecated since 1.8, please remove them" -#endif tmp = ll_set_opt("remote_client", s1, LL_SBI_RMT_CLIENT); if (tmp) { *flags |= tmp; @@ -1038,9 +1012,8 @@ int ll_fill_super(struct super_block *sb, struct vfsmount *mnt) /* Profile set with LCFG_MOUNTOPT so we can find our mdc and osc obds */ lprof = class_get_profile(profilenm); if (lprof == NULL) { - LCONSOLE_ERROR_MSG(0x156, "The client profile '%s' could not be" - " read from the MGS. Does that filesystem " - "exist?\n", profilenm); + LCONSOLE_ERROR_MSG(0x156, "The client profile '%s' could not be read from the MGS. Does that filesystem exist?\n", + profilenm); err = -EINVAL; goto out_free; } @@ -1119,9 +1092,8 @@ void ll_put_super(struct super_block *sb) } next = 0; - while ((obd = class_devices_in_group(&sbi->ll_sb_uuid, &next)) !=NULL) { + while ((obd = class_devices_in_group(&sbi->ll_sb_uuid, &next))) class_manual_cleanup(obd); - } if (sbi->ll_flags & LL_SBI_VERBOSE) LCONSOLE_WARN("Unmounted %s\n", profilenm ? profilenm : ""); @@ -1150,14 +1122,14 @@ struct inode *ll_inode_from_resource_lock(struct ldlm_lock *lock) lock_res_and_lock(lock); if (lock->l_resource->lr_lvb_inode) { struct ll_inode_info *lli; + lli = ll_i2info(lock->l_resource->lr_lvb_inode); if (lli->lli_inode_magic == LLI_INODE_MAGIC) { inode = igrab(lock->l_resource->lr_lvb_inode); } else { inode = lock->l_resource->lr_lvb_inode; LDLM_DEBUG_LIMIT(inode->i_state & I_FREEING ? D_INFO : - D_WARNING, lock, "lr_lvb_inode %p is " - "bogus: magic %08x", + D_WARNING, lock, "lr_lvb_inode %p is bogus: magic %08x", lock->l_resource->lr_lvb_inode, lli->lli_inode_magic); inode = NULL; @@ -1730,11 +1702,11 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md) if (body->valid & OBD_MD_FLTYPE) inode->i_mode = (inode->i_mode & ~S_IFMT)|(body->mode & S_IFMT); LASSERT(inode->i_mode != 0); - if (S_ISREG(inode->i_mode)) { - inode->i_blkbits = min(PTLRPC_MAX_BRW_BITS + 1, LL_MAX_BLKSIZE_BITS); - } else { + if (S_ISREG(inode->i_mode)) + inode->i_blkbits = min(PTLRPC_MAX_BRW_BITS + 1, + LL_MAX_BLKSIZE_BITS); + else inode->i_blkbits = inode->i_sb->s_blocksize_bits; - } if (body->valid & OBD_MD_FLUID) inode->i_uid = make_kuid(&init_user_ns, body->uid); if (body->valid & OBD_MD_FLGID) @@ -1778,9 +1750,7 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md) if (lli->lli_flags & (LLIF_DONE_WRITING | LLIF_EPOCH_PENDING | LLIF_SOM_DIRTY)) { - CERROR("ino %lu flags %u still has " - "size authority! do not trust " - "the size got from MDS\n", + CERROR("ino %lu flags %u still has size authority! do not trust the size got from MDS\n", inode->i_ino, lli->lli_flags); } else { /* Use old size assignment to avoid @@ -1848,6 +1818,7 @@ void ll_read_inode2(struct inode *inode, void *opaque) if (S_ISREG(inode->i_mode)) { struct ll_sb_info *sbi = ll_i2sbi(inode); + inode->i_op = &ll_file_inode_operations; inode->i_fop = sbi->ll_fop; inode->i_mapping->a_ops = (struct address_space_operations *)&ll_aops; @@ -1878,11 +1849,10 @@ void ll_delete_inode(struct inode *inode) /* Workaround for LU-118 */ if (inode->i_data.nrpages) { - TREE_READ_LOCK_IRQ(&inode->i_data); - TREE_READ_UNLOCK_IRQ(&inode->i_data); + spin_lock_irq(&inode->i_data.tree_lock); + spin_unlock_irq(&inode->i_data.tree_lock); LASSERTF(inode->i_data.nrpages == 0, - "inode=%lu/%u(%p) nrpages=%lu, see " - "http://jira.whamcloud.com/browse/LU-118\n", + "inode=%lu/%u(%p) nrpages=%lu, see http://jira.whamcloud.com/browse/LU-118\n", inode->i_ino, inode->i_generation, inode, inode->i_data.nrpages); } @@ -2164,7 +2134,13 @@ int ll_obd_statfs(struct inode *inode, void *arg) __u32 flags; int len = 0, rc; - if (!inode || !(sbi = ll_i2sbi(inode))) { + if (!inode) { + rc = -EINVAL; + goto out_statfs; + } + + sbi = ll_i2sbi(inode); + if (!sbi) { rc = -EINVAL; goto out_statfs; } @@ -2396,21 +2372,6 @@ char *ll_get_fsname(struct super_block *sb, char *buf, int buflen) return buf; } -static char* ll_d_path(struct dentry *dentry, char *buf, int bufsize) -{ - char *path = NULL; - - struct path p; - - p.dentry = dentry; - p.mnt = current->fs->root.mnt; - path_get(&p); - path = d_path(&p, buf, bufsize); - path_put(&p); - - return path; -} - void ll_dirty_page_discard_warn(struct page *page, int ioret) { char *buf, *path = NULL; @@ -2422,12 +2383,12 @@ void ll_dirty_page_discard_warn(struct page *page, int ioret) if (buf != NULL) { dentry = d_find_alias(page->mapping->host); if (dentry != NULL) - path = ll_d_path(dentry, buf, PAGE_SIZE); + path = dentry_path_raw(dentry, buf, PAGE_SIZE); } CDEBUG(D_WARNING, - "%s: dirty page discard: %s/fid: "DFID"/%s may get corrupted " - "(rc %d)\n", ll_get_fsname(page->mapping->host->i_sb, NULL, 0), + "%s: dirty page discard: %s/fid: " DFID "/%s may get corrupted (rc %d)\n", + ll_get_fsname(page->mapping->host->i_sb, NULL, 0), s2lsi(page->mapping->host->i_sb)->lsi_lmd->lmd_dev, PFID(&obj->cob_header.coh_lu.loh_fid), (path && !IS_ERR(path)) ? path : "", ioret); diff --git a/drivers/staging/lustre/lustre/llite/llite_mmap.c b/drivers/staging/lustre/lustre/llite/llite_mmap.c index ba1c047ae927..479bf428780c 100644 --- a/drivers/staging/lustre/lustre/llite/llite_mmap.c +++ b/drivers/staging/lustre/lustre/llite/llite_mmap.c @@ -234,8 +234,7 @@ static int ll_page_mkwrite0(struct vm_area_struct *vma, struct page *vmpage, */ unlock_page(vmpage); - CDEBUG(D_MMAP, "Race on page_mkwrite %p/%lu, page has " - "been written out, retry.\n", + CDEBUG(D_MMAP, "Race on page_mkwrite %p/%lu, page has been written out, retry.\n", vmpage, vmpage->index); *retry = true; @@ -366,8 +365,7 @@ restart: vmf->page = NULL; if (!printed && ++count > 16) { - CWARN("the page is under heavy contention," - "maybe your app(%s) needs revising :-)\n", + CWARN("the page is under heavy contention, maybe your app(%s) needs revising :-)\n", current->comm); printed = true; } @@ -393,8 +391,7 @@ static int ll_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) result = ll_page_mkwrite0(vma, vmf->page, &retry); if (!printed && ++count > 16) { - CWARN("app(%s): the page %lu of file %lu is under heavy" - " contention.\n", + CWARN("app(%s): the page %lu of file %lu is under heavy contention.\n", current->comm, vmf->pgoff, file_inode(vma->vm_file)->i_ino); printed = true; diff --git a/drivers/staging/lustre/lustre/llite/llite_rmtacl.c b/drivers/staging/lustre/lustre/llite/llite_rmtacl.c index 586f49a374ec..f4da156f3874 100644 --- a/drivers/staging/lustre/lustre/llite/llite_rmtacl.c +++ b/drivers/staging/lustre/lustre/llite/llite_rmtacl.c @@ -131,8 +131,8 @@ int rct_add(struct rmtacl_ctl_table *rct, pid_t key, int ops) spin_lock(&rct->rct_lock); e = __rct_search(rct, key); if (unlikely(e != NULL)) { - CWARN("Unexpected stale rmtacl_entry found: " - "[key: %d] [ops: %d]\n", (int)key, ops); + CWARN("Unexpected stale rmtacl_entry found: [key: %d] [ops: %d]\n", + (int)key, ops); rce_free(e); } list_add_tail(&rce->rce_list, &rct->rct_entries[rce_hashfunc(key)]); @@ -263,8 +263,7 @@ int ee_add(struct eacl_table *et, pid_t key, struct lu_fid *fid, int type, spin_lock(&et->et_lock); e = __et_search_del(et, key, fid, type); if (unlikely(e != NULL)) { - CWARN("Unexpected stale eacl_entry found: " - "[key: %d] [fid: "DFID"] [type: %d]\n", + CWARN("Unexpected stale eacl_entry found: [key: %d] [fid: " DFID "] [type: %d]\n", (int)key, PFID(fid), type); ee_free(e); } diff --git a/drivers/staging/lustre/lustre/llite/lloop.c b/drivers/staging/lustre/lustre/llite/lloop.c index 9e31b789b790..031248840642 100644 --- a/drivers/staging/lustre/lustre/llite/lloop.c +++ b/drivers/staging/lustre/lustre/llite/lloop.c @@ -777,8 +777,8 @@ static int __init lloop_init(void) if (max_loop < 1 || max_loop > 256) { max_loop = MAX_LOOP_DEFAULT; - CWARN("lloop: invalid max_loop (must be between" - " 1 and 256), using default (%u)\n", max_loop); + CWARN("lloop: invalid max_loop (must be between 1 and 256), using default (%u)\n", + max_loop); } lloop_major = register_blkdev(0, "lloop"); @@ -792,11 +792,11 @@ static int __init lloop_init(void) if (ll_iocontrol_magic == NULL) goto out_mem1; - loop_dev = kzalloc(max_loop * sizeof(*loop_dev), GFP_KERNEL); + loop_dev = kcalloc(max_loop, sizeof(*loop_dev), GFP_KERNEL); if (!loop_dev) goto out_mem1; - disks = kzalloc(max_loop * sizeof(*disks), GFP_KERNEL); + disks = kcalloc(max_loop, sizeof(*disks), GFP_KERNEL); if (!disks) goto out_mem2; diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c index 3b3df9f03422..e6a909e6faf0 100644 --- a/drivers/staging/lustre/lustre/llite/lproc_llite.c +++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c @@ -227,8 +227,9 @@ static int ll_max_readahead_mb_seq_show(struct seq_file *m, void *v) return lprocfs_seq_read_frac_helper(m, pages_number, mult); } -static ssize_t ll_max_readahead_mb_seq_write(struct file *file, const char *buffer, - size_t count, loff_t *off) +static ssize_t ll_max_readahead_mb_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { struct super_block *sb = ((struct seq_file *)file->private_data)->private; struct ll_sb_info *sbi = ll_s2sbi(sb); @@ -269,7 +270,7 @@ static int ll_max_readahead_per_file_mb_seq_show(struct seq_file *m, void *v) } static ssize_t ll_max_readahead_per_file_mb_seq_write(struct file *file, - const char *buffer, + const char __user *buffer, size_t count, loff_t *off) { struct super_block *sb = ((struct seq_file *)file->private_data)->private; @@ -283,8 +284,7 @@ static ssize_t ll_max_readahead_per_file_mb_seq_write(struct file *file, if (pages_number < 0 || pages_number > sbi->ll_ra_info.ra_max_pages) { - CERROR("can't set file readahead more than" - "max_read_ahead_mb %lu MB\n", + CERROR("can't set file readahead more than max_read_ahead_mb %lu MB\n", sbi->ll_ra_info.ra_max_pages); return -ERANGE; } @@ -313,7 +313,7 @@ static int ll_max_read_ahead_whole_mb_seq_show(struct seq_file *m, void *unused) } static ssize_t ll_max_read_ahead_whole_mb_seq_write(struct file *file, - const char *buffer, + const char __user *buffer, size_t count, loff_t *off) { struct super_block *sb = ((struct seq_file *)file->private_data)->private; @@ -329,9 +329,8 @@ static ssize_t ll_max_read_ahead_whole_mb_seq_write(struct file *file, * algorithm does this anyway so it's pointless to set it larger. */ if (pages_number < 0 || pages_number > sbi->ll_ra_info.ra_max_pages_per_file) { - CERROR("can't set max_read_ahead_whole_mb more than " - "max_read_ahead_per_file_mb: %lu\n", - sbi->ll_ra_info.ra_max_pages_per_file >> (20 - PAGE_CACHE_SHIFT)); + CERROR("can't set max_read_ahead_whole_mb more than max_read_ahead_per_file_mb: %lu\n", + sbi->ll_ra_info.ra_max_pages_per_file >> (20 - PAGE_CACHE_SHIFT)); return -ERANGE; } @@ -469,8 +468,9 @@ static int ll_checksum_seq_show(struct seq_file *m, void *v) return seq_printf(m, "%u\n", (sbi->ll_flags & LL_SBI_CHECKSUM) ? 1 : 0); } -static ssize_t ll_checksum_seq_write(struct file *file, const char *buffer, - size_t count, loff_t *off) +static ssize_t ll_checksum_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { struct super_block *sb = ((struct seq_file *)file->private_data)->private; struct ll_sb_info *sbi = ll_s2sbi(sb); @@ -504,8 +504,9 @@ static int ll_max_rw_chunk_seq_show(struct seq_file *m, void *v) return seq_printf(m, "%lu\n", ll_s2sbi(sb)->ll_max_rw_chunk); } -static ssize_t ll_max_rw_chunk_seq_write(struct file *file, const char *buffer, - size_t count, loff_t *off) +static ssize_t ll_max_rw_chunk_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { struct super_block *sb = ((struct seq_file *)file->private_data)->private; int rc, val; @@ -533,8 +534,8 @@ static int ll_rd_track_id(struct seq_file *m, enum stats_track_type type) } } -static int ll_wr_track_id(const char *buffer, unsigned long count, void *data, - enum stats_track_type type) +static int ll_wr_track_id(const char __user *buffer, unsigned long count, + void *data, enum stats_track_type type) { struct super_block *sb = data; int rc, pid; @@ -556,8 +557,9 @@ static int ll_track_pid_seq_show(struct seq_file *m, void *v) return ll_rd_track_id(m, STATS_TRACK_PID); } -static ssize_t ll_track_pid_seq_write(struct file *file, const char *buffer, - size_t count, loff_t *off) +static ssize_t ll_track_pid_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { struct seq_file *seq = file->private_data; return ll_wr_track_id(buffer, count, seq->private, STATS_TRACK_PID); @@ -569,8 +571,9 @@ static int ll_track_ppid_seq_show(struct seq_file *m, void *v) return ll_rd_track_id(m, STATS_TRACK_PPID); } -static ssize_t ll_track_ppid_seq_write(struct file *file, const char *buffer, - size_t count, loff_t *off) +static ssize_t ll_track_ppid_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { struct seq_file *seq = file->private_data; return ll_wr_track_id(buffer, count, seq->private, STATS_TRACK_PPID); @@ -582,8 +585,9 @@ static int ll_track_gid_seq_show(struct seq_file *m, void *v) return ll_rd_track_id(m, STATS_TRACK_GID); } -static ssize_t ll_track_gid_seq_write(struct file *file, const char *buffer, - size_t count, loff_t *off) +static ssize_t ll_track_gid_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { struct seq_file *seq = file->private_data; return ll_wr_track_id(buffer, count, seq->private, STATS_TRACK_GID); @@ -598,8 +602,9 @@ static int ll_statahead_max_seq_show(struct seq_file *m, void *v) return seq_printf(m, "%u\n", sbi->ll_sa_max); } -static ssize_t ll_statahead_max_seq_write(struct file *file, const char *buffer, - size_t count, loff_t *off) +static ssize_t ll_statahead_max_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { struct super_block *sb = ((struct seq_file *)file->private_data)->private; struct ll_sb_info *sbi = ll_s2sbi(sb); @@ -612,8 +617,8 @@ static ssize_t ll_statahead_max_seq_write(struct file *file, const char *buffer, if (val >= 0 && val <= LL_SA_RPC_MAX) sbi->ll_sa_max = val; else - CERROR("Bad statahead_max value %d. Valid values are in the " - "range [0, %d]\n", val, LL_SA_RPC_MAX); + CERROR("Bad statahead_max value %d. Valid values are in the range [0, %d]\n", + val, LL_SA_RPC_MAX); return count; } @@ -628,8 +633,9 @@ static int ll_statahead_agl_seq_show(struct seq_file *m, void *v) sbi->ll_flags & LL_SBI_AGL_ENABLED ? 1 : 0); } -static ssize_t ll_statahead_agl_seq_write(struct file *file, const char *buffer, - size_t count, loff_t *off) +static ssize_t ll_statahead_agl_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { struct super_block *sb = ((struct seq_file *)file->private_data)->private; struct ll_sb_info *sbi = ll_s2sbi(sb); @@ -672,8 +678,9 @@ static int ll_lazystatfs_seq_show(struct seq_file *m, void *v) (sbi->ll_flags & LL_SBI_LAZYSTATFS) ? 1 : 0); } -static ssize_t ll_lazystatfs_seq_write(struct file *file, const char *buffer, - size_t count, loff_t *off) +static ssize_t ll_lazystatfs_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { struct super_block *sb = ((struct seq_file *)file->private_data)->private; struct ll_sb_info *sbi = ll_s2sbi(sb); @@ -761,8 +768,8 @@ static int ll_sbi_flags_seq_show(struct seq_file *m, void *v) while (flags != 0) { if (ARRAY_SIZE(str) <= i) { - CERROR("%s: Revise array LL_SBI_FLAGS to match sbi " - "flags please.\n", ll_get_fsname(sb, NULL, 0)); + CERROR("%s: Revise array LL_SBI_FLAGS to match sbi flags please.\n", + ll_get_fsname(sb, NULL, 0)); return -EINVAL; } @@ -787,7 +794,8 @@ static int ll_xattr_cache_seq_show(struct seq_file *m, void *v) return rc; } -static ssize_t ll_xattr_cache_seq_write(struct file *file, const char *buffer, +static ssize_t ll_xattr_cache_seq_write(struct file *file, + const char __user *buffer, size_t count, loff_t *off) { struct seq_file *seq = file->private_data; @@ -813,7 +821,7 @@ LPROC_SEQ_FOPS(ll_xattr_cache); static struct lprocfs_vars lprocfs_llite_obd_vars[] = { { "uuid", &ll_sb_uuid_fops, NULL, 0 }, - //{ "mntpt_path", ll_rd_path, 0, 0 }, + /* { "mntpt_path", ll_rd_path, 0, 0 }, */ { "fstype", &ll_fstype_fops, NULL, 0 }, { "site", &ll_site_stats_fops, NULL, 0 }, { "blocksize", &ll_blksize_fops, NULL, 0 }, @@ -823,7 +831,7 @@ static struct lprocfs_vars lprocfs_llite_obd_vars[] = { { "filestotal", &ll_filestotal_fops, NULL, 0 }, { "filesfree", &ll_filesfree_fops, NULL, 0 }, { "client_type", &ll_client_type_fops, NULL, 0 }, - //{ "filegroups", lprocfs_rd_filegroups, 0, 0 }, + /* { "filegroups", lprocfs_rd_filegroups, 0, 0 }, */ { "max_read_ahead_mb", &ll_max_readahead_mb_fops, NULL }, { "max_read_ahead_per_file_mb", &ll_max_readahead_per_file_mb_fops, NULL }, @@ -1133,8 +1141,8 @@ static void ll_display_extents_info(struct ll_rw_extents_info *io_extents, read_cum += r; write_cum += w; end = 1 << (i + LL_HIST_START - units); - seq_printf(seq, "%4lu%c - %4lu%c%c: %14lu %4lu %4lu | " - "%14lu %4lu %4lu\n", start, *unitp, end, *unitp, + seq_printf(seq, "%4lu%c - %4lu%c%c: %14lu %4lu %4lu | %14lu %4lu %4lu\n", + start, *unitp, end, *unitp, (i == LL_HIST_MAX - 1) ? '+' : ' ', r, pct(r, read_tot), pct(read_cum, read_tot), w, pct(w, write_tot), pct(write_cum, write_tot)); @@ -1160,8 +1168,7 @@ static int ll_rw_extents_stats_pp_seq_show(struct seq_file *seq, void *v) if (!sbi->ll_rw_stats_on) { seq_printf(seq, "disabled\n" - "write anything in this file to activate, " - "then 0 or \"[D/d]isabled\" to deactivate\n"); + "write anything in this file to activate, then 0 or \"[D/d]isabled\" to deactivate\n"); return 0; } seq_printf(seq, "snapshot_time: %lu.%lu (secs.usecs)\n", @@ -1239,8 +1246,7 @@ static int ll_rw_extents_stats_seq_show(struct seq_file *seq, void *v) if (!sbi->ll_rw_stats_on) { seq_printf(seq, "disabled\n" - "write anything in this file to activate, " - "then 0 or \"[D/d]isabled\" to deactivate\n"); + "write anything in this file to activate, then 0 or \"[D/d]isabled\" to deactivate\n"); return 0; } seq_printf(seq, "snapshot_time: %lu.%lu (secs.usecs)\n", @@ -1418,8 +1424,7 @@ static int ll_rw_offset_stats_seq_show(struct seq_file *seq, void *v) if (!sbi->ll_rw_stats_on) { seq_printf(seq, "disabled\n" - "write anything in this file to activate, " - "then 0 or \"[D/d]isabled\" to deactivate\n"); + "write anything in this file to activate, then 0 or \"[D/d]isabled\" to deactivate\n"); return 0; } spin_lock(&sbi->ll_process_lock); diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index 8e926b385a60..4f361b77c749 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -83,8 +83,8 @@ static int ll_set_inode(struct inode *inode, void *opaque) lli->lli_fid = body->fid1; if (unlikely(!(body->valid & OBD_MD_FLTYPE))) { - CERROR("Can not initialize inode "DFID" without object type: " - "valid = %#llx\n", PFID(&lli->lli_fid), body->valid); + CERROR("Can not initialize inode " DFID " without object type: valid = %#llx\n", + PFID(&lli->lli_fid), body->valid); return -EINVAL; } @@ -264,7 +264,7 @@ int ll_md_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, if ((bits & (MDS_INODELOCK_LOOKUP | MDS_INODELOCK_PERM)) && inode->i_sb->s_root != NULL && - is_root_inode(inode)) + !is_root_inode(inode)) ll_invalidate_aliases(inode); iput(inode); @@ -598,8 +598,7 @@ static int ll_atomic_open(struct inode *dir, struct dentry *dentry, long long lookup_flags = LOOKUP_OPEN; int rc = 0; - CDEBUG(D_VFSTRACE, "VFS Op:name=%pd,dir=%lu/%u(%p),file %p," - "open_flags %x,mode %x opened %d\n", + CDEBUG(D_VFSTRACE, "VFS Op:name=%pd,dir=%lu/%u(%p),file %p,open_flags %x,mode %x opened %d\n", dentry, dir->i_ino, dir->i_generation, dir, file, open_flags, mode, *opened); @@ -843,8 +842,7 @@ static int ll_create_nd(struct inode *dir, struct dentry *dentry, { int rc; - CDEBUG(D_VFSTRACE, "VFS Op:name=%pd,dir=%lu/%u(%p)," - "flags=%u, excl=%d\n", + CDEBUG(D_VFSTRACE, "VFS Op:name=%pd,dir=%lu/%u(%p),flags=%u, excl=%d\n", dentry, dir->i_ino, dir->i_generation, dir, mode, want_excl); diff --git a/drivers/staging/lustre/lustre/llite/remote_perm.c b/drivers/staging/lustre/lustre/llite/remote_perm.c index c05a9126cfe3..a58182600dae 100644 --- a/drivers/staging/lustre/lustre/llite/remote_perm.c +++ b/drivers/staging/lustre/lustre/llite/remote_perm.c @@ -194,7 +194,7 @@ int ll_update_remote_perm(struct inode *inode, struct mdt_remote_perm *perm) if (!lli->lli_remote_perms) lli->lli_remote_perms = perm_hash; - else if (perm_hash) + else free_rmtperm_hash(perm_hash); head = lli->lli_remote_perms + remote_perm_hashfunc(perm->rp_uid); @@ -209,8 +209,7 @@ again: continue; if (tmp->lrp_fsgid != perm->rp_fsgid) continue; - if (lrp) - free_ll_remote_perm(lrp); + free_ll_remote_perm(lrp); lrp = tmp; break; } diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c index 1f53b9863385..10a0421366d0 100644 --- a/drivers/staging/lustre/lustre/llite/rw.c +++ b/drivers/staging/lustre/lustre/llite/rw.c @@ -121,8 +121,8 @@ static struct ll_cl_context *ll_cl_init(struct file *file, /* this is too bad. Someone is trying to write the * page w/o holding inode mutex. This means we can * add dirty pages into cache during truncate */ - CERROR("Proc %s is dirting page w/o inode lock, this" - "will break truncate.\n", current->comm); + CERROR("Proc %s is dirtying page w/o inode lock, this will break truncate\n", + current->comm); dump_stack(); LBUG(); return ERR_PTR(-EIO); @@ -145,7 +145,7 @@ static struct ll_cl_context *ll_cl_init(struct file *file, */ io->ci_lockreq = CILR_NEVER; - pos = (vmpage->index << PAGE_CACHE_SHIFT); + pos = vmpage->index << PAGE_CACHE_SHIFT; /* Create a temp IO to serve write. */ result = cl_io_rw_init(env, io, CIT_WRITE, pos, PAGE_CACHE_SIZE); @@ -606,8 +606,8 @@ stride_pg_count(pgoff_t st_off, unsigned long st_len, unsigned long st_pgs, else pg_count = start_left + st_pgs * (end - start - 1) + end_left; - CDEBUG(D_READA, "st_off %lu, st_len %lu st_pgs %lu off %lu length %lu" - "pgcount %lu\n", st_off, st_len, st_pgs, off, length, pg_count); + CDEBUG(D_READA, "st_off %lu, st_len %lu st_pgs %lu off %lu length %lu pgcount %lu\n", + st_off, st_len, st_pgs, off, length, pg_count); return pg_count; } @@ -667,10 +667,10 @@ static int ll_read_ahead_pages(const struct lu_env *env, /* FIXME: This assertion only is valid when it is for * forward read-ahead, it will be fixed when backward * read-ahead is implemented */ - LASSERTF(page_idx > ria->ria_stoff, "Invalid page_idx %lu" - "rs %lu re %lu ro %lu rl %lu rp %lu\n", page_idx, - ria->ria_start, ria->ria_end, ria->ria_stoff, - ria->ria_length, ria->ria_pages); + LASSERTF(page_idx > ria->ria_stoff, "Invalid page_idx %lu rs %lu re %lu ro %lu rl %lu rp %lu\n", + page_idx, + ria->ria_start, ria->ria_end, ria->ria_stoff, + ria->ria_length, ria->ria_pages); offset = page_idx - ria->ria_stoff; offset = offset % (ria->ria_length); if (offset > ria->ria_pages) { @@ -927,8 +927,8 @@ static void ras_stride_increase_window(struct ll_readahead_state *ras, LASSERT(ras->ras_stride_length > 0); LASSERTF(ras->ras_window_start + ras->ras_window_len - >= ras->ras_stride_offset, "window_start %lu, window_len %lu" - " stride_offset %lu\n", ras->ras_window_start, + >= ras->ras_stride_offset, "window_start %lu, window_len %lu stride_offset %lu\n", + ras->ras_window_start, ras->ras_window_len, ras->ras_stride_offset); stride_len = ras->ras_window_start + ras->ras_window_len - diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c index 4c77ae8b9350..2f21304046aa 100644 --- a/drivers/staging/lustre/lustre/llite/rw26.c +++ b/drivers/staging/lustre/lustre/llite/rw26.c @@ -183,7 +183,7 @@ static int ll_set_page_dirty(struct page *vmpage) return __set_page_dirty_nobuffers(vmpage); } -#define MAX_DIRECTIO_SIZE 2*1024*1024*1024UL +#define MAX_DIRECTIO_SIZE (2*1024*1024*1024UL) static inline int ll_get_user_pages(int rw, unsigned long user_addr, size_t size, struct page ***pages, @@ -417,7 +417,7 @@ static ssize_t ll_direct_IO_26(int rw, struct kiocb *iocb, result = iov_iter_get_pages_alloc(iter, &pages, count, &offs); if (likely(result > 0)) { - int n = (result + offs + PAGE_SIZE - 1) / PAGE_SIZE; + int n = DIV_ROUND_UP(result + offs, PAGE_SIZE); result = ll_direct_IO_26_seg(env, io, rw, inode, file->f_mapping, result, file_offset, @@ -535,7 +535,7 @@ const struct address_space_operations ll_aops = { #else const struct address_space_operations_ext ll_aops = { .orig_aops.readpage = ll_readpage, -// .orig_aops.readpages = ll_readpages, +/* .orig_aops.readpages = ll_readpages, */ .orig_aops.direct_IO = ll_direct_IO_26, .orig_aops.writepage = ll_writepage, .orig_aops.writepages = ll_writepages, diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c index 09d965e76842..6ad9dd0fe2b3 100644 --- a/drivers/staging/lustre/lustre/llite/statahead.c +++ b/drivers/staging/lustre/lustre/llite/statahead.c @@ -334,8 +334,7 @@ static void ll_sa_entry_put(struct ll_statahead_info *sai, LASSERT(ll_sa_entry_unhashed(entry)); ll_sa_entry_cleanup(sai, entry); - if (entry->se_inode) - iput(entry->se_inode); + iput(entry->se_inode); OBD_FREE(entry, entry->se_size); atomic_dec(&sai->sai_cache_count); @@ -915,7 +914,7 @@ static int do_sa_revalidate(struct inode *dir, struct ll_sa_entry *entry, return rc; } -static void ll_statahead_one(struct dentry *parent, const char* entry_name, +static void ll_statahead_one(struct dentry *parent, const char *entry_name, int entry_name_len) { struct inode *dir = parent->d_inode; @@ -1491,10 +1490,7 @@ ll_sai_unplug(struct ll_statahead_info *sai, struct ll_sa_entry *entry) sai->sai_consecutive_miss++; if (sa_low_hit(sai) && thread_is_running(thread)) { atomic_inc(&sbi->ll_sa_wrong); - CDEBUG(D_READA, "Statahead for dir "DFID" hit " - "ratio too low: hit/miss %llu/%llu" - ", sent/replied %llu/%llu, stopping " - "statahead thread\n", + CDEBUG(D_READA, "Statahead for dir " DFID " hit ratio too low: hit/miss %llu/%llu, sent/replied %llu/%llu, stopping statahead thread\n", PFID(&lli->lli_fid), sai->sai_hit, sai->sai_miss, sai->sai_sent, sai->sai_replied); @@ -1612,8 +1608,7 @@ int do_statahead_enter(struct inode *dir, struct dentry **dentryp, } else if ((*dentryp)->d_inode != inode) { /* revalidate, but inode is recreated */ CDEBUG(D_READA, - "stale dentry %pd inode %lu/%u, " - "statahead inode %lu/%u\n", + "stale dentry %pd inode %lu/%u, statahead inode %lu/%u\n", *dentryp, (*dentryp)->d_inode->i_ino, (*dentryp)->d_inode->i_generation, @@ -1665,8 +1660,7 @@ int do_statahead_enter(struct inode *dir, struct dentry **dentryp, if (unlikely(sai->sai_inode != parent->d_inode)) { struct ll_inode_info *nlli = ll_i2info(parent->d_inode); - CWARN("Race condition, someone changed %pd just now: " - "old parent "DFID", new parent "DFID"\n", + CWARN("Race condition, someone changed %pd just now: old parent "DFID", new parent "DFID"\n", *dentryp, PFID(&lli->lli_fid), PFID(&nlli->lli_fid)); dput(parent); diff --git a/drivers/staging/lustre/lustre/llite/super25.c b/drivers/staging/lustre/lustre/llite/super25.c index e61dbed120a3..6aff155651cc 100644 --- a/drivers/staging/lustre/lustre/llite/super25.c +++ b/drivers/staging/lustre/lustre/llite/super25.c @@ -162,7 +162,7 @@ static int __init init_lustre_lite(void) /* Nodes with small feet have little entropy * the NID for this node gives the most entropy in the low bits */ - for (i=0; ; i++) { + for (i = 0; ; i++) { if (LNetGetId(i, &lnet_id) == -ENOENT) { break; } diff --git a/drivers/staging/lustre/lustre/llite/symlink.c b/drivers/staging/lustre/lustre/llite/symlink.c index eccd3a717a4d..686b6a574cc5 100644 --- a/drivers/staging/lustre/lustre/llite/symlink.c +++ b/drivers/staging/lustre/lustre/llite/symlink.c @@ -100,8 +100,8 @@ static int ll_readlink_internal(struct inode *inode, if (*symname == NULL || strnlen(*symname, symlen) != symlen - 1) { /* not full/NULL terminated */ - CERROR("inode %lu: symlink not NULL terminated string" - "of length %d\n", inode->i_ino, symlen - 1); + CERROR("inode %lu: symlink not NULL terminated string of length %d\n", + inode->i_ino, symlen - 1); rc = -EPROTO; goto failed; } diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index e540a6d286f8..930f6010203e 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -709,7 +709,7 @@ static int vvp_io_fault_start(const struct lu_env *env, } - if (fio->ft_mkwrite ) { + if (fio->ft_mkwrite) { pgoff_t last_index; /* * Capture the size while holding the lli_trunc_sem from above @@ -720,9 +720,8 @@ static int vvp_io_fault_start(const struct lu_env *env, last_index = cl_index(obj, size - 1); if (last_index < fio->ft_index) { CDEBUG(D_PAGE, - "llite: mkwrite and truncate race happened: " - "%p: 0x%lx 0x%lx\n", - vmpage->mapping, fio->ft_index, last_index); + "llite: mkwrite and truncate race happened: %p: 0x%lx 0x%lx\n", + vmpage->mapping, fio->ft_index, last_index); /* * We need to return if we are * passed the end of the file. This will propagate diff --git a/drivers/staging/lustre/lustre/llite/vvp_page.c b/drivers/staging/lustre/lustre/llite/vvp_page.c index 4626346f6ee1..954ed08c6af2 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_page.c +++ b/drivers/staging/lustre/lustre/llite/vvp_page.c @@ -376,8 +376,7 @@ static int vvp_page_print(const struct lu_env *env, struct ccc_page *vp = cl2ccc_page(slice); struct page *vmpage = vp->cpg_page; - (*printer)(env, cookie, LUSTRE_VVP_NAME"-page@%p(%d:%d:%d) " - "vm@%p ", + (*printer)(env, cookie, LUSTRE_VVP_NAME "-page@%p(%d:%d:%d) vm@%p ", vp, vp->cpg_defer_uptodate, vp->cpg_ra_used, vp->cpg_write_queued, vmpage); if (vmpage != NULL) { diff --git a/drivers/staging/lustre/lustre/llite/xattr.c b/drivers/staging/lustre/lustre/llite/xattr.c index 3151baf5585c..b439936b4524 100644 --- a/drivers/staging/lustre/lustre/llite/xattr.c +++ b/drivers/staging/lustre/lustre/llite/xattr.c @@ -201,8 +201,7 @@ int ll_setxattr_common(struct inode *inode, const char *name, #endif if (rc) { if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) { - LCONSOLE_INFO("Disabling user_xattr feature because " - "it is not supported on the server\n"); + LCONSOLE_INFO("Disabling user_xattr feature because it is not supported on the server\n"); sbi->ll_flags &= ~LL_SBI_USER_XATTR; } return rc; @@ -234,6 +233,9 @@ int ll_setxattr(struct dentry *dentry, const char *name, struct lov_user_md *lump = (struct lov_user_md *)value; int rc = 0; + if (size != 0 && size < sizeof(struct lov_user_md)) + return -EINVAL; + /* Attributes that are saved via getxattr will always have * the stripe_offset as 0. Instead, the MDS should be * allowed to pick the starting OST index. b=17846 */ diff --git a/drivers/staging/lustre/lustre/llite/xattr_cache.c b/drivers/staging/lustre/lustre/llite/xattr_cache.c index 627cbe242f22..e2badf17d95e 100644 --- a/drivers/staging/lustre/lustre/llite/xattr_cache.c +++ b/drivers/staging/lustre/lustre/llite/xattr_cache.c @@ -126,9 +126,7 @@ static int ll_xattr_cache_add(struct list_head *cache, return -ENOMEM; } - xattr->xe_namelen = strlen(xattr_name) + 1; - - xattr->xe_name = kzalloc(xattr->xe_namelen, GFP_NOFS); + xattr->xe_name = kstrdup(xattr_name, GFP_NOFS); if (!xattr->xe_name) { CDEBUG(D_CACHE, "failed to alloc xattr name %u\n", xattr->xe_namelen); @@ -141,7 +139,6 @@ static int ll_xattr_cache_add(struct list_head *cache, goto err_value; } - memcpy(xattr->xe_name, xattr_name, xattr->xe_namelen); memcpy(xattr->xe_value, xattr_val, xattr_val_len); xattr->xe_vallen = xattr_val_len; list_add(&xattr->xe_list, cache); diff --git a/drivers/staging/lustre/lustre/lmv/lmv_fld.c b/drivers/staging/lustre/lustre/lmv/lmv_fld.c index e8421f04beda..ee235926f52b 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_fld.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_fld.c @@ -75,8 +75,7 @@ int lmv_fld_lookup(struct lmv_obd *lmv, *mds, PFID(fid)); if (*mds >= lmv->desc.ld_tgt_count) { - CERROR("FLD lookup got invalid mds #%x (max: %x) " - "for fid="DFID"\n", *mds, lmv->desc.ld_tgt_count, + CERROR("FLD lookup got invalid mds #%x (max: %x) for fid=" DFID "\n", *mds, lmv->desc.ld_tgt_count, PFID(fid)); rc = -EINVAL; } diff --git a/drivers/staging/lustre/lustre/lmv/lmv_intent.c b/drivers/staging/lustre/lustre/lmv/lmv_intent.c index 5106124b7d92..d22d57b4ff38 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_intent.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_intent.c @@ -186,8 +186,8 @@ int lmv_intent_open(struct obd_export *exp, struct md_op_data *op_data, return rc; } - CDEBUG(D_INODE, "OPEN_INTENT with fid1="DFID", fid2="DFID"," - " name='%s' -> mds #%d\n", PFID(&op_data->op_fid1), + CDEBUG(D_INODE, "OPEN_INTENT with fid1=" DFID ", fid2=" DFID ", name='%s' -> mds #%d\n", + PFID(&op_data->op_fid1), PFID(&op_data->op_fid2), op_data->op_name, tgt->ltd_idx); rc = md_intent_lock(tgt->ltd_exp, op_data, lmm, lmmsize, it, flags, @@ -226,8 +226,8 @@ int lmv_intent_open(struct obd_export *exp, struct md_op_data *op_data, * this is normal situation, we should not print error here, * only debug info. */ - CDEBUG(D_INODE, "Can't handle remote %s: dir "DFID"("DFID"):" - "%*s: %d\n", LL_IT2STR(it), PFID(&op_data->op_fid2), + CDEBUG(D_INODE, "Can't handle remote %s: dir " DFID "(" DFID "):%*s: %d\n", + LL_IT2STR(it), PFID(&op_data->op_fid2), PFID(&op_data->op_fid1), op_data->op_namelen, op_data->op_name, rc); return rc; diff --git a/drivers/staging/lustre/lustre/lmv/lmv_internal.h b/drivers/staging/lustre/lustre/lmv/lmv_internal.h index b911e7643874..852d78721ca9 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_internal.h +++ b/drivers/staging/lustre/lustre/lmv/lmv_internal.h @@ -42,8 +42,8 @@ #define LMV_MAX_TGT_COUNT 128 -#define lmv_init_lock(lmv) mutex_lock(&lmv->init_mutex); -#define lmv_init_unlock(lmv) mutex_unlock(&lmv->init_mutex); +#define lmv_init_lock(lmv) mutex_lock(&lmv->init_mutex) +#define lmv_init_unlock(lmv) mutex_unlock(&lmv->init_mutex) #define LL_IT2STR(it) \ ((it) ? ldlm_it2str((it)->it_op) : "0") diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c index 1a5821289c39..9f3837412cdf 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c @@ -325,8 +325,8 @@ static int lmv_init_ea_size(struct obd_export *exp, int easize, rc = md_init_ea_size(lmv->tgts[i]->ltd_exp, easize, def_easize, cookiesize, def_cookiesize); if (rc) { - CERROR("%s: obd_init_ea_size() failed on MDT target %d:" - " rc = %d.\n", obd->obd_name, i, rc); + CERROR("%s: obd_init_ea_size() failed on MDT target %d: rc = %d.\n", + obd->obd_name, i, rc); break; } } @@ -427,8 +427,7 @@ int lmv_connect_mdc(struct obd_device *obd, struct lmv_tgt_desc *tgt) mdc_obd->obd_type->typ_name, mdc_obd->obd_name); if (mdc_symlink == NULL) { - CERROR("Could not register LMV target " - "/proc/fs/lustre/%s/%s/target_obds/%s.", + CERROR("Could not register LMV target /proc/fs/lustre/%s/%s/target_obds/%s.", obd->obd_type->typ_name, obd->obd_name, mdc_obd->obd_name); lprocfs_remove(&lmv_proc_dir); @@ -474,8 +473,8 @@ static int lmv_add_target(struct obd_device *obd, struct obd_uuid *uuidp, if ((index < lmv->tgts_size) && (lmv->tgts[index] != NULL)) { tgt = lmv->tgts[index]; - CERROR("%s: UUID %s already assigned at LOV target index %d:" - " rc = %d\n", obd->obd_name, + CERROR("%s: UUID %s already assigned at LOV target index %d: rc = %d\n", + obd->obd_name, obd_uuid2str(&tgt->ltd_uuid), index, -EEXIST); lmv_init_unlock(lmv); return -EEXIST; @@ -600,8 +599,7 @@ int lmv_check_connect(struct obd_device *obd) --lmv->desc.ld_active_tgt_count; rc2 = obd_disconnect(tgt->ltd_exp); if (rc2) { - CERROR("LMV target %s disconnect on " - "MDC idx %d: error %d\n", + CERROR("LMV target %s disconnect on MDC idx %d: error %d\n", tgt->ltd_uuid.uuid, i, rc2); } } @@ -865,10 +863,9 @@ static int lmv_hsm_ct_register(struct lmv_obd *lmv, unsigned int cmd, int len, if (err) { if (lmv->tgts[i]->ltd_active) { /* permanent error */ - CERROR("error: iocontrol MDC %s on MDT" - "idx %d cmd %x: err = %d\n", - lmv->tgts[i]->ltd_uuid.uuid, - i, cmd, err); + CERROR("error: iocontrol MDC %s on MDTidx %d cmd %x: err = %d\n", + lmv->tgts[i]->ltd_uuid.uuid, + i, cmd, err); rc = err; lk->lk_flags |= LK_FLG_STOP; /* unregister from previous MDS */ @@ -925,7 +922,7 @@ static int lmv_iocontrol(unsigned int cmd, struct obd_export *exp, __u32 index; memcpy(&index, data->ioc_inlbuf2, sizeof(__u32)); - if ((index >= count)) + if (index >= count) return -ENODEV; if (lmv->tgts[index] == NULL || @@ -1147,10 +1144,9 @@ static int lmv_iocontrol(unsigned int cmd, struct obd_export *exp, return err; } else if (err) { if (lmv->tgts[i]->ltd_active) { - CERROR("error: iocontrol MDC %s on MDT" - "idx %d cmd %x: err = %d\n", - lmv->tgts[i]->ltd_uuid.uuid, - i, cmd, err); + CERROR("error: iocontrol MDC %s on MDTidx %d cmd %x: err = %d\n", + lmv->tgts[i]->ltd_uuid.uuid, + i, cmd, err); if (!rc) rc = err; } @@ -1234,8 +1230,8 @@ static int lmv_placement_policy(struct obd_device *obd, if (lum->lum_type == LMV_STRIPE_TYPE && lum->lum_stripe_offset != -1) { if (lum->lum_stripe_offset >= lmv->desc.ld_tgt_count) { - CERROR("%s: Stripe_offset %d > MDT count %d:" - " rc = %d\n", obd->obd_name, + CERROR("%s: Stripe_offset %d > MDT count %d: rc = %d\n", + obd->obd_name, lum->lum_stripe_offset, lmv->desc.ld_tgt_count, -ERANGE); return -ERANGE; @@ -1298,8 +1294,8 @@ int lmv_fid_alloc(struct obd_export *exp, struct lu_fid *fid, rc = lmv_placement_policy(obd, op_data, &mds); if (rc) { - CERROR("Can't get target for allocating fid, " - "rc %d\n", rc); + CERROR("Can't get target for allocating fid, rc %d\n", + rc); return rc; } @@ -2310,7 +2306,6 @@ retry: static int lmv_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) { struct lmv_obd *lmv = &obd->u.lmv; - int rc = 0; switch (stage) { case OBD_CLEANUP_EARLY: @@ -2324,7 +2319,7 @@ static int lmv_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) default: break; } - return rc; + return 0; } static int lmv_get_info(const struct lu_env *env, struct obd_export *exp, diff --git a/drivers/staging/lustre/lustre/lov/lov_ea.c b/drivers/staging/lustre/lustre/lov/lov_ea.c index 9e21e5efcdb6..e9ec39c5a6c2 100644 --- a/drivers/staging/lustre/lustre/lov/lov_ea.c +++ b/drivers/staging/lustre/lustre/lov/lov_ea.c @@ -348,9 +348,8 @@ const struct lsm_operations lsm_v3_ops = { void dump_lsm(unsigned int level, const struct lov_stripe_md *lsm) { - CDEBUG(level, "lsm %p, objid "DOSTID", maxbytes %#llx, magic 0x%08X," - " stripe_size %u, stripe_count %u, refc: %d," - " layout_gen %u, pool ["LOV_POOLNAMEF"]\n", lsm, + CDEBUG(level, "lsm %p, objid " DOSTID ", maxbytes %#llx, magic 0x%08X, stripe_size %u, stripe_count %u, refc: %d, layout_gen %u, pool [" LOV_POOLNAMEF "]\n", + lsm, POSTID(&lsm->lsm_oi), lsm->lsm_maxbytes, lsm->lsm_magic, lsm->lsm_stripe_size, lsm->lsm_stripe_count, atomic_read(&lsm->lsm_refc), lsm->lsm_layout_gen, diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c index 94dfd64bd283..ea503d2a19f8 100644 --- a/drivers/staging/lustre/lustre/lov/lov_obd.c +++ b/drivers/staging/lustre/lustre/lov/lov_obd.c @@ -168,8 +168,8 @@ int lov_connect_obd(struct obd_device *obd, __u32 index, int activate, if (imp->imp_invalid) { - CDEBUG(D_CONFIG, "not connecting OSC %s; administratively " - "disabled\n", obd_uuid2str(tgt_uuid)); + CDEBUG(D_CONFIG, "not connecting OSC %s; administratively disabled\n", + obd_uuid2str(tgt_uuid)); return 0; } @@ -201,10 +201,9 @@ int lov_connect_obd(struct obd_device *obd, __u32 index, int activate, osc_obd->obd_type->typ_name, osc_obd->obd_name); if (osc_symlink == NULL) { - CERROR("could not register LOV target " - "/proc/fs/lustre/%s/%s/target_obds/%s.", - obd->obd_type->typ_name, obd->obd_name, - osc_obd->obd_name); + CERROR("could not register LOV target /proc/fs/lustre/%s/%s/target_obds/%s.", + obd->obd_type->typ_name, obd->obd_name, + osc_obd->obd_name); lprocfs_remove(&lov_proc_dir); obd->obd_proc_private = NULL; } @@ -726,8 +725,7 @@ void lov_fix_desc_stripe_size(__u64 *val) { if (*val < LOV_MIN_STRIPE_SIZE) { if (*val != 0) - LCONSOLE_INFO("Increasing default stripe size to " - "minimum %u\n", + LCONSOLE_INFO("Increasing default stripe size to minimum %u\n", LOV_DESC_STRIPE_SIZE_DEFAULT); *val = LOV_DESC_STRIPE_SIZE_DEFAULT; } else if (*val & (LOV_MIN_STRIPE_SIZE - 1)) { @@ -847,7 +845,6 @@ out: static int lov_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) { - int rc = 0; struct lov_obd *lov = &obd->u.lov; switch (stage) { @@ -865,7 +862,7 @@ static int lov_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) break; } - return rc; + return 0; } static int lov_cleanup(struct obd_device *obd) @@ -900,8 +897,7 @@ static int lov_cleanup(struct obd_device *obd) /* We should never get here - these should have been removed in the disconnect. */ - CERROR("lov tgt %d not cleaned!" - " deathrow=%d, lovrc=%d\n", + CERROR("lov tgt %d not cleaned! deathrow=%d, lovrc=%d\n", i, lov->lov_death_row, atomic_read(&lov->lov_refcount)); lov_del_target(obd, i, NULL, 0); @@ -1176,8 +1172,8 @@ static int lov_getattr_async(struct obd_export *exp, struct obd_info *oinfo, list_for_each(pos, &lovset->set_list) { req = list_entry(pos, struct lov_request, rq_link); - CDEBUG(D_INFO, "objid "DOSTID"[%d] has subobj "DOSTID" at idx" - "%u\n", POSTID(&oinfo->oi_oa->o_oi), req->rq_stripe, + CDEBUG(D_INFO, "objid " DOSTID "[%d] has subobj " DOSTID " at idx%u\n", + POSTID(&oinfo->oi_oa->o_oi), req->rq_stripe, POSTID(&req->rq_oi.oi_oa->o_oi), req->rq_idx); rc = obd_getattr_async(lov->lov_tgts[req->rq_idx]->ltd_exp, &req->rq_oi, rqset); @@ -1256,8 +1252,8 @@ static int lov_setattr_async(struct obd_export *exp, struct obd_info *oinfo, if (oinfo->oi_oa->o_valid & OBD_MD_FLCOOKIE) oti->oti_logcookies = set->set_cookies + req->rq_stripe; - CDEBUG(D_INFO, "objid "DOSTID"[%d] has subobj "DOSTID" at idx" - "%u\n", POSTID(&oinfo->oi_oa->o_oi), req->rq_stripe, + CDEBUG(D_INFO, "objid " DOSTID "[%d] has subobj " DOSTID " at idx%u\n", + POSTID(&oinfo->oi_oa->o_oi), req->rq_stripe, POSTID(&req->rq_oi.oi_oa->o_oi), req->rq_idx); rc = obd_setattr_async(lov->lov_tgts[req->rq_idx]->ltd_exp, @@ -1568,8 +1564,7 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len, if (lov->lov_tgts[i]->ltd_active) { CDEBUG(err == -ENOTTY ? D_IOCTL : D_WARNING, - "iocontrol OSC %s on OST " - "idx %d cmd %x: err = %d\n", + "iocontrol OSC %s on OST idx %d cmd %x: err = %d\n", lov_uuid2str(lov, i), i, cmd, err); if (!rc) @@ -2266,8 +2261,8 @@ static int lov_quotacheck(struct obd_device *obd, struct obd_export *exp, /* Skip quota check on the administratively disabled OSTs. */ if (!lov->lov_tgts[i]->ltd_activate) { - CWARN("lov idx %d was administratively disabled, " - "skip quotacheck on it.\n", i); + CWARN("lov idx %d was administratively disabled, skip quotacheck on it.\n", + i); continue; } diff --git a/drivers/staging/lustre/lustre/lov/lov_pack.c b/drivers/staging/lustre/lustre/lov/lov_pack.c index 5edd6a3a9c54..5356d5324176 100644 --- a/drivers/staging/lustre/lustre/lov/lov_pack.c +++ b/drivers/staging/lustre/lustre/lov/lov_pack.c @@ -438,8 +438,7 @@ int lov_getstripe(struct obd_export *exp, struct lov_stripe_md *lsm, if (copy_from_user(&lum, lump, lum_size)) { rc = -EFAULT; goto out_set; - } - else if ((lum.lmm_magic != LOV_USER_MAGIC) && + } else if ((lum.lmm_magic != LOV_USER_MAGIC) && (lum.lmm_magic != LOV_USER_MAGIC_V3)) { rc = -EINVAL; goto out_set; diff --git a/drivers/staging/lustre/lustre/mdc/mdc_lib.c b/drivers/staging/lustre/lustre/mdc/mdc_lib.c index e8732cc30ce2..4e59995e0042 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_lib.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_lib.c @@ -194,10 +194,8 @@ static __u64 mds_pack_open_flags(__u64 flags, __u32 mode) cr_flags |= MDS_OPEN_SYNC; if (flags & O_DIRECTORY) cr_flags |= MDS_OPEN_DIRECTORY; -#ifdef FMODE_EXEC - if (flags & FMODE_EXEC) + if (flags & __FMODE_EXEC) cr_flags |= MDS_FMODE_EXEC; -#endif if (cl_is_lov_delay_create(flags)) cr_flags |= MDS_OPEN_DELAY_CREATE; diff --git a/drivers/staging/lustre/lustre/mdc/mdc_locks.c b/drivers/staging/lustre/lustre/mdc/mdc_locks.c index b58147ee62b6..8c9b4f5494e9 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_locks.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_locks.c @@ -296,10 +296,8 @@ static struct ptlrpc_request *mdc_intent_open_pack(struct obd_export *exp, } else { if (it->it_flags & (FMODE_WRITE|MDS_OPEN_TRUNC)) mode = LCK_CW; -#ifdef FMODE_EXEC - else if (it->it_flags & FMODE_EXEC) + else if (it->it_flags & __FMODE_EXEC) mode = LCK_PR; -#endif else mode = LCK_CR; } diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 14e1ba1675f6..3b0f245a8780 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -60,7 +60,7 @@ struct mdc_renew_capa_args { static int mdc_cleanup(struct obd_device *obd); -int mdc_unpack_capa(struct obd_export *exp, struct ptlrpc_request *req, +static int mdc_unpack_capa(struct obd_export *exp, struct ptlrpc_request *req, const struct req_msg_field *field, struct obd_capa **oc) { struct lustre_capa *capa; @@ -147,7 +147,7 @@ out: } /* This should be mdc_get_info("rootfid") */ -int mdc_getstatus(struct obd_export *exp, struct lu_fid *rootfid, +static int mdc_getstatus(struct obd_export *exp, struct lu_fid *rootfid, struct obd_capa **pc) { return send_getstatus(class_exp2cliimp(exp), rootfid, pc, @@ -214,7 +214,7 @@ static int mdc_getattr_common(struct obd_export *exp, return 0; } -int mdc_getattr(struct obd_export *exp, struct md_op_data *op_data, +static int mdc_getattr(struct obd_export *exp, struct md_op_data *op_data, struct ptlrpc_request **request) { struct ptlrpc_request *req; @@ -258,7 +258,7 @@ int mdc_getattr(struct obd_export *exp, struct md_op_data *op_data, return rc; } -int mdc_getattr_name(struct obd_export *exp, struct md_op_data *op_data, +static int mdc_getattr_name(struct obd_export *exp, struct md_op_data *op_data, struct ptlrpc_request **request) { struct ptlrpc_request *req; @@ -441,7 +441,7 @@ static int mdc_xattr_common(struct obd_export *exp, return rc; } -int mdc_setxattr(struct obd_export *exp, const struct lu_fid *fid, +static int mdc_setxattr(struct obd_export *exp, const struct lu_fid *fid, struct obd_capa *oc, u64 valid, const char *xattr_name, const char *input, int input_size, int output_size, int flags, __u32 suppgid, struct ptlrpc_request **request) @@ -452,7 +452,7 @@ int mdc_setxattr(struct obd_export *exp, const struct lu_fid *fid, suppgid, request); } -int mdc_getxattr(struct obd_export *exp, const struct lu_fid *fid, +static int mdc_getxattr(struct obd_export *exp, const struct lu_fid *fid, struct obd_capa *oc, u64 valid, const char *xattr_name, const char *input, int input_size, int output_size, int flags, struct ptlrpc_request **request) diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c index bc263adf09d4..60d2b0f12693 100644 --- a/drivers/staging/lustre/lustre/mgc/mgc_request.c +++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c @@ -510,8 +510,6 @@ static void do_requeue(struct config_llog_data *cld) static int mgc_requeue_thread(void *data) { - int rc = 0; - CDEBUG(D_MGC, "Starting requeue thread\n"); /* Keep trying failed locks periodically */ @@ -592,7 +590,7 @@ static int mgc_requeue_thread(void *data) complete(&rq_exit); CDEBUG(D_MGC, "Ending requeue thread\n"); - return rc; + return 0; } /* Add a cld to the list to requeue. Start the requeue thread if needed. @@ -736,8 +734,7 @@ static int mgc_setup(struct obd_device *obd, struct lustre_cfg *lcfg) rc = PTR_ERR(kthread_run(mgc_requeue_thread, NULL, "ll_cfg_requeue")); if (IS_ERR_VALUE(rc)) { - CERROR("%s: Cannot start requeue thread (%d)," - "no more log updates!\n", + CERROR("%s: Cannot start requeue thread (%d),no more log updates!\n", obd->obd_name, rc); goto err_cleanup; } @@ -1021,8 +1018,7 @@ int mgc_set_info_async(const struct lu_env *env, struct obd_export *exp, sptlrpc_flavor2name(&cli->cl_flvr_mgc, str, sizeof(str)); - LCONSOLE_ERROR("asking sptlrpc flavor %s to MGS but " - "currently %s is in use\n", + LCONSOLE_ERROR("asking sptlrpc flavor %s to MGS but currently %s is in use\n", (char *) val, str); rc = -EPERM; } @@ -1055,8 +1051,6 @@ static int mgc_import_event(struct obd_device *obd, struct obd_import *imp, enum obd_import_event event) { - int rc = 0; - LASSERT(imp->imp_obd == obd); CDEBUG(D_MGC, "import event %#x\n", event); @@ -1090,7 +1084,7 @@ static int mgc_import_event(struct obd_device *obd, CERROR("Unknown import event %#x\n", event); LBUG(); } - return rc; + return 0; } enum { diff --git a/drivers/staging/lustre/lustre/obdclass/acl.c b/drivers/staging/lustre/lustre/obdclass/acl.c index 2619bfeceb8b..9a69f6b35a0e 100644 --- a/drivers/staging/lustre/lustre/obdclass/acl.c +++ b/drivers/staging/lustre/lustre/obdclass/acl.c @@ -171,17 +171,17 @@ EXPORT_SYMBOL(lustre_posix_acl_xattr_2ext); /* * Filter out the "nobody" entries in the posix ACL. */ -int lustre_posix_acl_xattr_filter(posix_acl_xattr_header *header, int size, +int lustre_posix_acl_xattr_filter(posix_acl_xattr_header *header, size_t size, posix_acl_xattr_header **out) { int count, i, j, rc = 0; __u32 id; posix_acl_xattr_header *new; - if (unlikely(size < 0)) - return -EINVAL; - else if (!size) + if (!size) return 0; + if (size < sizeof(*new)) + return -EINVAL; OBD_ALLOC(new, size); if (unlikely(new == NULL)) diff --git a/drivers/staging/lustre/lustre/obdclass/capa.c b/drivers/staging/lustre/lustre/obdclass/capa.c index cd1abce378ea..d206b1046a18 100644 --- a/drivers/staging/lustre/lustre/obdclass/capa.c +++ b/drivers/staging/lustre/lustre/obdclass/capa.c @@ -272,8 +272,7 @@ int capa_hmac(__u8 *hmac, struct lustre_capa *capa, __u8 *key) tfm = crypto_alloc_hash(alg->ha_name, 0, 0); if (IS_ERR(tfm)) { - CERROR("crypto_alloc_tfm failed, check whether your kernel" - "has crypto support!\n"); + CERROR("crypto_alloc_tfm failed, check whether your kernel has crypto support!\n"); return PTR_ERR(tfm); } keylen = alg->ha_keylen; @@ -302,7 +301,7 @@ int capa_encrypt_id(__u32 *d, __u32 *s, __u8 *key, int keylen) /* passing "aes" in a variable instead of a constant string keeps gcc * 4.3.2 happy */ - tfm = crypto_alloc_blkcipher(alg, 0, 0 ); + tfm = crypto_alloc_blkcipher(alg, 0, 0); if (IS_ERR(tfm)) { CERROR("failed to load transform for aes\n"); return PTR_ERR(tfm); @@ -355,7 +354,7 @@ int capa_decrypt_id(__u32 *d, __u32 *s, __u8 *key, int keylen) /* passing "aes" in a variable instead of a constant string keeps gcc * 4.3.2 happy */ - tfm = crypto_alloc_blkcipher(alg, 0, 0 ); + tfm = crypto_alloc_blkcipher(alg, 0, 0); if (IS_ERR(tfm)) { CERROR("failed to load transform for aes\n"); return PTR_ERR(tfm); @@ -407,14 +406,13 @@ EXPORT_SYMBOL(capa_cpy); void _debug_capa(struct lustre_capa *c, struct libcfs_debug_msg_data *msgdata, - const char *fmt, ... ) + const char *fmt, ...) { va_list args; va_start(args, fmt); libcfs_debug_vmsg2(msgdata, fmt, args, - " capability@%p fid "DFID" opc %#llx uid %llu" - " gid %llu flags %u alg %d keyid %u timeout %u " - "expiry %u\n", c, PFID(capa_fid(c)), capa_opc(c), + " capability@%p fid " DFID " opc %#llx uid %llu gid %llu flags %u alg %d keyid %u timeout %u expiry %u\n", + c, PFID(capa_fid(c)), capa_opc(c), capa_uid(c), capa_gid(c), capa_flags(c), capa_alg(c), capa_keyid(c), capa_timeout(c), capa_expiry(c)); diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c index f2383a497cbe..3141b6043708 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c @@ -1622,8 +1622,7 @@ int cl_sync_io_wait(const struct lu_env *env, struct cl_io *io, atomic_read(&anchor->csi_sync_nr) == 0, &lwi); if (rc < 0) { - CERROR("SYNC IO failed with error: %d, try to cancel " - "%d remaining pages\n", + CERROR("SYNC IO failed with error: %d, try to cancel %d remaining pages\n", rc, atomic_read(&anchor->csi_sync_nr)); (void)cl_io_cancel(env, io, queue); diff --git a/drivers/staging/lustre/lustre/obdclass/cl_lock.c b/drivers/staging/lustre/lustre/obdclass/cl_lock.c index b204531ef710..b081167f9767 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_lock.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_lock.c @@ -129,8 +129,7 @@ static void cl_lock_trace0(int level, const struct lu_env *env, const char *func, const int line) { struct cl_object_header *h = cl_object_header(lock->cll_descr.cld_obj); - CDEBUG(level, "%s: %p@(%d %p %d %d %d %d %d %lx)" - "(%p/%d/%d) at %s():%d\n", + CDEBUG(level, "%s: %p@(%d %p %d %d %d %d %d %lx)(%p/%d/%d) at %s():%d\n", prefix, lock, atomic_read(&lock->cll_ref), lock->cll_guarder, lock->cll_depth, lock->cll_state, lock->cll_error, lock->cll_holds, diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c index 7265ecbc6f9d..89a3fb2e56b2 100644 --- a/drivers/staging/lustre/lustre/obdclass/class_obd.c +++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c @@ -144,13 +144,11 @@ int obd_alloc_fail(const void *ptr, const char *name, const char *type, CERROR("%s%salloc of %s (%llu bytes) failed at %s:%d\n", ptr ? "force " :"", type, name, (__u64)size, file, line); - CERROR("%llu total bytes and %llu total pages " - "(%llu bytes) allocated by Lustre, " - "%d total bytes by LNET\n", + CERROR("%llu total bytes and %llu total pages (%llu bytes) allocated by Lustre, %d total bytes by LNET\n", obd_memory_sum(), obd_pages_sum() << PAGE_CACHE_SHIFT, obd_pages_sum(), - atomic_read(&libcfs_kmemory)); + atomic_read(&libcfs_kmemory)); return 1; } return 0; diff --git a/drivers/staging/lustre/lustre/obdclass/debug.c b/drivers/staging/lustre/lustre/obdclass/debug.c index d0f8f875ddd6..9c934e6d2ea1 100644 --- a/drivers/staging/lustre/lustre/obdclass/debug.c +++ b/drivers/staging/lustre/lustre/obdclass/debug.c @@ -40,6 +40,7 @@ #define DEBUG_SUBSYSTEM D_OTHER +#include <linux/unaligned/access_ok.h> #include "../include/obd_support.h" #include "../include/lustre_debug.h" @@ -60,14 +61,11 @@ int block_debug_setup(void *addr, int len, __u64 off, __u64 id) { LASSERT(addr); - off = cpu_to_le64 (off); - id = cpu_to_le64 (id); - memcpy(addr, (char *)&off, LPDS); - memcpy(addr + LPDS, (char *)&id, LPDS); - + put_unaligned_le64(off, addr); + put_unaligned_le64(id, addr+LPDS); addr += len - LPDS - LPDS; - memcpy(addr, (char *)&off, LPDS); - memcpy(addr + LPDS, (char *)&id, LPDS); + put_unaligned_le64(off, addr); + put_unaligned_le64(id, addr+LPDS); return 0; } diff --git a/drivers/staging/lustre/lustre/obdclass/dt_object.c b/drivers/staging/lustre/lustre/obdclass/dt_object.c index 52256c26bf07..e7be26ec7521 100644 --- a/drivers/staging/lustre/lustre/obdclass/dt_object.c +++ b/drivers/staging/lustre/lustre/obdclass/dt_object.c @@ -332,8 +332,7 @@ static struct dt_object *dt_reg_open(const struct lu_env *env, result = dt_lookup_dir(env, p, name, fid); if (result == 0){ o = dt_locate(env, dt, fid); - } - else + } else o = ERR_PTR(result); return o; @@ -950,8 +949,8 @@ int lprocfs_dt_rd_blksize(char *page, char **start, off_t off, { struct dt_device *dt = data; struct obd_statfs osfs; - int rc = dt_statfs(NULL, dt, &osfs); + if (rc == 0) { *eof = 1; rc = snprintf(page, count, "%u\n", @@ -967,8 +966,8 @@ int lprocfs_dt_rd_kbytestotal(char *page, char **start, off_t off, { struct dt_device *dt = data; struct obd_statfs osfs; - int rc = dt_statfs(NULL, dt, &osfs); + if (rc == 0) { __u32 blk_size = osfs.os_bsize >> 10; __u64 result = osfs.os_blocks; @@ -989,8 +988,8 @@ int lprocfs_dt_rd_kbytesfree(char *page, char **start, off_t off, { struct dt_device *dt = data; struct obd_statfs osfs; - int rc = dt_statfs(NULL, dt, &osfs); + if (rc == 0) { __u32 blk_size = osfs.os_bsize >> 10; __u64 result = osfs.os_bfree; @@ -1011,8 +1010,8 @@ int lprocfs_dt_rd_kbytesavail(char *page, char **start, off_t off, { struct dt_device *dt = data; struct obd_statfs osfs; - int rc = dt_statfs(NULL, dt, &osfs); + if (rc == 0) { __u32 blk_size = osfs.os_bsize >> 10; __u64 result = osfs.os_bavail; @@ -1033,8 +1032,8 @@ int lprocfs_dt_rd_filestotal(char *page, char **start, off_t off, { struct dt_device *dt = data; struct obd_statfs osfs; - int rc = dt_statfs(NULL, dt, &osfs); + if (rc == 0) { *eof = 1; rc = snprintf(page, count, "%llu\n", osfs.os_files); @@ -1049,8 +1048,8 @@ int lprocfs_dt_rd_filesfree(char *page, char **start, off_t off, { struct dt_device *dt = data; struct obd_statfs osfs; - int rc = dt_statfs(NULL, dt, &osfs); + if (rc == 0) { *eof = 1; rc = snprintf(page, count, "%llu\n", osfs.os_ffree); diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c index c314e9c2343e..736ca410aca3 100644 --- a/drivers/staging/lustre/lustre/obdclass/genops.c +++ b/drivers/staging/lustre/lustre/obdclass/genops.c @@ -317,7 +317,7 @@ struct obd_device *class_newdev(const char *type_name, const char *name) result->obd_minor, new_obd_minor); obd_devs[result->obd_minor] = NULL; - result->obd_name[0]='\0'; + result->obd_name[0] = '\0'; } result = ERR_PTR(-EEXIST); break; @@ -524,8 +524,8 @@ void class_obd_list(void) /* Search for a client OBD connected to tgt_uuid. If grp_uuid is specified, then only the client with that uuid is returned, otherwise any client connected to the tgt is returned. */ -struct obd_device * class_find_client_obd(struct obd_uuid *tgt_uuid, - const char * typ_name, +struct obd_device *class_find_client_obd(struct obd_uuid *tgt_uuid, + const char *typ_name, struct obd_uuid *grp_uuid) { int i; @@ -557,7 +557,7 @@ EXPORT_SYMBOL(class_find_client_obd); searching at *next, and if a device is found, the next index to look at is saved in *next. If next is NULL, then the first matching device will always be returned. */ -struct obd_device * class_devices_in_group(struct obd_uuid *grp_uuid, int *next) +struct obd_device *class_devices_in_group(struct obd_uuid *grp_uuid, int *next) { int i; @@ -1087,8 +1087,7 @@ void __class_export_del_lock_ref(struct obd_export *exp, struct ldlm_lock *lock) spin_lock(&exp->exp_locks_list_guard); LASSERT(lock->l_exp_refs_nr > 0); if (lock->l_exp_refs_target != exp) { - LCONSOLE_WARN("lock %p, " - "mismatching export pointers: %p, %p\n", + LCONSOLE_WARN("lock %p, mismatching export pointers: %p, %p\n", lock, lock->l_exp_refs_target, exp); } if (-- lock->l_exp_refs_nr == 0) { @@ -1259,8 +1258,7 @@ static void class_disconnect_export_list(struct list_head *list, } class_export_get(exp); - CDEBUG(D_HA, "%s: disconnecting export at %s (%p), " - "last request at "CFS_TIME_T"\n", + CDEBUG(D_HA, "%s: disconnecting export at %s (%p), last request at " CFS_TIME_T "\n", exp->exp_obd->obd_name, obd_export_nid2str(exp), exp, exp->exp_last_request_time); /* release one export reference anyway */ @@ -1284,8 +1282,8 @@ void class_disconnect_exports(struct obd_device *obd) spin_unlock(&obd->obd_dev_lock); if (!list_empty(&work_list)) { - CDEBUG(D_HA, "OBD device %d (%p) has exports, " - "disconnecting them\n", obd->obd_minor, obd); + CDEBUG(D_HA, "OBD device %d (%p) has exports, disconnecting them\n", + obd->obd_minor, obd); class_disconnect_export_list(&work_list, exp_flags_from_obd(obd)); } else @@ -1422,8 +1420,8 @@ int obd_export_evict_by_nid(struct obd_device *obd, const char *nid) LASSERTF(doomed_exp != obd->obd_self_export, "self-export is hashed by NID?\n"); exports_evicted++; - LCONSOLE_WARN("%s: evicting %s (at %s) by administrative " - "request\n", obd->obd_name, + LCONSOLE_WARN("%s: evicting %s (at %s) by administrative request\n", + obd->obd_name, obd_uuid2str(&doomed_exp->exp_client_uuid), obd_export_nid2str(doomed_exp)); class_fail_export(doomed_exp); @@ -1546,9 +1544,7 @@ void obd_exports_barrier(struct obd_device *obd) set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(cfs_time_seconds(waited)); if (waited > 5 && IS_PO2(waited)) { - LCONSOLE_WARN("%s is waiting for obd_unlinked_exports " - "more than %d seconds. " - "The obd refcount = %d. Is it stuck?\n", + LCONSOLE_WARN("%s is waiting for obd_unlinked_exports more than %d seconds. The obd refcount = %d. Is it stuck?\n", obd->obd_name, waited, atomic_read(&obd->obd_refcount)); dump_exports(obd, 1); @@ -1783,7 +1779,7 @@ EXPORT_SYMBOL(kuc_len); * @param p Pointer to payload area * @returns Pointer to kuc header */ -struct kuc_hdr * kuc_ptr(void *p) +struct kuc_hdr *kuc_ptr(void *p) { struct kuc_hdr *lh = ((struct kuc_hdr *)p) - 1; LASSERT(lh->kuc_magic == KUC_MAGIC); diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c index 7eaaaa648dfb..66ceab20c743 100644 --- a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c +++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c @@ -166,14 +166,14 @@ int obd_ioctl_popdata(void *arg, void *data, int len) EXPORT_SYMBOL(obd_ioctl_popdata); /* opening /dev/obd */ -static int obd_class_open(struct inode * inode, struct file * file) +static int obd_class_open(struct inode *inode, struct file *file) { try_module_get(THIS_MODULE); return 0; } /* closing /dev/obd */ -static int obd_class_release(struct inode * inode, struct file * file) +static int obd_class_release(struct inode *inode, struct file *file) { module_put(THIS_MODULE); return 0; diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c index 38a9b319355e..dd46e7358160 100644 --- a/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c +++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c @@ -202,9 +202,8 @@ static int proc_max_dirty_pages_in_mb(struct ctl_table *table, int write, /* Don't allow them to let dirty pages exceed 90% of system * memory and set a hard minimum of 4MB. */ if (obd_max_dirty_pages > ((totalram_pages / 10) * 9)) { - CERROR("Refusing to set max dirty pages to %u, which " - "is more than 90%% of available RAM; setting " - "to %lu\n", obd_max_dirty_pages, + CERROR("Refusing to set max dirty pages to %u, which is more than 90%% of available RAM; setting to %lu\n", + obd_max_dirty_pages, ((totalram_pages / 10) * 9)); obd_max_dirty_pages = ((totalram_pages / 10) * 9); } else if (obd_max_dirty_pages < 4 << (20 - PAGE_CACHE_SHIFT)) { diff --git a/drivers/staging/lustre/lustre/obdclass/llog.c b/drivers/staging/lustre/lustre/obdclass/llog.c index 3ab05292152c..114be4a78ccf 100644 --- a/drivers/staging/lustre/lustre/obdclass/llog.c +++ b/drivers/staging/lustre/lustre/obdclass/llog.c @@ -346,8 +346,8 @@ repeat: } if (rec->lrh_len == 0 || rec->lrh_len > LLOG_CHUNK_SIZE) { - CWARN("invalid length %d in llog record for " - "index %d/%d\n", rec->lrh_len, + CWARN("invalid length %d in llog record for index %d/%d\n", + rec->lrh_len, rec->lrh_index, index); rc = -EINVAL; goto out; diff --git a/drivers/staging/lustre/lustre/obdclass/llog_cat.c b/drivers/staging/lustre/lustre/obdclass/llog_cat.c index 6e139cf372c4..4b850fc5f5d9 100644 --- a/drivers/staging/lustre/lustre/obdclass/llog_cat.c +++ b/drivers/staging/lustre/lustre/obdclass/llog_cat.c @@ -228,8 +228,7 @@ int llog_cat_close(const struct lu_env *env, struct llog_handle *cathandle) (llh->llh_count == 1)) { rc = llog_destroy(env, loghandle); if (rc) - CERROR("%s: failure destroying log during " - "cleanup: rc = %d\n", + CERROR("%s: failure destroying log during cleanup: rc = %d\n", loghandle->lgh_ctxt->loc_obd->obd_name, rc); @@ -746,8 +745,7 @@ int llog_cat_cleanup(const struct lu_env *env, struct llog_handle *cathandle, llog_cat_set_first_idx(cathandle, index); rc = llog_cancel_rec(env, cathandle, index); if (rc == 0) - CDEBUG(D_HA, "cancel plain log at index" - " %u of catalog "DOSTID"\n", + CDEBUG(D_HA, "cancel plain log at index %u of catalog " DOSTID "\n", index, POSTID(&cathandle->lgh_id.lgl_oi)); return rc; } @@ -810,8 +808,8 @@ int llog_cat_init_and_process(const struct lu_env *env, rc = llog_process_or_fork(env, llh, cat_cancel_cb, NULL, NULL, false); if (rc) - CERROR("%s: llog_process() with cat_cancel_cb failed: rc = " - "%d\n", llh->lgh_ctxt->loc_obd->obd_name, rc); + CERROR("%s: llog_process() with cat_cancel_cb failed: rc = %d\n", + llh->lgh_ctxt->loc_obd->obd_name, rc); return 0; } EXPORT_SYMBOL(llog_cat_init_and_process); diff --git a/drivers/staging/lustre/lustre/obdclass/llog_obd.c b/drivers/staging/lustre/lustre/obdclass/llog_obd.c index da769db0af77..978d886a1103 100644 --- a/drivers/staging/lustre/lustre/obdclass/llog_obd.c +++ b/drivers/staging/lustre/lustre/obdclass/llog_obd.c @@ -42,7 +42,7 @@ #include "llog_internal.h" /* helper functions for calling the llog obd methods */ -static struct llog_ctxt* llog_new_ctxt(struct obd_device *obd) +static struct llog_ctxt *llog_new_ctxt(struct obd_device *obd) { struct llog_ctxt *ctxt; diff --git a/drivers/staging/lustre/lustre/obdclass/llog_swab.c b/drivers/staging/lustre/lustre/obdclass/llog_swab.c index bfac8387021e..d3ec90e85eb9 100644 --- a/drivers/staging/lustre/lustre/obdclass/llog_swab.c +++ b/drivers/staging/lustre/lustre/obdclass/llog_swab.c @@ -400,8 +400,7 @@ void lustre_swab_cfg_marker(struct cfg_marker *marker, int swab, int size) } marker->cm_createtime = createtime; marker->cm_canceltime = canceltime; - CDEBUG(D_CONFIG, "Find old cfg_marker(Srv32b,Clt64b) " - "for target %s, converting\n", + CDEBUG(D_CONFIG, "Find old cfg_marker(Srv32b,Clt64b) for target %s, converting\n", marker->cm_tgtname); } else if (swab) { __swab64s(&marker->cm_createtime); diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c index 61e04af2464f..3b7dfc367722 100644 --- a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c +++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c @@ -177,7 +177,7 @@ int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val, } EXPORT_SYMBOL(lprocfs_read_frac_helper); -int lprocfs_write_frac_helper(const char *buffer, unsigned long count, +int lprocfs_write_frac_helper(const char __user *buffer, unsigned long count, int *val, int mult) { char kernbuf[20], *end, *pbuf; @@ -1400,8 +1400,8 @@ int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats) * LPROCFS_OBD_OP_INIT(.., .., opname) * is missing from the list above. */ LASSERTF(stats->ls_cnt_header[i].lc_name != NULL, - "Missing obd_stat initializer obd_op " - "operation at offset %d.\n", i - num_private_stats); + "Missing obd_stat initializer obd_op operation at offset %d.\n", + i - num_private_stats); } rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats); if (rc < 0) { @@ -1486,8 +1486,7 @@ int lprocfs_alloc_md_stats(struct obd_device *obd, for (i = num_private_stats; i < num_stats; i++) { if (stats->ls_cnt_header[i].lc_name == NULL) { - CERROR("Missing md_stat initializer md_op " - "operation at offset %d. Aborting.\n", + CERROR("Missing md_stat initializer md_op operation at offset %d. Aborting.\n", i - num_private_stats); LBUG(); } @@ -1607,8 +1606,7 @@ LPROC_SEQ_FOPS_RO(lproc_exp_hash); int lprocfs_nid_stats_clear_read(struct seq_file *m, void *data) { return seq_printf(m, "%s\n", - "Write into this file to clear all nid stats and " - "stale nid entries"); + "Write into this file to clear all nid stats and stale nid entries"); } EXPORT_SYMBOL(lprocfs_nid_stats_clear_read); @@ -1819,7 +1817,7 @@ __s64 lprocfs_read_helper(struct lprocfs_counter *lc, } EXPORT_SYMBOL(lprocfs_read_helper); -int lprocfs_write_helper(const char *buffer, unsigned long count, +int lprocfs_write_helper(const char __user *buffer, unsigned long count, int *val) { return lprocfs_write_frac_helper(buffer, count, val, 1); diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c b/drivers/staging/lustre/lustre/obdclass/lu_object.c index 2fc037cfb62f..83bf168c2939 100644 --- a/drivers/staging/lustre/lustre/obdclass/lu_object.c +++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c @@ -866,8 +866,7 @@ static int lu_htable_order(void) /* clear off unreasonable cache setting. */ if (lu_cache_percent == 0 || lu_cache_percent > LU_CACHE_PERCENT_MAX) { - CWARN("obdclass: invalid lu_cache_percent: %u, it must be in" - " the range of (0, %u]. Will use default value: %u.\n", + CWARN("obdclass: invalid lu_cache_percent: %u, it must be in the range of (0, %u]. Will use default value: %u.\n", lu_cache_percent, LU_CACHE_PERCENT_MAX, LU_CACHE_PERCENT_DEFAULT); diff --git a/drivers/staging/lustre/lustre/obdclass/obd_config.c b/drivers/staging/lustre/lustre/obdclass/obd_config.c index 5e7b3d7cc984..6ce9adc2f11c 100644 --- a/drivers/staging/lustre/lustre/obdclass/obd_config.c +++ b/drivers/staging/lustre/lustre/obdclass/obd_config.c @@ -835,7 +835,7 @@ int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg) LIST_HEAD(lustre_profile_list); -struct lustre_profile *class_get_profile(const char * prof) +struct lustre_profile *class_get_profile(const char *prof) { struct lustre_profile *lprof; @@ -1443,8 +1443,7 @@ int class_config_llog_handler(const struct lu_env *env, if (!(clli->cfg_flags & CFG_F_COMPAT146) && !(clli->cfg_flags & CFG_F_MARKER) && (lcfg->lcfg_command != LCFG_MARKER)) { - CWARN("Config not inside markers, ignoring! " - "(inst: %p, uuid: %s, flags: %#x)\n", + CWARN("Config not inside markers, ignoring! (inst: %p, uuid: %s, flags: %#x)\n", clli->cfg_instance, clli->cfg_uuid.uuid, clli->cfg_flags); clli->cfg_flags |= CFG_F_SKIP; @@ -1467,14 +1466,12 @@ int class_config_llog_handler(const struct lu_env *env, if ((lcfg->lcfg_command == LCFG_ATTACH && typename && strcmp(typename, "mds") == 0)) { - CWARN("For 1.8 interoperability, rename obd " - "type from mds to mdt\n"); + CWARN("For 1.8 interoperability, rename obd type from mds to mdt\n"); typename[2] = 't'; } if ((lcfg->lcfg_command == LCFG_SETUP && index && strcmp(index, "type") == 0)) { - CDEBUG(D_INFO, "For 1.8 interoperability, " - "set this index to '0'\n"); + CDEBUG(D_INFO, "For 1.8 interoperability, set this index to '0'\n"); index[0] = '0'; index[1] = 0; } diff --git a/drivers/staging/lustre/lustre/obdclass/obd_mount.c b/drivers/staging/lustre/lustre/obdclass/obd_mount.c index 1260c8713bc6..4f39cdee1b5c 100644 --- a/drivers/staging/lustre/lustre/obdclass/obd_mount.c +++ b/drivers/staging/lustre/lustre/obdclass/obd_mount.c @@ -100,19 +100,12 @@ int lustre_process_log(struct super_block *sb, char *logname, OBD_FREE_PTR(bufs); if (rc == -EINVAL) - LCONSOLE_ERROR_MSG(0x15b, "%s: The configuration from log '%s'" - "failed from the MGS (%d). Make sure this " - "client and the MGS are running compatible " - "versions of Lustre.\n", + LCONSOLE_ERROR_MSG(0x15b, "%s: The configuration from log '%s' failed from the MGS (%d). Make sure this client and the MGS are running compatible versions of Lustre.\n", mgc->obd_name, logname, rc); if (rc) - LCONSOLE_ERROR_MSG(0x15c, "%s: The configuration from log '%s' " - "failed (%d). This may be the result of " - "communication errors between this node and " - "the MGS, a bad configuration, or other " - "errors. See the syslog for more " - "information.\n", mgc->obd_name, logname, + LCONSOLE_ERROR_MSG(0x15c, "%s: The configuration from log '%s' failed (%d). This may be the result of communication errors between this node and the MGS, a bad configuration, or other errors. See the syslog for more information.\n", + mgc->obd_name, logname, rc); /* class_obd_list(); */ @@ -297,11 +290,8 @@ int lustre_start_mgc(struct super_block *sb) if (has_ir ^ !(*flags & LMD_FLG_NOIR)) { /* LMD_FLG_NOIR is for test purpose only */ LCONSOLE_WARN( - "Trying to mount a client with IR setting " - "not compatible with current mgc. " - "Force to use current mgc setting that is " - "IR %s.\n", - has_ir ? "enabled" : "disabled"); + "Trying to mount a client with IR setting not compatible with current mgc. Force to use current mgc setting that is IR %s.\n", + has_ir ? "enabled" : "disabled"); if (has_ir) *flags &= ~LMD_FLG_NOIR; else @@ -998,16 +988,14 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd) LASSERT(lmd); if (!options) { - LCONSOLE_ERROR_MSG(0x162, "Missing mount data: check that " - "/sbin/mount.lustre is installed.\n"); + LCONSOLE_ERROR_MSG(0x162, "Missing mount data: check that /sbin/mount.lustre is installed.\n"); return -EINVAL; } /* Options should be a string - try to detect old lmd data */ if ((raw->lmd_magic & 0xffffff00) == (LMD_MAGIC & 0xffffff00)) { - LCONSOLE_ERROR_MSG(0x163, "You're using an old version of " - "/sbin/mount.lustre. Please install " - "version %s\n", LUSTRE_VERSION_STRING); + LCONSOLE_ERROR_MSG(0x163, "You're using an old version of /sbin/mount.lustre. Please install version %s\n", + LUSTRE_VERSION_STRING); return -EINVAL; } lmd->lmd_magic = LMD_MAGIC; @@ -1139,8 +1127,7 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd) } if (!devname) { - LCONSOLE_ERROR_MSG(0x164, "Can't find the device name " - "(need mount option 'device=...')\n"); + LCONSOLE_ERROR_MSG(0x164, "Can't find the device name (need mount option 'device=...')\n"); goto invalid; } @@ -1232,9 +1219,7 @@ int lustre_fill_super(struct super_block *sb, void *data, int silent) if (client_fill_super == NULL) request_module("lustre"); if (client_fill_super == NULL) { - LCONSOLE_ERROR_MSG(0x165, "Nothing registered for " - "client mount! Is the 'lustre' " - "module loaded?\n"); + LCONSOLE_ERROR_MSG(0x165, "Nothing registered for client mount! Is the 'lustre' module loaded?\n"); lustre_put_lsi(sb); rc = -ENODEV; } else { @@ -1249,8 +1234,7 @@ int lustre_fill_super(struct super_block *sb, void *data, int silent) /* c_f_s will call lustre_common_put_super on failure */ } } else { - CERROR("This is client-side-only module, " - "cannot handle server mount.\n"); + CERROR("This is client-side-only module, cannot handle server mount.\n"); rc = -EINVAL; } diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c index 98e4290919d0..5f6d9441bc44 100644 --- a/drivers/staging/lustre/lustre/obdecho/echo_client.c +++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c @@ -698,14 +698,16 @@ static struct lu_device *echo_device_alloc(const struct lu_env *env, int cleanup = 0; OBD_ALLOC_PTR(ed); - if (ed == NULL) - GOTO(out, rc = -ENOMEM); + if (ed == NULL) { + rc = -ENOMEM; + goto out; + } cleanup = 1; cd = &ed->ed_cl; rc = cl_device_init(cd, t); if (rc) - GOTO(out, rc); + goto out; cd->cd_lu_dev.ld_ops = &echo_device_lu_ops; cd->cd_ops = &echo_device_cl_ops; @@ -719,24 +721,26 @@ static struct lu_device *echo_device_alloc(const struct lu_env *env, if (tgt == NULL) { CERROR("Can not find tgt device %s\n", lustre_cfg_string(cfg, 1)); - GOTO(out, rc = -ENODEV); + rc = -ENODEV; + goto out; } next = tgt->obd_lu_dev; if (!strcmp(tgt->obd_type->typ_name, LUSTRE_MDT_NAME)) { CERROR("echo MDT client must be run on server\n"); - GOTO(out, rc = -EOPNOTSUPP); + rc = -EOPNOTSUPP; + goto out; } rc = echo_site_init(env, ed); if (rc) - GOTO(out, rc); + goto out; cleanup = 3; rc = echo_client_setup(env, obd, cfg); if (rc) - GOTO(out, rc); + goto out; ed->ed_ec = &obd->u.echo_client; cleanup = 4; @@ -749,15 +753,17 @@ static struct lu_device *echo_device_alloc(const struct lu_env *env, tgt_type_name = tgt->obd_type->typ_name; if (next != NULL) { LASSERT(next != NULL); - if (next->ld_site != NULL) - GOTO(out, rc = -EBUSY); + if (next->ld_site != NULL) { + rc = -EBUSY; + goto out; + } next->ld_site = &ed->ed_site->cs_lu; rc = next->ld_type->ldt_ops->ldto_device_init(env, next, next->ld_type->ldt_name, NULL); if (rc) - GOTO(out, rc); + goto out; /* Tricky case, I have to determine the obd type since * CLIO uses the different parameters to initialize @@ -865,8 +871,7 @@ static struct lu_device *echo_device_free(const struct lu_env *env, spin_lock(&ec->ec_lock); while (!list_empty(&ec->ec_objects)) { spin_unlock(&ec->ec_lock); - CERROR("echo_client still has objects at cleanup time, " - "wait for 1 second\n"); + CERROR("echo_client still has objects at cleanup time, wait for 1 second\n"); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(cfs_time_seconds(1)); lu_site_purge(env, &ed->ed_site->cs_lu, -1); @@ -968,15 +973,19 @@ static struct echo_object *cl_echo_object_find(struct echo_device *d, fid = &info->eti_fid; rc = ostid_to_fid(fid, &lsm->lsm_oi, 0); - if (rc != 0) - GOTO(out, eco = ERR_PTR(rc)); + if (rc != 0) { + eco = ERR_PTR(rc); + goto out; + } /* In the function below, .hs_keycmp resolves to * lu_obj_hop_keycmp() */ /* coverity[overrun-buffer-val] */ obj = cl_object_find(env, echo_dev2cl(d), fid, &conf->eoc_cl); - if (IS_ERR(obj)) - GOTO(out, eco = (void *)obj); + if (IS_ERR(obj)) { + eco = (void *)obj; + goto out; + } eco = cl2echo_obj(obj); if (eco->eo_deleted) { @@ -1076,7 +1085,7 @@ static int cl_echo_enqueue(struct echo_object *eco, u64 start, u64 end, io->ci_ignore_layout = 1; result = cl_io_init(env, io, CIT_MISC, echo_obj2cl(eco)); if (result < 0) - GOTO(out, result); + goto out; LASSERT(result == 0); result = cl_echo_enqueue0(env, eco, start, end, mode, cookie, 0); @@ -1182,7 +1191,7 @@ static int cl_echo_object_brw(struct echo_object *eco, int rw, u64 offset, io->ci_ignore_layout = 1; rc = cl_io_init(env, io, CIT_MISC, obj); if (rc < 0) - GOTO(out, rc); + goto out; LASSERT(rc == 0); @@ -1191,7 +1200,7 @@ static int cl_echo_object_brw(struct echo_object *eco, int rw, u64 offset, rw == READ ? LCK_PR : LCK_PW, &lh.cookie, CEF_NEVER); if (rc < 0) - GOTO(error_lock, rc); + goto error_lock; for (i = 0; i < npages; i++) { LASSERT(pages[i]); @@ -1318,7 +1327,7 @@ static int echo_create_object(const struct lu_env *env, struct echo_device *ed, rc = echo_alloc_memmd(ed, &lsm); if (rc < 0) { CERROR("Cannot allocate md: rc = %d\n", rc); - GOTO(failed, rc); + goto failed; } if (ulsm != NULL) { @@ -1326,7 +1335,7 @@ static int echo_create_object(const struct lu_env *env, struct echo_device *ed, rc = echo_copyin_lsm (ed, lsm, ulsm, ulsm_nob); if (rc != 0) - GOTO(failed, rc); + goto failed; if (lsm->lsm_stripe_count == 0) lsm->lsm_stripe_count = ec->ec_nstripes; @@ -1363,7 +1372,7 @@ static int echo_create_object(const struct lu_env *env, struct echo_device *ed, rc = obd_create(env, ec->ec_exp, oa, &lsm, oti); if (rc != 0) { CERROR("Cannot create objects: rc = %d\n", rc); - GOTO(failed, rc); + goto failed; } created = 1; } @@ -1373,8 +1382,10 @@ static int echo_create_object(const struct lu_env *env, struct echo_device *ed, oa->o_valid |= OBD_MD_FLID; eco = cl_echo_object_find(ed, &lsm); - if (IS_ERR(eco)) - GOTO(failed, rc = PTR_ERR(eco)); + if (IS_ERR(eco)) { + rc = PTR_ERR(eco); + goto failed; + } cl_echo_object_put(eco); CDEBUG(D_INFO, "oa oid "DOSTID"\n", POSTID(&oa->o_oi)); @@ -1642,8 +1653,10 @@ static int echo_client_prep_commit(const struct lu_env *env, OBD_ALLOC(lnb, npages * sizeof(struct niobuf_local)); OBD_ALLOC(rnb, npages * sizeof(struct niobuf_remote)); - if (lnb == NULL || rnb == NULL) - GOTO(out, ret = -ENOMEM); + if (lnb == NULL || rnb == NULL) { + ret = -ENOMEM; + goto out; + } if (rw == OBD_BRW_WRITE && async) brw_flags |= OBD_BRW_ASYNC; @@ -1671,7 +1684,7 @@ static int echo_client_prep_commit(const struct lu_env *env, ret = obd_preprw(env, rw, exp, oa, 1, &ioo, rnb, &lpages, lnb, oti, NULL); if (ret != 0) - GOTO(out, ret); + goto out; LASSERT(lpages == npages); for (i = 0; i < lpages; i++) { @@ -1704,7 +1717,7 @@ static int echo_client_prep_commit(const struct lu_env *env, ret = obd_commitrw(env, rw, exp, oa, 1, &ioo, rnb, npages, lnb, oti, ret); if (ret != 0) - GOTO(out, ret); + goto out; /* Reset oti otherwise it would confuse ldiskfs. */ memset(oti, 0, sizeof(*oti)); @@ -1862,21 +1875,27 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, int len, return -ENOMEM; rc = lu_env_init(env, LCT_DT_THREAD); - if (rc) - GOTO(out, rc = -ENOMEM); + if (rc) { + rc = -ENOMEM; + goto out; + } switch (cmd) { case OBD_IOC_CREATE: /* may create echo object */ - if (!capable(CFS_CAP_SYS_ADMIN)) - GOTO (out, rc = -EPERM); + if (!capable(CFS_CAP_SYS_ADMIN)) { + rc = -EPERM; + goto out; + } rc = echo_create_object(env, ed, 1, oa, data->ioc_pbuf1, data->ioc_plen1, &dummy_oti); - GOTO(out, rc); + goto out; case OBD_IOC_DESTROY: - if (!capable(CFS_CAP_SYS_ADMIN)) - GOTO (out, rc = -EPERM); + if (!capable(CFS_CAP_SYS_ADMIN)) { + rc = -EPERM; + goto out; + } rc = echo_get_object(&eco, ed, oa); if (rc == 0) { @@ -1886,7 +1905,7 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, int len, eco->eo_deleted = 1; echo_put_object(eco); } - GOTO(out, rc); + goto out; case OBD_IOC_GETATTR: rc = echo_get_object(&eco, ed, oa); @@ -1897,11 +1916,13 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, int len, rc = obd_getattr(env, ec->ec_exp, &oinfo); echo_put_object(eco); } - GOTO(out, rc); + goto out; case OBD_IOC_SETATTR: - if (!capable(CFS_CAP_SYS_ADMIN)) - GOTO (out, rc = -EPERM); + if (!capable(CFS_CAP_SYS_ADMIN)) { + rc = -EPERM; + goto out; + } rc = echo_get_object(&eco, ed, oa); if (rc == 0) { @@ -1912,17 +1933,19 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, int len, rc = obd_setattr(env, ec->ec_exp, &oinfo, NULL); echo_put_object(eco); } - GOTO(out, rc); + goto out; case OBD_IOC_BRW_WRITE: - if (!capable(CFS_CAP_SYS_ADMIN)) - GOTO (out, rc = -EPERM); + if (!capable(CFS_CAP_SYS_ADMIN)) { + rc = -EPERM; + goto out; + } rw = OBD_BRW_WRITE; /* fall through */ case OBD_IOC_BRW_READ: rc = echo_client_brw_ioctl(env, rw, exp, data, &dummy_oti); - GOTO(out, rc); + goto out; case ECHO_IOC_GET_STRIPE: rc = echo_get_object(&eco, ed, oa); @@ -1931,11 +1954,13 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, int len, data->ioc_plen1); echo_put_object(eco); } - GOTO(out, rc); + goto out; case ECHO_IOC_SET_STRIPE: - if (!capable(CFS_CAP_SYS_ADMIN)) - GOTO (out, rc = -EPERM); + if (!capable(CFS_CAP_SYS_ADMIN)) { + rc = -EPERM; + goto out; + } if (data->ioc_pbuf1 == NULL) { /* unset */ rc = echo_get_object(&eco, ed, oa); @@ -1948,25 +1973,28 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, int len, data->ioc_pbuf1, data->ioc_plen1, &dummy_oti); } - GOTO (out, rc); + goto out; case ECHO_IOC_ENQUEUE: - if (!capable(CFS_CAP_SYS_ADMIN)) - GOTO (out, rc = -EPERM); + if (!capable(CFS_CAP_SYS_ADMIN)) { + rc = -EPERM; + goto out; + } rc = echo_client_enqueue(exp, oa, data->ioc_conn1, /* lock mode */ data->ioc_offset, data->ioc_count);/*extent*/ - GOTO (out, rc); + goto out; case ECHO_IOC_CANCEL: rc = echo_client_cancel(exp, oa); - GOTO (out, rc); + goto out; default: CERROR ("echo_ioctl(): unrecognised ioctl %#x\n", cmd); - GOTO (out, rc = -ENOTTY); + rc = -ENOTTY; + goto out; } out: @@ -2084,11 +2112,13 @@ static int echo_client_disconnect(struct obd_export *exp) { int rc; - if (exp == NULL) - GOTO(out, rc = -EINVAL); + if (exp == NULL) { + rc = -EINVAL; + goto out; + } rc = class_disconnect(exp); - GOTO(out, rc); + goto out; out: return rc; } diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c index 7734d666b7a1..370e6d4896c6 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cache.c +++ b/drivers/staging/lustre/lustre/osc/osc_cache.c @@ -178,76 +178,113 @@ static int osc_extent_sanity_check0(struct osc_extent *ext, int page_count; int rc = 0; - if (!osc_object_is_locked(obj)) - GOTO(out, rc = 9); + if (!osc_object_is_locked(obj)) { + rc = 9; + goto out; + } - if (ext->oe_state >= OES_STATE_MAX) - GOTO(out, rc = 10); + if (ext->oe_state >= OES_STATE_MAX) { + rc = 10; + goto out; + } - if (atomic_read(&ext->oe_refc) <= 0) - GOTO(out, rc = 20); + if (atomic_read(&ext->oe_refc) <= 0) { + rc = 20; + goto out; + } - if (atomic_read(&ext->oe_refc) < atomic_read(&ext->oe_users)) - GOTO(out, rc = 30); + if (atomic_read(&ext->oe_refc) < atomic_read(&ext->oe_users)) { + rc = 30; + goto out; + } switch (ext->oe_state) { case OES_INV: if (ext->oe_nr_pages > 0 || !list_empty(&ext->oe_pages)) - GOTO(out, rc = 35); - GOTO(out, rc = 0); - break; + rc = 35; + else + rc = 0; + goto out; case OES_ACTIVE: - if (atomic_read(&ext->oe_users) == 0) - GOTO(out, rc = 40); - if (ext->oe_hp) - GOTO(out, rc = 50); - if (ext->oe_fsync_wait && !ext->oe_urgent) - GOTO(out, rc = 55); + if (atomic_read(&ext->oe_users) == 0) { + rc = 40; + goto out; + } + if (ext->oe_hp) { + rc = 50; + goto out; + } + if (ext->oe_fsync_wait && !ext->oe_urgent) { + rc = 55; + goto out; + } break; case OES_CACHE: - if (ext->oe_grants == 0) - GOTO(out, rc = 60); - if (ext->oe_fsync_wait && !ext->oe_urgent && !ext->oe_hp) - GOTO(out, rc = 65); + if (ext->oe_grants == 0) { + rc = 60; + goto out; + } + if (ext->oe_fsync_wait && !ext->oe_urgent && !ext->oe_hp) { + rc = 65; + goto out; + } default: - if (atomic_read(&ext->oe_users) > 0) - GOTO(out, rc = 70); + if (atomic_read(&ext->oe_users) > 0) { + rc = 70; + goto out; + } } - if (ext->oe_max_end < ext->oe_end || ext->oe_end < ext->oe_start) - GOTO(out, rc = 80); + if (ext->oe_max_end < ext->oe_end || ext->oe_end < ext->oe_start) { + rc = 80; + goto out; + } - if (ext->oe_osclock == NULL && ext->oe_grants > 0) - GOTO(out, rc = 90); + if (ext->oe_osclock == NULL && ext->oe_grants > 0) { + rc = 90; + goto out; + } if (ext->oe_osclock) { struct cl_lock_descr *descr; descr = &ext->oe_osclock->cll_descr; if (!(descr->cld_start <= ext->oe_start && - descr->cld_end >= ext->oe_max_end)) - GOTO(out, rc = 100); + descr->cld_end >= ext->oe_max_end)) { + rc = 100; + goto out; + } } - if (ext->oe_nr_pages > ext->oe_mppr) - GOTO(out, rc = 105); + if (ext->oe_nr_pages > ext->oe_mppr) { + rc = 105; + goto out; + } /* Do not verify page list if extent is in RPC. This is because an * in-RPC extent is supposed to be exclusively accessible w/o lock. */ - if (ext->oe_state > OES_CACHE) - GOTO(out, rc = 0); + if (ext->oe_state > OES_CACHE) { + rc = 0; + goto out; + } - if (!extent_debug) - GOTO(out, rc = 0); + if (!extent_debug) { + rc = 0; + goto out; + } page_count = 0; list_for_each_entry(oap, &ext->oe_pages, oap_pending_item) { pgoff_t index = oap2cl_page(oap)->cp_index; ++page_count; - if (index > ext->oe_end || index < ext->oe_start) - GOTO(out, rc = 110); + if (index > ext->oe_end || index < ext->oe_start) { + rc = 110; + goto out; + } + } + if (page_count != ext->oe_nr_pages) { + rc = 120; + goto out; } - if (page_count != ext->oe_nr_pages) - GOTO(out, rc = 120); out: if (rc != 0) @@ -536,10 +573,9 @@ static int osc_extent_merge(const struct lu_env *env, struct osc_extent *cur, /** * Drop user count of osc_extent, and unplug IO asynchronously. */ -int osc_extent_release(const struct lu_env *env, struct osc_extent *ext) +void osc_extent_release(const struct lu_env *env, struct osc_extent *ext) { struct osc_object *obj = ext->oe_obj; - int rc = 0; LASSERT(atomic_read(&ext->oe_users) > 0); LASSERT(sanity_check(ext) == 0); @@ -571,7 +607,6 @@ int osc_extent_release(const struct lu_env *env, struct osc_extent *ext) osc_io_unplug_async(env, osc_cli(obj), obj); } osc_extent_put(env, ext); - return rc; } static inline int overlapped(struct osc_extent *ex1, struct osc_extent *ex2) @@ -776,8 +811,10 @@ restart: rc = osc_extent_wait(env, conflict, OES_INV); osc_extent_put(env, conflict); conflict = NULL; - if (rc < 0) - GOTO(out, found = ERR_PTR(rc)); + if (rc < 0) { + found = ERR_PTR(rc); + goto out; + } goto restart; } @@ -934,7 +971,7 @@ static int osc_extent_truncate(struct osc_extent *ext, pgoff_t trunc_index, io->ci_obj = cl_object_top(osc2cl(obj)); rc = cl_io_init(env, io, CIT_MISC, io->ci_obj); if (rc < 0) - GOTO(out, rc); + goto out; /* discard all pages with index greater then trunc_index */ list_for_each_entry_safe(oap, tmp, &ext->oe_pages, @@ -1114,21 +1151,27 @@ static int osc_extent_expand(struct osc_extent *ext, pgoff_t index, int *grants) osc_object_lock(obj); LASSERT(sanity_check_nolock(ext) == 0); end_chunk = ext->oe_end >> ppc_bits; - if (chunk > end_chunk + 1) - GOTO(out, rc = -ERANGE); + if (chunk > end_chunk + 1) { + rc = -ERANGE; + goto out; + } - if (end_chunk >= chunk) - GOTO(out, rc = 0); + if (end_chunk >= chunk) { + rc = 0; + goto out; + } LASSERT(end_chunk + 1 == chunk); /* try to expand this extent to cover @index */ end_index = min(ext->oe_max_end, ((chunk + 1) << ppc_bits) - 1); next = next_extent(ext); - if (next != NULL && next->oe_start <= end_index) + if (next != NULL && next->oe_start <= end_index) { /* complex mode - overlapped with the next extent, * this case will be handled by osc_extent_find() */ - GOTO(out, rc = -EAGAIN); + rc = -EAGAIN; + goto out; + } ext->oe_end = end_index; ext->oe_grants += chunksize; @@ -1497,12 +1540,16 @@ static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli, * of queued writes and create a discontiguous rpc stream */ if (OBD_FAIL_CHECK(OBD_FAIL_OSC_NO_GRANT) || cli->cl_dirty_max < PAGE_CACHE_SIZE || - cli->cl_ar.ar_force_sync || loi->loi_ar.ar_force_sync) - GOTO(out, rc = -EDQUOT); + cli->cl_ar.ar_force_sync || loi->loi_ar.ar_force_sync) { + rc = -EDQUOT; + goto out; + } /* Hopefully normal case - cache space and write credits available */ - if (osc_enter_cache_try(cli, oap, bytes, 0)) - GOTO(out, rc = 0); + if (osc_enter_cache_try(cli, oap, bytes, 0)) { + rc = 0; + goto out; + } /* We can get here for two reasons: too many dirty pages in cache, or * run out of grants. In both cases we should write dirty pages out. @@ -1530,16 +1577,18 @@ static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli, /* l_wait_event is interrupted by signal */ if (rc < 0) { list_del_init(&ocw.ocw_entry); - GOTO(out, rc); + goto out; } LASSERT(list_empty(&ocw.ocw_entry)); rc = ocw.ocw_rc; if (rc != -EDQUOT) - GOTO(out, rc); - if (osc_enter_cache_try(cli, oap, bytes, 0)) - GOTO(out, rc = 0); + goto out; + if (osc_enter_cache_try(cli, oap, bytes, 0)) { + rc = 0; + goto out; + } } out: client_obd_list_unlock(&cli->cl_loi_list_lock); @@ -1562,8 +1611,8 @@ void osc_wake_cache_waiters(struct client_obd *cli) if ((cli->cl_dirty + PAGE_CACHE_SIZE > cli->cl_dirty_max) || (atomic_read(&obd_dirty_pages) + 1 > obd_max_dirty_pages)) { - CDEBUG(D_CACHE, "no dirty room: dirty: %ld " - "osc max %ld, sys max %d\n", cli->cl_dirty, + CDEBUG(D_CACHE, "no dirty room: dirty: %ld osc max %ld, sys max %d\n", + cli->cl_dirty, cli->cl_dirty_max, obd_max_dirty_pages); goto wakeup; } @@ -2401,14 +2450,15 @@ int osc_flush_async_page(const struct lu_env *env, struct cl_io *io, * one making the extent active, we could deadlock waiting for * the page writeback to clear but it won't because the extent * is active and won't be written out. */ - GOTO(out, rc = -EAGAIN); + rc = -EAGAIN; + goto out; default: break; } rc = cl_page_prep(env, io, cl_page_top(cp), CRT_WRITE); if (rc) - GOTO(out, rc); + goto out; spin_lock(&oap->oap_lock); oap->oap_async_flags |= ASYNC_READY|ASYNC_URGENT; diff --git a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h index ebbd95c0cea8..365b2787b3c8 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h @@ -678,7 +678,7 @@ struct osc_extent { int osc_extent_finish(const struct lu_env *env, struct osc_extent *ext, int sent, int rc); -int osc_extent_release(const struct lu_env *env, struct osc_extent *ext); +void osc_extent_release(const struct lu_env *env, struct osc_extent *ext); /** @} osc */ diff --git a/drivers/staging/lustre/lustre/osc/osc_lock.c b/drivers/staging/lustre/lustre/osc/osc_lock.c index 8138856fda8c..a7f08bc48166 100644 --- a/drivers/staging/lustre/lustre/osc/osc_lock.c +++ b/drivers/staging/lustre/lustre/osc/osc_lock.c @@ -1067,14 +1067,12 @@ static int osc_lock_enqueue_wait(const struct lu_env *env, * conflicts, we do not wait but return 0 so the * request is send to the server */ - CDEBUG(D_DLMTRACE, "group lock %p is conflicted " - "with %p, no wait, send to server\n", + CDEBUG(D_DLMTRACE, "group lock %p is conflicted with %p, no wait, send to server\n", lock, conflict); cl_lock_put(env, conflict); rc = 0; } else { - CDEBUG(D_DLMTRACE, "lock %p is conflicted with %p, " - "will wait\n", + CDEBUG(D_DLMTRACE, "lock %p is conflicted with %p, will wait\n", lock, conflict); LASSERT(lock->cll_conflict == NULL); lu_ref_add(&conflict->cll_reference, "cancel-wait", diff --git a/drivers/staging/lustre/lustre/osc/osc_object.c b/drivers/staging/lustre/lustre/osc/osc_object.c index 69000584619d..92c202f70395 100644 --- a/drivers/staging/lustre/lustre/osc/osc_object.c +++ b/drivers/staging/lustre/lustre/osc/osc_object.c @@ -140,8 +140,7 @@ static int osc_object_print(const struct lu_env *env, void *cookie, struct lov_oinfo *oinfo = osc->oo_oinfo; struct osc_async_rc *ar = &oinfo->loi_ar; - (*p)(env, cookie, "id: "DOSTID" " - "idx: %d gen: %d kms_valid: %u kms %llu rc: %d force_sync: %d min_xid: %llu ", + (*p)(env, cookie, "id: " DOSTID " idx: %d gen: %d kms_valid: %u kms %llu rc: %d force_sync: %d min_xid: %llu ", POSTID(&oinfo->loi_oi), oinfo->loi_ost_idx, oinfo->loi_ost_gen, oinfo->loi_kms_valid, oinfo->loi_kms, ar->ar_rc, ar->ar_force_sync, ar->ar_min_xid); diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c index fcd079b1af01..76ba58b09c5d 100644 --- a/drivers/staging/lustre/lustre/osc/osc_page.c +++ b/drivers/staging/lustre/lustre/osc/osc_page.c @@ -369,12 +369,7 @@ static int osc_page_print(const struct lu_env *env, struct osc_object *obj = cl2osc(slice->cpl_obj); struct client_obd *cli = &osc_export(obj)->exp_obd->u.cli; - return (*printer)(env, cookie, LUSTRE_OSC_NAME"-page@%p: " - "1< %#x %d %u %s %s > " - "2< %llu %u %u %#x %#x | %p %p %p > " - "3< %s %p %d %lu %d > " - "4< %d %d %d %lu %s | %s %s %s %s > " - "5< %s %s %s %s | %d %s | %d %s %s>\n", + return (*printer)(env, cookie, LUSTRE_OSC_NAME "-page@%p: 1< %#x %d %u %s %s > 2< %llu %u %u %#x %#x | %p %p %p > 3< %s %p %d %lu %d > 4< %d %d %d %lu %s | %s %s %s %s > 5< %s %s %s %s | %d %s | %d %s %s>\n", opg, /* 1 */ oap->oap_magic, oap->oap_cmd, @@ -550,8 +545,8 @@ void osc_page_submit(const struct lu_env *env, struct osc_page *opg, LINVRNT(osc_page_protected(env, opg, crt == CRT_WRITE ? CLM_WRITE : CLM_READ, 1)); - LASSERTF(oap->oap_magic == OAP_MAGIC, "Bad oap magic: oap %p, " - "magic 0x%x\n", oap, oap->oap_magic); + LASSERTF(oap->oap_magic == OAP_MAGIC, "Bad oap magic: oap %p, magic 0x%x\n", + oap, oap->oap_magic); LASSERT(oap->oap_async_flags & ASYNC_READY); LASSERT(oap->oap_async_flags & ASYNC_COUNT_STABLE); diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index 44657a06b8a5..b9450b95f1c5 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -1078,9 +1078,9 @@ static void osc_init_grant(struct client_obd *cli, struct obd_connect_data *ocd) cli->cl_chunkbits = max_t(int, PAGE_CACHE_SHIFT, ocd->ocd_blocksize); client_obd_list_unlock(&cli->cl_loi_list_lock); - CDEBUG(D_CACHE, "%s, setting cl_avail_grant: %ld cl_lost_grant: %ld." - "chunk bits: %d.\n", cli->cl_import->imp_obd->obd_name, - cli->cl_avail_grant, cli->cl_lost_grant, cli->cl_chunkbits); + CDEBUG(D_CACHE, "%s, setting cl_avail_grant: %ld cl_lost_grant: %ld chunk bits: %d\n", + cli->cl_import->imp_obd->obd_name, + cli->cl_avail_grant, cli->cl_lost_grant, cli->cl_chunkbits); if (ocd->ocd_connect_flags & OBD_CONNECT_GRANT_SHRINK && list_empty(&cli->cl_grant_shrink_list)) @@ -1171,8 +1171,7 @@ static inline int can_merge_pages(struct brw_page *p1, struct brw_page *p2) /* warn if we try to combine flags that we don't know to be * safe to combine */ if (unlikely((p1->flag & mask) != (p2->flag & mask))) { - CWARN("Saw flags 0x%x and 0x%x in the same brw, please " - "report this at http://bugs.whamcloud.com/\n", + CWARN("Saw flags 0x%x and 0x%x in the same brw, please report this at http://bugs.whamcloud.com/\n", p1->flag, p2->flag); } return 0; @@ -1343,8 +1342,7 @@ static int osc_brw_prep_request(int cmd, struct client_obd *cli, "i: %d/%d pg: %p off: %llu, count: %u\n", i, page_count, pg, pg->off, pg->count); LASSERTF(i == 0 || pg->off > pg_prev->off, - "i %d p_c %u pg %p [pri %lu ind %lu] off %llu" - " prev_pg %p [pri %lu ind %lu] off %llu\n", + "i %d p_c %u pg %p [pri %lu ind %lu] off %llu prev_pg %p [pri %lu ind %lu] off %llu\n", i, page_count, pg->pg, page_private(pg->pg), pg->pg->index, pg->off, pg_prev->pg, page_private(pg_prev->pg), @@ -1467,16 +1465,16 @@ static int check_write_checksum(struct obdo *oa, const lnet_process_id_t *peer, cksum_type); if (cksum_type != client_cksum_type) - msg = "the server did not use the checksum type specified in " - "the original request - likely a protocol problem"; + msg = "the server did not use the checksum type specified in the original request - likely a protocol problem" + ; else if (new_cksum == server_cksum) - msg = "changed on the client after we checksummed it - " - "likely false positive due to mmap IO (bug 11742)"; + msg = "changed on the client after we checksummed it - likely false positive due to mmap IO (bug 11742)" + ; else if (new_cksum == client_cksum) msg = "changed in transit before arrival at OST"; else - msg = "changed in transit AND doesn't match the original - " - "likely false positive due to mmap IO (bug 11742)"; + msg = "changed in transit AND doesn't match the original - likely false positive due to mmap IO (bug 11742)" + ; LCONSOLE_ERROR_MSG(0x132, "BAD WRITE CHECKSUM: %s: from %s inode "DFID " object "DOSTID" extent [%llu-%llu]\n", @@ -1486,8 +1484,8 @@ static int check_write_checksum(struct obdo *oa, const lnet_process_id_t *peer, oa->o_valid & OBD_MD_FLFID ? oa->o_parent_ver : 0, POSTID(&oa->o_oi), pga[0]->off, pga[page_count-1]->off + pga[page_count-1]->count - 1); - CERROR("original client csum %x (type %x), server csum %x (type %x), " - "client csum now %x\n", client_cksum, client_cksum_type, + CERROR("original client csum %x (type %x), server csum %x (type %x), client csum now %x\n", + client_cksum, client_cksum_type, server_cksum, cksum_type, new_cksum); return 1; } @@ -1601,23 +1599,21 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc) } if (server_cksum != client_cksum) { - LCONSOLE_ERROR_MSG(0x133, "%s: BAD READ CHECKSUM: from " - "%s%s%s inode "DFID" object "DOSTID - " extent [%llu-%llu]\n", + LCONSOLE_ERROR_MSG(0x133, "%s: BAD READ CHECKSUM: from %s%s%s inode " DFID " object " DOSTID " extent [%llu-%llu]\n", req->rq_import->imp_obd->obd_name, libcfs_nid2str(peer->nid), via, router, body->oa.o_valid & OBD_MD_FLFID ? - body->oa.o_parent_seq : (__u64)0, + body->oa.o_parent_seq : (__u64)0, body->oa.o_valid & OBD_MD_FLFID ? - body->oa.o_parent_oid : 0, + body->oa.o_parent_oid : 0, body->oa.o_valid & OBD_MD_FLFID ? - body->oa.o_parent_ver : 0, + body->oa.o_parent_ver : 0, POSTID(&body->oa.o_oi), aa->aa_ppga[0]->off, aa->aa_ppga[aa->aa_page_count-1]->off + aa->aa_ppga[aa->aa_page_count-1]->count - - 1); + 1); CERROR("client %x, server %x, cksum_type %x\n", client_cksum, server_cksum, cksum_type); cksum_counter = 0; @@ -1771,8 +1767,7 @@ static int brw_interpret(const struct lu_env *env, if (osc_recoverable_error(rc)) { if (req->rq_import_generation != req->rq_import->imp_generation) { - CDEBUG(D_HA, "%s: resend cross eviction for object: " - ""DOSTID", rc = %d.\n", + CDEBUG(D_HA, "%s: resend cross eviction for object: " DOSTID ", rc = %d.\n", req->rq_import->imp_obd->obd_name, POSTID(&aa->aa_oa->o_oi), rc); } else if (rc == -EINPROGRESS || @@ -3013,8 +3008,8 @@ static int osc_reconnect(const struct lu_env *env, cli->cl_lost_grant = 0; client_obd_list_unlock(&cli->cl_loi_list_lock); - CDEBUG(D_RPCTRACE, "ocd_connect_flags: %#llx ocd_version: %d" - " ocd_grant: %d, lost: %ld.\n", data->ocd_connect_flags, + CDEBUG(D_RPCTRACE, "ocd_connect_flags: %#llx ocd_version: %d ocd_grant: %d, lost: %ld.\n", + data->ocd_connect_flags, data->ocd_version, data->ocd_grant, lost_grant); } @@ -3217,8 +3212,6 @@ out_ptlrpcd: static int osc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) { - int rc = 0; - switch (stage) { case OBD_CLEANUP_EARLY: { struct obd_import *imp; @@ -3253,7 +3246,7 @@ static int osc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) break; } } - return rc; + return 0; } int osc_cleanup(struct obd_device *obd) diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c index 38cc931a189c..dc9e406f3212 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/client.c +++ b/drivers/staging/lustre/lustre/ptlrpc/client.c @@ -265,8 +265,7 @@ static void ptlrpc_at_adj_service(struct ptlrpc_request *req, so just keep minimal history here */ oldse = at_measured(&at->iat_service_estimate[idx], serv_est); if (oldse != 0) - CDEBUG(D_ADAPTTO, "The RPC service estimate for %s ptl %d " - "has changed from %d to %d\n", + CDEBUG(D_ADAPTTO, "The RPC service estimate for %s ptl %d has changed from %d to %d\n", req->rq_import->imp_obd->obd_name, req->rq_request_portal, oldse, at_get(&at->iat_service_estimate[idx])); } @@ -297,8 +296,7 @@ static void ptlrpc_at_adj_net_latency(struct ptlrpc_request *req, oldnl = at_measured(&at->iat_net_latency, nl); if (oldnl != 0) - CDEBUG(D_ADAPTTO, "The network latency for %s (nid %s) " - "has changed from %d to %d\n", + CDEBUG(D_ADAPTTO, "The network latency for %s (nid %s) has changed from %d to %d\n", req->rq_import->imp_obd->obd_name, obd_uuid2str( &req->rq_import->imp_connection->c_remote_uuid), @@ -371,8 +369,8 @@ static int ptlrpc_at_recv_early_reply(struct ptlrpc_request *req) ptlrpc_at_get_net_latency(req); DEBUG_REQ(D_ADAPTTO, req, - "Early reply #%d, new deadline in "CFS_DURATION_T"s " - "("CFS_DURATION_T"s)", req->rq_early_count, + "Early reply #%d, new deadline in " CFS_DURATION_T "s (" CFS_DURATION_T "s)", + req->rq_early_count, cfs_time_sub(req->rq_deadline, get_seconds()), cfs_time_sub(req->rq_deadline, olddl)); @@ -445,8 +443,8 @@ void ptlrpc_add_rqs_to_pool(struct ptlrpc_request_pool *pool, int num_rq) LASSERTF(list_empty(&pool->prp_req_list) || size == pool->prp_rq_size, - "Trying to change pool size with nonempty pool " - "from %d to %d bytes\n", pool->prp_rq_size, size); + "Trying to change pool size with nonempty pool from %d to %d bytes\n", + pool->prp_rq_size, size); spin_lock(&pool->prp_lock); pool->prp_rq_size = size; @@ -1146,11 +1144,10 @@ static int ptlrpc_check_status(struct ptlrpc_request *req) struct obd_import *imp = req->rq_import; __u32 opc = lustre_msg_get_opc(req->rq_reqmsg); if (ptlrpc_console_allow(req)) - LCONSOLE_ERROR_MSG(0x011, "%s: Communicating with %s," - " operation %s failed with %d.\n", + LCONSOLE_ERROR_MSG(0x011, "%s: Communicating with %s, operation %s failed with %d.\n", imp->imp_obd->obd_name, libcfs_nid2str( - imp->imp_connection->c_peer.nid), + imp->imp_connection->c_peer.nid), ll_opcode2str(opc), err); return err < 0 ? err : -EINVAL; } @@ -1206,8 +1203,7 @@ static int after_reply(struct ptlrpc_request *req) if (req->rq_reply_truncate) { if (ptlrpc_no_resend(req)) { - DEBUG_REQ(D_ERROR, req, "reply buffer overflow," - " expected: %d, actual size: %d", + DEBUG_REQ(D_ERROR, req, "reply buffer overflow, expected: %d, actual size: %d", req->rq_nob_received, req->rq_repbuf_len); return -EOVERFLOW; } @@ -1259,8 +1255,7 @@ static int after_reply(struct ptlrpc_request *req) /* new xid is already allocated for bulk in * ptlrpc_check_set() */ req->rq_xid = ptlrpc_next_xid(); - DEBUG_REQ(D_RPCTRACE, req, "Allocating new xid for " - "resend on EINPROGRESS"); + DEBUG_REQ(D_RPCTRACE, req, "Allocating new xid for resend on EINPROGRESS"); } /* Readjust the timeout for current conditions */ @@ -1412,8 +1407,8 @@ static int ptlrpc_send_new_req(struct ptlrpc_request *req) req->rq_waiting = 1; spin_unlock(&req->rq_lock); - DEBUG_REQ(D_HA, req, "req from PID %d waiting for recovery: " - "(%s != %s)", lustre_msg_get_status(req->rq_reqmsg), + DEBUG_REQ(D_HA, req, "req from PID %d waiting for recovery: (%s != %s)", + lustre_msg_get_status(req->rq_reqmsg), ptlrpc_import_state_name(req->rq_send_state), ptlrpc_import_state_name(imp->imp_state)); LASSERT(list_empty(&req->rq_list)); @@ -1450,8 +1445,8 @@ static int ptlrpc_send_new_req(struct ptlrpc_request *req) } } - CDEBUG(D_RPCTRACE, "Sending RPC pname:cluuid:pid:xid:nid:opc" - " %s:%s:%d:%llu:%s:%d\n", current_comm(), + CDEBUG(D_RPCTRACE, "Sending RPC pname:cluuid:pid:xid:nid:opc %s:%s:%d:%llu:%s:%d\n", + current_comm(), imp->imp_obd->obd_uuid.uuid, lustre_msg_get_status(req->rq_reqmsg), req->rq_xid, libcfs_nid2str(imp->imp_connection->c_peer.nid), @@ -1828,12 +1823,11 @@ interpret: ptlrpc_rqphase_move(req, RQ_PHASE_COMPLETE); CDEBUG(req->rq_reqmsg != NULL ? D_RPCTRACE : 0, - "Completed RPC pname:cluuid:pid:xid:nid:" - "opc %s:%s:%d:%llu:%s:%d\n", - current_comm(), imp->imp_obd->obd_uuid.uuid, - lustre_msg_get_status(req->rq_reqmsg), req->rq_xid, - libcfs_nid2str(imp->imp_connection->c_peer.nid), - lustre_msg_get_opc(req->rq_reqmsg)); + "Completed RPC pname:cluuid:pid:xid:nid:opc %s:%s:%d:%llu:%s:%d\n", + current_comm(), imp->imp_obd->obd_uuid.uuid, + lustre_msg_get_status(req->rq_reqmsg), req->rq_xid, + libcfs_nid2str(imp->imp_connection->c_peer.nid), + lustre_msg_get_opc(req->rq_reqmsg)); spin_lock(&imp->imp_lock); /* Request already may be not on sending or delaying list. This @@ -2215,10 +2209,8 @@ EXPORT_SYMBOL(ptlrpc_set_wait); */ static void __ptlrpc_free_req(struct ptlrpc_request *request, int locked) { - if (request == NULL) { + if (request == NULL) return; - } - LASSERTF(!request->rq_receiving_reply, "req %p\n", request); LASSERTF(request->rq_rqbd == NULL, "req %p\n", request);/* client-side */ LASSERTF(list_empty(&request->rq_list), "req %p\n", request); diff --git a/drivers/staging/lustre/lustre/ptlrpc/events.c b/drivers/staging/lustre/lustre/ptlrpc/events.c index 32dfffa76a5e..7f8644e01112 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/events.c +++ b/drivers/staging/lustre/lustre/ptlrpc/events.c @@ -128,8 +128,8 @@ void reply_in_callback(lnet_event_t *ev) ((lustre_msghdr_get_flags(req->rq_reqmsg) & MSGHDR_AT_SUPPORT))) { /* Early reply */ DEBUG_REQ(D_ADAPTTO, req, - "Early reply received: mlen=%u offset=%d replen=%d " - "replied=%d unlinked=%d", ev->mlength, ev->offset, + "Early reply received: mlen=%u offset=%d replen=%d replied=%d unlinked=%d", + ev->mlength, ev->offset, req->rq_replen, req->rq_replied, ev->unlinked); req->rq_early_count++; /* number received, client side */ @@ -313,8 +313,7 @@ void request_in_callback(lnet_event_t *ev) } req = ptlrpc_request_cache_alloc(GFP_ATOMIC); if (req == NULL) { - CERROR("Can't allocate incoming request descriptor: " - "Dropping %s RPC from %s\n", + CERROR("Can't allocate incoming request descriptor: Dropping %s RPC from %s\n", service->srv_name, libcfs_id2str(ev->initiator)); return; diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c b/drivers/staging/lustre/lustre/ptlrpc/import.c index 2e7e7171ca63..4ceb90db02a3 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/import.c +++ b/drivers/staging/lustre/lustre/ptlrpc/import.c @@ -157,18 +157,14 @@ int ptlrpc_set_import_discon(struct obd_import *imp, __u32 conn_cnt) &target_start, &target_len); if (imp->imp_replayable) { - LCONSOLE_WARN("%s: Connection to %.*s (at %s) was " - "lost; in progress operations using this " - "service will wait for recovery to complete\n", - imp->imp_obd->obd_name, target_len, target_start, - libcfs_nid2str(imp->imp_connection->c_peer.nid)); + LCONSOLE_WARN("%s: Connection to %.*s (at %s) was lost; in progress operations using this service will wait for recovery to complete\n", + imp->imp_obd->obd_name, target_len, target_start, + libcfs_nid2str(imp->imp_connection->c_peer.nid)); } else { - LCONSOLE_ERROR_MSG(0x166, "%s: Connection to " - "%.*s (at %s) was lost; in progress " - "operations using this service will fail\n", - imp->imp_obd->obd_name, - target_len, target_start, - libcfs_nid2str(imp->imp_connection->c_peer.nid)); + LCONSOLE_ERROR_MSG(0x166, "%s: Connection to %.*s (at %s) was lost; in progress operations using this service will fail\n", + imp->imp_obd->obd_name, + target_len, target_start, + libcfs_nid2str(imp->imp_connection->c_peer.nid)); } IMPORT_SET_STATE_NOLOCK(imp, LUSTRE_IMP_DISCON); spin_unlock(&imp->imp_lock); @@ -328,8 +324,8 @@ void ptlrpc_invalidate_import(struct obd_import *imp) * sluggish nets). Let's check this. If there * is no inflight and unregistering != 0, this * is bug. */ - LASSERTF(count == 0, "Some RPCs are still " - "unregistering: %d\n", count); + LASSERTF(count == 0, "Some RPCs are still unregistering: %d\n", + count); /* Let's save one loop as soon as inflight have * dropped to zero. No new inflights possible at @@ -353,12 +349,11 @@ void ptlrpc_invalidate_import(struct obd_import *imp) "still on delayed list"); } - CERROR("%s: RPCs in \"%s\" phase found (%d). " - "Network is sluggish? Waiting them " - "to error out.\n", cli_tgt, + CERROR("%s: RPCs in \"%s\" phase found (%d). Network is sluggish? Waiting them to error out.\n", + cli_tgt, ptlrpc_phase2str(RQ_PHASE_UNREGISTERING), atomic_read(&imp-> - imp_unregistering)); + imp_unregistering)); } spin_unlock(&imp->imp_lock); } @@ -413,8 +408,7 @@ void ptlrpc_fail_import(struct obd_import *imp, __u32 conn_cnt) if (ptlrpc_set_import_discon(imp, conn_cnt)) { if (!imp->imp_replayable) { - CDEBUG(D_HA, "import %s@%s for %s not replayable, " - "auto-deactivating\n", + CDEBUG(D_HA, "import %s@%s for %s not replayable, auto-deactivating\n", obd2cli_tgt(imp->imp_obd), imp->imp_connection->c_remote_uuid.uuid, imp->imp_obd->obd_name); @@ -541,8 +535,8 @@ static int import_select_connection(struct obd_import *imp) at_reset(at, CONNECTION_SWITCH_MAX); } LASSERT(imp_conn->oic_last_attempt); - CDEBUG(D_HA, "%s: tried all connections, increasing latency " - "to %ds\n", imp->imp_obd->obd_name, at_get(at)); + CDEBUG(D_HA, "%s: tried all connections, increasing latency to %ds\n", + imp->imp_obd->obd_name, at_get(at)); } imp_conn->oic_last_attempt = cfs_time_current_64(); @@ -564,8 +558,7 @@ static int import_select_connection(struct obd_import *imp) deuuidify(obd2cli_tgt(imp->imp_obd), NULL, &target_start, &target_len); - CDEBUG(D_HA, "%s: Connection changing to" - " %.*s (at %s)\n", + CDEBUG(D_HA, "%s: Connection changing to %.*s (at %s)\n", imp->imp_obd->obd_name, target_len, target_start, libcfs_nid2str(imp_conn->oic_conn->c_peer.nid)); @@ -935,14 +928,13 @@ static int ptlrpc_connect_interpret(const struct lu_env *env, lustre_msg_get_handle( request->rq_repmsg)->cookie); } else { - LCONSOLE_WARN("Evicted from %s (at %s) " - "after server handle changed from %#llx to %#llx\n", + LCONSOLE_WARN("Evicted from %s (at %s) after server handle changed from %#llx to %#llx\n", obd2cli_tgt(imp->imp_obd), imp->imp_connection-> \ c_remote_uuid.uuid, imp->imp_remote_handle.cookie, lustre_msg_get_handle( - request->rq_repmsg)->cookie); + request->rq_repmsg)->cookie); } @@ -962,8 +954,8 @@ static int ptlrpc_connect_interpret(const struct lu_env *env, } if (imp->imp_invalid) { - CDEBUG(D_HA, "%s: reconnected but import is invalid; " - "marking evicted\n", imp->imp_obd->obd_name); + CDEBUG(D_HA, "%s: reconnected but import is invalid; marking evicted\n", + imp->imp_obd->obd_name); IMPORT_SET_STATE(imp, LUSTRE_IMP_EVICTED); } else if (MSG_CONNECT_RECOVERING & msg_flags) { CDEBUG(D_HA, "%s: reconnected to %s during replay\n", @@ -985,8 +977,8 @@ static int ptlrpc_connect_interpret(const struct lu_env *env, imp->imp_last_replay_transno = 0; IMPORT_SET_STATE(imp, LUSTRE_IMP_REPLAY); } else { - DEBUG_REQ(D_HA, request, "%s: evicting (reconnect/recover flags" - " not set: %x)", imp->imp_obd->obd_name, msg_flags); + DEBUG_REQ(D_HA, request, "%s: evicting (reconnect/recover flags not set: %x)", + imp->imp_obd->obd_name, msg_flags); imp->imp_remote_handle = *lustre_msg_get_handle(request->rq_repmsg); IMPORT_SET_STATE(imp, LUSTRE_IMP_EVICTED); @@ -994,17 +986,13 @@ static int ptlrpc_connect_interpret(const struct lu_env *env, /* Sanity checks for a reconnected import. */ if (!(imp->imp_replayable) != !(msg_flags & MSG_CONNECT_REPLAYABLE)) { - CERROR("imp_replayable flag does not match server " - "after reconnect. We should LBUG right here.\n"); + CERROR("imp_replayable flag does not match server after reconnect. We should LBUG right here.\n"); } if (lustre_msg_get_last_committed(request->rq_repmsg) > 0 && lustre_msg_get_last_committed(request->rq_repmsg) < aa->pcaa_peer_committed) { - CERROR("%s went back in time (transno %lld" - " was previously committed, server now claims %lld" - ")! See https://bugzilla.lustre.org/show_bug.cgi?" - "id=9646\n", + CERROR("%s went back in time (transno %lld was previously committed, server now claims %lld)! See https://bugzilla.lustre.org/show_bug.cgi?id=9646\n", obd2cli_tgt(imp->imp_obd), aa->pcaa_peer_committed, lustre_msg_get_last_committed(request->rq_repmsg)); } @@ -1013,8 +1001,7 @@ finish: rc = ptlrpc_import_recovery_state_machine(imp); if (rc != 0) { if (rc == -ENOTCONN) { - CDEBUG(D_HA, "evicted/aborted by %s@%s during recovery;" - "invalidating and reconnecting\n", + CDEBUG(D_HA, "evicted/aborted by %s@%s during recovery; invalidating and reconnecting\n", obd2cli_tgt(imp->imp_obd), imp->imp_connection->c_remote_uuid.uuid); ptlrpc_connect_import(imp); @@ -1034,9 +1021,7 @@ finish: if ((imp->imp_connect_flags_orig & OBD_CONNECT_IBITS) && !(ocd->ocd_connect_flags & OBD_CONNECT_IBITS)) { - LCONSOLE_WARN("%s: MDS %s does not support ibits " - "lock, either very old or invalid: " - "requested %llx, replied %llx\n", + LCONSOLE_WARN("%s: MDS %s does not support ibits lock, either very old or invalid: requested %llx, replied %llx\n", imp->imp_obd->obd_name, imp->imp_connection->c_remote_uuid.uuid, imp->imp_connect_flags_orig, @@ -1052,13 +1037,12 @@ finish: LUSTRE_VERSION_OFFSET_WARN)) { /* Sigh, some compilers do not like #ifdef in the middle of macro arguments */ - const char *older = "older. Consider upgrading server " - "or downgrading client"; - const char *newer = "newer than client version. " - "Consider upgrading client"; + const char *older = "older. Consider upgrading server or downgrading client" + ; + const char *newer = "newer than client version. Consider upgrading client" + ; - LCONSOLE_WARN("Server %s version (%d.%d.%d.%d) " - "is much %s (%s)\n", + LCONSOLE_WARN("Server %s version (%d.%d.%d.%d) is much %s (%s)\n", obd2cli_tgt(imp->imp_obd), OBD_OCD_VERSION_MAJOR(ocd->ocd_version), OBD_OCD_VERSION_MINOR(ocd->ocd_version), @@ -1095,10 +1079,7 @@ finish: * the checksum types it doesn't support */ if ((ocd->ocd_cksum_types & cksum_types_supported_client()) == 0) { - LCONSOLE_WARN("The negotiation of the checksum " - "algorithm to use with server %s " - "failed (%x/%x), disabling " - "checksums\n", + LCONSOLE_WARN("The negotiation of the checksum algorithm to use with server %s failed (%x/%x), disabling checksums\n", obd2cli_tgt(imp->imp_obd), ocd->ocd_cksum_types, cksum_types_supported_client()); @@ -1191,17 +1172,13 @@ out: * connection from liblustre clients, so we * should never see this from VFS context */ - LCONSOLE_ERROR_MSG(0x16a, "Server %s version " - "(%d.%d.%d.%d)" - " refused connection from this client " - "with an incompatible version (%s). " - "Client must be recompiled\n", - obd2cli_tgt(imp->imp_obd), - OBD_OCD_VERSION_MAJOR(ocd->ocd_version), - OBD_OCD_VERSION_MINOR(ocd->ocd_version), - OBD_OCD_VERSION_PATCH(ocd->ocd_version), - OBD_OCD_VERSION_FIX(ocd->ocd_version), - LUSTRE_VERSION_STRING); + LCONSOLE_ERROR_MSG(0x16a, "Server %s version (%d.%d.%d.%d) refused connection from this client with an incompatible version (%s). Client must be recompiled\n", + obd2cli_tgt(imp->imp_obd), + OBD_OCD_VERSION_MAJOR(ocd->ocd_version), + OBD_OCD_VERSION_MINOR(ocd->ocd_version), + OBD_OCD_VERSION_PATCH(ocd->ocd_version), + OBD_OCD_VERSION_FIX(ocd->ocd_version), + LUSTRE_VERSION_STRING); ptlrpc_deactivate_import(imp); IMPORT_SET_STATE(imp, LUSTRE_IMP_CLOSED); } @@ -1237,8 +1214,7 @@ static int completed_replay_interpret(const struct lu_env *env, "%s: version recovery fails, reconnecting\n", req->rq_import->imp_obd->obd_name); } else { - CDEBUG(D_HA, "%s: LAST_REPLAY message error: %d, " - "reconnecting\n", + CDEBUG(D_HA, "%s: LAST_REPLAY message error: %d, reconnecting\n", req->rq_import->imp_obd->obd_name, req->rq_status); } @@ -1343,9 +1319,7 @@ int ptlrpc_import_recovery_state_machine(struct obd_import *imp) /* Don't care about MGC eviction */ if (strcmp(imp->imp_obd->obd_type->typ_name, LUSTRE_MGC_NAME) != 0) { - LCONSOLE_ERROR_MSG(0x167, "%s: This client was evicted " - "by %.*s; in progress operations " - "using this service will fail.\n", + LCONSOLE_ERROR_MSG(0x167, "%s: This client was evicted by %.*s; in progress operations using this service will fail.\n", imp->imp_obd->obd_name, target_len, target_start); } @@ -1455,8 +1429,7 @@ int ptlrpc_disconnect_import(struct obd_import *imp, int noclose) break; default: rc = -EINVAL; - CERROR("%s: don't know how to disconnect from %s " - "(connect_op %d): rc = %d\n", + CERROR("%s: don't know how to disconnect from %s (connect_op %d): rc = %d\n", imp->imp_obd->obd_name, obd2cli_tgt(imp->imp_obd), imp->imp_connect_op, rc); return rc; @@ -1607,8 +1580,8 @@ int at_measured(struct adaptive_timeout *at, unsigned int val) at->at_current = max(at->at_current, at_min); if (at->at_current != old) - CDEBUG(D_OTHER, "AT %p change: old=%u new=%u delta=%d " - "(val=%u) hist %u %u %u %u\n", at, + CDEBUG(D_OTHER, "AT %p change: old=%u new=%u delta=%d (val=%u) hist %u %u %u %u\n", + at, old, at->at_current, at->at_current - old, val, at->at_hist[0], at->at_hist[1], at->at_hist[2], at->at_hist[3]); diff --git a/drivers/staging/lustre/lustre/ptlrpc/layout.c b/drivers/staging/lustre/lustre/ptlrpc/layout.c index 5b8337187b59..dc5ceb55d001 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/layout.c +++ b/drivers/staging/lustre/lustre/ptlrpc/layout.c @@ -980,18 +980,7 @@ EXPORT_SYMBOL(RMF_CONN); struct req_msg_field RMF_CONNECT_DATA = DEFINE_MSGF("cdata", RMF_F_NO_SIZE_CHECK /* we allow extra space for interop */, -#if LUSTRE_VERSION_CODE > OBD_OCD_VERSION(2, 7, 50, 0) sizeof(struct obd_connect_data), -#else -/* For interoperability with 1.8 and 2.0 clients/servers. - * The RPC verification code allows larger RPC buffers, but not - * smaller buffers. Until we no longer need to keep compatibility - * with older servers/clients we can only check that the buffer - * size is at least as large as obd_connect_data_v1. That is not - * not in itself harmful, since the chance of just corrupting this - * field is low. See JIRA LU-16 for details. */ - sizeof(struct obd_connect_data_v1), -#endif lustre_swab_connect, NULL); EXPORT_SYMBOL(RMF_CONNECT_DATA); @@ -1897,8 +1886,8 @@ swabber_dumper_helper(struct req_capsule *pill, swabber(value); ptlrpc_buf_set_swabbed(pill->rc_req, inout, offset); if (dump) { - CDEBUG(D_RPCTRACE, "Dump of swabbed field %s " - "follows\n", field->rmf_name); + CDEBUG(D_RPCTRACE, "Dump of swabbed field %s follows\n", + field->rmf_name); field->rmf_dumper(value); } @@ -1914,8 +1903,7 @@ swabber_dumper_helper(struct req_capsule *pill, i < n; i++, p += field->rmf_size) { if (dump) { - CDEBUG(D_RPCTRACE, "Dump of %sarray field %s, " - "element %d follows\n", + CDEBUG(D_RPCTRACE, "Dump of %sarray field %s, element %d follows\n", do_swab ? "unswabbed " : "", field->rmf_name, i); field->rmf_dumper(p); } @@ -1923,8 +1911,8 @@ swabber_dumper_helper(struct req_capsule *pill, continue; swabber(p); if (dump) { - CDEBUG(D_RPCTRACE, "Dump of swabbed array field %s, " - "element %d follows\n", field->rmf_name, i); + CDEBUG(D_RPCTRACE, "Dump of swabbed array field %s, element %d follows\n", + field->rmf_name, i); field->rmf_dumper(value); } } @@ -1983,8 +1971,7 @@ static void *__req_capsule_get(struct req_capsule *pill, */ len = lustre_msg_buflen(msg, offset); if ((len % field->rmf_size) != 0) { - CERROR("%s: array field size mismatch " - "%d modulo %d != 0 (%d)\n", + CERROR("%s: array field size mismatch %d modulo %d != 0 (%d)\n", field->rmf_name, len, field->rmf_size, loc); return NULL; } @@ -1997,8 +1984,7 @@ static void *__req_capsule_get(struct req_capsule *pill, if (value == NULL) { DEBUG_REQ(D_ERROR, pill->rc_req, - "Wrong buffer for field `%s' (%d of %d) " - "in format `%s': %d vs. %d (%s)\n", + "Wrong buffer for field `%s' (%d of %d) in format `%s': %d vs. %d (%s)\n", field->rmf_name, offset, lustre_msg_bufcount(msg), fmt->rf_name, lustre_msg_buflen(msg, offset), len, rcl_names[loc]); @@ -2013,7 +1999,7 @@ static void *__req_capsule_get(struct req_capsule *pill, /** * Dump a request and/or reply */ -void __req_capsule_dump(struct req_capsule *pill, enum req_location loc) +static void __req_capsule_dump(struct req_capsule *pill, enum req_location loc) { const struct req_format *fmt; const struct req_msg_field *field; @@ -2031,8 +2017,8 @@ void __req_capsule_dump(struct req_capsule *pill, enum req_location loc) * have a specific dumper */ len = req_capsule_get_size(pill, field, loc); - CDEBUG(D_RPCTRACE, "Field %s has no dumper function;" - "field size is %d\n", field->rmf_name, len); + CDEBUG(D_RPCTRACE, "Field %s has no dumper function; field size is %d\n", + field->rmf_name, len); } else { /* It's the dumping side-effect that we're interested in */ (void) __req_capsule_get(pill, field, loc, NULL, 1); @@ -2184,8 +2170,7 @@ void req_capsule_set_size(struct req_capsule *pill, (size > 0)) { if ((field->rmf_flags & RMF_F_STRUCT_ARRAY) && (size % field->rmf_size != 0)) { - CERROR("%s: array field size mismatch " - "%d %% %d != 0 (%d)\n", + CERROR("%s: array field size mismatch %d %% %d != 0 (%d)\n", field->rmf_name, size, field->rmf_size, loc); LBUG(); } else if (!(field->rmf_flags & RMF_F_STRUCT_ARRAY) && diff --git a/drivers/staging/lustre/lustre/ptlrpc/llog_client.c b/drivers/staging/lustre/lustre/ptlrpc/llog_client.c index 56f825fbb17c..e9baf5bbee3a 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/llog_client.c +++ b/drivers/staging/lustre/lustre/ptlrpc/llog_client.c @@ -334,8 +334,7 @@ static int llog_client_read_header(const struct lu_env *env, llh_hdr->lrh_type, LLOG_HDR_MAGIC); rc = -EIO; } else if (llh_hdr->lrh_len != LLOG_CHUNK_SIZE) { - CERROR("incorrectly sized log header: %#x " - "(expecting %#x)\n", + CERROR("incorrectly sized log header: %#x (expecting %#x)\n", llh_hdr->lrh_len, LLOG_CHUNK_SIZE); CERROR("you may need to re-run lconf --write_conf.\n"); rc = -EIO; diff --git a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c index 87b9764a4f19..4011e0050fcb 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c +++ b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c @@ -175,7 +175,7 @@ const char *ll_opcode2str(__u32 opcode) return ll_rpc_opcode_table[offset].opname; } -const char* ll_eopcode2str(__u32 opcode) +const char *ll_eopcode2str(__u32 opcode) { LASSERT(ll_eopcode_table[opcode].opcode == opcode); return ll_eopcode_table[opcode].opname; @@ -694,8 +694,7 @@ default_queue: if (queue == PTLRPC_NRS_QUEUE_HP && !nrs_svc_has_hp(svc)) { rc = -ENODEV; goto out; - } - else if (queue == PTLRPC_NRS_QUEUE_BOTH && !nrs_svc_has_hp(svc)) + } else if (queue == PTLRPC_NRS_QUEUE_BOTH && !nrs_svc_has_hp(svc)) queue = PTLRPC_NRS_QUEUE_REG; /** @@ -746,8 +745,7 @@ ptlrpc_lprocfs_svc_req_history_seek(struct ptlrpc_service_part *svcpt, svcpt->scp_service->srv_name, svcpt->scp_cpt, srhi->srhi_seq, srhi->srhi_req->rq_history_seq); LASSERTF(!list_empty(&svcpt->scp_hist_reqs), - "%s:%d: seek offset %llu, request seq %llu, " - "last culled %llu\n", + "%s:%d: seek offset %llu, request seq %llu, last culled %llu\n", svcpt->scp_service->srv_name, svcpt->scp_cpt, seq, srhi->srhi_seq, svcpt->scp_hist_seq_culled); e = &srhi->srhi_req->rq_history_list; @@ -814,8 +812,8 @@ ptlrpc_lprocfs_svc_req_history_start(struct seq_file *s, loff_t *pos) int i; if (sizeof(loff_t) != sizeof(__u64)) { /* can't support */ - CWARN("Failed to read request history because size of loff_t " - "%d can't match size of u64\n", (int)sizeof(loff_t)); + CWARN("Failed to read request history because size of loff_t %d can't match size of u64\n", + (int)sizeof(loff_t)); return NULL; } @@ -1298,14 +1296,12 @@ int lprocfs_wr_import(struct file *file, const char *buffer, if (*endptr) { CERROR("config: wrong instance # %s\n", ptr); } else if (inst != imp->imp_connect_data.ocd_instance) { - CDEBUG(D_INFO, "IR: %s is connecting to an obsoleted " - "target(%u/%u), reconnecting...\n", + CDEBUG(D_INFO, "IR: %s is connecting to an obsoleted target(%u/%u), reconnecting...\n", imp->imp_obd->obd_name, imp->imp_connect_data.ocd_instance, inst); do_reconn = 1; } else { - CDEBUG(D_INFO, "IR: %s has already been connecting to " - "new target(%u)\n", + CDEBUG(D_INFO, "IR: %s has already been connecting to new target(%u)\n", imp->imp_obd->obd_name, inst); } } diff --git a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c index c1e8aa4d5ec4..f715e9a8b996 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c +++ b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c @@ -224,8 +224,8 @@ int ptlrpc_register_bulk(struct ptlrpc_request *req) total_md - desc->bd_md_count); spin_unlock(&desc->bd_lock); - CDEBUG(D_NET, "Setup %u bulk %s buffers: %u pages %u bytes, " - "xid x%#llx-%#llx, portal %u\n", desc->bd_md_count, + CDEBUG(D_NET, "Setup %u bulk %s buffers: %u pages %u bytes, xid x%#llx-%#llx, portal %u\n", + desc->bd_md_count, desc->bd_type == BULK_GET_SOURCE ? "get-source" : "put-sink", desc->bd_iov_count, desc->bd_nob, desc->bd_last_xid, req->rq_xid, desc->bd_portal); @@ -337,8 +337,7 @@ static void ptlrpc_at_set_reply(struct ptlrpc_request *req, int flags) if (req->rq_reqmsg && !(lustre_msghdr_get_flags(req->rq_reqmsg) & MSGHDR_AT_SUPPORT)) { - CDEBUG(D_ADAPTTO, "No early reply support: flags=%#x " - "req_flags=%#x magic=%d:%x/%x len=%d\n", + CDEBUG(D_ADAPTTO, "No early reply support: flags=%#x req_flags=%#x magic=%d:%x/%x len=%d\n", flags, lustre_msg_get_flags(req->rq_reqmsg), lustre_msg_is_v1(req->rq_reqmsg), lustre_msg_get_magic(req->rq_reqmsg), diff --git a/drivers/staging/lustre/lustre/ptlrpc/nrs.c b/drivers/staging/lustre/lustre/ptlrpc/nrs.c index 181301bd2083..d5fd7215c72f 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/nrs.c +++ b/drivers/staging/lustre/lustre/ptlrpc/nrs.c @@ -770,8 +770,8 @@ static int nrs_policy_register(struct ptlrpc_nrs *nrs, tmp = nrs_policy_find_locked(nrs, policy->pol_desc->pd_name); if (tmp != NULL) { - CERROR("NRS policy %s has been registered, can't register it " - "for %s\n", policy->pol_desc->pd_name, + CERROR("NRS policy %s has been registered, can't register it for %s\n", + policy->pol_desc->pd_name, svcpt->scp_service->srv_name); nrs_policy_put_locked(tmp); @@ -882,8 +882,7 @@ static int nrs_register_policies_locked(struct ptlrpc_nrs *nrs) if (nrs_policy_compatible(svc, desc)) { rc = nrs_policy_register(nrs, desc); if (rc != 0) { - CERROR("Failed to register NRS policy %s for " - "partition %d of service %s: %d\n", + CERROR("Failed to register NRS policy %s for partition %d of service %s: %d\n", desc->pd_name, svcpt->scp_cpt, svc->srv_name, rc); /** @@ -1082,8 +1081,7 @@ again: if (rc == -ENOENT) { rc = 0; } else if (rc != 0) { - CERROR("Failed to unregister NRS policy %s for " - "partition %d of service %s: %d\n", + CERROR("Failed to unregister NRS policy %s for partition %d of service %s: %d\n", desc->pd_name, svcpt->scp_cpt, svcpt->scp_service->srv_name, rc); return rc; @@ -1145,18 +1143,15 @@ int ptlrpc_nrs_policy_register(struct ptlrpc_nrs_pol_conf *conf) if ((conf->nc_flags & PTLRPC_NRS_FL_REG_EXTERN) && (conf->nc_flags & (PTLRPC_NRS_FL_FALLBACK | PTLRPC_NRS_FL_REG_START))) { - CERROR("NRS: failing to register policy %s. Please check " - "policy flags; external policies cannot act as fallback " - "policies, or be started immediately upon registration " - "without interaction with lprocfs\n", conf->nc_name); + CERROR("NRS: failing to register policy %s. Please check policy flags; external policies cannot act as fallback policies, or be started immediately upon registration without interaction with lprocfs\n", + conf->nc_name); return -EINVAL; } mutex_lock(&nrs_core.nrs_mutex); if (nrs_policy_find_desc_locked(conf->nc_name) != NULL) { - CERROR("NRS: failing to register policy %s which has already " - "been registered with NRS core!\n", + CERROR("NRS: failing to register policy %s which has already been registered with NRS core!\n", conf->nc_name); rc = -EEXIST; goto fail; @@ -1209,8 +1204,7 @@ again: nrs = nrs_svcpt2nrs(svcpt, hp); rc = nrs_policy_register(nrs, desc); if (rc != 0) { - CERROR("Failed to register NRS policy %s for " - "partition %d of service %s: %d\n", + CERROR("Failed to register NRS policy %s for partition %d of service %s: %d\n", desc->pd_name, svcpt->scp_cpt, svcpt->scp_service->srv_name, rc); @@ -1281,8 +1275,7 @@ int ptlrpc_nrs_policy_unregister(struct ptlrpc_nrs_pol_conf *conf) LASSERT(conf != NULL); if (conf->nc_flags & PTLRPC_NRS_FL_FALLBACK) { - CERROR("Unable to unregister a fallback policy, unless the " - "PTLRPC service is stopping.\n"); + CERROR("Unable to unregister a fallback policy, unless the PTLRPC service is stopping.\n"); return -EPERM; } @@ -1292,8 +1285,7 @@ int ptlrpc_nrs_policy_unregister(struct ptlrpc_nrs_pol_conf *conf) desc = nrs_policy_find_desc_locked(conf->nc_name); if (desc == NULL) { - CERROR("Failing to unregister NRS policy %s which has " - "not been registered with NRS core!\n", + CERROR("Failing to unregister NRS policy %s which has not been registered with NRS core!\n", conf->nc_name); rc = -ENOENT; goto not_exist; @@ -1304,9 +1296,8 @@ int ptlrpc_nrs_policy_unregister(struct ptlrpc_nrs_pol_conf *conf) rc = nrs_policy_unregister_locked(desc); if (rc < 0) { if (rc == -EBUSY) - CERROR("Please first stop policy %s on all service " - "partitions and then retry to unregister the " - "policy.\n", conf->nc_name); + CERROR("Please first stop policy %s on all service partitions and then retry to unregister the policy.\n", + conf->nc_name); goto fail; } diff --git a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c index 50556db15f79..2f45f7657830 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c +++ b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c @@ -412,8 +412,8 @@ void *lustre_msg_buf_v2(struct lustre_msg_v2 *m, int n, int min_size) buflen = m->lm_buflens[n]; if (unlikely(buflen < min_size)) { - CERROR("msg %p buffer[%d] size %d too small " - "(required %d, opc=%d)\n", m, n, buflen, min_size, + CERROR("msg %p buffer[%d] size %d too small (required %d, opc=%d)\n", + m, n, buflen, min_size, n == MSG_PTLRPC_BODY_OFF ? -1 : lustre_msg_get_opc(m)); return NULL; } @@ -749,21 +749,19 @@ char *lustre_msg_string(struct lustre_msg *m, int index, int max_len) slen = strnlen(str, blen); if (slen == blen) { /* not NULL terminated */ - CERROR("can't unpack non-NULL terminated string in " - "msg %p buffer[%d] len %d\n", m, index, blen); + CERROR("can't unpack non-NULL terminated string in msg %p buffer[%d] len %d\n", + m, index, blen); return NULL; } if (max_len == 0) { if (slen != blen - 1) { - CERROR("can't unpack short string in msg %p " - "buffer[%d] len %d: strlen %d\n", + CERROR("can't unpack short string in msg %p buffer[%d] len %d: strlen %d\n", m, index, blen, slen); return NULL; } } else if (slen > max_len) { - CERROR("can't unpack oversized string in msg %p " - "buffer[%d] len %d strlen %d: max %d expected\n", + CERROR("can't unpack oversized string in msg %p buffer[%d] len %d strlen %d: max %d expected\n", m, index, blen, slen, max_len); return NULL; } @@ -1313,43 +1311,17 @@ __u32 lustre_msg_get_cksum(struct lustre_msg *msg) } } -#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0) -/* - * In 1.6 and 1.8 the checksum was computed only on struct ptlrpc_body as - * it was in 1.6 (88 bytes, smaller than the full size in 1.8). It makes - * more sense to compute the checksum on the full ptlrpc_body, regardless - * of what size it is, but in order to keep interoperability with 1.8 we - * can optionally also checksum only the first 88 bytes (caller decides). */ -# define ptlrpc_body_cksum_size_compat18 88 - -__u32 lustre_msg_calc_cksum(struct lustre_msg *msg, int compat18) -#else -# warning "remove checksum compatibility support for b1_8" __u32 lustre_msg_calc_cksum(struct lustre_msg *msg) -#endif { switch (msg->lm_magic) { case LUSTRE_MSG_MAGIC_V2: { struct ptlrpc_body *pb = lustre_msg_ptlrpc_body(msg); -#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0) - __u32 crc; - unsigned int hsize = 4; - __u32 len = compat18 ? ptlrpc_body_cksum_size_compat18 : - lustre_msg_buflen(msg, MSG_PTLRPC_BODY_OFF); - LASSERTF(pb, "invalid msg %p: no ptlrpc body!\n", msg); - cfs_crypto_hash_digest(CFS_HASH_ALG_CRC32, (unsigned char *)pb, - len, NULL, 0, (unsigned char *)&crc, - &hsize); - return crc; -#else -# warning "remove checksum compatibility support for b1_8" __u32 crc; unsigned int hsize = 4; cfs_crypto_hash_digest(CFS_HASH_ALG_CRC32, (unsigned char *)pb, lustre_msg_buflen(msg, MSG_PTLRPC_BODY_OFF), NULL, 0, (unsigned char *)&crc, &hsize); return crc; -#endif } default: CERROR("incorrect message magic: %08x\n", msg->lm_magic); @@ -2284,8 +2256,8 @@ void lustre_swab_quota_body(struct quota_body *b) void dump_ioo(struct obd_ioobj *ioo) { CDEBUG(D_RPCTRACE, - "obd_ioobj: ioo_oid="DOSTID", ioo_max_brw=%#x, " - "ioo_bufct=%d\n", POSTID(&ioo->ioo_oid), ioo->ioo_max_brw, + "obd_ioobj: ioo_oid=" DOSTID ", ioo_max_brw=%#x, ioo_bufct=%d\n", + POSTID(&ioo->ioo_oid), ioo->ioo_max_brw, ioo->ioo_bufcnt); } EXPORT_SYMBOL(dump_ioo); @@ -2356,8 +2328,7 @@ void dump_obdo(struct obdo *oa) CDEBUG(D_RPCTRACE, "obdo: o_handle = %lld\n", oa->o_handle.cookie); if (valid & OBD_MD_FLCOOKIE) - CDEBUG(D_RPCTRACE, "obdo: o_lcookie = " - "(llog_cookie dumping not yet implemented)\n"); + CDEBUG(D_RPCTRACE, "obdo: o_lcookie = (llog_cookie dumping not yet implemented)\n"); } EXPORT_SYMBOL(dump_obdo); @@ -2421,17 +2392,15 @@ void _debug_req(struct ptlrpc_request *req, va_start(args, fmt); libcfs_debug_vmsg2(msgdata, fmt, args, - " req@%p x%llu/t%lld(%lld) o%d->%s@%s:%d/%d" - " lens %d/%d e %d to %d dl "CFS_TIME_T" ref %d " - "fl "REQ_FLAGS_FMT"/%x/%x rc %d/%d\n", + " req@%p x%llu/t%lld(%lld) o%d->%s@%s:%d/%d lens %d/%d e %d to %d dl " CFS_TIME_T " ref %d fl " REQ_FLAGS_FMT "/%x/%x rc %d/%d\n", req, req->rq_xid, req->rq_transno, req_ok ? lustre_msg_get_transno(req->rq_reqmsg) : 0, req_ok ? lustre_msg_get_opc(req->rq_reqmsg) : -1, req->rq_import ? - req->rq_import->imp_obd->obd_name : - req->rq_export ? - req->rq_export->exp_client_uuid.uuid : - "<?>", + req->rq_import->imp_obd->obd_name : + req->rq_export ? + req->rq_export->exp_client_uuid.uuid : + "<?>", libcfs_nid2str(nid), req->rq_request_portal, req->rq_reply_portal, req->rq_reqlen, req->rq_replen, diff --git a/drivers/staging/lustre/lustre/ptlrpc/pinger.c b/drivers/staging/lustre/lustre/ptlrpc/pinger.c index 20341b27a06a..340d98a64137 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/pinger.c +++ b/drivers/staging/lustre/lustre/ptlrpc/pinger.c @@ -206,8 +206,7 @@ static void ptlrpc_pinger_process_import(struct obd_import *imp, spin_unlock(&imp->imp_lock); - CDEBUG(level == LUSTRE_IMP_FULL ? D_INFO : D_HA, "%s->%s: level %s/%u " - "force %u force_next %u deactive %u pingable %u suppress %u\n", + CDEBUG(level == LUSTRE_IMP_FULL ? D_INFO : D_HA, "%s->%s: level %s/%u force %u force_next %u deactive %u pingable %u suppress %u\n", imp->imp_obd->obd_uuid.uuid, obd2cli_tgt(imp->imp_obd), ptlrpc_import_state_name(level), level, force, force_next, imp->imp_deactive, imp->imp_pingable, suppress); @@ -220,8 +219,7 @@ static void ptlrpc_pinger_process_import(struct obd_import *imp, } else if (level != LUSTRE_IMP_FULL || imp->imp_obd->obd_no_recov || imp_is_deactive(imp)) { - CDEBUG(D_HA, "%s->%s: not pinging (in recovery " - "or recovery disabled: %s)\n", + CDEBUG(D_HA, "%s->%s: not pinging (in recovery or recovery disabled: %s)\n", imp->imp_obd->obd_uuid.uuid, obd2cli_tgt(imp->imp_obd), ptlrpc_import_state_name(level)); if (force) { @@ -334,11 +332,7 @@ int ptlrpc_start_pinger(void) thread_is_running(&pinger_thread), &lwi); if (suppress_pings) - CWARN("Pings will be suppressed at the request of the " - "administrator. The configuration shall meet the " - "additional requirements described in the manual. " - "(Search for the \"suppress_pings\" kernel module " - "parameter.)\n"); + CWARN("Pings will be suppressed at the request of the administrator. The configuration shall meet the additional requirements described in the manual. (Search for the \"suppress_pings\" kernel module parameter.)\n"); return 0; } @@ -428,7 +422,7 @@ EXPORT_SYMBOL(ptlrpc_pinger_del_import); * Register a timeout callback to the pinger list, and the callback will * be called when timeout happens. */ -struct timeout_item* ptlrpc_new_timeout(int time, enum timeout_event event, +struct timeout_item *ptlrpc_new_timeout(int time, enum timeout_event event, timeout_cb_t cb, void *data) { struct timeout_item *ti; @@ -448,7 +442,7 @@ struct timeout_item* ptlrpc_new_timeout(int time, enum timeout_event event, } /** - * Register timeout event on the the pinger thread. + * Register timeout event on the pinger thread. * Note: the timeout list is an sorted list with increased timeout value. */ static struct timeout_item* @@ -623,11 +617,7 @@ static int ping_evictor_main(void *arg) if (expire_time > exp->exp_last_request_time) { class_export_get(exp); spin_unlock(&obd->obd_dev_lock); - LCONSOLE_WARN("%s: haven't heard from client %s" - " (at %s) in %ld seconds. I think" - " it's dead, and I am evicting" - " it. exp %p, cur %ld expire %ld" - " last %ld\n", + LCONSOLE_WARN("%s: haven't heard from client %s (at %s) in %ld seconds. I think it's dead, and I am evicting it. exp %p, cur %ld expire %ld last %ld\n", obd->obd_name, obd_uuid2str(&exp->exp_client_uuid), obd_export_nid2str(exp), diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c index 357ea9f8bd57..cbcc541cac43 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c @@ -356,10 +356,9 @@ static int ptlrpcd_check(struct lu_env *env, struct ptlrpcd_ctl *pc) if (atomic_read(&ps->set_new_count)) { rc = ptlrpcd_steal_rqset(set, ps); if (rc > 0) - CDEBUG(D_RPCTRACE, "transfer %d" - " async RPCs [%d->%d]\n", - rc, partner->pc_index, - pc->pc_index); + CDEBUG(D_RPCTRACE, "transfer %d async RPCs [%d->%d]\n", + rc, partner->pc_index, + pc->pc_index); } ptlrpc_reqset_put(ps); } while (rc == 0 && pc->pc_cursor != first); diff --git a/drivers/staging/lustre/lustre/ptlrpc/recover.c b/drivers/staging/lustre/lustre/ptlrpc/recover.c index e1bc77b83ffb..7b1d72947330 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/recover.c +++ b/drivers/staging/lustre/lustre/ptlrpc/recover.c @@ -237,8 +237,7 @@ void ptlrpc_request_handle_notconn(struct ptlrpc_request *failed_req) if (ptlrpc_set_import_discon(imp, lustre_msg_get_conn_cnt(failed_req->rq_reqmsg))) { if (!imp->imp_replayable) { - CDEBUG(D_HA, "import %s@%s for %s not replayable, " - "auto-deactivating\n", + CDEBUG(D_HA, "import %s@%s for %s not replayable, auto-deactivating\n", obd2cli_tgt(imp->imp_obd), imp->imp_connection->c_remote_uuid.uuid, imp->imp_obd->obd_name); @@ -274,8 +273,8 @@ int ptlrpc_set_import_active(struct obd_import *imp, int active) /* When deactivating, mark import invalid, and abort in-flight * requests. */ if (!active) { - LCONSOLE_WARN("setting import %s INACTIVE by administrator " - "request\n", obd2cli_tgt(imp->imp_obd)); + LCONSOLE_WARN("setting import %s INACTIVE by administrator request\n", + obd2cli_tgt(imp->imp_obd)); /* set before invalidate to avoid messages about imp_inval * set without imp_deactive in ptlrpc_import_delay_req */ diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec.c b/drivers/staging/lustre/lustre/ptlrpc/sec.c index 4ce76852e6ee..21e9dc9d5580 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec.c @@ -209,7 +209,7 @@ EXPORT_SYMBOL(sptlrpc_flavor2name_bulk); char *sptlrpc_flavor2name(struct sptlrpc_flavor *sf, char *buf, int bufsize) { - snprintf(buf, bufsize, "%s", sptlrpc_flavor2name_base(sf->sf_rpc)); + strlcpy(buf, sptlrpc_flavor2name_base(sf->sf_rpc), bufsize); /* * currently we don't support customized bulk specification for @@ -220,10 +220,9 @@ char *sptlrpc_flavor2name(struct sptlrpc_flavor *sf, char *buf, int bufsize) bspec[0] = '-'; sptlrpc_flavor2name_bulk(sf, &bspec[1], sizeof(bspec) - 1); - strncat(buf, bspec, bufsize); + strlcat(buf, bspec, bufsize); } - buf[bufsize - 1] = '\0'; return buf; } EXPORT_SYMBOL(sptlrpc_flavor2name); @@ -457,8 +456,8 @@ int sptlrpc_req_ctx_switch(struct ptlrpc_request *req, LASSERT(req->rq_reqlen); LASSERT(req->rq_replen); - CDEBUG(D_SEC, "req %p: switch ctx %p(%u->%s) -> %p(%u->%s), " - "switch sec %p(%s) -> %p(%s)\n", req, + CDEBUG(D_SEC, "req %p: switch ctx %p(%u->%s) -> %p(%u->%s), switch sec %p(%s) -> %p(%s)\n", + req, oldctx, oldctx->cc_vcred.vc_uid, sec2target_str(oldctx->cc_sec), newctx, newctx->cc_vcred.vc_uid, sec2target_str(newctx->cc_sec), oldctx->cc_sec, oldctx->cc_sec->ps_policy->sp_name, @@ -1842,8 +1841,8 @@ int sptlrpc_target_export_check(struct obd_export *exp, req->rq_svc_ctx, &flavor); } else { - CDEBUG(D_SEC, "exp %p (%x|%x|%x): is current flavor, " - "install rvs ctx\n", exp, exp->exp_flvr.sf_rpc, + CDEBUG(D_SEC, "exp %p (%x|%x|%x): is current flavor, install rvs ctx\n", + exp, exp->exp_flvr.sf_rpc, exp->exp_flvr_old[0].sf_rpc, exp->exp_flvr_old[1].sf_rpc); spin_unlock(&exp->exp_lock); @@ -1856,13 +1855,12 @@ int sptlrpc_target_export_check(struct obd_export *exp, if (exp->exp_flvr_expire[0]) { if (exp->exp_flvr_expire[0] >= get_seconds()) { if (flavor_allowed(&exp->exp_flvr_old[0], req)) { - CDEBUG(D_SEC, "exp %p (%x|%x|%x): match the " - "middle one ("CFS_DURATION_T")\n", exp, + CDEBUG(D_SEC, "exp %p (%x|%x|%x): match the middle one (" CFS_DURATION_T ")\n", exp, exp->exp_flvr.sf_rpc, exp->exp_flvr_old[0].sf_rpc, exp->exp_flvr_old[1].sf_rpc, exp->exp_flvr_expire[0] - - get_seconds()); + get_seconds()); spin_unlock(&exp->exp_lock); return 0; } @@ -1881,13 +1879,13 @@ int sptlrpc_target_export_check(struct obd_export *exp, if (exp->exp_flvr_changed == 0 && exp->exp_flvr_expire[1]) { if (exp->exp_flvr_expire[1] >= get_seconds()) { if (flavor_allowed(&exp->exp_flvr_old[1], req)) { - CDEBUG(D_SEC, "exp %p (%x|%x|%x): match the " - "oldest one ("CFS_DURATION_T")\n", exp, + CDEBUG(D_SEC, "exp %p (%x|%x|%x): match the oldest one (" CFS_DURATION_T ")\n", + exp, exp->exp_flvr.sf_rpc, exp->exp_flvr_old[0].sf_rpc, exp->exp_flvr_old[1].sf_rpc, exp->exp_flvr_expire[1] - - get_seconds()); + get_seconds()); spin_unlock(&exp->exp_lock); return 0; } @@ -1907,8 +1905,7 @@ int sptlrpc_target_export_check(struct obd_export *exp, spin_unlock(&exp->exp_lock); - CWARN("exp %p(%s): req %p (%u|%u|%u|%u|%u|%u) with " - "unauthorized flavor %x, expect %x|%x(%+ld)|%x(%+ld)\n", + CWARN("exp %p(%s): req %p (%u|%u|%u|%u|%u|%u) with unauthorized flavor %x, expect %x|%x(%+ld)|%x(%+ld)\n", exp, exp->exp_obd->obd_name, req, req->rq_auth_gss, req->rq_ctx_init, req->rq_ctx_fini, req->rq_auth_usr_root, req->rq_auth_usr_mdt, req->rq_auth_usr_ost, diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c index cc68a1cf24e3..0dabd83fd46f 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c @@ -772,8 +772,7 @@ void sptlrpc_enc_pool_fini(void) if (page_pools.epp_st_access > 0) { CDEBUG(D_SEC, - "max pages %lu, grows %u, grow fails %u, shrinks %u, " - "access %lu, missing %lu, max qlen %u, max wait " + "max pages %lu, grows %u, grow fails %u, shrinks %u, access %lu, missing %lu, max qlen %u, max wait " CFS_TIME_T"/%d\n", page_pools.epp_st_max_pages, page_pools.epp_st_grows, page_pools.epp_st_grow_fails, diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_null.c b/drivers/staging/lustre/lustre/ptlrpc/sec_null.c index 099cec3b669f..4e132435b450 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_null.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_null.c @@ -101,16 +101,7 @@ int null_ctx_verify(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req) if (req->rq_early) { cksums = lustre_msg_get_cksum(req->rq_repdata); -#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0) - if (lustre_msghdr_get_flags(req->rq_reqmsg) & - MSGHDR_CKSUM_INCOMPAT18) - cksumc = lustre_msg_calc_cksum(req->rq_repmsg, 0); - else - cksumc = lustre_msg_calc_cksum(req->rq_repmsg, 1); -#else -# warning "remove checksum compatibility support for b1_8" cksumc = lustre_msg_calc_cksum(req->rq_repmsg); -#endif if (cksumc != cksums) { CDEBUG(D_SEC, "early reply checksum mismatch: %08x != %08x\n", @@ -371,16 +362,7 @@ int null_authorize(struct ptlrpc_request *req) } else { __u32 cksum; -#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0) - if (lustre_msghdr_get_flags(req->rq_reqmsg) & - MSGHDR_CKSUM_INCOMPAT18) - cksum = lustre_msg_calc_cksum(rs->rs_repbuf, 0); - else - cksum = lustre_msg_calc_cksum(rs->rs_repbuf, 1); -#else -# warning "remove checksum compatibility support for b1_8" cksum = lustre_msg_calc_cksum(rs->rs_repbuf); -#endif lustre_msg_set_cksum(rs->rs_repbuf, cksum); req->rq_reply_off = 0; } diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c b/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c index 3d72b810c45c..a79cd53010a4 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c @@ -938,8 +938,8 @@ int plain_svc_wrap_bulk(struct ptlrpc_request *req, rc = plain_generate_bulk_csum(desc, req->rq_flvr.u_bulk.hash.hash_alg, tokenv); if (rc) { - CERROR("bulk read: server failed to compute " - "checksum: %d\n", rc); + CERROR("bulk read: server failed to compute checksum: %d\n", + rc); } else { if (OBD_FAIL_CHECK(OBD_FAIL_OSC_CHECKSUM_RECEIVE)) corrupt_bulk_data(desc); diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c index a8df8a792333..635b12b22cef 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/service.c +++ b/drivers/staging/lustre/lustre/ptlrpc/service.c @@ -580,8 +580,7 @@ ptlrpc_server_nthreads_check(struct ptlrpc_service *svc, svc->srv_nthrs_cpt_init = init; if (nthrs * svc->srv_ncpts > tc->tc_nthrs_max) { - CDEBUG(D_OTHER, "%s: This service may have more threads (%d) " - "than the given soft limit (%d)\n", + CDEBUG(D_OTHER, "%s: This service may have more threads (%d) than the given soft limit (%d)\n", svc->srv_name, nthrs * svc->srv_ncpts, tc->tc_nthrs_max); } @@ -1251,8 +1250,8 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req) /* deadline is when the client expects us to reply, margin is the difference between clients' and servers' expectations */ DEBUG_REQ(D_ADAPTTO, req, - "%ssending early reply (deadline %+lds, margin %+lds) for " - "%d+%d", AT_OFF ? "AT off - not " : "", + "%ssending early reply (deadline %+lds, margin %+lds) for %d+%d", + AT_OFF ? "AT off - not " : "", olddl, olddl - at_get(&svcpt->scp_at_estimate), at_get(&svcpt->scp_at_estimate), at_extra); @@ -1260,17 +1259,15 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req) return 0; if (olddl < 0) { - DEBUG_REQ(D_WARNING, req, "Already past deadline (%+lds), " - "not sending early reply. Consider increasing " - "at_early_margin (%d)?", olddl, at_early_margin); + DEBUG_REQ(D_WARNING, req, "Already past deadline (%+lds), not sending early reply. Consider increasing at_early_margin (%d)?", + olddl, at_early_margin); /* Return an error so we're not re-added to the timed list. */ return -ETIMEDOUT; } if (!(lustre_msghdr_get_flags(req->rq_reqmsg) & MSGHDR_AT_SUPPORT)) { - DEBUG_REQ(D_INFO, req, "Wanted to ask client for more time, " - "but no AT support"); + DEBUG_REQ(D_INFO, req, "Wanted to ask client for more time, but no AT support"); return -ENOSYS; } @@ -1296,8 +1293,7 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req) * we may be past adaptive_max */ if (req->rq_deadline >= req->rq_arrival_time.tv_sec + at_get(&svcpt->scp_at_estimate)) { - DEBUG_REQ(D_WARNING, req, "Couldn't add any time " - "(%ld/%ld), not sending early reply\n", + DEBUG_REQ(D_WARNING, req, "Couldn't add any time (%ld/%ld), not sending early reply\n", olddl, req->rq_arrival_time.tv_sec + at_get(&svcpt->scp_at_estimate) - get_seconds()); @@ -1329,8 +1325,7 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req) LASSERT(atomic_read(&req->rq_refcount)); /** if it is last refcount then early reply isn't needed */ if (atomic_read(&req->rq_refcount) == 1) { - DEBUG_REQ(D_ADAPTTO, reqcopy, "Normal reply already sent out, " - "abort sending early reply\n"); + DEBUG_REQ(D_ADAPTTO, reqcopy, "Normal reply already sent out, abort sending early reply\n"); rc = -EINVAL; goto out; } @@ -1454,16 +1449,14 @@ static int ptlrpc_at_check_timed(struct ptlrpc_service_part *svcpt) spin_unlock(&svcpt->scp_at_lock); - CDEBUG(D_ADAPTTO, "timeout in %+ds, asking for %d secs on %d early " - "replies\n", first, at_extra, counter); + CDEBUG(D_ADAPTTO, "timeout in %+ds, asking for %d secs on %d early replies\n", + first, at_extra, counter); if (first < 0) { /* We're already past request deadlines before we even get a chance to send early replies */ - LCONSOLE_WARN("%s: This server is not able to keep up with " - "request traffic (cpu-bound).\n", + LCONSOLE_WARN("%s: This server is not able to keep up with request traffic (cpu-bound).\n", svcpt->scp_service->srv_name); - CWARN("earlyQ=%d reqQ=%d recA=%d, svcEst=%d, " - "delay="CFS_DURATION_T"(jiff)\n", + CWARN("earlyQ=%d reqQ=%d recA=%d, svcEst=%d, delay=" CFS_DURATION_T "(jiff)\n", counter, svcpt->scp_nreqs_incoming, svcpt->scp_nreqs_active, at_get(&svcpt->scp_at_estimate), delay); @@ -1825,8 +1818,7 @@ ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt, if (rc == 0) { rc = sptlrpc_target_export_check(req->rq_export, req); if (rc) - DEBUG_REQ(D_ERROR, req, "DROPPING req with " - "illegal security flavor,"); + DEBUG_REQ(D_ERROR, req, "DROPPING req with illegal security flavor,"); } if (rc) @@ -1942,18 +1934,17 @@ ptlrpc_server_handle_request(struct ptlrpc_service_part *svcpt, /* Discard requests queued for longer than the deadline. The deadline is increased if we send an early reply. */ if (get_seconds() > request->rq_deadline) { - DEBUG_REQ(D_ERROR, request, "Dropping timed-out request from %s" - ": deadline "CFS_DURATION_T":"CFS_DURATION_T"s ago\n", + DEBUG_REQ(D_ERROR, request, "Dropping timed-out request from %s: deadline " CFS_DURATION_T ":" CFS_DURATION_T "s ago\n", libcfs_id2str(request->rq_peer), cfs_time_sub(request->rq_deadline, - request->rq_arrival_time.tv_sec), + request->rq_arrival_time.tv_sec), cfs_time_sub(get_seconds(), - request->rq_deadline)); + request->rq_deadline)); goto put_conn; } - CDEBUG(D_RPCTRACE, "Handling RPC pname:cluuid+ref:pid:xid:nid:opc " - "%s:%s+%d:%d:x%llu:%s:%d\n", current_comm(), + CDEBUG(D_RPCTRACE, "Handling RPC pname:cluuid+ref:pid:xid:nid:opc %s:%s+%d:%d:x%llu:%s:%d\n", + current_comm(), (request->rq_export ? (char *)request->rq_export->exp_client_uuid.uuid : "0"), (request->rq_export ? @@ -1986,26 +1977,24 @@ put_conn: do_gettimeofday(&work_end); timediff = cfs_timeval_sub(&work_end, &work_start, NULL); - CDEBUG(D_RPCTRACE, "Handled RPC pname:cluuid+ref:pid:xid:nid:opc " - "%s:%s+%d:%d:x%llu:%s:%d Request processed in " - "%ldus (%ldus total) trans %llu rc %d/%d\n", - current_comm(), - (request->rq_export ? - (char *)request->rq_export->exp_client_uuid.uuid : "0"), - (request->rq_export ? - atomic_read(&request->rq_export->exp_refcount) : -99), - lustre_msg_get_status(request->rq_reqmsg), - request->rq_xid, - libcfs_id2str(request->rq_peer), - lustre_msg_get_opc(request->rq_reqmsg), - timediff, - cfs_timeval_sub(&work_end, &request->rq_arrival_time, NULL), - (request->rq_repmsg ? - lustre_msg_get_transno(request->rq_repmsg) : - request->rq_transno), - request->rq_status, - (request->rq_repmsg ? - lustre_msg_get_status(request->rq_repmsg) : -999)); + CDEBUG(D_RPCTRACE, "Handled RPC pname:cluuid+ref:pid:xid:nid:opc %s:%s+%d:%d:x%llu:%s:%d Request processed in %ldus (%ldus total) trans %llu rc %d/%d\n", + current_comm(), + (request->rq_export ? + (char *)request->rq_export->exp_client_uuid.uuid : "0"), + (request->rq_export ? + atomic_read(&request->rq_export->exp_refcount) : -99), + lustre_msg_get_status(request->rq_reqmsg), + request->rq_xid, + libcfs_id2str(request->rq_peer), + lustre_msg_get_opc(request->rq_reqmsg), + timediff, + cfs_timeval_sub(&work_end, &request->rq_arrival_time, NULL), + (request->rq_repmsg ? + lustre_msg_get_transno(request->rq_repmsg) : + request->rq_transno), + request->rq_status, + (request->rq_repmsg ? + lustre_msg_get_status(request->rq_repmsg) : -999)); if (likely(svc->srv_stats != NULL && request->rq_reqmsg != NULL)) { __u32 op = lustre_msg_get_opc(request->rq_reqmsg); int opc = opcode_offset(op); @@ -2557,8 +2546,8 @@ static int ptlrpc_start_hr_threads(void) if (!IS_ERR_VALUE(rc)) continue; - CERROR("Reply handling thread %d:%d Failed on starting: " - "rc = %d\n", i, j, rc); + CERROR("Reply handling thread %d:%d Failed on starting: rc = %d\n", + i, j, rc); ptlrpc_stop_hr_threads(); return rc; } @@ -2920,8 +2909,7 @@ ptlrpc_service_unlink_rqbd(struct ptlrpc_service *svc) rc = l_wait_event(svcpt->scp_waitq, svcpt->scp_nrqbds_posted == 0, &lwi); if (rc == -ETIMEDOUT) { - CWARN("Service %s waiting for " - "request buffers\n", + CWARN("Service %s waiting for request buffers\n", svcpt->scp_service->srv_name); } spin_lock(&svcpt->scp_lock); diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig index 96498b7fc20e..2a054a99d433 100644 --- a/drivers/staging/media/Kconfig +++ b/drivers/staging/media/Kconfig @@ -27,12 +27,18 @@ source "drivers/staging/media/davinci_vpfe/Kconfig" source "drivers/staging/media/dt3155v4l/Kconfig" +source "drivers/staging/media/tlg2300/Kconfig" + source "drivers/staging/media/mn88472/Kconfig" source "drivers/staging/media/mn88473/Kconfig" source "drivers/staging/media/omap4iss/Kconfig" +source "drivers/staging/media/parport/Kconfig" + +source "drivers/staging/media/vino/Kconfig" + # Keep LIRC at the end, as it has sub-menus source "drivers/staging/media/lirc/Kconfig" diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile index 30fb352fc4a9..412b28408398 100644 --- a/drivers/staging/media/Makefile +++ b/drivers/staging/media/Makefile @@ -6,4 +6,7 @@ obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/ obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ obj-$(CONFIG_DVB_MN88472) += mn88472/ obj-$(CONFIG_DVB_MN88473) += mn88473/ +obj-y += parport/ +obj-$(CONFIG_VIDEO_TLG2300) += tlg2300/ +obj-y += vino/ diff --git a/drivers/staging/media/cxd2099/cxd2099.c b/drivers/staging/media/cxd2099/cxd2099.c index 73e7b2c9e4a7..657ea480c6e7 100644 --- a/drivers/staging/media/cxd2099/cxd2099.c +++ b/drivers/staging/media/cxd2099/cxd2099.c @@ -527,7 +527,7 @@ static int slot_reset(struct dvb_ca_en50221 *ca, int slot) u8 val; #endif for (i = 0; i < 100; i++) { - msleep(10); + usleep_range(10000, 11000); #if 0 read_reg(ci, 0x06, &val); dev_info(&ci->i2c->dev, "%d:%02x\n", i, val); diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.h b/drivers/staging/media/davinci_vpfe/dm365_ipipe.h index cf4204603eb8..d81b29e19309 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.h +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.h @@ -120,8 +120,8 @@ struct vpfe_ipipe_device { enum ipipe_input_entity input; unsigned int output; struct v4l2_ctrl_handler ctrls; - void *__iomem base_addr; - void *__iomem isp5_base_addr; + void __iomem *base_addr; + void __iomem *isp5_base_addr; struct ipipe_module_params config; }; diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c index 6461de1a61fd..2a3a56b88de1 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c @@ -24,7 +24,7 @@ #define IPIPE_MODE_CONTINUOUS 0 #define IPIPE_MODE_SINGLE_SHOT 1 -static void ipipe_clock_enable(void *__iomem base_addr) +static void ipipe_clock_enable(void __iomem *base_addr) { /* enable IPIPE MMR for register write access */ regw_ip(base_addr, IPIPE_GCK_MMR_DEFAULT, IPIPE_GCK_MMR); @@ -34,7 +34,7 @@ static void ipipe_clock_enable(void *__iomem base_addr) } static void -rsz_set_common_params(void *__iomem rsz_base, struct resizer_params *params) +rsz_set_common_params(void __iomem *rsz_base, struct resizer_params *params) { struct rsz_common_params *rsz_common = ¶ms->rsz_common; u32 val; @@ -66,7 +66,7 @@ rsz_set_common_params(void *__iomem rsz_base, struct resizer_params *params) } static void -rsz_set_rsz_regs(void *__iomem rsz_base, unsigned int rsz_id, +rsz_set_rsz_regs(void __iomem *rsz_base, unsigned int rsz_id, struct resizer_params *params) { struct resizer_scale_param *rsc_params; @@ -171,7 +171,7 @@ rsz_set_rsz_regs(void *__iomem rsz_base, unsigned int rsz_id, /*set the registers of either RSZ0 or RSZ1 */ static void -ipipe_setup_resizer(void *__iomem rsz_base, struct resizer_params *params) +ipipe_setup_resizer(void __iomem *rsz_base, struct resizer_params *params) { /* enable MMR gate to write to Resizer */ regw_rsz(rsz_base, 1, RSZ_GCK_MMR); @@ -302,8 +302,8 @@ int config_rsz_hw(struct vpfe_resizer_device *resizer, struct resizer_params *config) { struct vpfe_device *vpfe_dev = to_vpfe_device(resizer); - void *__iomem ipipe_base = vpfe_dev->vpfe_ipipe.base_addr; - void *__iomem rsz_base = vpfe_dev->vpfe_resizer.base_addr; + void __iomem *ipipe_base = vpfe_dev->vpfe_ipipe.base_addr; + void __iomem *rsz_base = vpfe_dev->vpfe_resizer.base_addr; /* enable VPSS clock */ vpss_enable_clock(VPSS_IPIPE_CLOCK, 1); @@ -315,7 +315,7 @@ int config_rsz_hw(struct vpfe_resizer_device *resizer, } static void -rsz_set_y_address(void *__iomem rsz_base, unsigned int address, +rsz_set_y_address(void __iomem *rsz_base, unsigned int address, unsigned int offset) { u32 val; @@ -330,7 +330,7 @@ rsz_set_y_address(void *__iomem rsz_base, unsigned int address, } static void -rsz_set_c_address(void *__iomem rsz_base, unsigned int address, +rsz_set_c_address(void __iomem *rsz_base, unsigned int address, unsigned int offset) { u32 val; @@ -352,7 +352,7 @@ rsz_set_c_address(void *__iomem rsz_base, unsigned int address, * @address: the address to set */ int -resizer_set_outaddr(void *__iomem rsz_base, struct resizer_params *params, +resizer_set_outaddr(void __iomem *rsz_base, struct resizer_params *params, int resize_no, unsigned int address) { struct resizer_scale_param *rsc_param; @@ -411,7 +411,7 @@ resizer_set_outaddr(void *__iomem rsz_base, struct resizer_params *params, } void -ipipe_set_lutdpc_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, +ipipe_set_lutdpc_regs(void __iomem *base_addr, void __iomem *isp5_base_addr, struct vpfe_ipipe_lutdpc *dpc) { u32 max_tbl_size = LUT_DPC_MAX_SIZE >> 1; @@ -446,7 +446,7 @@ ipipe_set_lutdpc_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, } static void -set_dpc_thresholds(void *__iomem base_addr, +set_dpc_thresholds(void __iomem *base_addr, struct vpfe_ipipe_otfdpc_2_0_cfg *dpc_thr) { regw_ip(base_addr, dpc_thr->corr_thr.r & OTFDPC_DPC2_THR_MASK, @@ -467,7 +467,7 @@ set_dpc_thresholds(void *__iomem base_addr, DPC_OTF_2D_THR_B); } -void ipipe_set_otfdpc_regs(void *__iomem base_addr, +void ipipe_set_otfdpc_regs(void __iomem *base_addr, struct vpfe_ipipe_otfdpc *otfdpc) { struct vpfe_ipipe_otfdpc_2_0_cfg *dpc_2_0 = &otfdpc->alg_cfg.dpc_2_0; @@ -523,7 +523,7 @@ void ipipe_set_otfdpc_regs(void *__iomem base_addr, /* 2D Noise filter */ void -ipipe_set_d2f_regs(void *__iomem base_addr, unsigned int id, +ipipe_set_d2f_regs(void __iomem *base_addr, unsigned int id, struct vpfe_ipipe_nf *noise_filter) { @@ -571,7 +571,7 @@ ipipe_set_d2f_regs(void *__iomem base_addr, unsigned int id, (((decimal & 0x1f) | ((integer & 0x7) << 5))) /* Green Imbalance Correction */ -void ipipe_set_gic_regs(void *__iomem base_addr, struct vpfe_ipipe_gic *gic) +void ipipe_set_gic_regs(void __iomem *base_addr, struct vpfe_ipipe_gic *gic) { u32 val; @@ -609,7 +609,7 @@ void ipipe_set_gic_regs(void *__iomem base_addr, struct vpfe_ipipe_gic *gic) #define IPIPE_U13Q9(decimal, integer) \ (((decimal & 0x1ff) | ((integer & 0xf) << 9))) /* White balance */ -void ipipe_set_wb_regs(void *__iomem base_addr, struct vpfe_ipipe_wb *wb) +void ipipe_set_wb_regs(void __iomem *base_addr, struct vpfe_ipipe_wb *wb) { u32 val; @@ -635,7 +635,7 @@ void ipipe_set_wb_regs(void *__iomem base_addr, struct vpfe_ipipe_wb *wb) } /* CFA */ -void ipipe_set_cfa_regs(void *__iomem base_addr, struct vpfe_ipipe_cfa *cfa) +void ipipe_set_cfa_regs(void __iomem *base_addr, struct vpfe_ipipe_cfa *cfa) { ipipe_clock_enable(base_addr); @@ -671,7 +671,7 @@ void ipipe_set_cfa_regs(void *__iomem base_addr, struct vpfe_ipipe_cfa *cfa) } void -ipipe_set_rgb2rgb_regs(void *__iomem base_addr, unsigned int id, +ipipe_set_rgb2rgb_regs(void __iomem *base_addr, unsigned int id, struct vpfe_ipipe_rgb2rgb *rgb) { u32 offset_mask = RGB2RGB_1_OFST_MASK; @@ -724,7 +724,7 @@ ipipe_set_rgb2rgb_regs(void *__iomem base_addr, unsigned int id, } static void -ipipe_update_gamma_tbl(void *__iomem isp5_base_addr, +ipipe_update_gamma_tbl(void __iomem *isp5_base_addr, struct vpfe_ipipe_gamma_entry *table, int size, u32 addr) { int count; @@ -738,7 +738,7 @@ ipipe_update_gamma_tbl(void *__iomem isp5_base_addr, } void -ipipe_set_gamma_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, +ipipe_set_gamma_regs(void __iomem *base_addr, void __iomem *isp5_base_addr, struct vpfe_ipipe_gamma *gamma) { int table_size; @@ -770,7 +770,7 @@ ipipe_set_gamma_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, } void -ipipe_set_3d_lut_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, +ipipe_set_3d_lut_regs(void __iomem *base_addr, void __iomem *isp5_base_addr, struct vpfe_ipipe_3d_lut *lut_3d) { struct vpfe_ipipe_3d_lut_entry *tbl; @@ -819,7 +819,7 @@ ipipe_set_3d_lut_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, /* Lumina adjustments */ void -ipipe_set_lum_adj_regs(void *__iomem base_addr, struct ipipe_lum_adj *lum_adj) +ipipe_set_lum_adj_regs(void __iomem *base_addr, struct ipipe_lum_adj *lum_adj) { u32 val; @@ -834,7 +834,7 @@ ipipe_set_lum_adj_regs(void *__iomem base_addr, struct ipipe_lum_adj *lum_adj) #define IPIPE_S12Q8(decimal, integer) \ (((decimal & 0xff) | ((integer & 0xf) << 8))) -void ipipe_set_rgb2ycbcr_regs(void *__iomem base_addr, +void ipipe_set_rgb2ycbcr_regs(void __iomem *base_addr, struct vpfe_ipipe_rgb2yuv *yuv) { u32 val; @@ -866,7 +866,7 @@ void ipipe_set_rgb2ycbcr_regs(void *__iomem base_addr, /* YUV 422 conversion */ void -ipipe_set_yuv422_conv_regs(void *__iomem base_addr, +ipipe_set_yuv422_conv_regs(void __iomem *base_addr, struct vpfe_ipipe_yuv422_conv *conv) { u32 val; @@ -879,7 +879,7 @@ ipipe_set_yuv422_conv_regs(void *__iomem base_addr, } void -ipipe_set_gbce_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, +ipipe_set_gbce_regs(void __iomem *base_addr, void __iomem *isp5_base_addr, struct vpfe_ipipe_gbce *gbce) { unsigned int count; @@ -906,7 +906,7 @@ ipipe_set_gbce_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, } void -ipipe_set_ee_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, +ipipe_set_ee_regs(void __iomem *base_addr, void __iomem *isp5_base_addr, struct vpfe_ipipe_yee *ee) { unsigned int count; @@ -950,7 +950,7 @@ ipipe_set_ee_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, } /* Chromatic Artifact Correction. CAR */ -static void ipipe_set_mf(void *__iomem base_addr) +static void ipipe_set_mf(void __iomem *base_addr) { /* typ to dynamic switch */ regw_ip(base_addr, VPFE_IPIPE_CAR_DYN_SWITCH, CAR_TYP); @@ -959,7 +959,7 @@ static void ipipe_set_mf(void *__iomem base_addr) } static void -ipipe_set_gain_ctrl(void *__iomem base_addr, struct vpfe_ipipe_car *car) +ipipe_set_gain_ctrl(void __iomem *base_addr, struct vpfe_ipipe_car *car) { regw_ip(base_addr, VPFE_IPIPE_CAR_CHR_GAIN_CTRL, CAR_TYP); regw_ip(base_addr, car->hpf, CAR_HPF_TYP); @@ -975,7 +975,7 @@ ipipe_set_gain_ctrl(void *__iomem base_addr, struct vpfe_ipipe_car *car) CAR_GN2_MIN); } -void ipipe_set_car_regs(void *__iomem base_addr, struct vpfe_ipipe_car *car) +void ipipe_set_car_regs(void __iomem *base_addr, struct vpfe_ipipe_car *car) { u32 val; @@ -1010,7 +1010,7 @@ void ipipe_set_car_regs(void *__iomem base_addr, struct vpfe_ipipe_car *car) } /* Chromatic Gain Suppression */ -void ipipe_set_cgs_regs(void *__iomem base_addr, struct vpfe_ipipe_cgs *cgs) +void ipipe_set_cgs_regs(void __iomem *base_addr, struct vpfe_ipipe_cgs *cgs) { ipipe_clock_enable(base_addr); regw_ip(base_addr, cgs->en, CGS_EN); @@ -1025,12 +1025,12 @@ void ipipe_set_cgs_regs(void *__iomem base_addr, struct vpfe_ipipe_cgs *cgs) regw_ip(base_addr, cgs->h_min, CGS_GN1_H_MIN); } -void rsz_src_enable(void *__iomem rsz_base, int enable) +void rsz_src_enable(void __iomem *rsz_base, int enable) { regw_rsz(rsz_base, enable, RSZ_SRC_EN); } -int rsz_enable(void *__iomem rsz_base, int rsz_id, int enable) +int rsz_enable(void __iomem *rsz_base, int rsz_id, int enable) { if (rsz_id == RSZ_A) { regw_rsz(rsz_base, enable, RSZ_EN_A); diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.h b/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.h index 81176fb9d164..2bf2f7a69173 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.h +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.h @@ -490,29 +490,29 @@ #define RSZ_RGB_TYP_SHIFT 0 #define RSZ_RGB_ALPHA_MASK 0xff -static inline u32 regr_ip(void *__iomem addr, u32 offset) +static inline u32 regr_ip(void __iomem *addr, u32 offset) { return readl(addr + offset); } -static inline void regw_ip(void *__iomem addr, u32 val, u32 offset) +static inline void regw_ip(void __iomem *addr, u32 val, u32 offset) { writel(val, addr + offset); } -static inline u32 w_ip_table(void *__iomem addr, u32 val, u32 offset) +static inline u32 w_ip_table(void __iomem *addr, u32 val, u32 offset) { writel(val, addr + offset); return val; } -static inline u32 regr_rsz(void *__iomem addr, u32 offset) +static inline u32 regr_rsz(void __iomem *addr, u32 offset) { return readl(addr + offset); } -static inline u32 regw_rsz(void *__iomem addr, u32 val, u32 offset) +static inline u32 regw_rsz(void __iomem *addr, u32 val, u32 offset) { writel(val, addr + offset); @@ -520,39 +520,39 @@ static inline u32 regw_rsz(void *__iomem addr, u32 val, u32 offset) } int config_ipipe_hw(struct vpfe_ipipe_device *ipipe); -int resizer_set_outaddr(void *__iomem rsz_base, struct resizer_params *params, +int resizer_set_outaddr(void __iomem *rsz_base, struct resizer_params *params, int resize_no, unsigned int address); -int rsz_enable(void *__iomem rsz_base, int rsz_id, int enable); -void rsz_src_enable(void *__iomem rsz_base, int enable); +int rsz_enable(void __iomem *rsz_base, int rsz_id, int enable); +void rsz_src_enable(void __iomem *rsz_base, int enable); void rsz_set_in_pix_format(unsigned char y_c); int config_rsz_hw(struct vpfe_resizer_device *resizer, struct resizer_params *config); -void ipipe_set_d2f_regs(void *__iomem base_addr, unsigned int id, +void ipipe_set_d2f_regs(void __iomem *base_addr, unsigned int id, struct vpfe_ipipe_nf *noise_filter); -void ipipe_set_rgb2rgb_regs(void *__iomem base_addr, unsigned int id, +void ipipe_set_rgb2rgb_regs(void __iomem *base_addr, unsigned int id, struct vpfe_ipipe_rgb2rgb *rgb); -void ipipe_set_yuv422_conv_regs(void *__iomem base_addr, +void ipipe_set_yuv422_conv_regs(void __iomem *base_addr, struct vpfe_ipipe_yuv422_conv *conv); -void ipipe_set_lum_adj_regs(void *__iomem base_addr, +void ipipe_set_lum_adj_regs(void __iomem *base_addr, struct ipipe_lum_adj *lum_adj); -void ipipe_set_rgb2ycbcr_regs(void *__iomem base_addr, +void ipipe_set_rgb2ycbcr_regs(void __iomem *base_addr, struct vpfe_ipipe_rgb2yuv *yuv); -void ipipe_set_lutdpc_regs(void *__iomem base_addr, - void *__iomem isp5_base_addr, struct vpfe_ipipe_lutdpc *lutdpc); -void ipipe_set_otfdpc_regs(void *__iomem base_addr, +void ipipe_set_lutdpc_regs(void __iomem *base_addr, + void __iomem *isp5_base_addr, struct vpfe_ipipe_lutdpc *lutdpc); +void ipipe_set_otfdpc_regs(void __iomem *base_addr, struct vpfe_ipipe_otfdpc *otfdpc); -void ipipe_set_3d_lut_regs(void *__iomem base_addr, - void *__iomem isp5_base_addr, struct vpfe_ipipe_3d_lut *lut_3d); -void ipipe_set_gamma_regs(void *__iomem base_addr, - void *__iomem isp5_base_addr, struct vpfe_ipipe_gamma *gamma); -void ipipe_set_ee_regs(void *__iomem base_addr, - void *__iomem isp5_base_addr, struct vpfe_ipipe_yee *ee); -void ipipe_set_gbce_regs(void *__iomem base_addr, - void *__iomem isp5_base_addr, struct vpfe_ipipe_gbce *gbce); -void ipipe_set_gic_regs(void *__iomem base_addr, struct vpfe_ipipe_gic *gic); -void ipipe_set_cfa_regs(void *__iomem base_addr, struct vpfe_ipipe_cfa *cfa); -void ipipe_set_car_regs(void *__iomem base_addr, struct vpfe_ipipe_car *car); -void ipipe_set_cgs_regs(void *__iomem base_addr, struct vpfe_ipipe_cgs *cgs); -void ipipe_set_wb_regs(void *__iomem base_addr, struct vpfe_ipipe_wb *wb); +void ipipe_set_3d_lut_regs(void __iomem *base_addr, + void __iomem *isp5_base_addr, struct vpfe_ipipe_3d_lut *lut_3d); +void ipipe_set_gamma_regs(void __iomem *base_addr, + void __iomem *isp5_base_addr, struct vpfe_ipipe_gamma *gamma); +void ipipe_set_ee_regs(void __iomem *base_addr, + void __iomem *isp5_base_addr, struct vpfe_ipipe_yee *ee); +void ipipe_set_gbce_regs(void __iomem *base_addr, + void __iomem *isp5_base_addr, struct vpfe_ipipe_gbce *gbce); +void ipipe_set_gic_regs(void __iomem *base_addr, struct vpfe_ipipe_gic *gic); +void ipipe_set_cfa_regs(void __iomem *base_addr, struct vpfe_ipipe_cfa *cfa); +void ipipe_set_car_regs(void __iomem *base_addr, struct vpfe_ipipe_car *car); +void ipipe_set_cgs_regs(void __iomem *base_addr, struct vpfe_ipipe_cgs *cgs); +void ipipe_set_wb_regs(void __iomem *base_addr, struct vpfe_ipipe_wb *wb); #endif /* _DAVINCI_VPFE_DM365_IPIPE_HW_H */ diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c index a86f16ff5818..87d42e18377d 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c @@ -421,7 +421,7 @@ static int ipipeif_get_config(struct v4l2_subdev *sd, void __user *arg) { struct vpfe_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd); - struct ipipeif_params *config = (struct ipipeif_params *)arg; + struct ipipeif_params *config = arg; struct device *dev = ipipeif->subdev.v4l2_dev->dev; if (!arg) { @@ -462,7 +462,7 @@ ipipeif_get_config(struct v4l2_subdev *sd, void __user *arg) static long ipipeif_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { - struct ipipeif_params *config = (struct ipipeif_params *)arg; + struct ipipeif_params *config = arg; int ret = -ENOIOCTLCMD; switch (cmd) { diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.h b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.h index 608701fc5fed..cea3d61335af 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.h +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.h @@ -134,7 +134,7 @@ struct vpfe_ipipeif_device { unsigned int output; struct vpfe_video_device video_in; struct v4l2_ctrl_handler ctrls; - void *__iomem ipipeif_base_addr; + void __iomem *ipipeif_base_addr; struct ipipeif_params config; int dpcm_predictor; int gain; diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c index fa26f63831b7..0ba0bf2c1cff 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_isif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c @@ -70,17 +70,17 @@ static const u32 isif_srggb_pattern = ISIF_COLPTN_Gb_G << ISIF_CCOLP_CP15_4 | ISIF_COLPTN_B_Mg << ISIF_CCOLP_CP17_6; -static inline u32 isif_read(void *__iomem base_addr, u32 offset) +static inline u32 isif_read(void __iomem *base_addr, u32 offset) { return readl(base_addr + offset); } -static inline void isif_write(void *__iomem base_addr, u32 val, u32 offset) +static inline void isif_write(void __iomem *base_addr, u32 val, u32 offset) { writel(val, base_addr + offset); } -static inline u32 isif_merge(void *__iomem base_addr, u32 mask, u32 val, +static inline u32 isif_merge(void __iomem *base_addr, u32 mask, u32 val, u32 offset) { u32 new_val = (isif_read(base_addr, offset) & ~mask) | (val & mask); @@ -646,7 +646,7 @@ static void isif_config_gain_offset(struct vpfe_isif_device *isif) { struct vpfe_isif_gain_offsets_adj *gain_off_ptr = &isif->isif_cfg.bayer.config_params.gain_offset; - void *__iomem base = isif->isif_cfg.base_addr; + void __iomem *base = isif->isif_cfg.base_addr; u32 val; val = ((gain_off_ptr->gain_sdram_en & 1) << GAIN_SDRAM_EN_SHIFT) | @@ -1602,6 +1602,7 @@ isif_pad_get_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, if (crop->which == V4L2_SUBDEV_FORMAT_TRY) { struct v4l2_rect *rect; + rect = v4l2_subdev_get_try_crop(fh, ISIF_PAD_SINK); memcpy(&crop->rect, rect, sizeof(*rect)); } else { @@ -1991,7 +1992,7 @@ int vpfe_isif_init(struct vpfe_isif_device *isif, struct platform_device *pdev) struct media_entity *me = &sd->entity; static resource_size_t res_len; struct resource *res; - void *__iomem addr; + void __iomem *addr; int status; int i = 0; diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.h b/drivers/staging/media/davinci_vpfe/dm365_isif.h index 473fd2cfe350..89e814e9c0d7 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_isif.h +++ b/drivers/staging/media/davinci_vpfe/dm365_isif.h @@ -159,9 +159,9 @@ struct isif_oper_config { struct isif_params_raw bayer; enum isif_data_pack data_pack; struct isif_gain_values isif_gain_params; - void *__iomem base_addr; - void *__iomem linear_tbl0_addr; - void *__iomem linear_tbl1_addr; + void __iomem *base_addr; + void __iomem *linear_tbl0_addr; + void __iomem *linear_tbl1_addr; }; #define ISIF_PAD_SINK 0 diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c index e0b29c8ca221..75e70e14b724 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c +++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c @@ -149,7 +149,7 @@ configure_resizer_out_params(struct vpfe_resizer_device *resizer, int index, param->rsz_en[index] = DISABLE; return; } - output = (struct vpfe_rsz_output_spec *)output_spec; + output = output_spec; param->rsz_en[index] = ENABLE; if (partial) { param->rsz_rsc_param[index].h_flip = output->h_flip; @@ -633,7 +633,7 @@ resizer_calculate_normal_f_div_param(struct device *dev, int input_width, if (!(val % 2)) { h1 = val; } else { - val = (input_width << 7); + val = input_width << 7; val -= rsz >> 1; val /= rsz << 1; val <<= 1; @@ -1218,12 +1218,12 @@ static long resizer_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) switch (cmd) { case VIDIOC_VPFE_RSZ_S_CONFIG: - user_config = (struct vpfe_rsz_config *)arg; + user_config = arg; ret = resizer_set_configuration(resizer, user_config); break; case VIDIOC_VPFE_RSZ_G_CONFIG: - user_config = (struct vpfe_rsz_config *)arg; + user_config = arg; if (!user_config->config) { dev_err(dev, "error in VIDIOC_VPFE_RSZ_G_CONFIG\n"); return -EINVAL; diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.h b/drivers/staging/media/davinci_vpfe/dm365_resizer.h index 59a79422b914..93b0f44030aa 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_resizer.h +++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.h @@ -228,7 +228,7 @@ struct vpfe_resizer_device { struct dm365_resizer_device resizer_a; struct dm365_resizer_device resizer_b; struct resizer_params config; - void *__iomem base_addr; + void __iomem *base_addr; }; int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz, diff --git a/drivers/staging/media/lirc/lirc_bt829.c b/drivers/staging/media/lirc/lirc_bt829.c index 4c806ba41323..44f565547179 100644 --- a/drivers/staging/media/lirc/lirc_bt829.c +++ b/drivers/staging/media/lirc/lirc_bt829.c @@ -56,11 +56,6 @@ static unsigned char do_get_bits(void); #define DRIVER_NAME "lirc_bt829" static bool debug; -#define dprintk(fmt, args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG DRIVER_NAME ": "fmt, ## args); \ - } while (0) static int atir_minor; static phys_addr_t pci_addr_phys; @@ -101,7 +96,7 @@ static int atir_add_to_buf(void *data, struct lirc_buffer *buf) status = poll_main(); key = (status >> 8) & 0xFF; if (status & 0xFF) { - dprintk("reading key %02X\n", key); + dev_dbg(atir_driver.dev, "reading key %02X\n", key); lirc_buffer_write(buf, &key); return 0; } @@ -110,13 +105,13 @@ static int atir_add_to_buf(void *data, struct lirc_buffer *buf) static int atir_set_use_inc(void *data) { - dprintk("driver is opened\n"); + dev_dbg(atir_driver.dev, "driver is opened\n"); return 0; } static void atir_set_use_dec(void *data) { - dprintk("driver is closed\n"); + dev_dbg(atir_driver.dev, "driver is closed\n"); } int init_module(void) @@ -154,7 +149,8 @@ int init_module(void) rc = atir_minor; goto err_unmap; } - dprintk("driver is registered on minor %d\n", atir_minor); + dev_dbg(atir_driver.dev, "driver is registered on minor %d\n", + atir_minor); return 0; diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c index 232edd5b1742..9ce7d9990e3e 100644 --- a/drivers/staging/media/lirc/lirc_imon.c +++ b/drivers/staging/media/lirc/lirc_imon.c @@ -495,7 +495,7 @@ static int ir_open(void *data) /* prevent races with disconnect */ mutex_lock(&driver_lock); - context = (struct imon_context *)data; + context = data; /* initial IR protocol decode variables */ context->rx.count = 0; @@ -516,7 +516,7 @@ static void ir_close(void *data) { struct imon_context *context; - context = (struct imon_context *)data; + context = data; if (!context) { pr_err("%s: no context for device\n", __func__); return; @@ -572,29 +572,6 @@ static void submit_data(struct imon_context *context) wake_up(&context->driver->rbuf->wait_poll); } -static inline int tv2int(const struct timeval *a, const struct timeval *b) -{ - int usecs = 0; - int sec = 0; - - if (b->tv_usec > a->tv_usec) { - usecs = 1000000; - sec--; - } - - usecs += a->tv_usec - b->tv_usec; - - sec += a->tv_sec - b->tv_sec; - sec *= 1000; - usecs /= 1000; - sec += usecs; - - if (sec < 0) - sec = 1000; - - return sec; -} - /** * Process the incoming packet */ diff --git a/drivers/staging/media/lirc/lirc_sasem.c b/drivers/staging/media/lirc/lirc_sasem.c index 2f0463eb9887..4a268200cbf5 100644 --- a/drivers/staging/media/lirc/lirc_sasem.c +++ b/drivers/staging/media/lirc/lirc_sasem.c @@ -488,7 +488,7 @@ static int ir_open(void *data) /* prevent races with disconnect */ mutex_lock(&disconnect_lock); - context = (struct sasem_context *) data; + context = data; mutex_lock(&context->ctx_lock); @@ -530,7 +530,7 @@ static void ir_close(void *data) { struct sasem_context *context; - context = (struct sasem_context *)data; + context = data; if (!context) { pr_err("%s: no context for device\n", __func__); return; diff --git a/drivers/staging/media/lirc/lirc_sir.c b/drivers/staging/media/lirc/lirc_sir.c index e961b5218215..39f4733fb1ee 100644 --- a/drivers/staging/media/lirc/lirc_sir.c +++ b/drivers/staging/media/lirc/lirc_sir.c @@ -140,12 +140,6 @@ static int rx_buf[RBUF_LEN]; static unsigned int rx_tail, rx_head; static bool debug; -#define dprintk(fmt, args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \ - fmt, ## args); \ - } while (0) /* SECTION: Prototypes */ @@ -322,7 +316,7 @@ static void add_read_queue(int flag, unsigned long val) unsigned int new_rx_tail; int newval; - dprintk("add flag %d with val %lu\n", flag, val); + pr_debug("add flag %d with val %lu\n", flag, val); newval = val & PULSE_MASK; @@ -342,7 +336,7 @@ static void add_read_queue(int flag, unsigned long val) } new_rx_tail = (rx_tail + 1) & (RBUF_LEN - 1); if (new_rx_tail == rx_head) { - dprintk("Buffer overrun.\n"); + pr_debug("Buffer overrun.\n"); return; } rx_buf[rx_tail] = newval; @@ -439,7 +433,8 @@ static void sir_timeout(unsigned long data) outb(UART_FCR_CLEAR_RCVR, io + UART_FCR); /* determine 'virtual' pulse end: */ pulse_end = delta(&last_tv, &last_intr_tv); - dprintk("timeout add %d for %lu usec\n", last_value, pulse_end); + dev_dbg(driver.dev, "timeout add %d for %lu usec\n", + last_value, pulse_end); add_read_queue(last_value, pulse_end); last_value = 0; last_tv = last_intr_tv; @@ -479,14 +474,15 @@ static irqreturn_t sir_interrupt(int irq, void *dev_id) do_gettimeofday(&curr_tv); deltv = delta(&last_tv, &curr_tv); deltintrtv = delta(&last_intr_tv, &curr_tv); - dprintk("t %lu, d %d\n", deltintrtv, (int)data); + dev_dbg(driver.dev, "t %lu, d %d\n", + deltintrtv, (int)data); /* * if nothing came in last X cycles, * it was gap */ if (deltintrtv > TIME_CONST * threshold) { if (last_value) { - dprintk("GAP\n"); + dev_dbg(driver.dev, "GAP\n"); /* simulate signal change */ add_read_queue(last_value, deltv - diff --git a/drivers/staging/media/lirc/lirc_zilog.c b/drivers/staging/media/lirc/lirc_zilog.c index 1e15d2cab727..cc872fb4ca68 100644 --- a/drivers/staging/media/lirc/lirc_zilog.c +++ b/drivers/staging/media/lirc/lirc_zilog.c @@ -152,23 +152,12 @@ struct tx_data_struct { static struct tx_data_struct *tx_data; static struct mutex tx_data_lock; -#define zilog_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, \ - ## args) -#define zilog_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args) -#define zilog_info(s, args...) printk(KERN_INFO KBUILD_MODNAME ": " s, ## args) /* module parameters */ static bool debug; /* debug output */ static bool tx_only; /* only handle the IR Tx function */ static int minor = -1; /* minor number */ -#define dprintk(fmt, args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG KBUILD_MODNAME ": " fmt, \ - ## args); \ - } while (0) - /* struct IR reference counting */ static struct IR *get_ir_device(struct IR *ir, bool ir_devices_lock_held) @@ -333,7 +322,7 @@ static int add_to_buf(struct IR *ir) struct IR_tx *tx; if (lirc_buffer_full(rbuf)) { - dprintk("buffer overflow\n"); + dev_dbg(ir->l.dev, "buffer overflow\n"); return -EOVERFLOW; } @@ -379,16 +368,17 @@ static int add_to_buf(struct IR *ir) */ ret = i2c_master_send(rx->c, sendbuf, 1); if (ret != 1) { - zilog_error("i2c_master_send failed with %d\n", ret); + dev_err(ir->l.dev, "i2c_master_send failed with %d\n", + ret); if (failures >= 3) { mutex_unlock(&ir->ir_lock); - zilog_error("unable to read from the IR chip " + dev_err(ir->l.dev, "unable to read from the IR chip " "after 3 resets, giving up\n"); break; } /* Looks like the chip crashed, reset it */ - zilog_error("polling the IR receiver chip failed, " + dev_err(ir->l.dev, "polling the IR receiver chip failed, " "trying reset\n"); set_current_state(TASK_UNINTERRUPTIBLE); @@ -415,13 +405,14 @@ static int add_to_buf(struct IR *ir) ret = i2c_master_recv(rx->c, keybuf, sizeof(keybuf)); mutex_unlock(&ir->ir_lock); if (ret != sizeof(keybuf)) { - zilog_error("i2c_master_recv failed with %d -- " + dev_err(ir->l.dev, "i2c_master_recv failed with %d -- " "keeping last read buffer\n", ret); } else { rx->b[0] = keybuf[3]; rx->b[1] = keybuf[4]; rx->b[2] = keybuf[5]; - dprintk("key (0x%02x/0x%02x)\n", rx->b[0], rx->b[1]); + dev_dbg(ir->l.dev, "key (0x%02x/0x%02x)\n", + rx->b[0], rx->b[1]); } /* key pressed ? */ @@ -472,7 +463,7 @@ static int lirc_thread(void *arg) struct IR *ir = arg; struct lirc_buffer *rbuf = ir->l.rbuf; - dprintk("poll thread started\n"); + dev_dbg(ir->l.dev, "poll thread started\n"); while (!kthread_should_stop()) { set_current_state(TASK_INTERRUPTIBLE); @@ -500,7 +491,7 @@ static int lirc_thread(void *arg) wake_up_interruptible(&rbuf->wait_poll); } - dprintk("poll thread ended\n"); + dev_dbg(ir->l.dev, "poll thread ended\n"); return 0; } @@ -644,7 +635,7 @@ static int get_key_data(unsigned char *buf, return -EPROTO; corrupt: - zilog_error("firmware is corrupt\n"); + pr_err("firmware is corrupt\n"); return -EFAULT; } @@ -662,10 +653,11 @@ static int send_data_block(struct IR_tx *tx, unsigned char *data_block) buf[0] = (unsigned char)(i + 1); for (j = 0; j < tosend; ++j) buf[1 + j] = data_block[i + j]; - dprintk("%*ph", 5, buf); + dev_dbg(tx->ir->l.dev, "%*ph", 5, buf); ret = i2c_master_send(tx->c, buf, tosend + 1); if (ret != tosend + 1) { - zilog_error("i2c_master_send failed with %d\n", ret); + dev_err(tx->ir->l.dev, "i2c_master_send failed with %d\n", + ret); return ret < 0 ? ret : -EFAULT; } i += tosend; @@ -689,7 +681,7 @@ static int send_boot_data(struct IR_tx *tx) buf[1] = 0x20; ret = i2c_master_send(tx->c, buf, 2); if (ret != 2) { - zilog_error("i2c_master_send failed with %d\n", ret); + dev_err(tx->ir->l.dev, "i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } @@ -706,21 +698,22 @@ static int send_boot_data(struct IR_tx *tx) } if (ret != 1) { - zilog_error("i2c_master_send failed with %d\n", ret); + dev_err(tx->ir->l.dev, "i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } /* Here comes the firmware version... (hopefully) */ ret = i2c_master_recv(tx->c, buf, 4); if (ret != 4) { - zilog_error("i2c_master_recv failed with %d\n", ret); + dev_err(tx->ir->l.dev, "i2c_master_recv failed with %d\n", ret); return 0; } if ((buf[0] != 0x80) && (buf[0] != 0xa0)) { - zilog_error("unexpected IR TX init response: %02x\n", buf[0]); + dev_err(tx->ir->l.dev, "unexpected IR TX init response: %02x\n", + buf[0]); return 0; } - zilog_notify("Zilog/Hauppauge IR blaster firmware version " + dev_notice(tx->ir->l.dev, "Zilog/Hauppauge IR blaster firmware version " "%d.%d.%d loaded\n", buf[1], buf[2], buf[3]); return 0; @@ -736,7 +729,7 @@ static void fw_unload_locked(void) vfree(tx_data); tx_data = NULL; - dprintk("successfully unloaded IR blaster firmware\n"); + pr_debug("successfully unloaded IR blaster firmware\n"); } } @@ -766,17 +759,16 @@ static int fw_load(struct IR_tx *tx) /* Request codeset data file */ ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", tx->ir->l.dev); if (ret != 0) { - zilog_error("firmware haup-ir-blaster.bin not available (%d)\n", + dev_err(tx->ir->l.dev, "firmware haup-ir-blaster.bin not available (%d)\n", ret); ret = ret < 0 ? ret : -EFAULT; goto out; } - dprintk("firmware of size %zu loaded\n", fw_entry->size); + dev_dbg(tx->ir->l.dev, "firmware of size %zu loaded\n", fw_entry->size); /* Parse the file */ tx_data = vmalloc(sizeof(*tx_data)); if (tx_data == NULL) { - zilog_error("out of memory\n"); release_firmware(fw_entry); ret = -ENOMEM; goto out; @@ -786,7 +778,6 @@ static int fw_load(struct IR_tx *tx) /* Copy the data so hotplug doesn't get confused and timeout */ tx_data->datap = vmalloc(fw_entry->size); if (tx_data->datap == NULL) { - zilog_error("out of memory\n"); release_firmware(fw_entry); vfree(tx_data); ret = -ENOMEM; @@ -801,7 +792,7 @@ static int fw_load(struct IR_tx *tx) if (!read_uint8(&data, tx_data->endp, &version)) goto corrupt; if (version != 1) { - zilog_error("unsupported code set file version (%u, expected" + dev_err(tx->ir->l.dev, "unsupported code set file version (%u, expected" "1) -- please upgrade to a newer driver", version); fw_unload_locked(); @@ -818,7 +809,8 @@ static int fw_load(struct IR_tx *tx) &tx_data->num_code_sets)) goto corrupt; - dprintk("%u IR blaster codesets loaded\n", tx_data->num_code_sets); + dev_dbg(tx->ir->l.dev, "%u IR blaster codesets loaded\n", + tx_data->num_code_sets); tx_data->code_sets = vmalloc( tx_data->num_code_sets * sizeof(char *)); @@ -882,7 +874,7 @@ static int fw_load(struct IR_tx *tx) goto out; corrupt: - zilog_error("firmware is corrupt\n"); + dev_err(tx->ir->l.dev, "firmware is corrupt\n"); fw_unload_locked(); ret = -EFAULT; @@ -902,9 +894,9 @@ static ssize_t read(struct file *filep, char __user *outbuf, size_t n, unsigned int m; DECLARE_WAITQUEUE(wait, current); - dprintk("read called\n"); + dev_dbg(ir->l.dev, "read called\n"); if (n % rbuf->chunk_size) { - dprintk("read result = -EINVAL\n"); + dev_dbg(ir->l.dev, "read result = -EINVAL\n"); return -EINVAL; } @@ -948,7 +940,7 @@ static ssize_t read(struct file *filep, char __user *outbuf, size_t n, unsigned char buf[MAX_XFER_SIZE]; if (rbuf->chunk_size > sizeof(buf)) { - zilog_error("chunk_size is too big (%d)!\n", + dev_err(ir->l.dev, "chunk_size is too big (%d)!\n", rbuf->chunk_size); ret = -EINVAL; break; @@ -962,7 +954,7 @@ static ssize_t read(struct file *filep, char __user *outbuf, size_t n, retries++; } if (retries >= 5) { - zilog_error("Buffer read failed!\n"); + dev_err(ir->l.dev, "Buffer read failed!\n"); ret = -EIO; } } @@ -972,7 +964,8 @@ static ssize_t read(struct file *filep, char __user *outbuf, size_t n, put_ir_rx(rx, false); set_current_state(TASK_RUNNING); - dprintk("read result = %d (%s)\n", ret, ret ? "Error" : "OK"); + dev_dbg(ir->l.dev, "read result = %d (%s)\n", + ret, ret ? "Error" : "OK"); return ret ? ret : written; } @@ -988,7 +981,7 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) ret = get_key_data(data_block, code, key); if (ret == -EPROTO) { - zilog_error("failed to get data for code %u, key %u -- check " + dev_err(tx->ir->l.dev, "failed to get data for code %u, key %u -- check " "lircd.conf entries\n", code, key); return ret; } else if (ret != 0) @@ -1004,7 +997,7 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) buf[1] = 0x40; ret = i2c_master_send(tx->c, buf, 2); if (ret != 2) { - zilog_error("i2c_master_send failed with %d\n", ret); + dev_err(tx->ir->l.dev, "i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } @@ -1017,18 +1010,18 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) } if (ret != 1) { - zilog_error("i2c_master_send failed with %d\n", ret); + dev_err(tx->ir->l.dev, "i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } /* Send finished download? */ ret = i2c_master_recv(tx->c, buf, 1); if (ret != 1) { - zilog_error("i2c_master_recv failed with %d\n", ret); + dev_err(tx->ir->l.dev, "i2c_master_recv failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } if (buf[0] != 0xA0) { - zilog_error("unexpected IR TX response #1: %02x\n", + dev_err(tx->ir->l.dev, "unexpected IR TX response #1: %02x\n", buf[0]); return -EFAULT; } @@ -1038,7 +1031,7 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) buf[1] = 0x80; ret = i2c_master_send(tx->c, buf, 2); if (ret != 2) { - zilog_error("i2c_master_send failed with %d\n", ret); + dev_err(tx->ir->l.dev, "i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } @@ -1048,7 +1041,7 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) * going to skip this whole mess and say we're done on the HD PVR */ if (!tx->post_tx_ready_poll) { - dprintk("sent code %u, key %u\n", code, key); + dev_dbg(tx->ir->l.dev, "sent code %u, key %u\n", code, key); return 0; } @@ -1064,11 +1057,11 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) ret = i2c_master_send(tx->c, buf, 1); if (ret == 1) break; - dprintk("NAK expected: i2c_master_send " + dev_dbg(tx->ir->l.dev, "NAK expected: i2c_master_send " "failed with %d (try %d)\n", ret, i+1); } if (ret != 1) { - zilog_error("IR TX chip never got ready: last i2c_master_send " + dev_err(tx->ir->l.dev, "IR TX chip never got ready: last i2c_master_send " "failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } @@ -1076,16 +1069,17 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) /* Seems to be an 'ok' response */ i = i2c_master_recv(tx->c, buf, 1); if (i != 1) { - zilog_error("i2c_master_recv failed with %d\n", ret); + dev_err(tx->ir->l.dev, "i2c_master_recv failed with %d\n", ret); return -EFAULT; } if (buf[0] != 0x80) { - zilog_error("unexpected IR TX response #2: %02x\n", buf[0]); + dev_err(tx->ir->l.dev, "unexpected IR TX response #2: %02x\n", + buf[0]); return -EFAULT; } /* Oh good, it worked */ - dprintk("sent code %u, key %u\n", code, key); + dev_dbg(tx->ir->l.dev, "sent code %u, key %u\n", code, key); return 0; } @@ -1171,11 +1165,11 @@ static ssize_t write(struct file *filep, const char __user *buf, size_t n, */ if (ret != 0) { /* Looks like the chip crashed, reset it */ - zilog_error("sending to the IR transmitter chip " + dev_err(tx->ir->l.dev, "sending to the IR transmitter chip " "failed, trying reset\n"); if (failures >= 3) { - zilog_error("unable to send to the IR chip " + dev_err(tx->ir->l.dev, "unable to send to the IR chip " "after 3 resets, giving up\n"); mutex_unlock(&ir->ir_lock); mutex_unlock(&tx->client_lock); @@ -1210,7 +1204,7 @@ static unsigned int poll(struct file *filep, poll_table *wait) struct lirc_buffer *rbuf = ir->l.rbuf; unsigned int ret; - dprintk("poll called\n"); + dev_dbg(ir->l.dev, "poll called\n"); rx = get_ir_rx(ir); if (rx == NULL) { @@ -1218,7 +1212,7 @@ static unsigned int poll(struct file *filep, poll_table *wait) * Revisit this, if our poll function ever reports writeable * status for Tx */ - dprintk("poll result = POLLERR\n"); + dev_dbg(ir->l.dev, "poll result = POLLERR\n"); return POLLERR; } @@ -1231,7 +1225,8 @@ static unsigned int poll(struct file *filep, poll_table *wait) /* Indicate what ops could happen immediately without blocking */ ret = lirc_buffer_empty(rbuf) ? 0 : (POLLIN|POLLRDNORM); - dprintk("poll result = %s\n", ret ? "POLLIN|POLLRDNORM" : "none"); + dev_dbg(ir->l.dev, "poll result = %s\n", + ret ? "POLLIN|POLLRDNORM" : "none"); return ret; } @@ -1338,7 +1333,7 @@ static int close(struct inode *node, struct file *filep) struct IR *ir = filep->private_data; if (ir == NULL) { - zilog_error("close: no private_data attached to the file!\n"); + dev_err(ir->l.dev, "close: no private_data attached to the file!\n"); return -ENODEV; } @@ -1450,7 +1445,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) int ret; bool tx_probe = false; - dprintk("%s: %s on i2c-%d (%s), client addr=0x%02x\n", + dev_dbg(&client->dev, "%s: %s on i2c-%d (%s), client addr=0x%02x\n", __func__, id->name, adap->nr, adap->name, client->addr); /* @@ -1463,7 +1458,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) else if (tx_only) /* module option */ return -ENXIO; - zilog_info("probing IR %s on %s (i2c-%d)\n", + pr_info("probing IR %s on %s (i2c-%d)\n", tx_probe ? "Tx" : "Rx", adap->name, adap->nr); mutex_lock(&ir_devices_lock); @@ -1545,7 +1540,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) /* Proceed only if the Rx client is also ready or not needed */ if (rx == NULL && !tx_only) { - zilog_info("probe of IR Tx on %s (i2c-%d) done. Waiting" + dev_info(tx->ir->l.dev, "probe of IR Tx on %s (i2c-%d) done. Waiting" " on IR Rx.\n", adap->name, adap->nr); goto out_ok; } @@ -1584,7 +1579,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) "zilog-rx-i2c-%d", adap->nr); if (IS_ERR(rx->task)) { ret = PTR_ERR(rx->task); - zilog_error("%s: could not start IR Rx polling thread" + dev_err(tx->ir->l.dev, "%s: could not start IR Rx polling thread" "\n", __func__); /* Failed kthread, so put back the ir ref */ put_ir_device(ir, true); @@ -1597,7 +1592,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) /* Proceed only if the Tx client is also ready */ if (tx == NULL) { - zilog_info("probe of IR Rx on %s (i2c-%d) done. Waiting" + pr_info("probe of IR Rx on %s (i2c-%d) done. Waiting" " on IR Tx.\n", adap->name, adap->nr); goto out_ok; } @@ -1607,12 +1602,12 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) ir->l.minor = minor; /* module option: user requested minor number */ ir->l.minor = lirc_register_driver(&ir->l); if (ir->l.minor < 0 || ir->l.minor >= MAX_IRCTL_DEVICES) { - zilog_error("%s: \"minor\" must be between 0 and %d (%d)!\n", + dev_err(tx->ir->l.dev, "%s: \"minor\" must be between 0 and %d (%d)!\n", __func__, MAX_IRCTL_DEVICES-1, ir->l.minor); ret = -EBADRQC; goto out_put_xx; } - zilog_info("IR unit on %s (i2c-%d) registered as lirc%d and ready\n", + dev_info(ir->l.dev, "IR unit on %s (i2c-%d) registered as lirc%d and ready\n", adap->name, adap->nr, ir->l.minor); out_ok: @@ -1621,7 +1616,7 @@ out_ok: if (tx != NULL) put_ir_tx(tx, true); put_ir_device(ir, true); - zilog_info("probe of IR %s on %s (i2c-%d) done\n", + dev_info(ir->l.dev, "probe of IR %s on %s (i2c-%d) done\n", tx_probe ? "Tx" : "Rx", adap->name, adap->nr); mutex_unlock(&ir_devices_lock); return 0; @@ -1634,7 +1629,7 @@ out_put_xx: out_put_ir: put_ir_device(ir, true); out_no_ir: - zilog_error("%s: probing IR %s on %s (i2c-%d) failed with %d\n", + dev_err(&client->dev, "%s: probing IR %s on %s (i2c-%d) failed with %d\n", __func__, tx_probe ? "Tx" : "Rx", adap->name, adap->nr, ret); mutex_unlock(&ir_devices_lock); @@ -1645,7 +1640,7 @@ static int __init zilog_init(void) { int ret; - zilog_notify("Zilog/Hauppauge IR driver initializing\n"); + pr_notice("Zilog/Hauppauge IR driver initializing\n"); mutex_init(&tx_data_lock); @@ -1653,9 +1648,9 @@ static int __init zilog_init(void) ret = i2c_add_driver(&driver); if (ret) - zilog_error("initialization failed\n"); + pr_err("initialization failed\n"); else - zilog_notify("initialization complete\n"); + pr_notice("initialization complete\n"); return ret; } @@ -1665,7 +1660,7 @@ static void __exit zilog_exit(void) i2c_del_driver(&driver); /* if loaded */ fw_unload(); - zilog_notify("Zilog/Hauppauge IR driver unloaded\n"); + pr_notice("Zilog/Hauppauge IR driver unloaded\n"); } module_init(zilog_init); diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index 96b14b326e09..cc1dfadd91eb 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -1357,10 +1357,8 @@ static int iss_probe(struct platform_device *pdev) return -EINVAL; iss = devm_kzalloc(&pdev->dev, sizeof(*iss), GFP_KERNEL); - if (!iss) { - dev_err(&pdev->dev, "Could not allocate memory\n"); + if (!iss) return -ENOMEM; - } mutex_init(&iss->iss_mutex); diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c index 7dbf68cd3566..21971c675b8c 100644 --- a/drivers/staging/media/omap4iss/iss_csi2.c +++ b/drivers/staging/media/omap4iss/iss_csi2.c @@ -1231,7 +1231,7 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname) v4l2_subdev_init(sd, &csi2_ops); sd->internal_ops = &csi2_internal_ops; - sprintf(name, "CSI2%s", subname); + snprintf(name, sizeof(name), "CSI2%s", subname); snprintf(sd->name, sizeof(sd->name), "OMAP4 ISS %s", name); sd->grp_id = 1 << 16; /* group ID for iss subdevs */ diff --git a/drivers/media/parport/Kconfig b/drivers/staging/media/parport/Kconfig index 948c981d9f05..15974efdba1d 100644 --- a/drivers/media/parport/Kconfig +++ b/drivers/staging/media/parport/Kconfig @@ -7,18 +7,22 @@ menuconfig MEDIA_PARPORT_SUPPORT if MEDIA_PARPORT_SUPPORT config VIDEO_BWQCAM - tristate "Quickcam BW Video For Linux" + tristate "Quickcam BW Video For Linux (Deprecated)" depends on PARPORT && VIDEO_V4L2 select VIDEOBUF2_VMALLOC help Say Y have if you the black and white version of the QuickCam camera. See the next option for the color version. + This driver is deprecated and will be removed soon. If you have + hardware for this and you want to work on this driver, then contact + the linux-media mailinglist. + To compile this driver as a module, choose M here: the module will be called bw-qcam. config VIDEO_CQCAM - tristate "QuickCam Colour Video For Linux" + tristate "QuickCam Colour Video For Linux (Deprecated)" depends on PARPORT && VIDEO_V4L2 help This is the video4linux driver for the colour version of the @@ -28,18 +32,26 @@ config VIDEO_CQCAM as a module (c-qcam). Read <file:Documentation/video4linux/CQcam.txt> for more information. + This driver is deprecated and will be removed soon. If you have + hardware for this and you want to work on this driver, then contact + the linux-media mailinglist. + config VIDEO_PMS - tristate "Mediavision Pro Movie Studio Video For Linux" + tristate "Mediavision Pro Movie Studio Video For Linux (Deprecated)" depends on ISA && VIDEO_V4L2 help Say Y if you have the ISA Mediavision Pro Movie Studio capture card. + This driver is deprecated and will be removed soon. If you have + hardware for this and you want to work on this driver, then contact + the linux-media mailinglist. + To compile this driver as a module, choose M here: the module will be called pms. config VIDEO_W9966 - tristate "W9966CF Webcam (FlyCam Supra and others) Video For Linux" + tristate "W9966CF Webcam (FlyCam Supra and others) Video For Linux (Deprecated)" depends on PARPORT_1284 && PARPORT && VIDEO_V4L2 help Video4linux driver for Winbond's w9966 based Webcams. @@ -50,4 +62,8 @@ config VIDEO_W9966 Check out <file:Documentation/video4linux/w9966.txt> for more information. + + This driver is deprecated and will be removed soon. If you have + hardware for this and you want to work on this driver, then contact + the linux-media mailinglist. endif diff --git a/drivers/media/parport/Makefile b/drivers/staging/media/parport/Makefile index 4eea06d7af5b..4eea06d7af5b 100644 --- a/drivers/media/parport/Makefile +++ b/drivers/staging/media/parport/Makefile diff --git a/drivers/media/parport/bw-qcam.c b/drivers/staging/media/parport/bw-qcam.c index 67b9da1dc43f..67b9da1dc43f 100644 --- a/drivers/media/parport/bw-qcam.c +++ b/drivers/staging/media/parport/bw-qcam.c diff --git a/drivers/media/parport/c-qcam.c b/drivers/staging/media/parport/c-qcam.c index b9010bd3ed3e..b9010bd3ed3e 100644 --- a/drivers/media/parport/c-qcam.c +++ b/drivers/staging/media/parport/c-qcam.c diff --git a/drivers/media/parport/pms.c b/drivers/staging/media/parport/pms.c index e6b497528cea..e6b497528cea 100644 --- a/drivers/media/parport/pms.c +++ b/drivers/staging/media/parport/pms.c diff --git a/drivers/media/parport/w9966.c b/drivers/staging/media/parport/w9966.c index f7502f3a6a3c..f7502f3a6a3c 100644 --- a/drivers/media/parport/w9966.c +++ b/drivers/staging/media/parport/w9966.c diff --git a/drivers/media/usb/tlg2300/Kconfig b/drivers/staging/media/tlg2300/Kconfig index 645d915267e6..77d8753f6ba4 100644 --- a/drivers/media/usb/tlg2300/Kconfig +++ b/drivers/staging/media/tlg2300/Kconfig @@ -1,6 +1,7 @@ config VIDEO_TLG2300 - tristate "Telegent TLG2300 USB video capture support" + tristate "Telegent TLG2300 USB video capture support (Deprecated)" depends on VIDEO_DEV && I2C && SND && DVB_CORE + depends on MEDIA_USB_SUPPORT select VIDEO_TUNER select VIDEO_TVEEPROM depends on RC_CORE @@ -12,5 +13,9 @@ config VIDEO_TLG2300 This is a video4linux driver for Telegent tlg2300 based TV cards. The driver supports V4L2, DVB-T and radio. + This driver is deprecated and will be removed soon. If you have + hardware for this and you want to work on this driver, then contact + the linux-media mailinglist. + To compile this driver as a module, choose M here: the module will be called poseidon diff --git a/drivers/media/usb/tlg2300/Makefile b/drivers/staging/media/tlg2300/Makefile index 137f8e38cdec..137f8e38cdec 100644 --- a/drivers/media/usb/tlg2300/Makefile +++ b/drivers/staging/media/tlg2300/Makefile diff --git a/drivers/media/usb/tlg2300/pd-alsa.c b/drivers/staging/media/tlg2300/pd-alsa.c index dd8fe100590f..dd8fe100590f 100644 --- a/drivers/media/usb/tlg2300/pd-alsa.c +++ b/drivers/staging/media/tlg2300/pd-alsa.c diff --git a/drivers/media/usb/tlg2300/pd-common.h b/drivers/staging/media/tlg2300/pd-common.h index 9e23ad32d2fe..9e23ad32d2fe 100644 --- a/drivers/media/usb/tlg2300/pd-common.h +++ b/drivers/staging/media/tlg2300/pd-common.h diff --git a/drivers/media/usb/tlg2300/pd-dvb.c b/drivers/staging/media/tlg2300/pd-dvb.c index ca4994a5190c..ca4994a5190c 100644 --- a/drivers/media/usb/tlg2300/pd-dvb.c +++ b/drivers/staging/media/tlg2300/pd-dvb.c diff --git a/drivers/media/usb/tlg2300/pd-main.c b/drivers/staging/media/tlg2300/pd-main.c index b31f4791b8ff..b31f4791b8ff 100644 --- a/drivers/media/usb/tlg2300/pd-main.c +++ b/drivers/staging/media/tlg2300/pd-main.c diff --git a/drivers/media/usb/tlg2300/pd-radio.c b/drivers/staging/media/tlg2300/pd-radio.c index b391194a840c..b391194a840c 100644 --- a/drivers/media/usb/tlg2300/pd-radio.c +++ b/drivers/staging/media/tlg2300/pd-radio.c diff --git a/drivers/media/usb/tlg2300/pd-video.c b/drivers/staging/media/tlg2300/pd-video.c index 8cd7f02fcf9f..8cd7f02fcf9f 100644 --- a/drivers/media/usb/tlg2300/pd-video.c +++ b/drivers/staging/media/tlg2300/pd-video.c diff --git a/drivers/media/usb/tlg2300/vendorcmds.h b/drivers/staging/media/tlg2300/vendorcmds.h index ba6f4ae3b2c2..ba6f4ae3b2c2 100644 --- a/drivers/media/usb/tlg2300/vendorcmds.h +++ b/drivers/staging/media/tlg2300/vendorcmds.h diff --git a/drivers/staging/media/vino/Kconfig b/drivers/staging/media/vino/Kconfig new file mode 100644 index 000000000000..03700dadafd8 --- /dev/null +++ b/drivers/staging/media/vino/Kconfig @@ -0,0 +1,24 @@ +config VIDEO_VINO + tristate "SGI Vino Video For Linux (Deprecated)" + depends on I2C && SGI_IP22 && VIDEO_V4L2 + select VIDEO_SAA7191 if MEDIA_SUBDRV_AUTOSELECT + help + Say Y here to build in support for the Vino video input system found + on SGI Indy machines. + + This driver is deprecated and will be removed soon. If you have + hardware for this and you want to work on this driver, then contact + the linux-media mailinglist. + +config VIDEO_SAA7191 + tristate "Philips SAA7191 video decoder (Deprecated)" + depends on VIDEO_V4L2 && I2C + ---help--- + Support for the Philips SAA7191 video decoder. + + This driver is deprecated and will be removed soon. If you have + hardware for this and you want to work on this driver, then contact + the linux-media mailinglist. + + To compile this driver as a module, choose M here: the + module will be called saa7191. diff --git a/drivers/staging/media/vino/Makefile b/drivers/staging/media/vino/Makefile new file mode 100644 index 000000000000..914c2513687c --- /dev/null +++ b/drivers/staging/media/vino/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_VIDEO_VINO) += indycam.o +obj-$(CONFIG_VIDEO_VINO) += vino.o +obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o diff --git a/drivers/media/platform/indycam.c b/drivers/staging/media/vino/indycam.c index f1d192bbcb4c..f1d192bbcb4c 100644 --- a/drivers/media/platform/indycam.c +++ b/drivers/staging/media/vino/indycam.c diff --git a/drivers/media/platform/indycam.h b/drivers/staging/media/vino/indycam.h index 881f21c474c4..881f21c474c4 100644 --- a/drivers/media/platform/indycam.h +++ b/drivers/staging/media/vino/indycam.h diff --git a/drivers/media/i2c/saa7191.c b/drivers/staging/media/vino/saa7191.c index 8e9699268a63..8e9699268a63 100644 --- a/drivers/media/i2c/saa7191.c +++ b/drivers/staging/media/vino/saa7191.c diff --git a/drivers/media/i2c/saa7191.h b/drivers/staging/media/vino/saa7191.h index 803c74d6066f..803c74d6066f 100644 --- a/drivers/media/i2c/saa7191.h +++ b/drivers/staging/media/vino/saa7191.h diff --git a/drivers/media/platform/vino.c b/drivers/staging/media/vino/vino.c index 2c85357f774d..2c85357f774d 100644 --- a/drivers/media/platform/vino.c +++ b/drivers/staging/media/vino/vino.c diff --git a/drivers/media/platform/vino.h b/drivers/staging/media/vino/vino.h index de2d615ae7c9..de2d615ae7c9 100644 --- a/drivers/media/platform/vino.h +++ b/drivers/staging/media/vino/vino.h diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c index 2f8eaf768bf3..6b8b108c4e6d 100644 --- a/drivers/staging/octeon-usb/octeon-hcd.c +++ b/drivers/staging/octeon-usb/octeon-hcd.c @@ -456,6 +456,16 @@ struct octeon_temp_buffer { u8 data[0]; }; +static inline struct octeon_hcd *cvmx_usb_to_octeon(struct cvmx_usb_state *p) +{ + return container_of(p, struct octeon_hcd, usb); +} + +static inline struct usb_hcd *octeon_to_hcd(struct octeon_hcd *p) +{ + return container_of((void *)p, struct usb_hcd, hcd_priv); +} + /** * octeon_alloc_temp_buffer - allocate a temporary buffer for USB transfer * (if needed) @@ -640,8 +650,7 @@ static inline int __cvmx_usb_get_data_pid(struct cvmx_usb_pipe *pipe) { if (pipe->pid_toggle) return 2; /* Data1 */ - else - return 0; /* Data0 */ + return 0; /* Data0 */ } /** @@ -744,7 +753,7 @@ static int cvmx_usb_initialize(struct cvmx_usb_state *usb, * such that USB is as close as possible to 125Mhz */ { - int divisor = (octeon_get_clock_rate()+125000000-1)/125000000; + int divisor = DIV_ROUND_UP(octeon_get_clock_rate(), 125000000); /* Lower than 4 doesn't seem to work properly */ if (divisor < 4) divisor = 4; @@ -1328,7 +1337,8 @@ static void __cvmx_usb_poll_rx_fifo(struct cvmx_usb_state *usb) /* Loop writing the FIFO data for this packet into memory */ while (bytes > 0) { - *ptr++ = __cvmx_usb_read_csr32(usb, USB_FIFO_ADDRESS(channel, usb->index)); + *ptr++ = __cvmx_usb_read_csr32(usb, + USB_FIFO_ADDRESS(channel, usb->index)); bytes -= 4; } CVMX_SYNCW; @@ -1479,7 +1489,8 @@ static void __cvmx_usb_fill_tx_fifo(struct cvmx_usb_state *usb, int channel) fifo = &usb->nonperiodic; fifo->entry[fifo->head].channel = channel; - fifo->entry[fifo->head].address = __cvmx_usb_read_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8); + fifo->entry[fifo->head].address = __cvmx_usb_read_csr64(usb, + CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8); fifo->entry[fifo->head].size = (usbc_hctsiz.s.xfersize+3)>>2; fifo->head++; if (fifo->head > MAX_CHANNELS) @@ -1501,6 +1512,9 @@ static void __cvmx_usb_start_channel_control(struct cvmx_usb_state *usb, int channel, struct cvmx_usb_pipe *pipe) { + struct octeon_hcd *priv = cvmx_usb_to_octeon(usb); + struct usb_hcd *hcd = octeon_to_hcd(priv); + struct device *dev = hcd->self.controller; struct cvmx_usb_transaction *transaction = list_first_entry(&pipe->transactions, typeof(*transaction), node); @@ -1517,7 +1531,7 @@ static void __cvmx_usb_start_channel_control(struct cvmx_usb_state *usb, switch (transaction->stage) { case CVMX_USB_STAGE_NON_CONTROL: case CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE: - cvmx_dprintf("%s: ERROR - Non control stage\n", __func__); + dev_err(dev, "%s: ERROR - Non control stage\n", __func__); break; case CVMX_USB_STAGE_SETUP: usbc_hctsiz.s.pid = 3; /* Setup */ @@ -1607,8 +1621,8 @@ static void __cvmx_usb_start_channel_control(struct cvmx_usb_state *usb, * Calculate the number of packets to transfer. If the length is zero * we still need to transfer one packet */ - packets_to_transfer = (bytes_to_transfer + pipe->max_packet - 1) / - pipe->max_packet; + packets_to_transfer = DIV_ROUND_UP(bytes_to_transfer, + pipe->max_packet); if (packets_to_transfer == 0) packets_to_transfer = 1; else if ((packets_to_transfer > 1) && @@ -1700,7 +1714,9 @@ static void __cvmx_usb_start_channel(struct cvmx_usb_state *usb, usbc_hcintmsk.s.stallmsk = 1; usbc_hcintmsk.s.xfercomplmsk = 1; } - __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), usbc_hcintmsk.u32); + __cvmx_usb_write_csr32(usb, + CVMX_USBCX_HCINTMSKX(channel, usb->index), + usbc_hcintmsk.u32); /* Enable the channel interrupt to propagate */ usbc_haintmsk.u32 = __cvmx_usb_read_csr32(usb, @@ -1853,8 +1869,7 @@ static void __cvmx_usb_start_channel(struct cvmx_usb_state *usb, * zero we still need to transfer one packet */ packets_to_transfer = - (bytes_to_transfer + pipe->max_packet - 1) / - pipe->max_packet; + DIV_ROUND_UP(bytes_to_transfer, pipe->max_packet); if (packets_to_transfer == 0) packets_to_transfer = 1; else if ((packets_to_transfer > 1) && @@ -2110,16 +2125,6 @@ done: union cvmx_usbcx_gintmsk, sofmsk, need_sof); } -static inline struct octeon_hcd *cvmx_usb_to_octeon(struct cvmx_usb_state *p) -{ - return container_of(p, struct octeon_hcd, usb); -} - -static inline struct usb_hcd *octeon_to_hcd(struct octeon_hcd *p) -{ - return container_of((void *)p, struct usb_hcd, hcd_priv); -} - static void octeon_usb_urb_complete_callback(struct cvmx_usb_state *usb, enum cvmx_usb_complete status, struct cvmx_usb_pipe *pipe, @@ -2583,6 +2588,9 @@ static int cvmx_usb_get_frame_number(struct cvmx_usb_state *usb) */ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel) { + struct octeon_hcd *priv = cvmx_usb_to_octeon(usb); + struct usb_hcd *hcd = octeon_to_hcd(priv); + struct device *dev = hcd->self.controller; union cvmx_usbcx_hcintx usbc_hcint; union cvmx_usbcx_hctsizx usbc_hctsiz; union cvmx_usbcx_hccharx usbc_hcchar; @@ -2640,8 +2648,8 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel) * Channel halt isn't needed. */ } else { - cvmx_dprintf("USB%d: Channel %d interrupt without halt\n", - usb->index, channel); + dev_err(dev, "USB%d: Channel %d interrupt without halt\n", + usb->index, channel); return 0; } } @@ -2881,9 +2889,11 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel) struct usb_ctrlrequest *header = cvmx_phys_to_ptr(transaction->control_header); if (header->wLength) - transaction->stage = CVMX_USB_STAGE_DATA; + transaction->stage = + CVMX_USB_STAGE_DATA; else - transaction->stage = CVMX_USB_STAGE_STATUS; + transaction->stage = + CVMX_USB_STAGE_STATUS; } break; case CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE: @@ -2891,9 +2901,11 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel) struct usb_ctrlrequest *header = cvmx_phys_to_ptr(transaction->control_header); if (header->wLength) - transaction->stage = CVMX_USB_STAGE_DATA; + transaction->stage = + CVMX_USB_STAGE_DATA; else - transaction->stage = CVMX_USB_STAGE_STATUS; + transaction->stage = + CVMX_USB_STAGE_STATUS; } break; case CVMX_USB_STAGE_DATA: @@ -3015,7 +3027,8 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel) * is complete, the pipe sleeps until the next * schedule interval */ - if (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) { + if (pipe->transfer_dir == + CVMX_USB_DIRECTION_OUT) { /* * If no space left or this wasn't a max * size packet then this transfer is diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c index b2b6c3cd2bed..fcbe836aa997 100644 --- a/drivers/staging/octeon/ethernet-rx.c +++ b/drivers/staging/octeon/ethernet-rx.c @@ -61,66 +61,7 @@ #include <asm/octeon/cvmx-gmxx-defs.h> -struct cvm_napi_wrapper { - struct napi_struct napi; -} ____cacheline_aligned_in_smp; - -static struct cvm_napi_wrapper cvm_oct_napi[NR_CPUS] __cacheline_aligned_in_smp; - -struct cvm_oct_core_state { - int baseline_cores; - /* - * The number of additional cores that could be processing - * input packets. - */ - atomic_t available_cores; - cpumask_t cpu_state; -} ____cacheline_aligned_in_smp; - -static struct cvm_oct_core_state core_state __cacheline_aligned_in_smp; - -static int cvm_irq_cpu; - -static void cvm_oct_enable_napi(void *_) -{ - int cpu = smp_processor_id(); - napi_schedule(&cvm_oct_napi[cpu].napi); -} - -static void cvm_oct_enable_one_cpu(void) -{ - int v; - int cpu; - - /* Check to see if more CPUs are available for receive processing... */ - v = atomic_sub_if_positive(1, &core_state.available_cores); - if (v < 0) - return; - - /* ... if a CPU is available, Turn on NAPI polling for that CPU. */ - for_each_online_cpu(cpu) { - if (!cpu_test_and_set(cpu, core_state.cpu_state)) { - v = smp_call_function_single(cpu, cvm_oct_enable_napi, - NULL, 0); - if (v) - panic("Can't enable NAPI."); - break; - } - } -} - -static void cvm_oct_no_more_work(void) -{ - int cpu = smp_processor_id(); - - if (cpu == cvm_irq_cpu) { - enable_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group); - return; - } - - cpu_clear(cpu, core_state.cpu_state); - atomic_add(1, &core_state.available_cores); -} +static struct napi_struct cvm_oct_napi; /** * cvm_oct_do_interrupt - interrupt handler. @@ -132,8 +73,7 @@ static irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id) { /* Disable the IRQ and start napi_poll. */ disable_irq_nosync(OCTEON_IRQ_WORKQ0 + pow_receive_group); - cvm_irq_cpu = smp_processor_id(); - cvm_oct_enable_napi(NULL); + napi_schedule(&cvm_oct_napi); return IRQ_HANDLED; } @@ -186,13 +126,15 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) if (*ptr == 0xd5) { /* - printk_ratelimited("Port %d received 0xd5 preamble\n", work->ipprt); + printk_ratelimited("Port %d received 0xd5 preamble\n", + work->ipprt); */ work->packet_ptr.s.addr += i + 1; work->len -= i + 5; } else if ((*ptr & 0xf) == 0xd) { /* - printk_ratelimited("Port %d received 0x?d preamble\n", work->ipprt); + printk_ratelimited("Port %d received 0x?d preamble\n", + work->ipprt); */ work->packet_ptr.s.addr += i; work->len -= i + 4; @@ -278,28 +220,15 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) cvmx_write_csr(CVMX_POW_WQ_INT, wq_int.u64); break; } - pskb = (struct sk_buff **)(cvm_oct_get_buffer_ptr(work->packet_ptr) - sizeof(void *)); + pskb = (struct sk_buff **)(cvm_oct_get_buffer_ptr(work->packet_ptr) - + sizeof(void *)); prefetch(pskb); if (USE_ASYNC_IOBDMA && rx_count < (budget - 1)) { - cvmx_pow_work_request_async_nocheck(CVMX_SCR_SCRATCH, CVMX_POW_NO_WAIT); + cvmx_pow_work_request_async_nocheck(CVMX_SCR_SCRATCH, + CVMX_POW_NO_WAIT); did_work_request = 1; } - - if (rx_count == 0) { - /* - * First time through, see if there is enough - * work waiting to merit waking another - * CPU. - */ - union cvmx_pow_wq_int_cntx counts; - int backlog; - int cores_in_use = core_state.baseline_cores - atomic_read(&core_state.available_cores); - counts.u64 = cvmx_read_csr(CVMX_POW_WQ_INT_CNTX(pow_receive_group)); - backlog = counts.s.iq_cnt + counts.s.ds_cnt; - if (backlog > budget * cores_in_use && napi != NULL) - cvm_oct_enable_one_cpu(); - } rx_count++; skb_in_hw = USE_SKBUFFS_IN_HW && work->word2.s.bufs == 1; @@ -322,7 +251,8 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) * buffer. */ if (likely(skb_in_hw)) { - skb->data = skb->head + work->packet_ptr.s.addr - cvmx_ptr_to_phys(skb->head); + skb->data = skb->head + work->packet_ptr.s.addr - + cvmx_ptr_to_phys(skb->head); prefetch(skb->data); skb->len = work->len; skb_set_tail_pointer(skb, skb->len); @@ -359,7 +289,8 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) /* No packet buffers to free */ } else { int segments = work->word2.s.bufs; - union cvmx_buf_ptr segment_ptr = work->packet_ptr; + union cvmx_buf_ptr segment_ptr = + work->packet_ptr; int len = work->len; while (segments--) { @@ -375,8 +306,11 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) * one: int segment_size = * segment_ptr.s.size; */ - int segment_size = CVMX_FPA_PACKET_POOL_SIZE - - (segment_ptr.s.addr - (((segment_ptr.s.addr >> 7) - segment_ptr.s.back) << 7)); + int segment_size = + CVMX_FPA_PACKET_POOL_SIZE - + (segment_ptr.s.addr - + (((segment_ptr.s.addr >> 7) - + segment_ptr.s.back) << 7)); /* * Don't copy more than what * is left in the packet. @@ -407,8 +341,10 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) skb->protocol = eth_type_trans(skb, dev); skb->dev = dev; - if (unlikely(work->word2.s.not_IP || work->word2.s.IP_exc || - work->word2.s.L4_error || !work->word2.s.tcp_or_udp)) + if (unlikely(work->word2.s.not_IP || + work->word2.s.IP_exc || + work->word2.s.L4_error || + !work->word2.s.tcp_or_udp)) skb->ip_summed = CHECKSUM_NONE; else skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -416,11 +352,15 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) /* Increment RX stats for virtual ports */ if (work->ipprt >= CVMX_PIP_NUM_INPUT_PORTS) { #ifdef CONFIG_64BIT - atomic64_add(1, (atomic64_t *)&priv->stats.rx_packets); - atomic64_add(skb->len, (atomic64_t *)&priv->stats.rx_bytes); + atomic64_add(1, + (atomic64_t *)&priv->stats.rx_packets); + atomic64_add(skb->len, + (atomic64_t *)&priv->stats.rx_bytes); #else - atomic_add(1, (atomic_t *)&priv->stats.rx_packets); - atomic_add(skb->len, (atomic_t *)&priv->stats.rx_bytes); + atomic_add(1, + (atomic_t *)&priv->stats.rx_packets); + atomic_add(skb->len, + (atomic_t *)&priv->stats.rx_bytes); #endif } netif_receive_skb(skb); @@ -431,9 +371,11 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) dev->name); */ #ifdef CONFIG_64BIT - atomic64_add(1, (atomic64_t *)&priv->stats.rx_dropped); + atomic64_add(1, + (atomic64_t *)&priv->stats.rx_dropped); #else - atomic_add(1, (atomic_t *)&priv->stats.rx_dropped); + atomic_add(1, + (atomic_t *)&priv->stats.rx_dropped); #endif dev_kfree_skb_irq(skb); } @@ -476,7 +418,7 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) if (rx_count < budget && napi != NULL) { /* No more work */ napi_complete(napi); - cvm_oct_no_more_work(); + enable_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group); } return rx_count; } @@ -511,18 +453,10 @@ void cvm_oct_rx_initialize(void) if (NULL == dev_for_napi) panic("No net_devices were allocated."); - if (max_rx_cpus >= 1 && max_rx_cpus < num_online_cpus()) - atomic_set(&core_state.available_cores, max_rx_cpus); - else - atomic_set(&core_state.available_cores, num_online_cpus()); - core_state.baseline_cores = atomic_read(&core_state.available_cores); - - core_state.cpu_state = CPU_MASK_NONE; - for_each_possible_cpu(i) { - netif_napi_add(dev_for_napi, &cvm_oct_napi[i].napi, - cvm_oct_napi_poll, rx_napi_weight); - napi_enable(&cvm_oct_napi[i].napi); - } + netif_napi_add(dev_for_napi, &cvm_oct_napi, cvm_oct_napi_poll, + rx_napi_weight); + napi_enable(&cvm_oct_napi); + /* Register an IRQ handler to receive POW interrupts */ i = request_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group, cvm_oct_do_interrupt, 0, "Ethernet", cvm_oct_device); @@ -543,15 +477,11 @@ void cvm_oct_rx_initialize(void) int_pc.s.pc_thr = 5; cvmx_write_csr(CVMX_POW_WQ_INT_PC, int_pc.u64); - - /* Scheduld NAPI now. This will indirectly enable interrupts. */ - cvm_oct_enable_one_cpu(); + /* Schedule NAPI now. This will indirectly enable the interrupt. */ + napi_schedule(&cvm_oct_napi); } void cvm_oct_rx_shutdown(void) { - int i; - /* Shutdown all of the NAPIs */ - for_each_possible_cpu(i) - netif_napi_del(&cvm_oct_napi[i].napi); + netif_napi_del(&cvm_oct_napi); } diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c index 4e54d8540219..b7a7854d3f7e 100644 --- a/drivers/staging/octeon/ethernet-tx.c +++ b/drivers/staging/octeon/ethernet-tx.c @@ -77,6 +77,7 @@ static DECLARE_TASKLET(cvm_oct_tx_cleanup_tasklet, cvm_oct_tx_do_cleanup, 0); static inline int32_t cvm_oct_adjust_skb_to_free(int32_t skb_to_free, int fau) { int32_t undo; + undo = skb_to_free > 0 ? MAX_SKB_TO_FREE : skb_to_free + MAX_SKB_TO_FREE; if (undo > 0) @@ -89,6 +90,7 @@ static inline int32_t cvm_oct_adjust_skb_to_free(int32_t skb_to_free, int fau) static void cvm_oct_kick_tx_poll_watchdog(void) { union cvmx_ciu_timx ciu_timx; + ciu_timx.u64 = 0; ciu_timx.s.one_shot = 1; ciu_timx.s.len = cvm_oct_tx_poll_interval; @@ -118,9 +120,11 @@ static void cvm_oct_free_tx_skbs(struct net_device *dev) total_freed += skb_to_free; if (skb_to_free > 0) { struct sk_buff *to_free_list = NULL; + spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags); while (skb_to_free > 0) { struct sk_buff *t; + t = __skb_dequeue(&priv->tx_free_list[qos]); t->next = to_free_list; to_free_list = t; @@ -131,6 +135,7 @@ static void cvm_oct_free_tx_skbs(struct net_device *dev) /* Do the actual freeing outside of the lock. */ while (to_free_list) { struct sk_buff *t = to_free_list; + to_free_list = to_free_list->next; dev_kfree_skb_any(t); } @@ -258,6 +263,7 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); if (gmx_prt_cfg.s.duplex == 0) { int add_bytes = 64 - skb->len; + if ((skb_tail_pointer(skb) + add_bytes) <= skb_end_pointer(skb)) memset(__skb_put(skb, add_bytes), 0, @@ -289,6 +295,7 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) CVM_OCT_SKB_CB(skb)[0] = hw_buffer.u64; for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { struct skb_frag_struct *fs = skb_shinfo(skb)->frags + i; + hw_buffer.s.addr = XKPHYS_TO_PHYS( (u64)(page_address(fs->page.p) + fs->page_offset)); @@ -495,6 +502,7 @@ skip_xmit: while (skb_to_free > 0) { struct sk_buff *t = __skb_dequeue(&priv->tx_free_list[qos]); + t->next = to_free_list; to_free_list = t; skb_to_free--; @@ -505,6 +513,7 @@ skip_xmit: /* Do the actual freeing outside of the lock. */ while (to_free_list) { struct sk_buff *t = to_free_list; + to_free_list = to_free_list->next; dev_kfree_skb_any(t); } @@ -550,6 +559,7 @@ int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev) /* Get a work queue entry */ cvmx_wqe_t *work = cvmx_fpa_alloc(CVMX_FPA_WQE_POOL); + if (unlikely(work == NULL)) { printk_ratelimited("%s: Failed to allocate a work queue entry\n", dev->name); @@ -713,6 +723,7 @@ static void cvm_oct_tx_do_cleanup(unsigned long arg) for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) { if (cvm_oct_device[port]) { struct net_device *dev = cvm_oct_device[port]; + cvm_oct_free_tx_skbs(dev); } } diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index af24294d9466..ee321496dcdd 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c @@ -98,12 +98,6 @@ MODULE_PARM_DESC(pow_send_list, "\n" "\t\"eth2,spi3,spi7\" would cause these three devices to transmit\n" "\tusing the pow_send_group."); -int max_rx_cpus = -1; -module_param(max_rx_cpus, int, 0444); -MODULE_PARM_DESC(max_rx_cpus, "\n" - "\t\tThe maximum number of CPUs to use for packet reception.\n" - "\t\tUse -1 to use all available CPUs."); - int rx_napi_weight = 32; module_param(rx_napi_weight, int, 0444); MODULE_PARM_DESC(rx_napi_weight, "The NAPI WEIGHT parameter."); @@ -452,7 +446,7 @@ int cvm_oct_common_init(struct net_device *dev) mac = of_get_mac_address(priv->of_node); if (mac) - memcpy(dev->dev_addr, mac, ETH_ALEN); + ether_addr_copy(dev->dev_addr, mac); else eth_hw_addr_random(dev); diff --git a/drivers/staging/octeon/octeon-ethernet.h b/drivers/staging/octeon/octeon-ethernet.h index d0e321119914..f48dc766fada 100644 --- a/drivers/staging/octeon/octeon-ethernet.h +++ b/drivers/staging/octeon/octeon-ethernet.h @@ -99,7 +99,6 @@ extern struct workqueue_struct *cvm_oct_poll_queue; extern atomic_t cvm_oct_poll_queue_stopping; extern u64 cvm_oct_tx_poll_interval; -extern int max_rx_cpus; extern int rx_napi_weight; #endif diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index eb83b28b8cd1..6a9a8815477c 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -682,8 +682,7 @@ static int dcon_remove(struct i2c_client *client) free_irq(DCON_IRQ, dcon); - if (dcon->bl_dev) - backlight_device_unregister(dcon->bl_dev); + backlight_device_unregister(dcon->bl_dev); if (dcon_device != NULL) platform_device_unregister(dcon_device); diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index 347b8b1ffa29..8543bb29a138 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c @@ -353,8 +353,7 @@ static void oz_complete_urb(struct usb_hcd *hcd, struct urb *urb, } spin_lock(&g_tasklet_lock); spin_unlock_irqrestore(&g_tasklet_lock, irq_state); - if (cancel_urbl) - oz_free_urb_link(cancel_urbl); + oz_free_urb_link(cancel_urbl); } /* @@ -522,8 +521,7 @@ static int oz_dequeue_ep_urb(struct oz_port *port, u8 ep_addr, int in_dir, } } spin_unlock_bh(&port->ozhcd->hcd_lock); - if (urbl) - oz_free_urb_link(urbl); + oz_free_urb_link(urbl); return urbl ? 0 : -EIDRM; } @@ -729,7 +727,7 @@ void oz_hcd_pd_reset(void *hpd, void *hport) { /* Cleanup the current configuration and report reset to the core. */ - struct oz_port *port = (struct oz_port *)hport; + struct oz_port *port = hport; struct oz_hcd *ozhcd = port->ozhcd; oz_dbg(ON, "PD Reset\n"); @@ -748,7 +746,7 @@ void oz_hcd_pd_reset(void *hpd, void *hport) void oz_hcd_get_desc_cnf(void *hport, u8 req_id, int status, const u8 *desc, int length, int offset, int total_size) { - struct oz_port *port = (struct oz_port *)hport; + struct oz_port *port = hport; struct urb *urb; int err = 0; @@ -888,7 +886,7 @@ static void oz_hcd_complete_set_interface(struct oz_port *port, struct urb *urb, void oz_hcd_control_cnf(void *hport, u8 req_id, u8 rcode, const u8 *data, int data_len) { - struct oz_port *port = (struct oz_port *)hport; + struct oz_port *port = hport; struct urb *urb; struct usb_ctrlrequest *setup; struct usb_hcd *hcd = port->ozhcd->hcd; @@ -1035,7 +1033,7 @@ static inline int oz_usb_get_frame_number(void) int oz_hcd_heartbeat(void *hport) { int rc = 0; - struct oz_port *port = (struct oz_port *)hport; + struct oz_port *port = hport; struct oz_hcd *ozhcd = port->ozhcd; struct oz_urb_link *urbl, *n; LIST_HEAD(xfr_list); @@ -1913,7 +1911,7 @@ static void oz_get_hub_descriptor(struct usb_hcd *hcd, memset(desc, 0, sizeof(*desc)); desc->bDescriptorType = 0x29; desc->bDescLength = 9; - desc->wHubCharacteristics = (__force __u16)cpu_to_le16(0x0001); + desc->wHubCharacteristics = cpu_to_le16(0x0001); desc->bNbrPorts = OZ_NB_PORTS; } @@ -2031,11 +2029,11 @@ static int oz_clear_port_feature(struct usb_hcd *hcd, u16 wvalue, u16 windex) break; case USB_PORT_FEAT_C_CONNECTION: oz_dbg(HUB, "USB_PORT_FEAT_C_CONNECTION\n"); - clear_bits = (USB_PORT_STAT_C_CONNECTION << 16); + clear_bits = USB_PORT_STAT_C_CONNECTION << 16; break; case USB_PORT_FEAT_C_ENABLE: oz_dbg(HUB, "USB_PORT_FEAT_C_ENABLE\n"); - clear_bits = (USB_PORT_STAT_C_ENABLE << 16); + clear_bits = USB_PORT_STAT_C_ENABLE << 16; break; case USB_PORT_FEAT_C_SUSPEND: oz_dbg(HUB, "USB_PORT_FEAT_C_SUSPEND\n"); @@ -2045,7 +2043,7 @@ static int oz_clear_port_feature(struct usb_hcd *hcd, u16 wvalue, u16 windex) break; case USB_PORT_FEAT_C_RESET: oz_dbg(HUB, "USB_PORT_FEAT_C_RESET\n"); - clear_bits = (USB_PORT_FEAT_C_RESET << 16); + clear_bits = USB_PORT_FEAT_C_RESET << 16; break; case USB_PORT_FEAT_TEST: oz_dbg(HUB, "USB_PORT_FEAT_TEST\n"); diff --git a/drivers/staging/ozwpan/ozusbsvc1.c b/drivers/staging/ozwpan/ozusbsvc1.c index be7ee01c50ab..d434d8c6fff6 100644 --- a/drivers/staging/ozwpan/ozusbsvc1.c +++ b/drivers/staging/ozwpan/ozusbsvc1.c @@ -56,7 +56,7 @@ static int oz_usb_submit_elt(struct oz_elt_buf *eb, struct oz_elt_info *ei, int oz_usb_get_desc_req(void *hpd, u8 req_id, u8 req_type, u8 desc_type, u8 index, __le16 windex, int offset, int len) { - struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd; + struct oz_usb_ctx *usb_ctx = hpd; struct oz_pd *pd = usb_ctx->pd; struct oz_elt *elt; struct oz_get_desc_req *body; @@ -92,7 +92,7 @@ int oz_usb_get_desc_req(void *hpd, u8 req_id, u8 req_type, u8 desc_type, */ static int oz_usb_set_config_req(void *hpd, u8 req_id, u8 index) { - struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd; + struct oz_usb_ctx *usb_ctx = hpd; struct oz_pd *pd = usb_ctx->pd; struct oz_elt *elt; struct oz_elt_buf *eb = &pd->elt_buff; @@ -115,7 +115,7 @@ static int oz_usb_set_config_req(void *hpd, u8 req_id, u8 index) */ static int oz_usb_set_interface_req(void *hpd, u8 req_id, u8 index, u8 alt) { - struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd; + struct oz_usb_ctx *usb_ctx = hpd; struct oz_pd *pd = usb_ctx->pd; struct oz_elt *elt; struct oz_elt_buf *eb = &pd->elt_buff; @@ -140,7 +140,7 @@ static int oz_usb_set_interface_req(void *hpd, u8 req_id, u8 index, u8 alt) static int oz_usb_set_clear_feature_req(void *hpd, u8 req_id, u8 type, u8 recipient, u8 index, __le16 feature) { - struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd; + struct oz_usb_ctx *usb_ctx = hpd; struct oz_pd *pd = usb_ctx->pd; struct oz_elt *elt; struct oz_elt_buf *eb = &pd->elt_buff; @@ -166,7 +166,7 @@ static int oz_usb_set_clear_feature_req(void *hpd, u8 req_id, u8 type, static int oz_usb_vendor_class_req(void *hpd, u8 req_id, u8 req_type, u8 request, __le16 value, __le16 index, const u8 *data, int data_len) { - struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd; + struct oz_usb_ctx *usb_ctx = hpd; struct oz_pd *pd = usb_ctx->pd; struct oz_elt *elt; struct oz_elt_buf *eb = &pd->elt_buff; @@ -244,7 +244,7 @@ int oz_usb_control_req(void *hpd, u8 req_id, struct usb_ctrlrequest *setup, */ int oz_usb_send_isoc(void *hpd, u8 ep_num, struct urb *urb) { - struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd; + struct oz_usb_ctx *usb_ctx = hpd; struct oz_pd *pd = usb_ctx->pd; struct oz_elt_buf *eb; int i; diff --git a/drivers/staging/panel/TODO b/drivers/staging/panel/TODO index a4be749bcdfc..2db3f994b632 100644 --- a/drivers/staging/panel/TODO +++ b/drivers/staging/panel/TODO @@ -1,6 +1,5 @@ TODO: - checkpatch.pl cleanups - - Lindent - review major/minor usages - review userspace api - see if all of this could be easier done in userspace instead. diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index 6d1a32097d3c..98325b7b4462 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c @@ -133,6 +133,8 @@ #define LCD_ESCAPE_LEN 24 /* max chars for LCD escape command */ #define LCD_ESCAPE_CHAR 27 /* use char 27 for escape command */ +#define NOT_SET -1 + /* macros to simplify use of the parallel port */ #define r_ctr(x) (parport_read_control((x)->port)) #define r_dtr(x) (parport_read_data((x)->port)) @@ -210,6 +212,10 @@ static pmask_t phys_prev; static char inputs_stable; /* these variables are specific to the keypad */ +static struct { + bool enabled; +} keypad; + static char keypad_buffer[KEYPAD_BUFFER]; static int keypad_buflen; static int keypad_start; @@ -217,17 +223,50 @@ static char keypressed; static wait_queue_head_t keypad_read_wait; /* lcd-specific variables */ - -/* contains the LCD config state */ -static unsigned long int lcd_flags; -/* contains the LCD X offset */ -static unsigned long int lcd_addr_x; -/* contains the LCD Y offset */ -static unsigned long int lcd_addr_y; -/* current escape sequence, 0 terminated */ -static char lcd_escape[LCD_ESCAPE_LEN + 1]; -/* not in escape state. >=0 = escape cmd len */ -static int lcd_escape_len = -1; +static struct { + bool enabled; + bool initialized; + bool must_clear; + + /* TODO: use bool here? */ + char left_shift; + + int height; + int width; + int bwidth; + int hwidth; + int charset; + int proto; + int light_tempo; + + /* TODO: use union here? */ + struct { + int e; + int rs; + int rw; + int cl; + int da; + int bl; + } pins; + + /* contains the LCD config state */ + unsigned long int flags; + + /* Contains the LCD X and Y offset */ + struct { + unsigned long int x; + unsigned long int y; + } addr; + + /* Current escape sequence and it's length or -1 if outside */ + struct { + char buf[LCD_ESCAPE_LEN + 1]; + int len; + } esc_seq; +} lcd; + +/* Needed only for init */ +static int selected_lcd_type = NOT_SET; /* * Bit masks to convert LCD signals to parallel port outputs. @@ -302,14 +341,15 @@ static unsigned char lcd_bits[LCD_PORTS][LCD_BITS][BIT_STATES]; /* * Construct custom config from the kernel's configuration */ -#define DEFAULT_PROFILE PANEL_PROFILE_LARGE #define DEFAULT_PARPORT 0 -#define DEFAULT_LCD LCD_TYPE_OLD -#define DEFAULT_KEYPAD KEYPAD_TYPE_OLD +#define DEFAULT_PROFILE PANEL_PROFILE_LARGE +#define DEFAULT_KEYPAD_TYPE KEYPAD_TYPE_OLD +#define DEFAULT_LCD_TYPE LCD_TYPE_OLD +#define DEFAULT_LCD_HEIGHT 2 #define DEFAULT_LCD_WIDTH 40 #define DEFAULT_LCD_BWIDTH 40 #define DEFAULT_LCD_HWIDTH 64 -#define DEFAULT_LCD_HEIGHT 2 +#define DEFAULT_LCD_CHARSET LCD_CHARSET_NORMAL #define DEFAULT_LCD_PROTO LCD_PROTO_PARALLEL #define DEFAULT_LCD_PIN_E PIN_AUTOLF @@ -318,27 +358,31 @@ static unsigned char lcd_bits[LCD_PORTS][LCD_BITS][BIT_STATES]; #define DEFAULT_LCD_PIN_SCL PIN_STROBE #define DEFAULT_LCD_PIN_SDA PIN_D0 #define DEFAULT_LCD_PIN_BL PIN_NOT_SET -#define DEFAULT_LCD_CHARSET LCD_CHARSET_NORMAL - -#ifdef CONFIG_PANEL_PROFILE -#undef DEFAULT_PROFILE -#define DEFAULT_PROFILE CONFIG_PANEL_PROFILE -#endif #ifdef CONFIG_PANEL_PARPORT #undef DEFAULT_PARPORT #define DEFAULT_PARPORT CONFIG_PANEL_PARPORT #endif +#ifdef CONFIG_PANEL_PROFILE +#undef DEFAULT_PROFILE +#define DEFAULT_PROFILE CONFIG_PANEL_PROFILE +#endif + #if DEFAULT_PROFILE == 0 /* custom */ #ifdef CONFIG_PANEL_KEYPAD -#undef DEFAULT_KEYPAD -#define DEFAULT_KEYPAD CONFIG_PANEL_KEYPAD +#undef DEFAULT_KEYPAD_TYPE +#define DEFAULT_KEYPAD_TYPE CONFIG_PANEL_KEYPAD #endif #ifdef CONFIG_PANEL_LCD -#undef DEFAULT_LCD -#define DEFAULT_LCD CONFIG_PANEL_LCD +#undef DEFAULT_LCD_TYPE +#define DEFAULT_LCD_TYPE CONFIG_PANEL_LCD +#endif + +#ifdef CONFIG_PANEL_LCD_HEIGHT +#undef DEFAULT_LCD_HEIGHT +#define DEFAULT_LCD_HEIGHT CONFIG_PANEL_LCD_HEIGHT #endif #ifdef CONFIG_PANEL_LCD_WIDTH @@ -356,9 +400,9 @@ static unsigned char lcd_bits[LCD_PORTS][LCD_BITS][BIT_STATES]; #define DEFAULT_LCD_HWIDTH CONFIG_PANEL_LCD_HWIDTH #endif -#ifdef CONFIG_PANEL_LCD_HEIGHT -#undef DEFAULT_LCD_HEIGHT -#define DEFAULT_LCD_HEIGHT CONFIG_PANEL_LCD_HEIGHT +#ifdef CONFIG_PANEL_LCD_CHARSET +#undef DEFAULT_LCD_CHARSET +#define DEFAULT_LCD_CHARSET CONFIG_PANEL_LCD_CHARSET #endif #ifdef CONFIG_PANEL_LCD_PROTO @@ -396,25 +440,18 @@ static unsigned char lcd_bits[LCD_PORTS][LCD_BITS][BIT_STATES]; #define DEFAULT_LCD_PIN_BL CONFIG_PANEL_LCD_PIN_BL #endif -#ifdef CONFIG_PANEL_LCD_CHARSET -#undef DEFAULT_LCD_CHARSET -#define DEFAULT_LCD_CHARSET CONFIG_PANEL_LCD_CHARSET -#endif - #endif /* DEFAULT_PROFILE == 0 */ /* global variables */ -static int keypad_open_cnt; /* #times opened */ -static int lcd_open_cnt; /* #times opened */ + +/* Device single-open policy control */ +static atomic_t lcd_available = ATOMIC_INIT(1); +static atomic_t keypad_available = ATOMIC_INIT(1); + static struct pardevice *pprt; -static int lcd_initialized; static int keypad_initialized; -static int light_tempo; - -static char lcd_must_clear; -static char lcd_left_shift; static char init_in_progress; static void (*lcd_write_cmd)(int); @@ -426,59 +463,51 @@ static struct timer_list scan_timer; MODULE_DESCRIPTION("Generic parallel port LCD/Keypad driver"); -static int parport = -1; +static int parport = DEFAULT_PARPORT; module_param(parport, int, 0000); MODULE_PARM_DESC(parport, "Parallel port index (0=lpt1, 1=lpt2, ...)"); -static int lcd_height = -1; +static int profile = DEFAULT_PROFILE; +module_param(profile, int, 0000); +MODULE_PARM_DESC(profile, + "1=16x2 old kp; 2=serial 16x2, new kp; 3=16x2 hantronix; " + "4=16x2 nexcom; default=40x2, old kp"); + +static int keypad_type = NOT_SET; +module_param(keypad_type, int, 0000); +MODULE_PARM_DESC(keypad_type, + "Keypad type: 0=none, 1=old 6 keys, 2=new 6+1 keys, 3=nexcom 4 keys"); + +static int lcd_type = NOT_SET; +module_param(lcd_type, int, 0000); +MODULE_PARM_DESC(lcd_type, + "LCD type: 0=none, 1=old //, 2=serial ks0074, 3=hantronix //, 4=nexcom //, 5=compiled-in"); + +static int lcd_height = NOT_SET; module_param(lcd_height, int, 0000); MODULE_PARM_DESC(lcd_height, "Number of lines on the LCD"); -static int lcd_width = -1; +static int lcd_width = NOT_SET; module_param(lcd_width, int, 0000); MODULE_PARM_DESC(lcd_width, "Number of columns on the LCD"); -static int lcd_bwidth = -1; /* internal buffer width (usually 40) */ +static int lcd_bwidth = NOT_SET; /* internal buffer width (usually 40) */ module_param(lcd_bwidth, int, 0000); MODULE_PARM_DESC(lcd_bwidth, "Internal LCD line width (40)"); -static int lcd_hwidth = -1; /* hardware buffer width (usually 64) */ +static int lcd_hwidth = NOT_SET; /* hardware buffer width (usually 64) */ module_param(lcd_hwidth, int, 0000); MODULE_PARM_DESC(lcd_hwidth, "LCD line hardware address (64)"); -static int lcd_enabled = -1; -module_param(lcd_enabled, int, 0000); -MODULE_PARM_DESC(lcd_enabled, "Deprecated option, use lcd_type instead"); - -static int keypad_enabled = -1; -module_param(keypad_enabled, int, 0000); -MODULE_PARM_DESC(keypad_enabled, "Deprecated option, use keypad_type instead"); - -static int lcd_type = -1; -module_param(lcd_type, int, 0000); -MODULE_PARM_DESC(lcd_type, - "LCD type: 0=none, 1=old //, 2=serial ks0074, 3=hantronix //, 4=nexcom //, 5=compiled-in"); +static int lcd_charset = NOT_SET; +module_param(lcd_charset, int, 0000); +MODULE_PARM_DESC(lcd_charset, "LCD character set: 0=standard, 1=KS0074"); -static int lcd_proto = -1; +static int lcd_proto = NOT_SET; module_param(lcd_proto, int, 0000); MODULE_PARM_DESC(lcd_proto, "LCD communication: 0=parallel (//), 1=serial, 2=TI LCD Interface"); -static int lcd_charset = -1; -module_param(lcd_charset, int, 0000); -MODULE_PARM_DESC(lcd_charset, "LCD character set: 0=standard, 1=KS0074"); - -static int keypad_type = -1; -module_param(keypad_type, int, 0000); -MODULE_PARM_DESC(keypad_type, - "Keypad type: 0=none, 1=old 6 keys, 2=new 6+1 keys, 3=nexcom 4 keys"); - -static int profile = DEFAULT_PROFILE; -module_param(profile, int, 0000); -MODULE_PARM_DESC(profile, - "1=16x2 old kp; 2=serial 16x2, new kp; 3=16x2 hantronix; " - "4=16x2 nexcom; default=40x2, old kp"); - /* * These are the parallel port pins the LCD control signals are connected to. * Set this to 0 if the signal is not used. Set it to its opposite value @@ -503,20 +532,31 @@ module_param(lcd_rw_pin, int, 0000); MODULE_PARM_DESC(lcd_rw_pin, "# of the // port pin connected to LCD 'RW' signal, with polarity (-17..17)"); -static int lcd_bl_pin = PIN_NOT_SET; -module_param(lcd_bl_pin, int, 0000); -MODULE_PARM_DESC(lcd_bl_pin, - "# of the // port pin connected to LCD backlight, with polarity (-17..17)"); +static int lcd_cl_pin = PIN_NOT_SET; +module_param(lcd_cl_pin, int, 0000); +MODULE_PARM_DESC(lcd_cl_pin, + "# of the // port pin connected to serial LCD 'SCL' signal, with polarity (-17..17)"); static int lcd_da_pin = PIN_NOT_SET; module_param(lcd_da_pin, int, 0000); MODULE_PARM_DESC(lcd_da_pin, "# of the // port pin connected to serial LCD 'SDA' signal, with polarity (-17..17)"); -static int lcd_cl_pin = PIN_NOT_SET; -module_param(lcd_cl_pin, int, 0000); -MODULE_PARM_DESC(lcd_cl_pin, - "# of the // port pin connected to serial LCD 'SCL' signal, with polarity (-17..17)"); +static int lcd_bl_pin = PIN_NOT_SET; +module_param(lcd_bl_pin, int, 0000); +MODULE_PARM_DESC(lcd_bl_pin, + "# of the // port pin connected to LCD backlight, with polarity (-17..17)"); + +/* Deprecated module parameters - consider not using them anymore */ + +static int lcd_enabled = NOT_SET; +module_param(lcd_enabled, int, 0000); +MODULE_PARM_DESC(lcd_enabled, "Deprecated option, use lcd_type instead"); + +static int keypad_enabled = NOT_SET; +module_param(keypad_enabled, int, 0000); +MODULE_PARM_DESC(keypad_enabled, "Deprecated option, use keypad_type instead"); + static const unsigned char *lcd_char_conv; @@ -748,7 +788,7 @@ static void lcd_send_serial(int byte) /* turn the backlight on or off */ static void lcd_backlight(int on) { - if (lcd_bl_pin == PIN_NONE) + if (lcd.pins.bl == PIN_NONE) return; /* The backlight is activated by setting the AUTOFEED line to +5V */ @@ -847,23 +887,23 @@ static void lcd_write_data_tilcd(int data) static void lcd_gotoxy(void) { lcd_write_cmd(0x80 /* set DDRAM address */ - | (lcd_addr_y ? lcd_hwidth : 0) + | (lcd.addr.y ? lcd.hwidth : 0) /* we force the cursor to stay at the end of the line if it wants to go farther */ - | ((lcd_addr_x < lcd_bwidth) ? lcd_addr_x & - (lcd_hwidth - 1) : lcd_bwidth - 1)); + | ((lcd.addr.x < lcd.bwidth) ? lcd.addr.x & + (lcd.hwidth - 1) : lcd.bwidth - 1)); } static void lcd_print(char c) { - if (lcd_addr_x < lcd_bwidth) { + if (lcd.addr.x < lcd.bwidth) { if (lcd_char_conv != NULL) c = lcd_char_conv[(unsigned char)c]; lcd_write_data(c); - lcd_addr_x++; + lcd.addr.x++; } /* prevents the cursor from wrapping onto the next line */ - if (lcd_addr_x == lcd_bwidth) + if (lcd.addr.x == lcd.bwidth) lcd_gotoxy(); } @@ -872,12 +912,12 @@ static void lcd_clear_fast_s(void) { int pos; - lcd_addr_x = 0; - lcd_addr_y = 0; + lcd.addr.x = 0; + lcd.addr.y = 0; lcd_gotoxy(); spin_lock_irq(&pprt_lock); - for (pos = 0; pos < lcd_height * lcd_hwidth; pos++) { + for (pos = 0; pos < lcd.height * lcd.hwidth; pos++) { lcd_send_serial(0x5F); /* R/W=W, RS=1 */ lcd_send_serial(' ' & 0x0F); lcd_send_serial((' ' >> 4) & 0x0F); @@ -885,8 +925,8 @@ static void lcd_clear_fast_s(void) } spin_unlock_irq(&pprt_lock); - lcd_addr_x = 0; - lcd_addr_y = 0; + lcd.addr.x = 0; + lcd.addr.y = 0; lcd_gotoxy(); } @@ -895,12 +935,12 @@ static void lcd_clear_fast_p8(void) { int pos; - lcd_addr_x = 0; - lcd_addr_y = 0; + lcd.addr.x = 0; + lcd.addr.y = 0; lcd_gotoxy(); spin_lock_irq(&pprt_lock); - for (pos = 0; pos < lcd_height * lcd_hwidth; pos++) { + for (pos = 0; pos < lcd.height * lcd.hwidth; pos++) { /* present the data to the data port */ w_dtr(pprt, ' '); @@ -923,8 +963,8 @@ static void lcd_clear_fast_p8(void) } spin_unlock_irq(&pprt_lock); - lcd_addr_x = 0; - lcd_addr_y = 0; + lcd.addr.x = 0; + lcd.addr.y = 0; lcd_gotoxy(); } @@ -933,12 +973,12 @@ static void lcd_clear_fast_tilcd(void) { int pos; - lcd_addr_x = 0; - lcd_addr_y = 0; + lcd.addr.x = 0; + lcd.addr.y = 0; lcd_gotoxy(); spin_lock_irq(&pprt_lock); - for (pos = 0; pos < lcd_height * lcd_hwidth; pos++) { + for (pos = 0; pos < lcd.height * lcd.hwidth; pos++) { /* present the data to the data port */ w_dtr(pprt, ' '); udelay(60); @@ -946,8 +986,8 @@ static void lcd_clear_fast_tilcd(void) spin_unlock_irq(&pprt_lock); - lcd_addr_x = 0; - lcd_addr_y = 0; + lcd.addr.x = 0; + lcd.addr.y = 0; lcd_gotoxy(); } @@ -955,15 +995,15 @@ static void lcd_clear_fast_tilcd(void) static void lcd_clear_display(void) { lcd_write_cmd(0x01); /* clear display */ - lcd_addr_x = 0; - lcd_addr_y = 0; + lcd.addr.x = 0; + lcd.addr.y = 0; /* we must wait a few milliseconds (15) */ long_sleep(15); } static void lcd_init_display(void) { - lcd_flags = ((lcd_height > 1) ? LCD_FLAG_N : 0) + lcd.flags = ((lcd.height > 1) ? LCD_FLAG_N : 0) | LCD_FLAG_D | LCD_FLAG_C | LCD_FLAG_B; long_sleep(20); /* wait 20 ms after power-up for the paranoid */ @@ -976,8 +1016,8 @@ static void lcd_init_display(void) long_sleep(10); lcd_write_cmd(0x30 /* set font height and lines number */ - | ((lcd_flags & LCD_FLAG_F) ? 4 : 0) - | ((lcd_flags & LCD_FLAG_N) ? 8 : 0) + | ((lcd.flags & LCD_FLAG_F) ? 4 : 0) + | ((lcd.flags & LCD_FLAG_N) ? 8 : 0) ); long_sleep(10); @@ -985,12 +1025,12 @@ static void lcd_init_display(void) long_sleep(10); lcd_write_cmd(0x08 /* set display mode */ - | ((lcd_flags & LCD_FLAG_D) ? 4 : 0) - | ((lcd_flags & LCD_FLAG_C) ? 2 : 0) - | ((lcd_flags & LCD_FLAG_B) ? 1 : 0) + | ((lcd.flags & LCD_FLAG_D) ? 4 : 0) + | ((lcd.flags & LCD_FLAG_C) ? 2 : 0) + | ((lcd.flags & LCD_FLAG_B) ? 1 : 0) ); - lcd_backlight((lcd_flags & LCD_FLAG_L) ? 1 : 0); + lcd_backlight((lcd.flags & LCD_FLAG_L) ? 1 : 0); long_sleep(10); @@ -1013,100 +1053,101 @@ static inline int handle_lcd_special_code(void) int processed = 0; - char *esc = lcd_escape + 2; - int oldflags = lcd_flags; + char *esc = lcd.esc_seq.buf + 2; + int oldflags = lcd.flags; /* check for display mode flags */ switch (*esc) { case 'D': /* Display ON */ - lcd_flags |= LCD_FLAG_D; + lcd.flags |= LCD_FLAG_D; processed = 1; break; case 'd': /* Display OFF */ - lcd_flags &= ~LCD_FLAG_D; + lcd.flags &= ~LCD_FLAG_D; processed = 1; break; case 'C': /* Cursor ON */ - lcd_flags |= LCD_FLAG_C; + lcd.flags |= LCD_FLAG_C; processed = 1; break; case 'c': /* Cursor OFF */ - lcd_flags &= ~LCD_FLAG_C; + lcd.flags &= ~LCD_FLAG_C; processed = 1; break; case 'B': /* Blink ON */ - lcd_flags |= LCD_FLAG_B; + lcd.flags |= LCD_FLAG_B; processed = 1; break; case 'b': /* Blink OFF */ - lcd_flags &= ~LCD_FLAG_B; + lcd.flags &= ~LCD_FLAG_B; processed = 1; break; case '+': /* Back light ON */ - lcd_flags |= LCD_FLAG_L; + lcd.flags |= LCD_FLAG_L; processed = 1; break; case '-': /* Back light OFF */ - lcd_flags &= ~LCD_FLAG_L; + lcd.flags &= ~LCD_FLAG_L; processed = 1; break; case '*': /* flash back light using the keypad timer */ if (scan_timer.function != NULL) { - if (light_tempo == 0 && ((lcd_flags & LCD_FLAG_L) == 0)) + if (lcd.light_tempo == 0 + && ((lcd.flags & LCD_FLAG_L) == 0)) lcd_backlight(1); - light_tempo = FLASH_LIGHT_TEMPO; + lcd.light_tempo = FLASH_LIGHT_TEMPO; } processed = 1; break; case 'f': /* Small Font */ - lcd_flags &= ~LCD_FLAG_F; + lcd.flags &= ~LCD_FLAG_F; processed = 1; break; case 'F': /* Large Font */ - lcd_flags |= LCD_FLAG_F; + lcd.flags |= LCD_FLAG_F; processed = 1; break; case 'n': /* One Line */ - lcd_flags &= ~LCD_FLAG_N; + lcd.flags &= ~LCD_FLAG_N; processed = 1; break; case 'N': /* Two Lines */ - lcd_flags |= LCD_FLAG_N; + lcd.flags |= LCD_FLAG_N; break; case 'l': /* Shift Cursor Left */ - if (lcd_addr_x > 0) { + if (lcd.addr.x > 0) { /* back one char if not at end of line */ - if (lcd_addr_x < lcd_bwidth) + if (lcd.addr.x < lcd.bwidth) lcd_write_cmd(0x10); - lcd_addr_x--; + lcd.addr.x--; } processed = 1; break; case 'r': /* shift cursor right */ - if (lcd_addr_x < lcd_width) { + if (lcd.addr.x < lcd.width) { /* allow the cursor to pass the end of the line */ - if (lcd_addr_x < - (lcd_bwidth - 1)) + if (lcd.addr.x < + (lcd.bwidth - 1)) lcd_write_cmd(0x14); - lcd_addr_x++; + lcd.addr.x++; } processed = 1; break; case 'L': /* shift display left */ - lcd_left_shift++; + lcd.left_shift++; lcd_write_cmd(0x18); processed = 1; break; case 'R': /* shift display right */ - lcd_left_shift--; + lcd.left_shift--; lcd_write_cmd(0x1C); processed = 1; break; case 'k': { /* kill end of line */ int x; - for (x = lcd_addr_x; x < lcd_bwidth; x++) + for (x = lcd.addr.x; x < lcd.bwidth; x++) lcd_write_data(' '); /* restore cursor position */ @@ -1116,7 +1157,7 @@ static inline int handle_lcd_special_code(void) } case 'I': /* reinitialize display */ lcd_init_display(); - lcd_left_shift = 0; + lcd.left_shift = 0; processed = 1; break; case 'G': { @@ -1187,11 +1228,11 @@ static inline int handle_lcd_special_code(void) while (*esc) { if (*esc == 'x') { esc++; - if (kstrtoul(esc, 10, &lcd_addr_x) < 0) + if (kstrtoul(esc, 10, &lcd.addr.x) < 0) break; } else if (*esc == 'y') { esc++; - if (kstrtoul(esc, 10, &lcd_addr_y) < 0) + if (kstrtoul(esc, 10, &lcd.addr.y) < 0) break; } else { break; @@ -1204,25 +1245,25 @@ static inline int handle_lcd_special_code(void) } /* Check whether one flag was changed */ - if (oldflags != lcd_flags) { + if (oldflags != lcd.flags) { /* check whether one of B,C,D flags were changed */ - if ((oldflags ^ lcd_flags) & + if ((oldflags ^ lcd.flags) & (LCD_FLAG_B | LCD_FLAG_C | LCD_FLAG_D)) /* set display mode */ lcd_write_cmd(0x08 - | ((lcd_flags & LCD_FLAG_D) ? 4 : 0) - | ((lcd_flags & LCD_FLAG_C) ? 2 : 0) - | ((lcd_flags & LCD_FLAG_B) ? 1 : 0)); + | ((lcd.flags & LCD_FLAG_D) ? 4 : 0) + | ((lcd.flags & LCD_FLAG_C) ? 2 : 0) + | ((lcd.flags & LCD_FLAG_B) ? 1 : 0)); /* check whether one of F,N flags was changed */ - else if ((oldflags ^ lcd_flags) & (LCD_FLAG_F | LCD_FLAG_N)) + else if ((oldflags ^ lcd.flags) & (LCD_FLAG_F | LCD_FLAG_N)) lcd_write_cmd(0x30 - | ((lcd_flags & LCD_FLAG_F) ? 4 : 0) - | ((lcd_flags & LCD_FLAG_N) ? 8 : 0)); + | ((lcd.flags & LCD_FLAG_F) ? 4 : 0) + | ((lcd.flags & LCD_FLAG_N) ? 8 : 0)); /* check whether L flag was changed */ - else if ((oldflags ^ lcd_flags) & (LCD_FLAG_L)) { - if (lcd_flags & (LCD_FLAG_L)) + else if ((oldflags ^ lcd.flags) & (LCD_FLAG_L)) { + if (lcd.flags & (LCD_FLAG_L)) lcd_backlight(1); - else if (light_tempo == 0) + else if (lcd.light_tempo == 0) /* switch off the light only when the tempo lighting is gone */ lcd_backlight(0); @@ -1235,29 +1276,29 @@ static inline int handle_lcd_special_code(void) static void lcd_write_char(char c) { /* first, we'll test if we're in escape mode */ - if ((c != '\n') && lcd_escape_len >= 0) { + if ((c != '\n') && lcd.esc_seq.len >= 0) { /* yes, let's add this char to the buffer */ - lcd_escape[lcd_escape_len++] = c; - lcd_escape[lcd_escape_len] = 0; + lcd.esc_seq.buf[lcd.esc_seq.len++] = c; + lcd.esc_seq.buf[lcd.esc_seq.len] = 0; } else { /* aborts any previous escape sequence */ - lcd_escape_len = -1; + lcd.esc_seq.len = -1; switch (c) { case LCD_ESCAPE_CHAR: /* start of an escape sequence */ - lcd_escape_len = 0; - lcd_escape[lcd_escape_len] = 0; + lcd.esc_seq.len = 0; + lcd.esc_seq.buf[lcd.esc_seq.len] = 0; break; case '\b': /* go back one char and clear it */ - if (lcd_addr_x > 0) { + if (lcd.addr.x > 0) { /* check if we're not at the end of the line */ - if (lcd_addr_x < lcd_bwidth) + if (lcd.addr.x < lcd.bwidth) /* back one char */ lcd_write_cmd(0x10); - lcd_addr_x--; + lcd.addr.x--; } /* replace with a space */ lcd_write_data(' '); @@ -1271,15 +1312,15 @@ static void lcd_write_char(char c) case '\n': /* flush the remainder of the current line and go to the beginning of the next line */ - for (; lcd_addr_x < lcd_bwidth; lcd_addr_x++) + for (; lcd.addr.x < lcd.bwidth; lcd.addr.x++) lcd_write_data(' '); - lcd_addr_x = 0; - lcd_addr_y = (lcd_addr_y + 1) % lcd_height; + lcd.addr.x = 0; + lcd.addr.y = (lcd.addr.y + 1) % lcd.height; lcd_gotoxy(); break; case '\r': /* go to the beginning of the same line */ - lcd_addr_x = 0; + lcd.addr.x = 0; lcd_gotoxy(); break; case '\t': @@ -1295,32 +1336,32 @@ static void lcd_write_char(char c) /* now we'll see if we're in an escape mode and if the current escape sequence can be understood. */ - if (lcd_escape_len >= 2) { + if (lcd.esc_seq.len >= 2) { int processed = 0; - if (!strcmp(lcd_escape, "[2J")) { + if (!strcmp(lcd.esc_seq.buf, "[2J")) { /* clear the display */ lcd_clear_fast(); processed = 1; - } else if (!strcmp(lcd_escape, "[H")) { + } else if (!strcmp(lcd.esc_seq.buf, "[H")) { /* cursor to home */ - lcd_addr_x = 0; - lcd_addr_y = 0; + lcd.addr.x = 0; + lcd.addr.y = 0; lcd_gotoxy(); processed = 1; } /* codes starting with ^[[L */ - else if ((lcd_escape_len >= 3) && - (lcd_escape[0] == '[') && - (lcd_escape[1] == 'L')) { + else if ((lcd.esc_seq.len >= 3) && + (lcd.esc_seq.buf[0] == '[') && + (lcd.esc_seq.buf[1] == 'L')) { processed = handle_lcd_special_code(); } /* LCD special escape codes */ /* flush the escape sequence if it's been processed or if it is getting too long. */ - if (processed || (lcd_escape_len >= LCD_ESCAPE_LEN)) - lcd_escape_len = -1; + if (processed || (lcd.esc_seq.len >= LCD_ESCAPE_LEN)) + lcd.esc_seq.len = -1; } /* escape codes */ } @@ -1347,23 +1388,22 @@ static ssize_t lcd_write(struct file *file, static int lcd_open(struct inode *inode, struct file *file) { - if (lcd_open_cnt) + if (!atomic_dec_and_test(&lcd_available)) return -EBUSY; /* open only once at a time */ if (file->f_mode & FMODE_READ) /* device is write-only */ return -EPERM; - if (lcd_must_clear) { + if (lcd.must_clear) { lcd_clear_display(); - lcd_must_clear = 0; + lcd.must_clear = false; } - lcd_open_cnt++; return nonseekable_open(inode, file); } static int lcd_release(struct inode *inode, struct file *file) { - lcd_open_cnt--; + atomic_inc(&lcd_available); return 0; } @@ -1375,9 +1415,9 @@ static const struct file_operations lcd_fops = { }; static struct miscdevice lcd_dev = { - LCD_MINOR, - "lcd", - &lcd_fops + .minor = LCD_MINOR, + .name = "lcd", + .fops = &lcd_fops, }; /* public function usable from the kernel for any purpose */ @@ -1386,7 +1426,7 @@ static void panel_lcd_print(const char *s) const char *tmp = s; int count = strlen(s); - if (lcd_enabled && lcd_initialized) { + if (lcd.enabled && lcd.initialized) { for (; count-- > 0; tmp++) { if (!in_interrupt() && (((count + 1) & 0x1f) == 0)) /* let's be a little nice with other processes @@ -1401,183 +1441,173 @@ static void panel_lcd_print(const char *s) /* initialize the LCD driver */ static void lcd_init(void) { - switch (lcd_type) { + switch (selected_lcd_type) { case LCD_TYPE_OLD: /* parallel mode, 8 bits */ - if (lcd_proto < 0) - lcd_proto = LCD_PROTO_PARALLEL; - if (lcd_charset < 0) - lcd_charset = LCD_CHARSET_NORMAL; - if (lcd_e_pin == PIN_NOT_SET) - lcd_e_pin = PIN_STROBE; - if (lcd_rs_pin == PIN_NOT_SET) - lcd_rs_pin = PIN_AUTOLF; - - if (lcd_width < 0) - lcd_width = 40; - if (lcd_bwidth < 0) - lcd_bwidth = 40; - if (lcd_hwidth < 0) - lcd_hwidth = 64; - if (lcd_height < 0) - lcd_height = 2; + lcd.proto = LCD_PROTO_PARALLEL; + lcd.charset = LCD_CHARSET_NORMAL; + lcd.pins.e = PIN_STROBE; + lcd.pins.rs = PIN_AUTOLF; + + lcd.width = 40; + lcd.bwidth = 40; + lcd.hwidth = 64; + lcd.height = 2; break; case LCD_TYPE_KS0074: /* serial mode, ks0074 */ - if (lcd_proto < 0) - lcd_proto = LCD_PROTO_SERIAL; - if (lcd_charset < 0) - lcd_charset = LCD_CHARSET_KS0074; - if (lcd_bl_pin == PIN_NOT_SET) - lcd_bl_pin = PIN_AUTOLF; - if (lcd_cl_pin == PIN_NOT_SET) - lcd_cl_pin = PIN_STROBE; - if (lcd_da_pin == PIN_NOT_SET) - lcd_da_pin = PIN_D0; - - if (lcd_width < 0) - lcd_width = 16; - if (lcd_bwidth < 0) - lcd_bwidth = 40; - if (lcd_hwidth < 0) - lcd_hwidth = 16; - if (lcd_height < 0) - lcd_height = 2; + lcd.proto = LCD_PROTO_SERIAL; + lcd.charset = LCD_CHARSET_KS0074; + lcd.pins.bl = PIN_AUTOLF; + lcd.pins.cl = PIN_STROBE; + lcd.pins.da = PIN_D0; + + lcd.width = 16; + lcd.bwidth = 40; + lcd.hwidth = 16; + lcd.height = 2; break; case LCD_TYPE_NEXCOM: /* parallel mode, 8 bits, generic */ - if (lcd_proto < 0) - lcd_proto = LCD_PROTO_PARALLEL; - if (lcd_charset < 0) - lcd_charset = LCD_CHARSET_NORMAL; - if (lcd_e_pin == PIN_NOT_SET) - lcd_e_pin = PIN_AUTOLF; - if (lcd_rs_pin == PIN_NOT_SET) - lcd_rs_pin = PIN_SELECP; - if (lcd_rw_pin == PIN_NOT_SET) - lcd_rw_pin = PIN_INITP; - - if (lcd_width < 0) - lcd_width = 16; - if (lcd_bwidth < 0) - lcd_bwidth = 40; - if (lcd_hwidth < 0) - lcd_hwidth = 64; - if (lcd_height < 0) - lcd_height = 2; + lcd.proto = LCD_PROTO_PARALLEL; + lcd.charset = LCD_CHARSET_NORMAL; + lcd.pins.e = PIN_AUTOLF; + lcd.pins.rs = PIN_SELECP; + lcd.pins.rw = PIN_INITP; + + lcd.width = 16; + lcd.bwidth = 40; + lcd.hwidth = 64; + lcd.height = 2; break; case LCD_TYPE_CUSTOM: /* customer-defined */ - if (lcd_proto < 0) - lcd_proto = DEFAULT_LCD_PROTO; - if (lcd_charset < 0) - lcd_charset = DEFAULT_LCD_CHARSET; + lcd.proto = DEFAULT_LCD_PROTO; + lcd.charset = DEFAULT_LCD_CHARSET; /* default geometry will be set later */ break; case LCD_TYPE_HANTRONIX: /* parallel mode, 8 bits, hantronix-like */ default: - if (lcd_proto < 0) - lcd_proto = LCD_PROTO_PARALLEL; - if (lcd_charset < 0) - lcd_charset = LCD_CHARSET_NORMAL; - if (lcd_e_pin == PIN_NOT_SET) - lcd_e_pin = PIN_STROBE; - if (lcd_rs_pin == PIN_NOT_SET) - lcd_rs_pin = PIN_SELECP; - - if (lcd_width < 0) - lcd_width = 16; - if (lcd_bwidth < 0) - lcd_bwidth = 40; - if (lcd_hwidth < 0) - lcd_hwidth = 64; - if (lcd_height < 0) - lcd_height = 2; + lcd.proto = LCD_PROTO_PARALLEL; + lcd.charset = LCD_CHARSET_NORMAL; + lcd.pins.e = PIN_STROBE; + lcd.pins.rs = PIN_SELECP; + + lcd.width = 16; + lcd.bwidth = 40; + lcd.hwidth = 64; + lcd.height = 2; break; } + /* Overwrite with module params set on loading */ + if (lcd_height != NOT_SET) + lcd.height = lcd_height; + if (lcd_width != NOT_SET) + lcd.width = lcd_width; + if (lcd_bwidth != NOT_SET) + lcd.bwidth = lcd_bwidth; + if (lcd_hwidth != NOT_SET) + lcd.hwidth = lcd_hwidth; + if (lcd_charset != NOT_SET) + lcd.charset = lcd_charset; + if (lcd_proto != NOT_SET) + lcd.proto = lcd_proto; + if (lcd_e_pin != PIN_NOT_SET) + lcd.pins.e = lcd_e_pin; + if (lcd_rs_pin != PIN_NOT_SET) + lcd.pins.rs = lcd_rs_pin; + if (lcd_rw_pin != PIN_NOT_SET) + lcd.pins.rw = lcd_rw_pin; + if (lcd_cl_pin != PIN_NOT_SET) + lcd.pins.cl = lcd_cl_pin; + if (lcd_da_pin != PIN_NOT_SET) + lcd.pins.da = lcd_da_pin; + if (lcd_bl_pin != PIN_NOT_SET) + lcd.pins.bl = lcd_bl_pin; + /* this is used to catch wrong and default values */ - if (lcd_width <= 0) - lcd_width = DEFAULT_LCD_WIDTH; - if (lcd_bwidth <= 0) - lcd_bwidth = DEFAULT_LCD_BWIDTH; - if (lcd_hwidth <= 0) - lcd_hwidth = DEFAULT_LCD_HWIDTH; - if (lcd_height <= 0) - lcd_height = DEFAULT_LCD_HEIGHT; - - if (lcd_proto == LCD_PROTO_SERIAL) { /* SERIAL */ + if (lcd.width <= 0) + lcd.width = DEFAULT_LCD_WIDTH; + if (lcd.bwidth <= 0) + lcd.bwidth = DEFAULT_LCD_BWIDTH; + if (lcd.hwidth <= 0) + lcd.hwidth = DEFAULT_LCD_HWIDTH; + if (lcd.height <= 0) + lcd.height = DEFAULT_LCD_HEIGHT; + + if (lcd.proto == LCD_PROTO_SERIAL) { /* SERIAL */ lcd_write_cmd = lcd_write_cmd_s; lcd_write_data = lcd_write_data_s; lcd_clear_fast = lcd_clear_fast_s; - if (lcd_cl_pin == PIN_NOT_SET) - lcd_cl_pin = DEFAULT_LCD_PIN_SCL; - if (lcd_da_pin == PIN_NOT_SET) - lcd_da_pin = DEFAULT_LCD_PIN_SDA; + if (lcd.pins.cl == PIN_NOT_SET) + lcd.pins.cl = DEFAULT_LCD_PIN_SCL; + if (lcd.pins.da == PIN_NOT_SET) + lcd.pins.da = DEFAULT_LCD_PIN_SDA; - } else if (lcd_proto == LCD_PROTO_PARALLEL) { /* PARALLEL */ + } else if (lcd.proto == LCD_PROTO_PARALLEL) { /* PARALLEL */ lcd_write_cmd = lcd_write_cmd_p8; lcd_write_data = lcd_write_data_p8; lcd_clear_fast = lcd_clear_fast_p8; - if (lcd_e_pin == PIN_NOT_SET) - lcd_e_pin = DEFAULT_LCD_PIN_E; - if (lcd_rs_pin == PIN_NOT_SET) - lcd_rs_pin = DEFAULT_LCD_PIN_RS; - if (lcd_rw_pin == PIN_NOT_SET) - lcd_rw_pin = DEFAULT_LCD_PIN_RW; + if (lcd.pins.e == PIN_NOT_SET) + lcd.pins.e = DEFAULT_LCD_PIN_E; + if (lcd.pins.rs == PIN_NOT_SET) + lcd.pins.rs = DEFAULT_LCD_PIN_RS; + if (lcd.pins.rw == PIN_NOT_SET) + lcd.pins.rw = DEFAULT_LCD_PIN_RW; } else { lcd_write_cmd = lcd_write_cmd_tilcd; lcd_write_data = lcd_write_data_tilcd; lcd_clear_fast = lcd_clear_fast_tilcd; } - if (lcd_bl_pin == PIN_NOT_SET) - lcd_bl_pin = DEFAULT_LCD_PIN_BL; - - if (lcd_e_pin == PIN_NOT_SET) - lcd_e_pin = PIN_NONE; - if (lcd_rs_pin == PIN_NOT_SET) - lcd_rs_pin = PIN_NONE; - if (lcd_rw_pin == PIN_NOT_SET) - lcd_rw_pin = PIN_NONE; - if (lcd_bl_pin == PIN_NOT_SET) - lcd_bl_pin = PIN_NONE; - if (lcd_cl_pin == PIN_NOT_SET) - lcd_cl_pin = PIN_NONE; - if (lcd_da_pin == PIN_NOT_SET) - lcd_da_pin = PIN_NONE; - - if (lcd_charset < 0) - lcd_charset = DEFAULT_LCD_CHARSET; - - if (lcd_charset == LCD_CHARSET_KS0074) + if (lcd.pins.bl == PIN_NOT_SET) + lcd.pins.bl = DEFAULT_LCD_PIN_BL; + + if (lcd.pins.e == PIN_NOT_SET) + lcd.pins.e = PIN_NONE; + if (lcd.pins.rs == PIN_NOT_SET) + lcd.pins.rs = PIN_NONE; + if (lcd.pins.rw == PIN_NOT_SET) + lcd.pins.rw = PIN_NONE; + if (lcd.pins.bl == PIN_NOT_SET) + lcd.pins.bl = PIN_NONE; + if (lcd.pins.cl == PIN_NOT_SET) + lcd.pins.cl = PIN_NONE; + if (lcd.pins.da == PIN_NOT_SET) + lcd.pins.da = PIN_NONE; + + if (lcd.charset == NOT_SET) + lcd.charset = DEFAULT_LCD_CHARSET; + + if (lcd.charset == LCD_CHARSET_KS0074) lcd_char_conv = lcd_char_conv_ks0074; else lcd_char_conv = NULL; - if (lcd_bl_pin != PIN_NONE) + if (lcd.pins.bl != PIN_NONE) init_scan_timer(); - pin_to_bits(lcd_e_pin, lcd_bits[LCD_PORT_D][LCD_BIT_E], + pin_to_bits(lcd.pins.e, lcd_bits[LCD_PORT_D][LCD_BIT_E], lcd_bits[LCD_PORT_C][LCD_BIT_E]); - pin_to_bits(lcd_rs_pin, lcd_bits[LCD_PORT_D][LCD_BIT_RS], + pin_to_bits(lcd.pins.rs, lcd_bits[LCD_PORT_D][LCD_BIT_RS], lcd_bits[LCD_PORT_C][LCD_BIT_RS]); - pin_to_bits(lcd_rw_pin, lcd_bits[LCD_PORT_D][LCD_BIT_RW], + pin_to_bits(lcd.pins.rw, lcd_bits[LCD_PORT_D][LCD_BIT_RW], lcd_bits[LCD_PORT_C][LCD_BIT_RW]); - pin_to_bits(lcd_bl_pin, lcd_bits[LCD_PORT_D][LCD_BIT_BL], + pin_to_bits(lcd.pins.bl, lcd_bits[LCD_PORT_D][LCD_BIT_BL], lcd_bits[LCD_PORT_C][LCD_BIT_BL]); - pin_to_bits(lcd_cl_pin, lcd_bits[LCD_PORT_D][LCD_BIT_CL], + pin_to_bits(lcd.pins.cl, lcd_bits[LCD_PORT_D][LCD_BIT_CL], lcd_bits[LCD_PORT_C][LCD_BIT_CL]); - pin_to_bits(lcd_da_pin, lcd_bits[LCD_PORT_D][LCD_BIT_DA], + pin_to_bits(lcd.pins.da, lcd_bits[LCD_PORT_D][LCD_BIT_DA], lcd_bits[LCD_PORT_C][LCD_BIT_DA]); /* before this line, we must NOT send anything to the display. * Since lcd_init_display() needs to write data, we have to * enable mark the LCD initialized just before. */ - lcd_initialized = 1; + lcd.initialized = true; lcd_init_display(); /* display a short message */ @@ -1589,10 +1619,10 @@ static void lcd_init(void) panel_lcd_print("\x1b[Lc\x1b[Lb\x1b[L*Linux-" UTS_RELEASE "\nPanel-" PANEL_VERSION); #endif - lcd_addr_x = 0; - lcd_addr_y = 0; + lcd.addr.x = 0; + lcd.addr.y = 0; /* clear the display on the next device opening */ - lcd_must_clear = 1; + lcd.must_clear = true; lcd_gotoxy(); } @@ -1627,20 +1657,19 @@ static ssize_t keypad_read(struct file *file, static int keypad_open(struct inode *inode, struct file *file) { - if (keypad_open_cnt) + if (!atomic_dec_and_test(&keypad_available)) return -EBUSY; /* open only once at a time */ if (file->f_mode & FMODE_WRITE) /* device is read-only */ return -EPERM; keypad_buflen = 0; /* flush the buffer on opening */ - keypad_open_cnt++; return 0; } static int keypad_release(struct inode *inode, struct file *file) { - keypad_open_cnt--; + atomic_inc(&keypad_available); return 0; } @@ -1652,9 +1681,9 @@ static const struct file_operations keypad_fops = { }; static struct miscdevice keypad_dev = { - KEYPAD_MINOR, - "keypad", - &keypad_fops + .minor = KEYPAD_MINOR, + .name = "keypad", + .fops = &keypad_fops, }; static void keypad_send_key(const char *string, int max_len) @@ -1663,7 +1692,7 @@ static void keypad_send_key(const char *string, int max_len) return; /* send the key to the device only if a process is attached to it. */ - if (keypad_open_cnt > 0) { + if (!atomic_read(&keypad_available)) { while (max_len-- && keypad_buflen < KEYPAD_BUFFER && *string) { keypad_buffer[(keypad_start + keypad_buflen++) % KEYPAD_BUFFER] = *string++; @@ -1917,7 +1946,7 @@ static void panel_process_inputs(void) static void panel_scan_timer(void) { - if (keypad_enabled && keypad_initialized) { + if (keypad.enabled && keypad_initialized) { if (spin_trylock_irq(&pprt_lock)) { phys_scan_contacts(); @@ -1929,14 +1958,16 @@ static void panel_scan_timer(void) panel_process_inputs(); } - if (lcd_enabled && lcd_initialized) { + if (lcd.enabled && lcd.initialized) { if (keypressed) { - if (light_tempo == 0 && ((lcd_flags & LCD_FLAG_L) == 0)) + if (lcd.light_tempo == 0 + && ((lcd.flags & LCD_FLAG_L) == 0)) lcd_backlight(1); - light_tempo = FLASH_LIGHT_TEMPO; - } else if (light_tempo > 0) { - light_tempo--; - if (light_tempo == 0 && ((lcd_flags & LCD_FLAG_L) == 0)) + lcd.light_tempo = FLASH_LIGHT_TEMPO; + } else if (lcd.light_tempo > 0) { + lcd.light_tempo--; + if (lcd.light_tempo == 0 + && ((lcd.flags & LCD_FLAG_L) == 0)) lcd_backlight(0); } } @@ -2108,7 +2139,7 @@ static void keypad_init(void) static int panel_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { - if (lcd_enabled && lcd_initialized) { + if (lcd.enabled && lcd.initialized) { switch (code) { case SYS_DOWN: panel_lcd_print @@ -2164,13 +2195,13 @@ static void panel_attach(struct parport *port) /* must init LCD first, just in case an IRQ from the keypad is * generated at keypad init */ - if (lcd_enabled) { + if (lcd.enabled) { lcd_init(); if (misc_register(&lcd_dev)) goto err_unreg_device; } - if (keypad_enabled) { + if (keypad.enabled) { keypad_init(); if (misc_register(&keypad_dev)) goto err_lcd_unreg; @@ -2178,7 +2209,7 @@ static void panel_attach(struct parport *port) return; err_lcd_unreg: - if (lcd_enabled) + if (lcd.enabled) misc_deregister(&lcd_dev); err_unreg_device: parport_unregister_device(pprt); @@ -2196,14 +2227,14 @@ static void panel_detach(struct parport *port) return; } - if (keypad_enabled && keypad_initialized) { + if (keypad.enabled && keypad_initialized) { misc_deregister(&keypad_dev); keypad_initialized = 0; } - if (lcd_enabled && lcd_initialized) { + if (lcd.enabled && lcd.initialized) { misc_deregister(&lcd_dev); - lcd_initialized = 0; + lcd.initialized = false; } parport_release(pprt); @@ -2218,72 +2249,89 @@ static struct parport_driver panel_driver = { }; /* init function */ -static int panel_init(void) +static int __init panel_init_module(void) { - /* for backwards compatibility */ - if (keypad_type < 0) - keypad_type = keypad_enabled; - - if (lcd_type < 0) - lcd_type = lcd_enabled; - - if (parport < 0) - parport = DEFAULT_PARPORT; + int selected_keypad_type = NOT_SET; /* take care of an eventual profile */ switch (profile) { case PANEL_PROFILE_CUSTOM: /* custom profile */ - if (keypad_type < 0) - keypad_type = DEFAULT_KEYPAD; - if (lcd_type < 0) - lcd_type = DEFAULT_LCD; + selected_keypad_type = DEFAULT_KEYPAD_TYPE; + selected_lcd_type = DEFAULT_LCD_TYPE; break; case PANEL_PROFILE_OLD: /* 8 bits, 2*16, old keypad */ - if (keypad_type < 0) - keypad_type = KEYPAD_TYPE_OLD; - if (lcd_type < 0) - lcd_type = LCD_TYPE_OLD; - if (lcd_width < 0) + selected_keypad_type = KEYPAD_TYPE_OLD; + selected_lcd_type = LCD_TYPE_OLD; + + /* TODO: This two are a little hacky, sort it out later */ + if (lcd_width == NOT_SET) lcd_width = 16; - if (lcd_hwidth < 0) + if (lcd_hwidth == NOT_SET) lcd_hwidth = 16; break; case PANEL_PROFILE_NEW: /* serial, 2*16, new keypad */ - if (keypad_type < 0) - keypad_type = KEYPAD_TYPE_NEW; - if (lcd_type < 0) - lcd_type = LCD_TYPE_KS0074; + selected_keypad_type = KEYPAD_TYPE_NEW; + selected_lcd_type = LCD_TYPE_KS0074; break; case PANEL_PROFILE_HANTRONIX: /* 8 bits, 2*16 hantronix-like, no keypad */ - if (keypad_type < 0) - keypad_type = KEYPAD_TYPE_NONE; - if (lcd_type < 0) - lcd_type = LCD_TYPE_HANTRONIX; + selected_keypad_type = KEYPAD_TYPE_NONE; + selected_lcd_type = LCD_TYPE_HANTRONIX; break; case PANEL_PROFILE_NEXCOM: /* generic 8 bits, 2*16, nexcom keypad, eg. Nexcom. */ - if (keypad_type < 0) - keypad_type = KEYPAD_TYPE_NEXCOM; - if (lcd_type < 0) - lcd_type = LCD_TYPE_NEXCOM; + selected_keypad_type = KEYPAD_TYPE_NEXCOM; + selected_lcd_type = LCD_TYPE_NEXCOM; break; case PANEL_PROFILE_LARGE: /* 8 bits, 2*40, old keypad */ - if (keypad_type < 0) - keypad_type = KEYPAD_TYPE_OLD; - if (lcd_type < 0) - lcd_type = LCD_TYPE_OLD; + selected_keypad_type = KEYPAD_TYPE_OLD; + selected_lcd_type = LCD_TYPE_OLD; break; } - lcd_enabled = (lcd_type > 0); - keypad_enabled = (keypad_type > 0); + /* + * Init lcd struct with load-time values to preserve exact current + * functionality (at least for now). + */ + lcd.height = lcd_height; + lcd.width = lcd_width; + lcd.bwidth = lcd_bwidth; + lcd.hwidth = lcd_hwidth; + lcd.charset = lcd_charset; + lcd.proto = lcd_proto; + lcd.pins.e = lcd_e_pin; + lcd.pins.rs = lcd_rs_pin; + lcd.pins.rw = lcd_rw_pin; + lcd.pins.cl = lcd_cl_pin; + lcd.pins.da = lcd_da_pin; + lcd.pins.bl = lcd_bl_pin; + + /* Leave it for now, just in case */ + lcd.esc_seq.len = -1; + + /* + * Overwrite selection with module param values (both keypad and lcd), + * where the deprecated params have lower prio. + */ + if (keypad_enabled != NOT_SET) + selected_keypad_type = keypad_enabled; + if (keypad_type != NOT_SET) + selected_keypad_type = keypad_type; - switch (keypad_type) { + keypad.enabled = (selected_keypad_type > 0); + + if (lcd_enabled != NOT_SET) + selected_lcd_type = lcd_enabled; + if (lcd_type != NOT_SET) + selected_lcd_type = lcd_type; + + lcd.enabled = (selected_lcd_type > 0); + + switch (selected_keypad_type) { case KEYPAD_TYPE_OLD: keypad_profile = old_keypad_profile; break; @@ -2306,7 +2354,7 @@ static int panel_init(void) return -EIO; } - if (!lcd_enabled && !keypad_enabled) { + if (!lcd.enabled && !keypad.enabled) { /* no device enabled, let's release the parport */ if (pprt) { parport_release(pprt); @@ -2333,11 +2381,6 @@ static int panel_init(void) return 0; } -static int __init panel_init_module(void) -{ - return panel_init(); -} - static void __exit panel_cleanup_module(void) { unregister_reboot_notifier(&panel_notifier); @@ -2346,16 +2389,16 @@ static void __exit panel_cleanup_module(void) del_timer_sync(&scan_timer); if (pprt != NULL) { - if (keypad_enabled) { + if (keypad.enabled) { misc_deregister(&keypad_dev); keypad_initialized = 0; } - if (lcd_enabled) { + if (lcd.enabled) { panel_lcd_print("\x0cLCD driver " PANEL_VERSION "\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-"); misc_deregister(&lcd_dev); - lcd_initialized = 0; + lcd.initialized = false; } /* TODO: free all input signals */ diff --git a/drivers/staging/rtl8188eu/core/rtw_ap.c b/drivers/staging/rtl8188eu/core/rtw_ap.c index 9224e029ef2b..d61842ed673e 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ap.c +++ b/drivers/staging/rtl8188eu/core/rtw_ap.c @@ -888,7 +888,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) pbss_network->Rssi = 0; - memcpy(pbss_network->MacAddress, myid(&(padapter->eeprompriv)), ETH_ALEN); + ether_addr_copy(pbss_network->MacAddress, myid(&(padapter->eeprompriv))); /* beacon interval */ p = rtw_get_beacon_interval_from_ie(ie);/* 8: TimeStamp, 2: Beacon Interval 2:Capability */ @@ -1164,7 +1164,7 @@ int rtw_acl_add_sta(struct adapter *padapter, u8 *addr) if (!paclnode->valid) { INIT_LIST_HEAD(&paclnode->list); - memcpy(paclnode->addr, addr, ETH_ALEN); + ether_addr_copy(paclnode->addr, addr); paclnode->valid = true; @@ -1186,7 +1186,6 @@ int rtw_acl_add_sta(struct adapter *padapter, u8 *addr) int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr) { struct list_head *plist, *phead; - int ret = 0; struct rtw_wlan_acl_node *paclnode; struct sta_priv *pstapriv = &padapter->stapriv; struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; @@ -1217,7 +1216,7 @@ int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr) spin_unlock_bh(&(pacl_node_q->lock)); DBG_88E("%s, acl_num =%d\n", __func__, pacl_list->num); - return ret; + return 0; } static void update_bcn_fixed_ie(struct adapter *padapter) @@ -1753,7 +1752,6 @@ u8 ap_free_sta(struct adapter *padapter, struct sta_info *psta, int rtw_ap_inform_ch_switch(struct adapter *padapter, u8 new_ch, u8 ch_offset) { struct list_head *phead, *plist; - int ret = 0; struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; @@ -1761,7 +1759,7 @@ int rtw_ap_inform_ch_switch(struct adapter *padapter, u8 new_ch, u8 ch_offset) u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) - return ret; + return 0; DBG_88E(FUNC_NDEV_FMT" with ch:%u, offset:%u\n", FUNC_NDEV_ARG(padapter->pnetdev), new_ch, ch_offset); @@ -1782,13 +1780,12 @@ int rtw_ap_inform_ch_switch(struct adapter *padapter, u8 new_ch, u8 ch_offset) issue_action_spct_ch_switch(padapter, bc_addr, new_ch, ch_offset); - return ret; + return 0; } int rtw_sta_flush(struct adapter *padapter) { struct list_head *phead, *plist; - int ret = 0; struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; @@ -1798,7 +1795,7 @@ int rtw_sta_flush(struct adapter *padapter) DBG_88E(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev)); if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) - return ret; + return 0; spin_lock_bh(&pstapriv->asoc_list_lock); phead = &pstapriv->asoc_list; @@ -1822,7 +1819,7 @@ int rtw_sta_flush(struct adapter *padapter) associated_clients_update(padapter, true); - return ret; + return 0; } /* called > TSR LEVEL for USB or SDIO Interface*/ diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c index eddef9cd2e16..4b4346244953 100644 --- a/drivers/staging/rtl8188eu/core/rtw_cmd.c +++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c @@ -167,7 +167,7 @@ int rtw_cmd_thread(void *context) struct cmd_obj *pcmd; u8 (*cmd_hdl)(struct adapter *padapter, u8 *pbuf); void (*pcmd_callback)(struct adapter *dev, struct cmd_obj *pcmd); - struct adapter *padapter = (struct adapter *)context; + struct adapter *padapter = context; struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); allow_signal(SIGTERM); @@ -433,8 +433,7 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) psecnetwork = (struct wlan_bssid_ex *)&psecuritypriv->sec_bss; if (psecnetwork == NULL) { - if (pcmd != NULL) - kfree(pcmd); + kfree(pcmd); res = _FAIL; @@ -456,7 +455,7 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) psecnetwork->IELength = 0; /* Added by Albert 2009/02/18 */ - /* If the the driver wants to use the bssid to create the connection. */ + /* If the driver wants to use the bssid to create the connection. */ /* If not, we have to copy the connecting AP's MAC address to it so that */ /* the driver just has the bssid information for PMKIDList searching. */ @@ -638,7 +637,7 @@ u8 rtw_setstakey_cmd(struct adapter *padapter, u8 *psta, u8 unicast_key) ether_addr_copy(psetstakey_para->addr, sta->hwaddr); if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) - psetstakey_para->algorithm = (unsigned char) psecuritypriv->dot11PrivacyAlgrthm; + psetstakey_para->algorithm = (unsigned char)psecuritypriv->dot11PrivacyAlgrthm; else GET_ENCRY_ALGO(psecuritypriv, sta, psetstakey_para->algorithm, false); diff --git a/drivers/staging/rtl8188eu/core/rtw_debug.c b/drivers/staging/rtl8188eu/core/rtw_debug.c index 1f72f7d8097e..bc3fe10ff247 100644 --- a/drivers/staging/rtl8188eu/core/rtw_debug.c +++ b/drivers/staging/rtl8188eu/core/rtw_debug.c @@ -45,7 +45,7 @@ int proc_get_write_reg(char *page, char **start, int proc_set_write_reg(struct file *file, const char __user *buffer, unsigned long count, void *data) { - struct net_device *dev = (struct net_device *)data; + struct net_device *dev = data; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); char tmp[32]; u32 addr, val, len; @@ -577,7 +577,7 @@ int proc_get_rx_signal(char *page, char **start, int proc_set_rx_signal(struct file *file, const char __user *buffer, unsigned long count, void *data) { - struct net_device *dev = (struct net_device *)data; + struct net_device *dev = data; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); char tmp[32]; u32 is_signal_dbg; @@ -627,7 +627,7 @@ int proc_get_ht_enable(char *page, char **start, int proc_set_ht_enable(struct file *file, const char __user *buffer, unsigned long count, void *data) { - struct net_device *dev = (struct net_device *)data; + struct net_device *dev = data; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); struct registry_priv *pregpriv = &padapter->registrypriv; char tmp[32]; @@ -669,7 +669,7 @@ int proc_get_cbw40_enable(char *page, char **start, int proc_set_cbw40_enable(struct file *file, const char __user *buffer, unsigned long count, void *data) { - struct net_device *dev = (struct net_device *)data; + struct net_device *dev = data; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); struct registry_priv *pregpriv = &padapter->registrypriv; char tmp[32]; @@ -710,7 +710,7 @@ int proc_get_ampdu_enable(char *page, char **start, int proc_set_ampdu_enable(struct file *file, const char __user *buffer, unsigned long count, void *data) { - struct net_device *dev = (struct net_device *)data; + struct net_device *dev = data; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); struct registry_priv *pregpriv = &padapter->registrypriv; char tmp[32]; @@ -771,7 +771,7 @@ int proc_get_rx_stbc(char *page, char **start, int proc_set_rx_stbc(struct file *file, const char __user *buffer, unsigned long count, void *data) { - struct net_device *dev = (struct net_device *)data; + struct net_device *dev = data; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); struct registry_priv *pregpriv = &padapter->registrypriv; char tmp[32]; @@ -800,7 +800,7 @@ int proc_get_rssi_disp(char *page, char **start, int proc_set_rssi_disp(struct file *file, const char __user *buffer, unsigned long count, void *data) { - struct net_device *dev = (struct net_device *)data; + struct net_device *dev = data; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); char tmp[32]; u32 enable = 0; diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c b/drivers/staging/rtl8188eu/core/rtw_efuse.c index 7006088d1ad0..8816d116a8b8 100644 --- a/drivers/staging/rtl8188eu/core/rtw_efuse.c +++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c @@ -106,13 +106,13 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf) efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL); if (efuseTbl == NULL) { DBG_88E("%s: alloc efuseTbl fail!\n", __func__); - goto exit; + return; } eFuseWord = (u16 **)rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16)); if (eFuseWord == NULL) { DBG_88E("%s: alloc eFuseWord fail!\n", __func__); - goto exit; + goto eFuseWord_failed; } /* 0. Refresh efuse init map as all oxFF. */ @@ -210,10 +210,10 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf) /* */ exit: - kfree(efuseTbl); + kfree(eFuseWord); - if (eFuseWord) - kfree(eFuseWord); +eFuseWord_failed: + kfree(efuseTbl); } static void efuse_read_phymap_from_txpktbuf( @@ -250,7 +250,7 @@ static void efuse_read_phymap_from_txpktbuf( while (!(reg_0x143 = usb_read8(adapter, REG_TXPKTBUF_DBG)) && (passing_time = rtw_get_passing_time_ms(start)) < 1000) { DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n", __func__, reg_0x143, usb_read8(adapter, 0x106)); - msleep(1); + usleep_range(1000, 2000); } lo32 = usb_read32(adapter, REG_PKTBUF_DBG_DATA_L); @@ -322,7 +322,6 @@ void efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _si iol_read_efuse(Adapter, 0, _offset, _size_byte, pbuf); iol_mode_enable(Adapter, 0); } - return; } /* Do not support BT */ @@ -332,56 +331,56 @@ void EFUSE_GetEfuseDefinition(struct adapter *pAdapter, u8 efuseType, u8 type, v case TYPE_EFUSE_MAX_SECTION: { u8 *pMax_section; - pMax_section = (u8 *)pOut; + pMax_section = pOut; *pMax_section = EFUSE_MAX_SECTION_88E; } break; case TYPE_EFUSE_REAL_CONTENT_LEN: { u16 *pu2Tmp; - pu2Tmp = (u16 *)pOut; + pu2Tmp = pOut; *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E; } break; case TYPE_EFUSE_CONTENT_LEN_BANK: { u16 *pu2Tmp; - pu2Tmp = (u16 *)pOut; + pu2Tmp = pOut; *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E; } break; case TYPE_AVAILABLE_EFUSE_BYTES_BANK: { u16 *pu2Tmp; - pu2Tmp = (u16 *)pOut; + pu2Tmp = pOut; *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E); } break; case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL: { u16 *pu2Tmp; - pu2Tmp = (u16 *)pOut; + pu2Tmp = pOut; *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E); } break; case TYPE_EFUSE_MAP_LEN: { u16 *pu2Tmp; - pu2Tmp = (u16 *)pOut; + pu2Tmp = pOut; *pu2Tmp = (u16)EFUSE_MAP_LEN_88E; } break; case TYPE_EFUSE_PROTECT_BYTES_BANK: { u8 *pu1Tmp; - pu1Tmp = (u8 *)pOut; + pu1Tmp = pOut; *pu1Tmp = (u8)(EFUSE_OOB_PROTECT_BYTES_88E); } break; default: { u8 *pu1Tmp; - pu1Tmp = (u8 *)pOut; + pu1Tmp = pOut; *pu1Tmp = 0; } break; @@ -638,10 +637,9 @@ static bool hal_EfusePgPacketWrite2ByteHeader(struct adapter *pAdapter, u8 efuse if ((tmp_header & 0x0F) == 0x0F) { /* word_en PG fail */ if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) { return false; - } else { - efuse_addr++; - continue; } + efuse_addr++; + continue; } else if (pg_header != tmp_header) { /* offset PG fail */ struct pgpkt fixPkt; fixPkt.offset = ((pg_header_temp & 0xE0) >> 5) | ((tmp_header & 0xF0) >> 1); @@ -708,14 +706,13 @@ static bool hal_EfusePgPacketWriteData(struct adapter *pAdapter, u8 efuseType, u if (badworden == 0x0F) { /* write ok */ return true; - } else { - /* reorganize other pg packet */ - PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data); - if (!PgWriteSuccess) - return false; - else - return true; } + /* reorganize other pg packet */ + PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data); + if (!PgWriteSuccess) + return false; + else + return true; } static bool diff --git a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c index 755d3effd0a7..f2c3ca79c0c9 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c +++ b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c @@ -159,7 +159,7 @@ u8 *rtw_set_ie return pbuf + len + 2; } -inline u8 *rtw_set_ie_ch_switch (u8 *buf, u32 *buf_len, u8 ch_switch_mode, +inline u8 *rtw_set_ie_ch_switch(u8 *buf, u32 *buf_len, u8 ch_switch_mode, u8 new_ch, u8 ch_switch_cnt) { u8 ie_data[3]; @@ -870,7 +870,7 @@ static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, if (elen < 4) { if (show_errors) { DBG_88E("short vendor specific information element ignored (len=%lu)\n", - (unsigned long) elen); + (unsigned long)elen); } return -1; } @@ -890,7 +890,7 @@ static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, case WME_OUI_TYPE: /* this is a Wi-Fi WME info. element */ if (elen < 5) { DBG_88E("short WME information element ignored (len=%lu)\n", - (unsigned long) elen); + (unsigned long)elen); return -1; } switch (pos[4]) { @@ -905,7 +905,7 @@ static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, break; default: DBG_88E("unknown WME information element ignored (subtype=%d len=%lu)\n", - pos[4], (unsigned long) elen); + pos[4], (unsigned long)elen); return -1; } break; @@ -916,7 +916,7 @@ static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, break; default: DBG_88E("Unknown Microsoft information element ignored (type=%d len=%lu)\n", - pos[3], (unsigned long) elen); + pos[3], (unsigned long)elen); return -1; } break; @@ -929,13 +929,13 @@ static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, break; default: DBG_88E("Unknown Broadcom information element ignored (type=%d len=%lu)\n", - pos[3], (unsigned long) elen); + pos[3], (unsigned long)elen); return -1; } break; default: DBG_88E("unknown vendor specific information element ignored (vendor OUI %02x:%02x:%02x len=%lu)\n", - pos[0], pos[1], pos[2], (unsigned long) elen); + pos[0], pos[1], pos[2], (unsigned long)elen); return -1; } return 0; @@ -969,7 +969,7 @@ enum parse_res rtw_ieee802_11_parse_elems(u8 *start, uint len, if (elen > left) { if (show_errors) { DBG_88E("IEEE 802.11 element parse failed (id=%d elen=%d left=%lu)\n", - id, elen, (unsigned long) left); + id, elen, (unsigned long)left); } return ParseFailed; } diff --git a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c index fc280ce57d2c..2faf6b2e8129 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c @@ -98,7 +98,6 @@ u8 rtw_do_join(struct adapter *padapter) pibss = padapter->registrypriv.dev_network.MacAddress; - memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid)); memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); rtw_update_registrypriv_dev_network(padapter); diff --git a/drivers/staging/rtl8188eu/core/rtw_led.c b/drivers/staging/rtl8188eu/core/rtw_led.c index 384be22052e5..1b8264b978da 100644 --- a/drivers/staging/rtl8188eu/core/rtw_led.c +++ b/drivers/staging/rtl8188eu/core/rtw_led.c @@ -11,10 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * ******************************************************************************/ @@ -28,7 +24,7 @@ /* */ void BlinkTimerCallback(void *data) { - struct LED_871x *pLed = (struct LED_871x *)data; + struct LED_871x *pLed = data; struct adapter *padapter = pLed->padapter; if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped)) @@ -228,7 +224,8 @@ static void SwLedBlink1(struct LED_871x *pLed) pLed->bLedWPSBlinkInProgress = false; } else { pLed->BlinkingLedState = RTW_LED_OFF; - _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); + _set_timer(&(pLed->BlinkTimer), + LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA); } break; default: @@ -392,7 +389,8 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct pLed->CurrLedState = LED_BLINK_WPS_STOP; if (pLed->bLedOn) { pLed->BlinkingLedState = RTW_LED_OFF; - _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); + _set_timer(&(pLed->BlinkTimer), + LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA); } else { pLed->BlinkingLedState = RTW_LED_ON; _set_timer(&(pLed->BlinkTimer), 0); diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c b/drivers/staging/rtl8188eu/core/rtw_mlme.c index 149c271e966d..d4632da50c1d 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c @@ -674,7 +674,6 @@ void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf) RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("switching to adhoc master\n")); - memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid)); memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); rtw_update_registrypriv_dev_network(adapter); @@ -1334,7 +1333,6 @@ void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf) memcpy(pdev_network, &tgt_network->network, get_wlan_bssid_ex_sz(&tgt_network->network)); - memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid)); memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); rtw_update_registrypriv_dev_network(adapter); @@ -1364,7 +1362,7 @@ void rtw_cpwm_event_callback(struct adapter *padapter, u8 *pbuf) */ void _rtw_join_timeout_handler (void *function_context) { - struct adapter *adapter = (struct adapter *)function_context; + struct adapter *adapter = function_context; struct mlme_priv *pmlmepriv = &adapter->mlmepriv; int do_join_r; @@ -1406,7 +1404,7 @@ void _rtw_join_timeout_handler (void *function_context) */ void rtw_scan_timeout_handler (void *function_context) { - struct adapter *adapter = (struct adapter *)function_context; + struct adapter *adapter = function_context; struct mlme_priv *pmlmepriv = &adapter->mlmepriv; DBG_88E(FUNC_ADPT_FMT" fw_state=%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv)); @@ -1437,7 +1435,7 @@ void rtw_dynamic_check_timer_handlder(void *function_context) struct registry_priv *pregistrypriv = &adapter->registrypriv; if (!adapter) - goto exit; + return; if (!adapter->hw_init_completed) goto exit; if ((adapter->bDriverStopped) || (adapter->bSurpriseRemoved)) @@ -2117,7 +2115,7 @@ void rtw_issue_addbareq_cmd(struct adapter *padapter, struct xmit_frame *pxmitfr if (0 == issued) { DBG_88E("rtw_issue_addbareq_cmd, p=%d\n", priority); psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority); - rtw_addbareq_cmd(padapter, (u8) priority, pattrib->ra); + rtw_addbareq_cmd(padapter, (u8)priority, pattrib->ra); } } } diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index 70b1bc3e0e63..e4b7ee4c99d5 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -227,7 +227,7 @@ static void init_mlme_ext_priv_value(struct adapter *padapter) pmlmeext->cur_channel = padapter->registrypriv.channel; pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - pmlmeext->oper_channel = pmlmeext->cur_channel ; + pmlmeext->oper_channel = pmlmeext->cur_channel; pmlmeext->oper_bwmode = pmlmeext->cur_bwmode; pmlmeext->oper_ch_offset = pmlmeext->cur_ch_offset; pmlmeext->retry = 0; @@ -371,7 +371,6 @@ static u8 init_channel_set(struct adapter *padapter, u8 ChannelPlan, struct rt_c int init_mlme_ext_priv(struct adapter *padapter) { - int res = _SUCCESS; struct registry_priv *pregistrypriv = &padapter->registrypriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); @@ -397,7 +396,7 @@ int init_mlme_ext_priv(struct adapter *padapter) pmlmeext->active_keep_alive_check = true; - return res; + return _SUCCESS; } void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext) @@ -945,7 +944,7 @@ unsigned int OnAssocReq(struct adapter *padapter, struct recv_frame *precv_frame } pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); - if (pstat == (struct sta_info *)NULL) { + if (pstat == NULL) { status = _RSON_CLS2_; goto asoc_class2_error; } @@ -1554,7 +1553,6 @@ unsigned int OnAtim(struct adapter *padapter, struct recv_frame *precv_frame) unsigned int on_action_spct(struct adapter *padapter, struct recv_frame *precv_frame) { - unsigned int ret = _FAIL; struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; u8 *pframe = precv_frame->rx_data; @@ -1587,7 +1585,7 @@ unsigned int on_action_spct(struct adapter *padapter, struct recv_frame *precv_f } exit: - return ret; + return _FAIL; } unsigned int OnAction_qos(struct adapter *padapter, struct recv_frame *precv_frame) @@ -2000,7 +1998,7 @@ void issue_beacon(struct adapter *padapter, int timeout_ms) DBG_88E("%s, alloc mgnt frame fail\n", __func__); return; } -#if defined (CONFIG_88EU_AP_MODE) +#if defined(CONFIG_88EU_AP_MODE) spin_lock_bh(&pmlmepriv->bcn_update_lock); #endif /* if defined (CONFIG_88EU_AP_MODE) */ @@ -2027,7 +2025,7 @@ void issue_beacon(struct adapter *padapter, int timeout_ms) SetFrameSubType(pframe, WIFI_BEACON); pframe += sizeof(struct rtw_ieee80211_hdr_3addr); - pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) { int len_diff; @@ -2042,8 +2040,8 @@ void issue_beacon(struct adapter *padapter, int timeout_ms) ); pframe += (cur_network->IELength+len_diff); pattrib->pktlen += (cur_network->IELength+len_diff); - wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof (struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_, - pattrib->pktlen-sizeof (struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen); + wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_, + pattrib->pktlen-sizeof(struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen); if (wps_ie && wps_ielen > 0) rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL); if (sr != 0) @@ -2101,7 +2099,7 @@ void issue_beacon(struct adapter *padapter, int timeout_ms) /* todo:HT for adhoc */ _issue_bcn: -#if defined (CONFIG_88EU_AP_MODE) +#if defined(CONFIG_88EU_AP_MODE) pmlmepriv->update_bcn = false; spin_unlock_bh(&pmlmepriv->bcn_update_lock); @@ -2130,7 +2128,7 @@ void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p __le16 *fctrl; unsigned char *mac, *bssid; struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); -#if defined (CONFIG_88EU_AP_MODE) +#if defined(CONFIG_88EU_AP_MODE) u8 *pwps_ie; uint wps_ielen; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -2323,8 +2321,8 @@ static int _issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *ps pmlmeext->mgnt_seq++; SetFrameSubType(pframe, WIFI_PROBEREQ); - pframe += sizeof (struct rtw_ieee80211_hdr_3addr); - pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr); + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); if (pssid) pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen)); @@ -3209,7 +3207,7 @@ exit: return ret; } -void issue_action_spct_ch_switch (struct adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset) +void issue_action_spct_ch_switch(struct adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset) { struct xmit_frame *pmgntframe; struct pkt_attrib *pattrib; @@ -3260,7 +3258,7 @@ void issue_action_spct_ch_switch (struct adapter *padapter, u8 *ra, u8 new_ch, u pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen)); } - pframe = rtw_set_ie_ch_switch (pframe, &(pattrib->pktlen), 0, new_ch, 0); + pframe = rtw_set_ie_ch_switch(pframe, &(pattrib->pktlen), 0, new_ch, 0); pframe = rtw_set_ie_secondary_ch_offset(pframe, &(pattrib->pktlen), hal_ch_offset_to_secondary_ch_offset(ch_offset)); @@ -4835,7 +4833,7 @@ void linked_status_chk(struct adapter *padapter) void survey_timer_hdl(void *function_context) { - struct adapter *padapter = (struct adapter *)function_context; + struct adapter *padapter = function_context; struct cmd_obj *ph2c; struct sitesurvey_parm *psurveyPara; struct cmd_priv *pcmdpriv = &padapter->cmdpriv; @@ -4912,7 +4910,7 @@ void link_timer_hdl(void *function_context) void addba_timer_hdl(void *function_context) { - struct sta_info *psta = (struct sta_info *)function_context; + struct sta_info *psta = function_context; struct ht_priv *phtpriv; if (!psta) diff --git a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c index 27ed83cca193..df463a29b641 100644 --- a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c @@ -279,12 +279,11 @@ void rtw_ps_processor(struct adapter *padapter) exit: rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv); pwrpriv->ps_processing = false; - return; } static void pwr_state_check_handler(void *FunctionContext) { - struct adapter *padapter = (struct adapter *)FunctionContext; + struct adapter *padapter = FunctionContext; rtw_ps_cmd(padapter); } @@ -527,7 +526,7 @@ void rtw_init_pwrctrl_priv(struct adapter *padapter) pwrctrlpriv->LpsIdleCount = 0; if (padapter->registrypriv.mp_mode == 1) - pwrctrlpriv->power_mgnt = PS_MODE_ACTIVE ; + pwrctrlpriv->power_mgnt = PS_MODE_ACTIVE; else pwrctrlpriv->power_mgnt = padapter->registrypriv.power_mgnt;/* PS_MODE_MIN; */ pwrctrlpriv->bLeisurePs = (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt) ? true : false; @@ -577,7 +576,7 @@ int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *cal if (pwrpriv->ps_processing) { DBG_88E("%s wait ps_processing...\n", __func__); while (pwrpriv->ps_processing && rtw_get_passing_time_ms(start) <= 3000) - msleep(10); + usleep_range(1000, 3000); if (pwrpriv->ps_processing) DBG_88E("%s wait ps_processing timeout\n", __func__); else diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c b/drivers/staging/rtl8188eu/core/rtw_recv.c index 4d56dbad2a7d..bd79e9e7105a 100644 --- a/drivers/staging/rtl8188eu/core/rtw_recv.c +++ b/drivers/staging/rtl8188eu/core/rtw_recv.c @@ -46,7 +46,7 @@ void rtw_signal_stat_timer_hdl(RTW_TIMER_HDL_ARGS); void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv) { - memset((u8 *)psta_recvpriv, 0, sizeof (struct sta_recv_priv)); + memset((u8 *)psta_recvpriv, 0, sizeof(struct sta_recv_priv)); spin_lock_init(&psta_recvpriv->lock); @@ -109,7 +109,7 @@ exit: return res; } -void _rtw_free_recv_priv (struct recv_priv *precvpriv) +void _rtw_free_recv_priv(struct recv_priv *precvpriv) { struct adapter *padapter = precvpriv->adapter; @@ -124,7 +124,7 @@ void _rtw_free_recv_priv (struct recv_priv *precvpriv) } -struct recv_frame *_rtw_alloc_recvframe (struct __queue *pfree_recv_queue) +struct recv_frame *_rtw_alloc_recvframe(struct __queue *pfree_recv_queue) { struct recv_frame *hdr; struct list_head *plist, *phead; @@ -797,7 +797,7 @@ exit: return ret; } -static int ap2sta_data_frame ( +static int ap2sta_data_frame( struct adapter *adapter, struct recv_frame *precv_frame, struct sta_info **psta) @@ -1266,7 +1266,7 @@ static int validate_recv_frame(struct adapter *adapter, u8 bDumpRxPkt; struct rx_pkt_attrib *pattrib = &precv_frame->attrib; u8 *ptr = precv_frame->rx_data; - u8 ver = (unsigned char) (*ptr)&0x3; + u8 ver = (unsigned char)(*ptr)&0x3; struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; @@ -1373,7 +1373,6 @@ static int wlanhdr_to_ethhdr(struct recv_frame *precvframe) u8 *psnap_type; struct ieee80211_snap_hdr *psnap; - int ret = _SUCCESS; struct adapter *adapter = precvframe->adapter; struct mlme_priv *pmlmepriv = &adapter->mlmepriv; u8 *ptr = precvframe->rx_data; @@ -1428,7 +1427,7 @@ static int wlanhdr_to_ethhdr(struct recv_frame *precvframe) memcpy(ptr+12, &be_tmp, 2); } - return ret; + return _SUCCESS; } /* perform defrag */ @@ -1624,7 +1623,6 @@ static int amsdu_to_msdu(struct adapter *padapter, struct recv_frame *prframe) struct sk_buff *sub_skb, *subframes[MAX_SUBFRAME_COUNT]; struct recv_priv *precvpriv = &padapter->recvpriv; struct __queue *pfree_recv_queue = &(precvpriv->free_recv_queue); - int ret = _SUCCESS; nr_subframes = 0; pattrib = &prframe->attrib; @@ -1728,7 +1726,7 @@ exit: prframe->len = 0; rtw_free_recvframe(prframe, pfree_recv_queue);/* free this recv_frame */ - return ret; + return _SUCCESS; } static int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num) @@ -1949,7 +1947,7 @@ _err_exit: void rtw_reordering_ctrl_timeout_handler(void *pcontext) { - struct recv_reorder_ctrl *preorder_ctrl = (struct recv_reorder_ctrl *)pcontext; + struct recv_reorder_ctrl *preorder_ctrl = pcontext; struct adapter *padapter = preorder_ctrl->padapter; struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; @@ -1981,7 +1979,7 @@ static int process_recv_indicatepkts(struct adapter *padapter, } } } else { /* B/G mode */ - retval = wlanhdr_to_ethhdr (prframe); + retval = wlanhdr_to_ethhdr(prframe); if (retval != _SUCCESS) { RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("wlanhdr_to_ethhdr: drop pkt\n")); return retval; diff --git a/drivers/staging/rtl8188eu/core/rtw_security.c b/drivers/staging/rtl8188eu/core/rtw_security.c index f9096a512da5..bd8d60a230e9 100644 --- a/drivers/staging/rtl8188eu/core/rtw_security.c +++ b/drivers/staging/rtl8188eu/core/rtw_security.c @@ -189,7 +189,7 @@ void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe) arcfour_encrypt(&mycontext, payload+length, crc, 4); pframe += pxmitpriv->frag_len; - pframe = (u8 *) round_up((size_t)(pframe), 4); + pframe = (u8 *)round_up((size_t)(pframe), 4); } } } @@ -258,7 +258,7 @@ static void secmicputuint32(u8 *p, u32 val) { long i; for (i = 0; i < 4; i++) { - *p++ = (u8) (val & 0xff); + *p++ = (u8)(val & 0xff); val >>= 8; } } @@ -621,14 +621,14 @@ u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe) arcfour_encrypt(&mycontext, payload, payload, length); arcfour_encrypt(&mycontext, payload+length, crc, 4); } else { - length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len ; + length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len; *((__le32 *)crc) = getcrc32(payload, length);/* modified by Amy*/ arcfour_init(&mycontext, rc4key, 16); arcfour_encrypt(&mycontext, payload, payload, length); arcfour_encrypt(&mycontext, payload+length, crc, 4); pframe += pxmitpriv->frag_len; - pframe = (u8 *) round_up((size_t)(pframe), 4); + pframe = (u8 *)round_up((size_t)(pframe), 4); } } } else { @@ -953,8 +953,8 @@ static void construct_mic_iv(u8 *mic_iv, int qc_exists, int a4_exists, u8 *mpdu, mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */ for (i = 8; i < 14; i++) mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */ - mic_iv[14] = (unsigned char) (payload_length / 256); - mic_iv[15] = (unsigned char) (payload_length % 256); + mic_iv[14] = (unsigned char)(payload_length / 256); + mic_iv[15] = (unsigned char)(payload_length % 256); } /************************************************/ @@ -1045,8 +1045,8 @@ static void construct_ctr_preload(u8 *ctr_preload, int a4_exists, int qc_exists, ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */ for (i = 8; i < 14; i++) ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */ - ctr_preload[14] = (unsigned char) (c / 256); /* Ctr */ - ctr_preload[15] = (unsigned char) (c % 256); + ctr_preload[14] = (unsigned char)(c / 256); /* Ctr */ + ctr_preload[15] = (unsigned char)(c % 256); } /************************************/ @@ -1219,7 +1219,7 @@ u32 rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe) pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset; /* 4 start to encrypt each fragment */ - if ((pattrib->encrypt == _AES_)) { + if (pattrib->encrypt == _AES_) { if (pattrib->psta) stainfo = pattrib->psta; else @@ -1238,11 +1238,11 @@ u32 rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe) aes_cipher(prwskey, pattrib->hdrlen, pframe, length); } else{ - length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len ; + length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len; aes_cipher(prwskey, pattrib->hdrlen, pframe, length); pframe += pxmitpriv->frag_len; - pframe = (u8 *) round_up((size_t)(pframe), 8); + pframe = (u8 *)round_up((size_t)(pframe), 8); } } } else{ @@ -1460,7 +1460,7 @@ u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe) u32 res = _SUCCESS; pframe = (unsigned char *)((struct recv_frame *)precvframe)->rx_data; /* 4 start to encrypt each fragment */ - if ((prxattrib->encrypt == _AES_)) { + if (prxattrib->encrypt == _AES_) { stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]); if (stainfo != NULL) { RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_decrypt: stainfo!= NULL!!!\n")); diff --git a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c index e1dc8fa82d38..dc9d0ddf6b3a 100644 --- a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c +++ b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c @@ -29,7 +29,7 @@ static void _rtw_init_stainfo(struct sta_info *psta) { - memset((u8 *)psta, 0, sizeof (struct sta_info)); + memset((u8 *)psta, 0, sizeof(struct sta_info)); spin_lock_init(&psta->lock); INIT_LIST_HEAD(&psta->list); diff --git a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c index d300369977fa..324c1a7fd0bc 100644 --- a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c @@ -1394,7 +1394,6 @@ unsigned char check_assoc_AP(u8 *pframe, uint len) DBG_88E("link to Artheros AP\n"); return HT_IOT_PEER_ATHEROS; } else if ((!memcmp(pIE->data, BROADCOM_OUI1, 3)) || - (!memcmp(pIE->data, BROADCOM_OUI2, 3)) || (!memcmp(pIE->data, BROADCOM_OUI2, 3))) { DBG_88E("link to Broadcom AP\n"); return HT_IOT_PEER_BROADCOM; diff --git a/drivers/staging/rtl8188eu/core/rtw_xmit.c b/drivers/staging/rtl8188eu/core/rtw_xmit.c index 639ace06a3d6..7a71df167464 100644 --- a/drivers/staging/rtl8188eu/core/rtw_xmit.c +++ b/drivers/staging/rtl8188eu/core/rtw_xmit.c @@ -37,7 +37,7 @@ static void _init_txservq(struct tx_servq *ptxservq) void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv) { - memset((unsigned char *)psta_xmitpriv, 0, sizeof (struct sta_xmit_priv)); + memset((unsigned char *)psta_xmitpriv, 0, sizeof(struct sta_xmit_priv)); spin_lock_init(&psta_xmitpriv->lock); _init_txservq(&psta_xmitpriv->be_q); _init_txservq(&psta_xmitpriv->bk_q); @@ -223,7 +223,7 @@ exit: return res; } -void _rtw_free_xmit_priv (struct xmit_priv *pxmitpriv) +void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv) { int i; struct adapter *padapter = pxmitpriv->adapter; @@ -691,7 +691,7 @@ static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitfr payload = pframe; for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { - payload = (u8 *) round_up((size_t)(payload), 4); + payload = (u8 *)round_up((size_t)(payload), 4); RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("=== curfragnum=%d, pframe = 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x,!!!\n", curfragnum, *payload, *(payload+1), @@ -772,7 +772,7 @@ static s32 xmitframe_swencrypt(struct adapter *padapter, struct xmit_frame *pxmi return _SUCCESS; } -s32 rtw_make_wlanhdr (struct adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib) +s32 rtw_make_wlanhdr(struct adapter *padapter, u8 *hdr, struct pkt_attrib *pattrib) { u16 *qc; @@ -1025,8 +1025,7 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct /* adding icv, if necessary... */ if (pattrib->iv_len) { - if (psta != NULL) { - switch (pattrib->encrypt) { + switch (pattrib->encrypt) { case _WEP40_: case _WEP104_: WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); @@ -1043,7 +1042,6 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct else AES_IV(pattrib->iv, psta->dot11txpn, 0); break; - } } memcpy(pframe, pattrib->iv, pattrib->iv_len); @@ -1098,7 +1096,7 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct addr = (size_t)(pframe); - mem_start = (unsigned char *) round_up(addr, 4) + hw_hdr_offset; + mem_start = (unsigned char *)round_up(addr, 4) + hw_hdr_offset; memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen); } diff --git a/drivers/staging/rtl8188eu/hal/bb_cfg.c b/drivers/staging/rtl8188eu/hal/bb_cfg.c index 80e8cc92c10a..1e963bf9e48b 100644 --- a/drivers/staging/rtl8188eu/hal/bb_cfg.c +++ b/drivers/staging/rtl8188eu/hal/bb_cfg.c @@ -173,7 +173,7 @@ static bool set_baseband_agc_config(struct adapter *adapt) u32 v1 = array[i]; u32 v2 = array[i+1]; - if (v1 < 0xCDCDCDCD){ + if (v1 < 0xCDCDCDCD) { phy_set_bb_reg(adapt, v1, bMaskDWord, v2); udelay(1); } @@ -552,7 +552,7 @@ static void store_pwrindex_offset(struct adapter *Adapter, u32 regaddr, u32 bitm } } -static void rtl_addr_delay(struct adapter *adapt, u32 addr, u32 bit_mask ,u32 data) +static void rtl_addr_delay(struct adapter *adapt, u32 addr, u32 bit_mask, u32 data) { if (addr == 0xfe) { msleep(50); diff --git a/drivers/staging/rtl8188eu/hal/fw.c b/drivers/staging/rtl8188eu/hal/fw.c index 17b7f3750547..3b2875481fc5 100644 --- a/drivers/staging/rtl8188eu/hal/fw.c +++ b/drivers/staging/rtl8188eu/hal/fw.c @@ -84,7 +84,7 @@ static void _rtl88e_fw_block_write(struct adapter *adapt, static void _rtl88e_fill_dummy(u8 *pfwbuf, u32 *pfwlen) { u32 fwlen = *pfwlen; - u8 remain = (u8) (fwlen % 4); + u8 remain = (u8)(fwlen % 4); remain = (remain == 0) ? 0 : (4 - remain); @@ -101,7 +101,7 @@ static void _rtl88e_fw_page_write(struct adapter *adapt, u32 page, const u8 *buffer, u32 size) { u8 value8; - u8 u8page = (u8) (page & 0x07); + u8 u8page = (u8)(page & 0x07); value8 = (usb_read8(adapt, REG_MCUFWDL + 2) & 0xF8) | u8page; @@ -193,13 +193,13 @@ int rtl88eu_download_fw(struct adapter *adapt) u32 fwsize; int err; - if (request_firmware(&fw, fw_name, device)){ + if (request_firmware(&fw, fw_name, device)) { dev_err(device, "Firmware %s not available\n", fw_name); return -ENOENT; } if (fw->size > FW_8188E_SIZE) { - dev_err(device,"Firmware size exceed 0x%X. Check it.\n", + dev_err(device, "Firmware size exceed 0x%X. Check it.\n", FW_8188E_SIZE); return -1; } diff --git a/drivers/staging/rtl8188eu/hal/hal_intf.c b/drivers/staging/rtl8188eu/hal/hal_intf.c index 538a0f65d09c..4bdbed28774e 100644 --- a/drivers/staging/rtl8188eu/hal/hal_intf.c +++ b/drivers/staging/rtl8188eu/hal/hal_intf.c @@ -275,13 +275,6 @@ void rtw_hal_write_rfreg(struct adapter *adapt, enum rf_radio_path rfpath, bitmask, data); } -s32 rtw_hal_interrupt_handler(struct adapter *adapt) -{ - if (adapt->HalFunc.interrupt_handler) - return adapt->HalFunc.interrupt_handler(adapt); - return _FAIL; -} - void rtw_hal_set_bwmode(struct adapter *adapt, enum ht_channel_width bandwidth, u8 offset) { @@ -329,15 +322,6 @@ void rtw_hal_sreset_init(struct adapter *adapt) adapt->HalFunc.sreset_init_value(adapt); } -u8 rtw_hal_sreset_get_wifi_status(struct adapter *adapt) -{ - u8 status = 0; - - if (adapt->HalFunc.sreset_get_wifi_status) - status = adapt->HalFunc.sreset_get_wifi_status(adapt); - return status; -} - void rtw_hal_notch_filter(struct adapter *adapter, bool enable) { if (adapter->HalFunc.hal_notch_filter) diff --git a/drivers/staging/rtl8188eu/hal/mac_cfg.c b/drivers/staging/rtl8188eu/hal/mac_cfg.c index c0e7fa938059..febc83a5adb8 100644 --- a/drivers/staging/rtl8188eu/hal/mac_cfg.c +++ b/drivers/staging/rtl8188eu/hal/mac_cfg.c @@ -127,7 +127,7 @@ bool rtl88eu_phy_mac_config(struct adapter *adapt) ptrarray = array_MAC_REG_8188E; for (i = 0; i < arraylength; i = i + 2) - usb_write8(adapt, ptrarray[i], (u8) ptrarray[i + 1]); + usb_write8(adapt, ptrarray[i], (u8)ptrarray[i + 1]); usb_write8(adapt, REG_MAX_AGGR_NUM, MAX_AGGR_NUM); return true; diff --git a/drivers/staging/rtl8188eu/hal/odm.c b/drivers/staging/rtl8188eu/hal/odm.c index e4df83710ca6..9873998011d2 100644 --- a/drivers/staging/rtl8188eu/hal/odm.c +++ b/drivers/staging/rtl8188eu/hal/odm.c @@ -437,8 +437,8 @@ void odm_CommonInfoSelfInit(struct odm_dm_struct *pDM_Odm) { struct adapter *adapter = pDM_Odm->Adapter; - pDM_Odm->bCckHighPower = (bool) phy_query_bb_reg(adapter, 0x824, BIT9); - pDM_Odm->RFPathRxEnable = (u8) phy_query_bb_reg(adapter, 0xc04, 0x0F); + pDM_Odm->bCckHighPower = (bool)phy_query_bb_reg(adapter, 0x824, BIT9); + pDM_Odm->RFPathRxEnable = (u8)phy_query_bb_reg(adapter, 0xc04, 0x0F); ODM_InitDebugSetting(pDM_Odm); } @@ -529,7 +529,7 @@ void odm_DIGInit(struct odm_dm_struct *pDM_Odm) struct adapter *adapter = pDM_Odm->Adapter; struct rtw_dig *pDM_DigTable = &pDM_Odm->DM_DigTable; - pDM_DigTable->CurIGValue = (u8) phy_query_bb_reg(adapter, ODM_REG_IGI_A_11N, ODM_BIT_IGI_11N); + pDM_DigTable->CurIGValue = (u8)phy_query_bb_reg(adapter, ODM_REG_IGI_A_11N, ODM_BIT_IGI_11N); pDM_DigTable->RssiLowThresh = DM_DIG_THRESH_LOW; pDM_DigTable->RssiHighThresh = DM_DIG_THRESH_HIGH; pDM_DigTable->FALowThresh = DM_false_ALARM_THRESH_LOW; @@ -620,7 +620,7 @@ void odm_DIG(struct odm_dm_struct *pDM_Odm) } else if (pDM_Odm->SupportAbility & ODM_BB_ANT_DIV) { /* 1 Lower Bound for 88E AntDiv */ if (pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV) { - DIG_Dynamic_MIN = (u8) pDM_DigTable->AntDiv_RSSI_max; + DIG_Dynamic_MIN = (u8)pDM_DigTable->AntDiv_RSSI_max; ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_DIG(): pDM_DigTable->AntDiv_RSSI_max=%d\n", pDM_DigTable->AntDiv_RSSI_max)); diff --git a/drivers/staging/rtl8188eu/hal/odm_HWConfig.c b/drivers/staging/rtl8188eu/hal/odm_HWConfig.c index 4e4e21936e7c..29f87dffbad3 100644 --- a/drivers/staging/rtl8188eu/hal/odm_HWConfig.c +++ b/drivers/staging/rtl8188eu/hal/odm_HWConfig.c @@ -118,7 +118,7 @@ static void odm_RxPhyStatus92CSeries_Parsing(struct odm_dm_struct *dm_odm, cck_highpwr = dm_odm->bCckHighPower; - cck_agc_rpt = pPhyStaRpt->cck_agc_rpt_ofdm_cfosho_a ; + cck_agc_rpt = pPhyStaRpt->cck_agc_rpt_ofdm_cfosho_a; /* 2011.11.28 LukeLee: 88E use different LNA & VGA gain table */ /* The RSSI formula should be modified according to the gain table */ diff --git a/drivers/staging/rtl8188eu/hal/odm_RTL8188E.c b/drivers/staging/rtl8188eu/hal/odm_RTL8188E.c index 5342af778eb0..d3c6873925ba 100644 --- a/drivers/staging/rtl8188eu/hal/odm_RTL8188E.c +++ b/drivers/staging/rtl8188eu/hal/odm_RTL8188E.c @@ -278,7 +278,7 @@ static void rtl88eu_dm_hw_ant_div(struct odm_dm_struct *dm_odm) struct rtw_dig *dig_table = &dm_odm->DM_DigTable; struct sta_info *entry; u32 i, min_rssi = 0xFF, ant_div_max_rssi = 0, max_rssi = 0; - u32 local_min_rssi,local_max_rssi; + u32 local_min_rssi, local_max_rssi; u32 main_rssi, aux_rssi; u8 RxIdleAnt = 0, target_ant = 7; diff --git a/drivers/staging/rtl8188eu/hal/phy.c b/drivers/staging/rtl8188eu/hal/phy.c index c4f7f358a81c..3f663fe151ba 100644 --- a/drivers/staging/rtl8188eu/hal/phy.c +++ b/drivers/staging/rtl8188eu/hal/phy.c @@ -478,7 +478,7 @@ void rtl88eu_dm_txpower_tracking_callback_thermalmeter(struct adapter *adapt) /* 2.4G, decrease power */ {0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11}, /* 2.4G, increase power */ - {0, 0, -1, -2, -3, -4,-4, -4, -4, -5, -7, -8,-9, -9, -10}, + {0, 0, -1, -2, -3, -4, -4, -4, -4, -5, -7, -8, -9, -9, -10}, }; u8 thermal_mapping[2][index_mapping_NUM_88E] = { /* 2.4G, decrease power */ diff --git a/drivers/staging/rtl8188eu/hal/rf.c b/drivers/staging/rtl8188eu/hal/rf.c index c2fac34c8132..eea4c8a6022b 100644 --- a/drivers/staging/rtl8188eu/hal/rf.c +++ b/drivers/staging/rtl8188eu/hal/rf.c @@ -131,7 +131,7 @@ void rtl88eu_phy_rf6052_set_cck_txpower(struct adapter *adapt, u8 *powerlevel) /* powerbase1 for HT MCS rates */ static void getpowerbase88e(struct adapter *adapt, u8 *pwr_level_ofdm, u8 *pwr_level_bw20, u8 *pwr_level_bw40, - u8 channel,u32 *ofdmbase, u32 *mcs_base) + u8 channel, u32 *ofdmbase, u32 *mcs_base) { struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); u32 powerbase0, powerbase1; diff --git a/drivers/staging/rtl8188eu/hal/rf_cfg.c b/drivers/staging/rtl8188eu/hal/rf_cfg.c index ddc2f55fe13f..5dc11cae2ef9 100644 --- a/drivers/staging/rtl8188eu/hal/rf_cfg.c +++ b/drivers/staging/rtl8188eu/hal/rf_cfg.c @@ -164,7 +164,7 @@ do { \ #define B3WIREDATALENGTH 0x800 #define BRFSI_RFENV 0x10 -static void rtl_rfreg_delay(struct adapter *adapt, enum rf_radio_path rfpath,u32 addr, u32 mask, u32 data) +static void rtl_rfreg_delay(struct adapter *adapt, enum rf_radio_path rfpath, u32 addr, u32 mask, u32 data) { if (addr == 0xfe) { mdelay(50); @@ -190,7 +190,7 @@ static void rtl8188e_config_rf_reg(struct adapter *adapt, u32 content = 0x1000; /*RF Content: radio_a_txt*/ u32 maskforphyset = (u32)(content & 0xE000); - rtl_rfreg_delay(adapt, RF90_PATH_A, addr| maskforphyset, + rtl_rfreg_delay(adapt, RF90_PATH_A, addr | maskforphyset, RFREG_OFFSET_MASK, data); } diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c index 023a3d84ee8b..7f30dea1b53b 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c @@ -150,11 +150,9 @@ u8 rtl8188e_set_raid_cmd(struct adapter *adapt, u32 mask) struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); if (haldata->fw_ractrl) { - __le32 lmask; memset(buf, 0, 3); - lmask = cpu_to_le32(mask); - memcpy(buf, &lmask, 3); + put_unaligned_le32(mask, buf); FillH2CCmd_88E(adapt, H2C_DM_MACID_CFG, 3, buf); } else { @@ -254,7 +252,7 @@ void rtl8188e_set_FwMediaStatus_cmd(struct adapter *adapt, __le16 mstatus_rpt) { u8 opmode, macid; u16 mst_rpt = le16_to_cpu(mstatus_rpt); - opmode = (u8) mst_rpt; + opmode = (u8)mst_rpt; macid = (u8)(mst_rpt >> 8); DBG_88E("### %s: MStatus=%x MACID=%d\n", __func__, opmode, macid); diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c b/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c index dab4c337a863..01566210bbd2 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c @@ -155,6 +155,8 @@ void rtl8188e_HalDmWatchDog(struct adapter *Adapter) bool fw_ps_awake = true; u8 hw_init_completed = false; struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter); + struct mlme_priv *pmlmepriv = NULL; + u8 bLinked = false; hw_init_completed = Adapter->hw_init_completed; @@ -170,22 +172,20 @@ void rtl8188e_HalDmWatchDog(struct adapter *Adapter) fw_ps_awake = false; /* ODM */ - if (hw_init_completed) { - struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; - u8 bLinked = false; - - if ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) || - (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))) { - if (Adapter->stapriv.asoc_sta_count > 2) - bLinked = true; - } else {/* Station mode */ - if (check_fwstate(pmlmepriv, _FW_LINKED)) - bLinked = true; - } - - ODM_CmnInfoUpdate(&hal_data->odmpriv, ODM_CMNINFO_LINK, bLinked); - ODM_DMWatchdog(&hal_data->odmpriv); + pmlmepriv = &Adapter->mlmepriv; + + if ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | + WIFI_ADHOC_MASTER_STATE))) { + if (Adapter->stapriv.asoc_sta_count > 2) + bLinked = true; + } else {/* Station mode */ + if (check_fwstate(pmlmepriv, _FW_LINKED)) + bLinked = true; } + + ODM_CmnInfoUpdate(&hal_data->odmpriv, ODM_CMNINFO_LINK, bLinked); + ODM_DMWatchdog(&hal_data->odmpriv); skip_dm: /* Check GPIO to determine current RF on/off and Pbc status. */ /* Check Hardware Radio ON/OFF or not */ diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c index d6fe5e6aa4f4..7d460eaafa35 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c @@ -181,7 +181,8 @@ static void rtl8188e_SetHalODMVar(struct adapter *Adapter, enum hal_odm_variable switch (eVariable) { case HAL_ODM_STA_INFO: { - struct sta_info *psta = (struct sta_info *)pValue1; + struct sta_info *psta = pValue1; + if (bSet) { DBG_88E("### Set STA_(%d) info\n", psta->mac_id); ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, psta); diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c b/drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c index 7a4f754d86df..a6ba53b488e3 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c @@ -25,7 +25,7 @@ void dump_txrpt_ccx_88e(void *buf) { - struct txrpt_ccx_88e *txrpt_ccx = (struct txrpt_ccx_88e *)buf; + struct txrpt_ccx_88e *txrpt_ccx = buf; DBG_88E("%s:\n" "tag1:%u, pkt_num:%u, txdma_underflow:%u, int_bt:%u, int_tri:%u, int_ccx:%u\n" diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c index be9eede6931d..594c1da9db23 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c @@ -399,7 +399,7 @@ static s32 rtw_dump_xframe(struct adapter *adapt, struct xmit_frame *pxmitframe) mem_addr += w_sz; - mem_addr = (u8 *) round_up((size_t)mem_addr, 4); + mem_addr = (u8 *)round_up((size_t)mem_addr, 4); } rtw_free_xmitframe(pxmitpriv, pxmitframe); diff --git a/drivers/staging/rtl8188eu/hal/usb_halinit.c b/drivers/staging/rtl8188eu/hal/usb_halinit.c index caf2ca3a47e7..14650e91c78a 100644 --- a/drivers/staging/rtl8188eu/hal/usb_halinit.c +++ b/drivers/staging/rtl8188eu/hal/usb_halinit.c @@ -1673,7 +1673,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val) pRegToSet = RegToSet_Normal; /* 0xb972a841; */ FactorToSet = *((u8 *)val); if (FactorToSet <= 3) { - FactorToSet = (1<<(FactorToSet + 2)); + FactorToSet = 1 << (FactorToSet + 2); if (FactorToSet > 0xf) FactorToSet = 0xf; @@ -2012,7 +2012,7 @@ static u8 SetHalDefVar8188EUsb(struct adapter *Adapter, enum hal_def_variable eV u8 bRSSIDump = *((u8 *)pValue); struct odm_dm_struct *dm_ocm = &(haldata->odmpriv); if (bRSSIDump) - dm_ocm->DebugComponents = ODM_COMP_DIG|ODM_COMP_FA_CNT ; + dm_ocm->DebugComponents = ODM_COMP_DIG|ODM_COMP_FA_CNT; else dm_ocm->DebugComponents = 0; } diff --git a/drivers/staging/rtl8188eu/include/hal_intf.h b/drivers/staging/rtl8188eu/include/hal_intf.h index 9191993dd3f5..3b476d80f64d 100644 --- a/drivers/staging/rtl8188eu/include/hal_intf.h +++ b/drivers/staging/rtl8188eu/include/hal_intf.h @@ -304,8 +304,6 @@ void rtw_hal_write_rfreg(struct adapter *padapter, enum rf_radio_path eRFPath, u32 RegAddr, u32 BitMask, u32 Data); -s32 rtw_hal_interrupt_handler(struct adapter *padapter); - void rtw_hal_set_bwmode(struct adapter *padapter, enum ht_channel_width Bandwidth, u8 Offset); void rtw_hal_set_chan(struct adapter *padapter, u8 channel); @@ -317,7 +315,6 @@ void rtw_hal_antdiv_rssi_compared(struct adapter *padapter, struct wlan_bssid_ex *src); void rtw_hal_sreset_init(struct adapter *padapter); -u8 rtw_hal_sreset_get_wifi_status(struct adapter *padapter); void rtw_hal_notch_filter(struct adapter *adapter, bool enable); void rtw_hal_reset_security_engine(struct adapter *adapter); diff --git a/drivers/staging/rtl8188eu/include/ieee80211_ext.h b/drivers/staging/rtl8188eu/include/ieee80211_ext.h index 1052d1817a97..15e53d380ad0 100644 --- a/drivers/staging/rtl8188eu/include/ieee80211_ext.h +++ b/drivers/staging/rtl8188eu/include/ieee80211_ext.h @@ -103,24 +103,24 @@ struct wme_parameter_element { #define WPA_PUT_LE16(a, val) \ do { \ - (a)[1] = ((u16) (val)) >> 8; \ - (a)[0] = ((u16) (val)) & 0xff; \ + (a)[1] = ((u16)(val)) >> 8; \ + (a)[0] = ((u16)(val)) & 0xff; \ } while (0) #define WPA_PUT_BE32(a, val) \ do { \ - (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \ - (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \ - (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \ - (a)[3] = (u8) (((u32) (val)) & 0xff); \ + (a)[0] = (u8)((((u32) (val)) >> 24) & 0xff); \ + (a)[1] = (u8)((((u32) (val)) >> 16) & 0xff); \ + (a)[2] = (u8)((((u32) (val)) >> 8) & 0xff); \ + (a)[3] = (u8)(((u32) (val)) & 0xff); \ } while (0) #define WPA_PUT_LE32(a, val) \ do { \ - (a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff); \ - (a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff); \ - (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \ - (a)[0] = (u8) (((u32) (val)) & 0xff); \ + (a)[3] = (u8)((((u32) (val)) >> 24) & 0xff); \ + (a)[2] = (u8)((((u32) (val)) >> 16) & 0xff); \ + (a)[1] = (u8)((((u32) (val)) >> 8) & 0xff); \ + (a)[0] = (u8)(((u32) (val)) & 0xff); \ } while (0) #define RSN_SELECTOR_PUT(a, val) WPA_PUT_BE32((u8 *)(a), (val)) diff --git a/drivers/staging/rtl8188eu/include/odm_debug.h b/drivers/staging/rtl8188eu/include/odm_debug.h index db7b44e16c48..914f831a5b77 100644 --- a/drivers/staging/rtl8188eu/include/odm_debug.h +++ b/drivers/staging/rtl8188eu/include/odm_debug.h @@ -83,9 +83,8 @@ #define ODM_COMP_INIT BIT31 /*------------------------Export Marco Definition---------------------------*/ -#define DbgPrint pr_info #define RT_PRINTK(fmt, args...) \ - DbgPrint("%s(): " fmt, __func__, ## args); + pr_info("%s(): " fmt, __func__, ## args); #ifndef ASSERT #define ASSERT(expr) @@ -94,40 +93,18 @@ #define ODM_RT_TRACE(pDM_Odm, comp, level, fmt) \ if (((comp) & pDM_Odm->DebugComponents) && \ (level <= pDM_Odm->DebugLevel)) { \ - DbgPrint("[ODM-8188E] "); \ - RT_PRINTK fmt; \ - } - -#define ODM_RT_TRACE_F(pDM_Odm, comp, level, fmt) \ - if (((comp) & pDM_Odm->DebugComponents) && \ - (level <= pDM_Odm->DebugLevel)) { \ + pr_info("[ODM-8188E] "); \ RT_PRINTK fmt; \ } #define ODM_RT_ASSERT(pDM_Odm, expr, fmt) \ if (!(expr)) { \ - DbgPrint("Assertion failed! %s at ......\n", #expr); \ - DbgPrint(" ......%s,%s,line=%d\n", __FILE__, \ + pr_info("Assertion failed! %s at ......\n", #expr); \ + pr_info(" ......%s,%s,line=%d\n", __FILE__, \ __func__, __LINE__); \ RT_PRINTK fmt; \ ASSERT(false); \ } -#define ODM_dbg_enter() { DbgPrint("==> %s\n", __func__); } -#define ODM_dbg_exit() { DbgPrint("<== %s\n", __func__); } -#define ODM_dbg_trace(str) { DbgPrint("%s:%s\n", __func__, str); } - -#define ODM_PRINT_ADDR(pDM_Odm, comp, level, title_str, ptr) \ - if (((comp) & pDM_Odm->DebugComponents) && \ - (level <= pDM_Odm->DebugLevel)) { \ - int __i; \ - u8 *__ptr = (u8 *)ptr; \ - DbgPrint("[ODM] "); \ - DbgPrint(title_str); \ - DbgPrint(" "); \ - for (__i = 0; __i < 6; __i++) \ - DbgPrint("%02X%s", __ptr[__i], (__i == 5)?"":"-");\ - DbgPrint("\n"); \ - } void ODM_InitDebugSetting(struct odm_dm_struct *pDM_Odm); diff --git a/drivers/staging/rtl8188eu/include/osdep_service.h b/drivers/staging/rtl8188eu/include/osdep_service.h index fed9c86890b4..82f58f87656a 100644 --- a/drivers/staging/rtl8188eu/include/osdep_service.h +++ b/drivers/staging/rtl8188eu/include/osdep_service.h @@ -182,8 +182,8 @@ u64 rtw_modular64(u64 x, u64 y); /* Macros for handling unaligned memory accesses */ -#define RTW_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \ - ((u32) (a)[2])) +#define RTW_GET_BE24(a) ((((u32)(a)[0]) << 16) | (((u32) (a)[1]) << 8) | \ + ((u32)(a)[2])) void rtw_buf_free(u8 **buf, u32 *buf_len); void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len); diff --git a/drivers/staging/rtl8188eu/include/rtw_debug.h b/drivers/staging/rtl8188eu/include/rtw_debug.h index a38616e3cad2..971bf457f32d 100644 --- a/drivers/staging/rtl8188eu/include/rtw_debug.h +++ b/drivers/staging/rtl8188eu/include/rtw_debug.h @@ -106,7 +106,7 @@ extern u32 GlobalDebugLevel; u8 *ptr = (u8 *)_hexdata; \ pr_info("%s", DRIVER_PREFIX); \ pr_info(_titlestring); \ - for (__i = 0; __i < (int)_hexdatalen; __i++ ) { \ + for (__i = 0; __i < (int)_hexdatalen; __i++) { \ pr_info("%02X%s", ptr[__i], \ (((__i + 1) % 4) == 0) ? \ " " : " "); \ diff --git a/drivers/staging/rtl8188eu/include/rtw_led.h b/drivers/staging/rtl8188eu/include/rtw_led.h index c5194b620da4..23f0cfe312f3 100644 --- a/drivers/staging/rtl8188eu/include/rtw_led.h +++ b/drivers/staging/rtl8188eu/include/rtw_led.h @@ -11,10 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * ******************************************************************************/ #ifndef __RTW_LED_H_ @@ -27,7 +23,7 @@ #define LED_BLINK_LINK_INTERVAL_ALPHA 500 /* 500 */ #define LED_BLINK_SCAN_INTERVAL_ALPHA 180 /* 150 */ #define LED_BLINK_FASTER_INTERVAL_ALPHA 50 -#define LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA 5000 +#define LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA 5000 enum LED_CTL_MODE { LED_CTL_POWER_ON, @@ -92,7 +88,7 @@ struct LED_871x { void LedControl8188eu(struct adapter *padapter, enum LED_CTL_MODE LedAction); -struct led_priv{ +struct led_priv { /* add for led control */ struct LED_871x SwLed0; u8 bRegUseLed; diff --git a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h index d699ca19ef16..8d72ccf5f2a0 100644 --- a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h @@ -448,7 +448,7 @@ struct mlme_ext_priv { int init_mlme_ext_priv(struct adapter *adapter); int init_hw_mlme_ext(struct adapter *padapter); -void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext); +void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext); extern void init_mlme_ext_timer(struct adapter *padapter); extern void init_addba_retry_timer(struct adapter *adapt, struct sta_info *sta); extern struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv); @@ -646,8 +646,8 @@ void mlmeext_sta_add_event_callback(struct adapter *padapter, void linked_status_chk(struct adapter *padapter); -void survey_timer_hdl (void *function_context); -void link_timer_hdl (void *funtion_context); +void survey_timer_hdl(void *function_context); +void link_timer_hdl(void *funtion_context); void addba_timer_hdl(void *function_context); #define set_survey_timer(mlmeext, ms) \ @@ -708,15 +708,15 @@ u8 tdls_hdl(struct adapter *padapter, unsigned char *pbuf); #ifdef _RTW_CMD_C_ static struct cmd_hdl wlancmds[] = { - GEN_MLME_EXT_HANDLER(sizeof (struct wlan_bssid_ex), join_cmd_hdl) - GEN_MLME_EXT_HANDLER(sizeof (struct disconnect_parm), disconnect_hdl) - GEN_MLME_EXT_HANDLER(sizeof (struct wlan_bssid_ex), createbss_hdl) - GEN_MLME_EXT_HANDLER(sizeof (struct setopmode_parm), setopmode_hdl) - GEN_MLME_EXT_HANDLER(sizeof (struct sitesurvey_parm), sitesurvey_cmd_hdl) - GEN_MLME_EXT_HANDLER(sizeof (struct setauth_parm), setauth_hdl) - GEN_MLME_EXT_HANDLER(sizeof (struct setkey_parm), setkey_hdl) - GEN_MLME_EXT_HANDLER(sizeof (struct set_stakey_parm), set_stakey_hdl) - GEN_MLME_EXT_HANDLER(sizeof (struct set_assocsta_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct wlan_bssid_ex), join_cmd_hdl) + GEN_MLME_EXT_HANDLER(sizeof(struct disconnect_parm), disconnect_hdl) + GEN_MLME_EXT_HANDLER(sizeof(struct wlan_bssid_ex), createbss_hdl) + GEN_MLME_EXT_HANDLER(sizeof(struct setopmode_parm), setopmode_hdl) + GEN_MLME_EXT_HANDLER(sizeof(struct sitesurvey_parm), sitesurvey_cmd_hdl) + GEN_MLME_EXT_HANDLER(sizeof(struct setauth_parm), setauth_hdl) + GEN_MLME_EXT_HANDLER(sizeof(struct setkey_parm), setkey_hdl) + GEN_MLME_EXT_HANDLER(sizeof(struct set_stakey_parm), set_stakey_hdl) + GEN_MLME_EXT_HANDLER(sizeof(struct set_assocsta_parm), NULL) GEN_MLME_EXT_HANDLER(sizeof(struct addBaReq_parm), add_ba_hdl) GEN_MLME_EXT_HANDLER(sizeof(struct set_ch_parm), set_ch_hdl) GEN_MLME_EXT_HANDLER(sizeof(struct wlan_bssid_ex), tx_beacon_hdl) @@ -787,7 +787,7 @@ static struct fwevent wlanevents[] = { {0, NULL}, {0, NULL}, {0, &rtw_survey_event_callback}, /*8*/ - {sizeof (struct surveydone_event), &rtw_surveydone_event_callback},/*9*/ + {sizeof(struct surveydone_event), &rtw_surveydone_event_callback},/*9*/ {0, &rtw_joinbss_event_callback}, /*10*/ {sizeof(struct stassoc_event), &rtw_stassoc_event_callback}, {sizeof(struct stadel_event), &rtw_stadel_event_callback}, diff --git a/drivers/staging/rtl8188eu/include/wifi.h b/drivers/staging/rtl8188eu/include/wifi.h index a88ebf41bba1..8dbdfafd52b5 100644 --- a/drivers/staging/rtl8188eu/include/wifi.h +++ b/drivers/staging/rtl8188eu/include/wifi.h @@ -766,27 +766,27 @@ enum ht_cap_ampdu_factor { #define OP_MODE_20MHZ_HT_STA_ASSOCED 2 #define OP_MODE_MIXED 3 -#define HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK ((u8) BIT(0) | BIT(1)) -#define HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE ((u8) BIT(0)) -#define HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW ((u8) BIT(0) | BIT(1)) -#define HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH ((u8) BIT(2)) -#define HT_INFO_HT_PARAM_RIFS_MODE ((u8) BIT(3)) -#define HT_INFO_HT_PARAM_CTRL_ACCESS_ONLY ((u8) BIT(4)) -#define HT_INFO_HT_PARAM_SRV_INTERVAL_GRANULARITY ((u8) BIT(5)) +#define HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK ((u8)BIT(0) | BIT(1)) +#define HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE ((u8)BIT(0)) +#define HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW ((u8)BIT(0) | BIT(1)) +#define HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH ((u8)BIT(2)) +#define HT_INFO_HT_PARAM_RIFS_MODE ((u8)BIT(3)) +#define HT_INFO_HT_PARAM_CTRL_ACCESS_ONLY ((u8)BIT(4)) +#define HT_INFO_HT_PARAM_SRV_INTERVAL_GRANULARITY ((u8)BIT(5)) #define HT_INFO_OPERATION_MODE_OP_MODE_MASK \ - ((u16) (0x0001 | 0x0002)) + ((u16)(0x0001 | 0x0002)) #define HT_INFO_OPERATION_MODE_OP_MODE_OFFSET 0 -#define HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT ((u8) BIT(2)) -#define HT_INFO_OPERATION_MODE_TRANSMIT_BURST_LIMIT ((u8) BIT(3)) -#define HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT ((u8) BIT(4)) - -#define HT_INFO_STBC_PARAM_DUAL_BEACON ((u16) BIT(6)) -#define HT_INFO_STBC_PARAM_DUAL_STBC_PROTECT ((u16) BIT(7)) -#define HT_INFO_STBC_PARAM_SECONDARY_BC ((u16) BIT(8)) -#define HT_INFO_STBC_PARAM_LSIG_TXOP_PROTECT_ALLOWED ((u16) BIT(9)) -#define HT_INFO_STBC_PARAM_PCO_ACTIVE ((u16) BIT(10)) -#define HT_INFO_STBC_PARAM_PCO_PHASE ((u16) BIT(11)) +#define HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT ((u8)BIT(2)) +#define HT_INFO_OPERATION_MODE_TRANSMIT_BURST_LIMIT ((u8)BIT(3)) +#define HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT ((u8)BIT(4)) + +#define HT_INFO_STBC_PARAM_DUAL_BEACON ((u16)BIT(6)) +#define HT_INFO_STBC_PARAM_DUAL_STBC_PROTECT ((u16)BIT(7)) +#define HT_INFO_STBC_PARAM_SECONDARY_BC ((u16)BIT(8)) +#define HT_INFO_STBC_PARAM_LSIG_TXOP_PROTECT_ALLOWED ((u16)BIT(9)) +#define HT_INFO_STBC_PARAM_PCO_ACTIVE ((u16)BIT(10)) +#define HT_INFO_STBC_PARAM_PCO_PHASE ((u16)BIT(11)) /* ===============WPS Section=============== */ /* For WPSv1.0 */ diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index d598fec4abbf..24a8f5ac96e5 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -361,7 +361,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, param->u.crypt.err = 0; param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; - if (param_len < (u32) ((u8 *)param->u.crypt.key - (u8 *)param) + param->u.crypt.key_len) { + if (param_len < (u32)((u8 *)param->u.crypt.key - (u8 *)param) + param->u.crypt.key_len) { ret = -EINVAL; goto exit; } @@ -512,14 +512,12 @@ static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ie } if (ielen) { - buf = kzalloc(ielen, GFP_KERNEL); + buf = kmemdup(pie, ielen, GFP_KERNEL); if (buf == NULL) { ret = -ENOMEM; goto exit; } - memcpy(buf, pie, ielen); - /* dump */ { int i; @@ -1136,7 +1134,8 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, struct iw_scan_req *req = (struct iw_scan_req *)extra; if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { - int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE); + int len = min_t(int, req->essid_len, + IW_ESSID_MAX_SIZE); memcpy(ssid[0].Ssid, req->essid, len); ssid[0].SsidLength = len; @@ -1417,7 +1416,7 @@ static int rtw_wx_set_rate(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *extra) { - int i, ret = 0; + int i; u8 datarates[NumRates]; u32 target_rate = wrqu->bitrate.value; u32 fixed = wrqu->bitrate.fixed; @@ -1490,7 +1489,7 @@ set_rate: RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("datarate_inx =%d\n", datarates[i])); } - return ret; + return 0; } static int rtw_wx_get_rate(struct net_device *dev, @@ -2699,10 +2698,8 @@ static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, ie_len = len-12-2;/* 12 = param header, 2:no packed */ - if (pmlmepriv->wps_beacon_ie) { - kfree(pmlmepriv->wps_beacon_ie); - pmlmepriv->wps_beacon_ie = NULL; - } + kfree(pmlmepriv->wps_beacon_ie); + pmlmepriv->wps_beacon_ie = NULL; if (ie_len > 0) { pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len); @@ -2736,10 +2733,8 @@ static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *par ie_len = len-12-2;/* 12 = param header, 2:no packed */ - if (pmlmepriv->wps_probe_resp_ie) { - kfree(pmlmepriv->wps_probe_resp_ie); - pmlmepriv->wps_probe_resp_ie = NULL; - } + kfree(pmlmepriv->wps_probe_resp_ie); + pmlmepriv->wps_probe_resp_ie = NULL; if (ie_len > 0) { pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len); @@ -2768,10 +2763,8 @@ static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *par ie_len = len-12-2;/* 12 = param header, 2:no packed */ - if (pmlmepriv->wps_assoc_resp_ie) { - kfree(pmlmepriv->wps_assoc_resp_ie); - pmlmepriv->wps_assoc_resp_ie = NULL; - } + kfree(pmlmepriv->wps_assoc_resp_ie); + pmlmepriv->wps_assoc_resp_ie = NULL; if (ie_len > 0) { pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len); diff --git a/drivers/staging/rtl8188eu/os_dep/os_intfs.c b/drivers/staging/rtl8188eu/os_dep/os_intfs.c index 08a80f759b8d..88a909c9e457 100644 --- a/drivers/staging/rtl8188eu/os_dep/os_intfs.c +++ b/drivers/staging/rtl8188eu/os_dep/os_intfs.c @@ -512,7 +512,6 @@ void rtw_proc_remove_one(struct net_device *dev) static uint loadparam(struct adapter *padapter, struct net_device *pnetdev) { - uint status = _SUCCESS; struct registry_priv *registry_par = &padapter->registrypriv; @@ -527,7 +526,7 @@ static uint loadparam(struct adapter *padapter, struct net_device *pnetdev) registry_par->channel = (u8)rtw_channel; registry_par->wireless_mode = (u8)rtw_wireless_mode; - registry_par->vrtl_carrier_sense = (u8)rtw_vrtl_carrier_sense ; + registry_par->vrtl_carrier_sense = (u8)rtw_vrtl_carrier_sense; registry_par->vcs_type = (u8)rtw_vcs_type; registry_par->rts_thresh = (u16)rtw_rts_thresh; registry_par->frag_thresh = (u16)rtw_frag_thresh; @@ -582,7 +581,7 @@ static uint loadparam(struct adapter *padapter, struct net_device *pnetdev) snprintf(registry_par->ifname, 16, "%s", ifname); snprintf(registry_par->if2name, 16, "%s", if2name); registry_par->notch_filter = (u8)rtw_notch_filter; - return status; + return _SUCCESS; } static int rtw_net_set_mac_address(struct net_device *pnetdev, void *p) @@ -760,7 +759,6 @@ void rtw_stop_drv_threads(struct adapter *padapter) static u8 rtw_init_default_value(struct adapter *padapter) { - u8 ret = _SUCCESS; struct registry_priv *pregistrypriv = &padapter->registrypriv; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -803,12 +801,11 @@ static u8 rtw_init_default_value(struct adapter *padapter) padapter->bWritePortCancel = false; padapter->bRxRSSIDisplay = 0; padapter->bNotifyChannelChange = 0; - return ret; + return _SUCCESS; } u8 rtw_reset_drv_sw(struct adapter *padapter) { - u8 ret8 = _SUCCESS; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; @@ -833,7 +830,7 @@ u8 rtw_reset_drv_sw(struct adapter *padapter) rtw_set_signal_stat_timer(&padapter->recvpriv); - return ret8; + return _SUCCESS; } u8 rtw_init_drv_sw(struct adapter *padapter) diff --git a/drivers/staging/rtl8188eu/os_dep/osdep_service.c b/drivers/staging/rtl8188eu/os_dep/osdep_service.c index 8af4a8d24cce..abcb3a8589ef 100644 --- a/drivers/staging/rtl8188eu/os_dep/osdep_service.c +++ b/drivers/staging/rtl8188eu/os_dep/osdep_service.c @@ -51,7 +51,7 @@ void *rtw_malloc2d(int h, int w, int size) { int j; - void **a = (void **)kzalloc(h*sizeof(void *) + h*w*size, GFP_KERNEL); + void **a = kzalloc(h*sizeof(void *) + h*w*size, GFP_KERNEL); if (a == NULL) { pr_info("%s: alloc memory fail!\n", __func__); return NULL; diff --git a/drivers/staging/rtl8188eu/os_dep/rtw_android.c b/drivers/staging/rtl8188eu/os_dep/rtw_android.c index d9d55d12fd5f..99ce077007f4 100644 --- a/drivers/staging/rtl8188eu/os_dep/rtw_android.c +++ b/drivers/staging/rtl8188eu/os_dep/rtw_android.c @@ -148,36 +148,21 @@ static int rtw_android_set_block(struct net_device *net, char *command, int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) { int ret = 0; - char *command = NULL; + char *command; int cmd_num; int bytes_written = 0; struct android_wifi_priv_cmd priv_cmd; - if (!ifr->ifr_data) { - ret = -EINVAL; - goto exit; - } - if (copy_from_user(&priv_cmd, ifr->ifr_data, - sizeof(struct android_wifi_priv_cmd))) { - ret = -EFAULT; - goto exit; - } - command = kmalloc(priv_cmd.total_len, GFP_KERNEL); - if (!command) { - DBG_88E("%s: failed to allocate memory\n", __func__); - ret = -ENOMEM; - goto exit; - } - if (!access_ok(VERIFY_READ, priv_cmd.buf, priv_cmd.total_len)) { - DBG_88E("%s: failed to access memory\n", __func__); - ret = -EFAULT; - goto exit; - } - if (copy_from_user(command, (char __user *)priv_cmd.buf, - priv_cmd.total_len)) { - ret = -EFAULT; - goto exit; - } + if (!ifr->ifr_data) + return -EINVAL; + if (copy_from_user(&priv_cmd, ifr->ifr_data, sizeof(priv_cmd))) + return -EFAULT; + if (priv_cmd.total_len < 1) + return -EINVAL; + command = memdup_user(priv_cmd.buf, priv_cmd.total_len); + if (IS_ERR(command)) + return PTR_ERR(command); + command[priv_cmd.total_len - 1] = 0; DBG_88E("%s: Android private cmd \"%s\" on %s\n", __func__, command, ifr->ifr_name); cmd_num = rtw_android_cmdstr_to_num(command); @@ -191,7 +176,7 @@ int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) DBG_88E("%s: Ignore private cmd \"%s\" - iface %s is down\n", __func__, command, ifr->ifr_name); ret = 0; - goto exit; + goto free; } switch (cmd_num) { case ANDROID_WIFI_CMD_STOP: @@ -279,7 +264,7 @@ response: } else { ret = bytes_written; } -exit: +free: kfree(command); return ret; } diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c index 2f87150a21b7..bee39c2278f1 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c @@ -63,7 +63,6 @@ static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf) struct usb_config_descriptor *pconf_desc; struct usb_host_interface *phost_iface; struct usb_interface_descriptor *piface_desc; - struct usb_host_endpoint *phost_endp; struct usb_endpoint_descriptor *pendp_desc; struct usb_device *pusbd; @@ -92,24 +91,22 @@ static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf) for (i = 0; i < pdvobjpriv->nr_endpoint; i++) { int ep_num; - phost_endp = phost_iface->endpoint + i; - - if (phost_endp) { - pendp_desc = &phost_endp->desc; - ep_num = usb_endpoint_num(pendp_desc); - - if (usb_endpoint_is_bulk_in(pendp_desc)) { - pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = ep_num; - pdvobjpriv->RtNumInPipes++; - } else if (usb_endpoint_is_int_in(pendp_desc)) { - pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = ep_num; - pdvobjpriv->RtNumInPipes++; - } else if (usb_endpoint_is_bulk_out(pendp_desc)) { - pdvobjpriv->RtOutPipe[pdvobjpriv->RtNumOutPipes] = ep_num; - pdvobjpriv->RtNumOutPipes++; - } - pdvobjpriv->ep_num[i] = ep_num; + pendp_desc = &phost_iface->endpoint[i].desc; + + ep_num = usb_endpoint_num(pendp_desc); + + if (usb_endpoint_is_bulk_in(pendp_desc)) { + pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = ep_num; + pdvobjpriv->RtNumInPipes++; + } else if (usb_endpoint_is_int_in(pendp_desc)) { + pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = ep_num; + pdvobjpriv->RtNumInPipes++; + } else if (usb_endpoint_is_bulk_out(pendp_desc)) { + pdvobjpriv->RtOutPipe[pdvobjpriv->RtNumOutPipes] = + ep_num; + pdvobjpriv->RtNumOutPipes++; } + pdvobjpriv->ep_num[i] = ep_num; } if (pusbd->speed == USB_SPEED_HIGH) @@ -557,8 +554,6 @@ static void rtw_dev_remove(struct usb_interface *pusb_intf) RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-dev_remove()\n")); DBG_88E("-r871xu_dev_remove, done\n"); - - return; } static struct usb_driver rtl8188e_usb_drv = { diff --git a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c index ba1e178fb510..d2efa9dfc8c0 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c @@ -160,10 +160,10 @@ static int recvbuf2recvframe(struct adapter *adapt, struct sk_buff *pskb) switch (haldata->UsbRxAggMode) { case USB_RX_AGG_DMA: case USB_RX_AGG_MIX: - pkt_offset = (u16) round_up(pkt_offset, 128); + pkt_offset = (u16)round_up(pkt_offset, 128); break; case USB_RX_AGG_USB: - pkt_offset = (u16) round_up(pkt_offset, 4); + pkt_offset = (u16)round_up(pkt_offset, 4); break; case USB_RX_AGG_DISABLE: default: @@ -843,7 +843,7 @@ void usb_write_port_cancel(struct adapter *padapter) void rtl8188eu_recv_tasklet(void *priv) { struct sk_buff *pskb; - struct adapter *adapt = (struct adapter *)priv; + struct adapter *adapt = priv; struct recv_priv *precvpriv = &adapt->recvpriv; while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue))) { @@ -862,7 +862,7 @@ void rtl8188eu_recv_tasklet(void *priv) void rtl8188eu_xmit_tasklet(void *priv) { int ret = false; - struct adapter *adapt = (struct adapter *)priv; + struct adapter *adapt = priv; struct xmit_priv *pxmitpriv = &adapt->xmitpriv; if (check_fwstate(&adapt->mlmepriv, _FW_UNDER_SURVEY)) diff --git a/drivers/staging/rtl8188eu/os_dep/xmit_linux.c b/drivers/staging/rtl8188eu/os_dep/xmit_linux.c index 0ce47b07ef86..5acf9a9dddeb 100644 --- a/drivers/staging/rtl8188eu/os_dep/xmit_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/xmit_linux.c @@ -46,7 +46,7 @@ void _rtw_open_pktfile(struct sk_buff *pktptr, struct pkt_file *pfile) } -uint _rtw_pktfile_read (struct pkt_file *pfile, u8 *rmem, uint rlen) +uint _rtw_pktfile_read(struct pkt_file *pfile, u8 *rmem, uint rlen) { uint len = 0; @@ -66,13 +66,7 @@ uint _rtw_pktfile_read (struct pkt_file *pfile, u8 *rmem, uint rlen) int rtw_endofpktfile(struct pkt_file *pfile) { - - if (pfile->pkt_len == 0) { - return true; - } - - - return false; + return pfile->pkt_len == 0; } int rtw_os_xmit_resource_alloc(struct adapter *padapter, struct xmit_buf *pxmitbuf, u32 alloc_sz) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index 0ffed2d06b58..552d943b1761 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -1287,7 +1287,7 @@ void rtl8192_tx_fill_desc(struct net_device *dev, struct tx_desc *pdesc, void rtl8192_tx_fill_cmd_desc(struct net_device *dev, struct tx_desc_cmd *entry, - struct cb_desc *cb_desc, struct sk_buff* skb) + struct cb_desc *cb_desc, struct sk_buff *skb) { struct r8192_priv *priv = rtllib_priv(dev); dma_addr_t mapping = pci_map_single(priv->pdev, skb->data, skb->len, @@ -1302,7 +1302,7 @@ void rtl8192_tx_fill_cmd_desc(struct net_device *dev, if (cb_desc->bCmdOrInit == DESC_PACKET_TYPE_INIT) { entry->CmdInit = DESC_PACKET_TYPE_INIT; } else { - struct tx_desc * entry_tmp = (struct tx_desc *)entry; + struct tx_desc *entry_tmp = (struct tx_desc *)entry; entry_tmp->CmdInit = DESC_PACKET_TYPE_NORMAL; entry_tmp->Offset = sizeof(struct tx_fwinfo_8190pci) + 8; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index b6ce8c3b2f8c..885315cac3a4 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -1449,13 +1449,11 @@ static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14) (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ; rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); - TempVal = 0; TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] + (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) + (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16)+ (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24)); rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); - TempVal = 0; TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] + (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ; @@ -1465,13 +1463,11 @@ static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14) (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ; rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); - TempVal = 0; TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] + (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) + (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16)+ (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24)); rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); - TempVal = 0; TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] + (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ; @@ -1493,7 +1489,6 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter1, TempVal); - TempVal = 0; TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16)+ @@ -1501,7 +1496,6 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter2, TempVal); - TempVal = 0; TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8) ; @@ -1515,7 +1509,6 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter1, TempVal); - TempVal = 0; TempVal = CCKSwingTable_Ch14[priv->CCK_index][2] + (CCKSwingTable_Ch14[priv->CCK_index][3]<<8) + (CCKSwingTable_Ch14[priv->CCK_index][4]<<16)+ @@ -1523,7 +1516,6 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter2, TempVal); - TempVal = 0; TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] + (CCKSwingTable_Ch14[priv->CCK_index][7]<<8) ; diff --git a/drivers/staging/rtl8192e/rtl819x_BAProc.c b/drivers/staging/rtl8192e/rtl819x_BAProc.c index 6da57847a533..0415e02b4eff 100644 --- a/drivers/staging/rtl8192e/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/rtl819x_BAProc.c @@ -16,6 +16,8 @@ * Contact Information: * wlanfae <wlanfae@realtek.com> ******************************************************************************/ +#include <asm/byteorder.h> +#include <asm/unaligned.h> #include "rtllib.h" #include "rtl819x_BA.h" @@ -79,7 +81,6 @@ static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst, struct sk_buff *skb = NULL; struct rtllib_hdr_3addr *BAReq = NULL; u8 *tag = NULL; - u16 tmp = 0; u16 len = ieee->tx_headroom + 9; RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, "========>%s(), frame(%d)" @@ -115,15 +116,15 @@ static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst, if (ACT_ADDBARSP == type) { RT_TRACE(COMP_DBG, "====>to send ADDBARSP\n"); - tmp = StatusCode; - memcpy(tag, (u8 *)&tmp, 2); + + put_unaligned_le16(StatusCode, tag); tag += 2; } - tmp = pBA->BaParamSet.shortData; - memcpy(tag, (u8 *)&tmp, 2); + + put_unaligned_le16(pBA->BaParamSet.shortData, tag); tag += 2; - tmp = pBA->BaTimeoutValue; - memcpy(tag, (u8 *)&tmp, 2); + + put_unaligned_le16(pBA->BaTimeoutValue, tag); tag += 2; if (ACT_ADDBAREQ == type) { @@ -143,7 +144,6 @@ static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst, struct sk_buff *skb = NULL; struct rtllib_hdr_3addr *Delba = NULL; u8 *tag = NULL; - u16 tmp = 0; u16 len = 6 + ieee->tx_headroom; if (net_ratelimit()) @@ -178,11 +178,11 @@ static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst, *tag++ = ACT_CAT_BA; *tag++ = ACT_DELBA; - tmp = DelbaParamSet.shortData; - memcpy(tag, (u8 *)&tmp, 2); + + put_unaligned_le16(DelbaParamSet.shortData, tag); tag += 2; - tmp = ReasonCode; - memcpy(tag, (u8 *)&tmp, 2); + + put_unaligned_le16(ReasonCode, tag); tag += 2; RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len); diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index 2d82f8993ea1..cef2dc27103f 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -2762,8 +2762,6 @@ extern void rtllib_stop_scan(struct rtllib_device *ieee); extern bool rtllib_act_scanning(struct rtllib_device *ieee, bool sync_scan); extern void rtllib_stop_scan_syncro(struct rtllib_device *ieee); extern void rtllib_start_scan_syncro(struct rtllib_device *ieee, u8 is_mesh); -extern inline struct sk_buff *rtllib_probe_req(struct rtllib_device *ieee); -extern u8 MgntQuery_MgntFrameTxRate(struct rtllib_device *ieee); extern void rtllib_sta_ps_send_null_frame(struct rtllib_device *ieee, short pwr); extern void rtllib_sta_wakeup(struct rtllib_device *ieee, short nl); @@ -2944,12 +2942,12 @@ void rtllib_softmac_scan_syncro(struct rtllib_device *ieee, u8 is_mesh); extern const long rtllib_wlan_frequencies[]; -extern inline void rtllib_increment_scans(struct rtllib_device *ieee) +static inline void rtllib_increment_scans(struct rtllib_device *ieee) { ieee->scans++; } -extern inline int rtllib_get_scans(struct rtllib_device *ieee) +static inline int rtllib_get_scans(struct rtllib_device *ieee) { return ieee->scans; } diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index 1c2014fd8d81..cf11b042b93a 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -1415,10 +1415,6 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, return 1; rx_dropped: - if (rxb != NULL) { - kfree(rxb); - rxb = NULL; - } ieee->stats.rx_dropped++; /* Returning 0 indicates to caller that we have not handled the SKB-- @@ -2691,7 +2687,7 @@ void rtllib_rx_mgt(struct rtllib_device *ieee, struct sk_buff *skb, struct rtllib_rx_stats *stats) { - struct rtllib_hdr_4addr *header = (struct rtllib_hdr_4addr *)skb->data ; + struct rtllib_hdr_4addr *header = (struct rtllib_hdr_4addr *)skb->data; if ((WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) != RTLLIB_STYPE_PROBE_RESP) && diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index abb6729ae279..d992a754e72d 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -193,7 +193,7 @@ MgntQuery_TxRateExcludeCCKRates(struct rtllib_device *ieee) return QueryRate; } -u8 MgntQuery_MgntFrameTxRate(struct rtllib_device *ieee) +static u8 MgntQuery_MgntFrameTxRate(struct rtllib_device *ieee) { struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; u8 rate; @@ -343,7 +343,7 @@ inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, } } -inline struct sk_buff *rtllib_probe_req(struct rtllib_device *ieee) +static inline struct sk_buff *rtllib_probe_req(struct rtllib_device *ieee) { unsigned int len, rate_len; u8 *tag; @@ -1311,7 +1311,7 @@ inline struct sk_buff *rtllib_association_req(struct rtllib_network *beacon, } if (beacon->bCkipSupported) { - static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; + static const u8 AironetIeOui[] = {0x00, 0x01, 0x66}; u8 CcxAironetBuf[30]; struct octet_string osCcxAironetIE; @@ -1331,10 +1331,11 @@ inline struct sk_buff *rtllib_association_req(struct rtllib_network *beacon, } if (beacon->bCcxRmEnable) { - static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00}; + static const u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, + 0x00}; struct octet_string osCcxRmCap; - osCcxRmCap.Octet = CcxRmCapBuf; + osCcxRmCap.Octet = (u8 *) CcxRmCapBuf; osCcxRmCap.Length = sizeof(CcxRmCapBuf); tag = skb_put(skb, ccxrm_ie_len); *tag++ = MFIE_TYPE_GENERIC; @@ -3167,6 +3168,7 @@ void rtllib_softmac_free(struct rtllib_device *ieee) cancel_delayed_work(&ieee->associate_retry_wq); destroy_workqueue(ieee->wq); up(&ieee->wx_sem); + tasklet_kill(&ieee->ps_task); } /******************************************************** diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index 73de9e9669f6..d401dbf4c7c6 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -713,8 +713,8 @@ static void RxReorderIndicatePacket(struct ieee80211_device *ieee, while(!list_empty(&pTS->RxPendingPktList)) { IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): start RREORDER indicate\n",__func__); pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List); - if( SN_LESS(pReorderEntry->SeqNum, pTS->RxIndicateSeq) || - SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq)) + if (SN_LESS(pReorderEntry->SeqNum, pTS->RxIndicateSeq) || + SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq)) { /* This protect buffer from overflow. */ if(index >= REORDER_WIN_SIZE) { @@ -800,9 +800,8 @@ static u8 parse_subframe(struct sk_buff *skb, // Null packet, don't indicate it to upper layer ChkLength = LLCOffset;/* + (Frame_WEP(frame)!=0 ?Adapter->MgntInfo.SecurityInfo.EncryptionHeadOverhead:0);*/ - if( skb->len <= ChkLength ) { + if (skb->len <= ChkLength) return 0; - } skb_pull(skb, LLCOffset); @@ -1035,10 +1034,9 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, { // IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): pRxTS->RxLastFragNum is %d,frag is %d,pRxTS->RxLastSeqNum is %d,seq is %d\n",__func__,pRxTS->RxLastFragNum,frag,pRxTS->RxLastSeqNum,WLAN_GET_SEQ_SEQ(sc)); - if( (fc & (1<<11)) && - (frag == pRxTS->RxLastFragNum) && - (WLAN_GET_SEQ_SEQ(sc) == pRxTS->RxLastSeqNum) ) - { + if ((fc & (1<<11)) && + (frag == pRxTS->RxLastFragNum) && + (WLAN_GET_SEQ_SEQ(sc) == pRxTS->RxLastSeqNum)) { goto rx_dropped; } else @@ -2456,7 +2454,7 @@ static inline void ieee80211_process_probe_response( // then wireless adapter should do active scan from ch1~11 and // passive scan from ch12~14 - if( !IsLegalChannel(ieee, network.channel) ) + if (!IsLegalChannel(ieee, network.channel)) return; if(ieee->bGlobalDomain) { @@ -2465,8 +2463,7 @@ static inline void ieee80211_process_probe_response( // Case 1: Country code if(IS_COUNTRY_IE_VALID(ieee) ) { - if( !IsLegalChannel(ieee, network.channel) ) - { + if (!IsLegalChannel(ieee, network.channel)) { printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel); return; } @@ -2487,8 +2484,7 @@ static inline void ieee80211_process_probe_response( // Case 1: Country code if(IS_COUNTRY_IE_VALID(ieee) ) { - if( !IsLegalChannel(ieee, network.channel) ) - { + if (!IsLegalChannel(ieee, network.channel)) { printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network.channel); return; } diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index a85bb232be97..d1471877e19d 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -411,7 +411,7 @@ static void ieee80211_send_probe(struct ieee80211_device *ieee) } } -void ieee80211_send_probe_requests(struct ieee80211_device *ieee) +static void ieee80211_send_probe_requests(struct ieee80211_device *ieee) { if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){ ieee80211_send_probe(ieee); @@ -517,7 +517,7 @@ static void ieee80211_softmac_scan_wq(struct work_struct *work) goto out; ieee->set_chan(ieee->dev, ieee->current_network.channel); if(channel_map[ieee->current_network.channel] == 1) - ieee80211_send_probe_requests(ieee); + ieee80211_send_probe_requests(ieee); queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME); @@ -804,12 +804,11 @@ static struct sk_buff *ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d *(tag++) = ieee->current_network.channel; if(atim_len){ - u16 val16; *(tag++) = MFIE_TYPE_IBSS_SET; *(tag++) = 2; - //*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window); - val16 = cpu_to_le16(ieee->current_network.atim_window); - memcpy((u8 *)tag, (u8 *)&val16, 2); + + put_unaligned_le16(ieee->current_network.atim_window, + (u8 *)tag); tag+=2; } @@ -1043,10 +1042,9 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco { ccxrm_ie_len = 6+2; } - if( beacon->BssCcxVerNumber >= 2 ) - { + if (beacon->BssCcxVerNumber >= 2) cxvernum_ie_len = 5+2; - } + #ifdef THOMAS_TURBO len = sizeof(struct ieee80211_assoc_request_frame)+ 2 + beacon->ssid_len//essid tagged val @@ -1103,7 +1101,7 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco if(ieee->short_slot) hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); if (wmm_info_len) //QOS - hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS); + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS); hdr->listen_interval = 0xa; //FIXME @@ -1118,8 +1116,7 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco ieee80211_MFIE_Brate(ieee, &tag); ieee80211_MFIE_Grate(ieee, &tag); // For CCX 1 S13, CKIP. Added by Annie, 2006-08-14. - if( beacon->bCkipSupported ) - { + if (beacon->bCkipSupported) { static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client" u8 CcxAironetBuf[30]; OCTET_STRING osCcxAironetIE; @@ -1158,8 +1155,7 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco tag += osCcxRmCap.Length; } - if( beacon->BssCcxVerNumber >= 2 ) - { + if (beacon->BssCcxVerNumber >= 2) { u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00}; OCTET_STRING osCcxVerNum; CcxVerNumBuf[4] = beacon->BssCcxVerNumber; @@ -1533,7 +1529,7 @@ void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee) break; if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies)) - ieee80211_softmac_new_net(ieee, target); + ieee80211_softmac_new_net(ieee, target); } spin_unlock_irqrestore(&ieee->lock, flags); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c index 82ea533a0cf4..644368df6342 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c @@ -374,7 +374,7 @@ int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info goto out; } - if ( ieee->state == IEEE80211_LINKED){ + if (ieee->state == IEEE80211_LINKED) { queue_work(ieee->wq, &ieee->wx_sync_scan_wq); /* intentionally forget to up sem */ return 0; diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c index 57bef219687b..fca73c7c9fbe 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c @@ -529,8 +529,7 @@ static void ieee80211_query_protectionmode(struct ieee80211_device *ieee, } } // For test , CTS replace with RTS - if( 0 ) - { + if (0) { tcb_desc->bCTSEnable = true; tcb_desc->rts_rate = MGN_24M; tcb_desc->bRTSEnable = true; diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c index 68f5ede86633..ae1b3cf2866c 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c @@ -172,7 +172,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee, iwe.cmd = IWEVCUSTOM; iwe.u.data.length = p - custom; if (iwe.u.data.length) - start = iwe_stream_add_point(info, start, stop, &iwe, custom); + start = iwe_stream_add_point(info, start, stop, &iwe, custom); /* Add quality statistics */ /* TODO: Fix these values... */ iwe.cmd = IWEVQUAL; diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c index 51552d42d66c..cd196cec0dd9 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c @@ -110,7 +110,7 @@ static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, P struct sk_buff *skb = NULL; struct ieee80211_hdr_3addr *BAReq = NULL; u8 *tag = NULL; - u16 tmp = 0; + __le16 tmp = 0; u16 len = ieee->tx_headroom + 9; //category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2)) IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __func__, type, Dst, ieee->dev); @@ -196,7 +196,7 @@ static struct sk_buff *ieee80211_DELBA( struct sk_buff *skb = NULL; struct ieee80211_hdr_3addr *Delba = NULL; u8 *tag = NULL; - u16 tmp = 0; + __le16 tmp = 0; //len = head len + DELBA Parameter Set(2) + Reason Code(2) u16 len = 6 + ieee->tx_headroom; @@ -342,8 +342,7 @@ int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee, struct sk_buff *skb) PSEQUENCE_CONTROL pBaStartSeqCtrl = NULL; PRX_TS_RECORD pTS = NULL; - if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) - { + if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 9) { IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %zu)\n", skb->len, @@ -444,8 +443,7 @@ int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee, struct sk_buff *skb) PBA_PARAM_SET pBaParamSet = NULL; u16 ReasonCode; - if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) - { + if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 9) { IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %zu)\n", skb->len, @@ -463,10 +461,9 @@ int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee, struct sk_buff *skb) // Check the capability // Since we can always receive A-MPDU, we just check if it is under HT mode. - if( ieee->current_network.qos_data.active == 0 || - ieee->pHTInfo->bCurrentHTSupport == false || - ieee->pHTInfo->bCurrentAMPDUEnable == false ) - { + if (ieee->current_network.qos_data.active == 0 || + ieee->pHTInfo->bCurrentHTSupport == false || + ieee->pHTInfo->bCurrentAMPDUEnable == false) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bCurrentAMPDUEnable); ReasonCode = DELBA_REASON_UNKNOWN_BA; goto OnADDBARsp_Reject; @@ -577,8 +574,7 @@ int ieee80211_rx_DELBA(struct ieee80211_device *ieee, struct sk_buff *skb) u16 *pReasonCode = NULL; u8 *dst = NULL; - if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6) - { + if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 6) { IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %zu)\n", skb->len, diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c index 1ea2cd392670..e60d926a3973 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c @@ -602,8 +602,7 @@ void HTConstructCapabilityElement(struct ieee80211_device *ieee, u8 *posHTCap, u // TODO: Nedd to take care of this part IEEE80211_DEBUG(IEEE80211_DL_HT, "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n", pCapELE->ChlWidth, pCapELE->MaxAMSDUSize, pCapELE->DssCCk); - if( IsEncrypt) - { + if (IsEncrypt) { pCapELE->MPDUDensity = 7; // 8us pCapELE->MaxRxAMPDUFactor = 2; // 2 is for 32 K and 3 is 64K } @@ -951,8 +950,7 @@ void HTOnAssocRsp(struct ieee80211_device *ieee) static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; // For 11n EWC definition, 2007.07.17, by Emily static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; // For 11n EWC definition, 2007.07.17, by Emily - if( pHTInfo->bCurrentHTSupport == false ) - { + if (pHTInfo->bCurrentHTSupport == false) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "<=== HTOnAssocRsp(): HT_DISABLE\n"); return; } @@ -1043,7 +1041,7 @@ void HTOnAssocRsp(struct ieee80211_device *ieee) // Replace MPDU factor declared in original association response frame format. 2007.08.20 by Emily if (ieee->current_network.bssht.bdRT2RTAggregation) { - if( ieee->pairwise_key_type != KEY_TYPE_NA) + if (ieee->pairwise_key_type != KEY_TYPE_NA) // Realtek may set 32k in security mode and 64k for others pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor; else @@ -1332,8 +1330,7 @@ u8 HTCCheck(struct ieee80211_device *ieee, u8 *pFrame) { if(ieee->pHTInfo->bCurrentHTSupport) { - if( (IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) - { + if ((IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) { IEEE80211_DEBUG(IEEE80211_DL_HT, "HT CONTROL FILED EXIST!!\n"); return true; } diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 929ac29197cc..e031a253e2ae 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -1791,8 +1791,8 @@ static void rtl8192_link_change(struct net_device *dev) } static struct ieee80211_qos_parameters def_qos_parameters = { - {3, 3, 3, 3},/* cw_min */ - {7, 7, 7, 7},/* cw_max */ + {cpu_to_le16(3), cpu_to_le16(3), cpu_to_le16(3), cpu_to_le16(3)}, + {cpu_to_le16(7), cpu_to_le16(7), cpu_to_le16(7), cpu_to_le16(7)}, {2, 2, 2, 2},/* aifs */ {0, 0, 0, 0},/* flags */ {0, 0, 0, 0} /* tx_op_limit */ @@ -1821,8 +1821,11 @@ static void rtl8192_qos_activate(struct work_struct *work) struct net_device *dev = priv->ieee80211->dev; struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters; u8 mode = priv->ieee80211->current_network.mode; - u8 u1bAIFS; + u32 u1bAIFS; u32 u4bAcParam; + u32 op_limit; + u32 cw_max; + u32 cw_min; int i; mutex_lock(&priv->mutex); @@ -1835,11 +1838,14 @@ static void rtl8192_qos_activate(struct work_struct *work) for (i = 0; i < QOS_QUEUE_NUM; i++) { //Mode G/A: slotTimeTimer = 9; Mode B: 20 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ? 9 : 20) + aSifsTime; - u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)| - (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)| - (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)| - ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET)); - + u1bAIFS <<= AC_PARAM_AIFS_OFFSET; + op_limit = (u32)le16_to_cpu(qos_parameters->tx_op_limit[i]); + op_limit <<= AC_PARAM_TXOP_LIMIT_OFFSET; + cw_max = (u32)le16_to_cpu(qos_parameters->cw_max[i]); + cw_max <<= AC_PARAM_ECW_MAX_OFFSET; + cw_min = (u32)le16_to_cpu(qos_parameters->cw_min[i]); + cw_min <<= AC_PARAM_ECW_MIN_OFFSET; + u4bAcParam = op_limit | cw_max | cw_min | u1bAIFS; write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam); } diff --git a/drivers/staging/rtl8192u/r8192U_dm.c b/drivers/staging/rtl8192u/r8192U_dm.c index b0b66fba563b..936565d46014 100644 --- a/drivers/staging/rtl8192u/r8192U_dm.c +++ b/drivers/staging/rtl8192u/r8192U_dm.c @@ -1476,14 +1476,12 @@ static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14) rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); //Write 0xa24 ~ 0xa27 - TempVal = 0; TempVal = priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[2] + (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[3]<<8) + (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[4]<<16)+ (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[5]<<24); rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); //Write 0xa28 0xa29 - TempVal = 0; TempVal = priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[6] + (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[7]<<8) ; @@ -1496,14 +1494,12 @@ static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14) rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); //Write 0xa24 ~ 0xa27 - TempVal = 0; TempVal = priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[2] + (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[3]<<8) + (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[4]<<16)+ (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[5]<<24); rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); //Write 0xa28 0xa29 - TempVal = 0; TempVal = priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[6] + (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[7]<<8) ; @@ -1528,7 +1524,6 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter1, TempVal); //Write 0xa24 ~ 0xa27 - TempVal = 0; TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16)+ @@ -1537,7 +1532,6 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter2, TempVal); //Write 0xa28 0xa29 - TempVal = 0; TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8) ; @@ -1556,7 +1550,6 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter1, TempVal); //Write 0xa24 ~ 0xa27 - TempVal = 0; TempVal = CCKSwingTable_Ch14[priv->CCK_index][2] + (CCKSwingTable_Ch14[priv->CCK_index][3]<<8) + (CCKSwingTable_Ch14[priv->CCK_index][4]<<16)+ @@ -1565,7 +1558,6 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter2, TempVal); //Write 0xa28 0xa29 - TempVal = 0; TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] + (CCKSwingTable_Ch14[priv->CCK_index][7]<<8) ; @@ -1810,85 +1802,6 @@ void dm_change_dynamic_initgain_thresh(struct net_device *dev, u32 dm_type, } } /* DM_ChangeDynamicInitGainThresh */ -void -dm_change_rxpath_selection_setting( - struct net_device *dev, - s32 DM_Type, - s32 DM_Value) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - prate_adaptive pRA = (prate_adaptive)&(priv->rate_adaptive); - - - if(DM_Type == 0) - { - if(DM_Value > 1) - DM_Value = 1; - DM_RxPathSelTable.Enable = (u8)DM_Value; - } - else if(DM_Type == 1) - { - if(DM_Value > 1) - DM_Value = 1; - DM_RxPathSelTable.DbgMode = (u8)DM_Value; - } - else if(DM_Type == 2) - { - if(DM_Value > 40) - DM_Value = 40; - DM_RxPathSelTable.SS_TH_low = (u8)DM_Value; - } - else if(DM_Type == 3) - { - if(DM_Value > 25) - DM_Value = 25; - DM_RxPathSelTable.diff_TH = (u8)DM_Value; - } - else if(DM_Type == 4) - { - if(DM_Value >= CCK_Rx_Version_MAX) - DM_Value = CCK_Rx_Version_1; - DM_RxPathSelTable.cck_method= (u8)DM_Value; - } - else if(DM_Type == 10) - { - if(DM_Value > 100) - DM_Value = 50; - DM_RxPathSelTable.rf_rssi[0] = (u8)DM_Value; - } - else if(DM_Type == 11) - { - if(DM_Value > 100) - DM_Value = 50; - DM_RxPathSelTable.rf_rssi[1] = (u8)DM_Value; - } - else if(DM_Type == 12) - { - if(DM_Value > 100) - DM_Value = 50; - DM_RxPathSelTable.rf_rssi[2] = (u8)DM_Value; - } - else if(DM_Type == 13) - { - if(DM_Value > 100) - DM_Value = 50; - DM_RxPathSelTable.rf_rssi[3] = (u8)DM_Value; - } - else if(DM_Type == 20) - { - if(DM_Value > 1) - DM_Value = 1; - pRA->ping_rssi_enable = (u8)DM_Value; - } - else if(DM_Type == 21) - { - if(DM_Value > 30) - DM_Value = 30; - pRA->ping_rssi_thresh_for_ra = DM_Value; - } -} - - /*----------------------------------------------------------------------------- * Function: dm_dig_init() * @@ -3554,7 +3467,6 @@ static void dm_check_txrateandretrycount(struct net_device *dev) static void dm_send_rssi_tofw(struct net_device *dev) { - DCMD_TXCMD_T tx_cmd; struct r8192_priv *priv = ieee80211_priv(dev); // If we test chariot, we should stop the TX command ? @@ -3562,9 +3474,6 @@ static void dm_send_rssi_tofw(struct net_device *dev) // 0x1e0(byte) to notify driver. write_nic_byte(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb); return; - tx_cmd.Op = TXCMD_SET_RX_RSSI; - tx_cmd.Length = 4; - tx_cmd.Value = priv->undecorated_smoothed_pwdb; } /*---------------------------Define function prototype------------------------*/ diff --git a/drivers/staging/rtl8192u/r8192U_wx.c b/drivers/staging/rtl8192u/r8192U_wx.c index 28f60d2dbe5b..361d2d0c3df1 100644 --- a/drivers/staging/rtl8192u/r8192U_wx.c +++ b/drivers/staging/rtl8192u/r8192U_wx.c @@ -171,7 +171,6 @@ static int r8192_wx_set_crcmon(struct net_device *dev, struct r8192_priv *priv = ieee80211_priv(dev); int *parms = (int *)extra; int enable = (parms[0] > 0); - short prev = priv->crcmon; down(&priv->wx_sem); @@ -183,11 +182,6 @@ static int r8192_wx_set_crcmon(struct net_device *dev, DMESG("bad CRC in monitor mode are %s", priv->crcmon ? "accepted" : "rejected"); - if (prev != priv->crcmon && priv->up) { - /* rtl8180_down(dev); */ - /* rtl8180_up(dev); */ - } - up(&priv->wx_sem); return 0; diff --git a/drivers/staging/rtl8192u/r819xU_firmware.c b/drivers/staging/rtl8192u/r819xU_firmware.c index f66ad8a0dfe0..c230be290ab6 100644 --- a/drivers/staging/rtl8192u/r819xU_firmware.c +++ b/drivers/staging/rtl8192u/r819xU_firmware.c @@ -45,6 +45,7 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, unsigned char *seg_ptr; cb_desc *tcb_desc; u8 bLastIniPkt; + u8 index; firmware_init_param(dev); //Fragmentation might be required @@ -78,18 +79,19 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, * Transform from little endian to big endian * and pending zero */ - for (i=0; i < frag_length; i+=4) { - *seg_ptr++ = ((i+0)<frag_length)?code_virtual_address[i+3]:0; - *seg_ptr++ = ((i+1)<frag_length)?code_virtual_address[i+2]:0; - *seg_ptr++ = ((i+2)<frag_length)?code_virtual_address[i+1]:0; - *seg_ptr++ = ((i+3)<frag_length)?code_virtual_address[i+0]:0; + for (i = 0; i < frag_length; i += 4) { + *seg_ptr++ = ((i+0) < frag_length)?code_virtual_address[i+3] : 0; + *seg_ptr++ = ((i+1) < frag_length)?code_virtual_address[i+2] : 0; + *seg_ptr++ = ((i+2) < frag_length)?code_virtual_address[i+1] : 0; + *seg_ptr++ = ((i+3) < frag_length)?code_virtual_address[i+0] : 0; } - tcb_desc->txbuf_size= (u16)i; + tcb_desc->txbuf_size = (u16)i; skb_put(skb, i); - if (!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index)|| - (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index]))||\ - (priv->ieee80211->queue_stop)) { + index = tcb_desc->queue_index; + if (!priv->ieee80211->check_nic_enough_desc(dev, index) || + (!skb_queue_empty(&priv->ieee80211->skb_waitQ[index])) || + (priv->ieee80211->queue_stop)) { RT_TRACE(COMP_FIRMWARE,"=====================================================> tx full!\n"); skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb); } else { diff --git a/drivers/staging/rtl8192u/r819xU_firmware.h b/drivers/staging/rtl8192u/r819xU_firmware.h index c48c884aa1af..cfa222350a9a 100644 --- a/drivers/staging/rtl8192u/r819xU_firmware.h +++ b/drivers/staging/rtl8192u/r819xU_firmware.h @@ -12,15 +12,15 @@ #define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) (4*(v/4) - 8 - USB_HWDESC_HEADER_LEN) //#endif -typedef enum _firmware_init_step{ +typedef enum _firmware_init_step { FW_INIT_STEP0_BOOT = 0, FW_INIT_STEP1_MAIN = 1, FW_INIT_STEP2_DATA = 2, -}firmware_init_step_e; +} firmware_init_step_e; -typedef enum _opt_rst_type{ +typedef enum _opt_rst_type { OPT_SYSTEM_RESET = 0, OPT_FIRMWARE_RESET = 1, -}opt_rst_type_e; +} opt_rst_type_e; #endif diff --git a/drivers/staging/rtl8192u/r819xU_phy.c b/drivers/staging/rtl8192u/r819xU_phy.c index e9c15fe8ded5..058960251bac 100644 --- a/drivers/staging/rtl8192u/r819xU_phy.c +++ b/drivers/staging/rtl8192u/r819xU_phy.c @@ -1463,6 +1463,7 @@ void rtl8192_SwChnl_WorkItem(struct net_device *dev) u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel) { struct r8192_priv *priv = ieee80211_priv(dev); + RT_TRACE(COMP_CH, "%s(), SwChnlInProgress: %d\n", __func__, priv->SwChnlInProgress); if (!priv->up) diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c index 1d6ade05fa18..324da34383ea 100644 --- a/drivers/staging/rtl8712/hal_init.c +++ b/drivers/staging/rtl8712/hal_init.c @@ -86,7 +86,7 @@ static u32 rtl871x_open_fw(struct _adapter *padapter, const u8 **ppmappedfw) (int)padapter->fw->size); return 0; } - *ppmappedfw = (u8 *)((*praw)->data); + *ppmappedfw = (*praw)->data; return (*praw)->size; } @@ -136,15 +136,10 @@ static void update_fwhdr(struct fw_hdr *pfwhdr, const u8 *pmappedfw) static u8 chk_fwhdr(struct fw_hdr *pfwhdr, u32 ulfilelength) { u32 fwhdrsz, fw_sz; - u8 intf, rfconf; /* check signature */ if ((pfwhdr->signature != 0x8712) && (pfwhdr->signature != 0x8192)) return _FAIL; - /* check interface */ - intf = (u8)((pfwhdr->version&0x3000) >> 12); - /* check rf_conf */ - rfconf = (u8)((pfwhdr->version&0xC000) >> 14); /* check fw_priv_sze & sizeof(struct fw_priv) */ if (pfwhdr->fw_priv_sz != sizeof(struct fw_priv)) return _FAIL; @@ -162,7 +157,7 @@ static u8 rtl8712_dl_fw(struct _adapter *padapter) sint i; u8 tmp8, tmp8_a; u16 tmp16; - u32 maxlen = 0, tmp32; /* for compare usage */ + u32 maxlen = 0; /* for compare usage */ uint dump_imem_sz, imem_sz, dump_emem_sz, emem_sz; /* max = 49152; */ struct fw_hdr fwhdr; u32 ulfilelength; /* FW file size */ @@ -262,7 +257,7 @@ static u8 rtl8712_dl_fw(struct _adapter *padapter) if (tmp8_a != (tmp8|BIT(2))) goto exit_fail; - tmp32 = r8712_read32(padapter, TCR); + r8712_read32(padapter, TCR); /* 4.polling IMEM Ready */ i = 100; diff --git a/drivers/staging/rtl8712/ieee80211.c b/drivers/staging/rtl8712/ieee80211.c index fe9459e483c5..57868085ce58 100644 --- a/drivers/staging/rtl8712/ieee80211.c +++ b/drivers/staging/rtl8712/ieee80211.c @@ -124,11 +124,10 @@ u8 *r8712_get_ie(u8 *pbuf, sint index, sint *len, sint limit) if (*p == index) { *len = *(p + 1); return p; - } else { - tmp = *(p + 1); - p += (tmp + 2); - i += (tmp + 2); } + tmp = *(p + 1); + p += (tmp + 2); + i += (tmp + 2); if (i >= limit) break; } @@ -237,10 +236,9 @@ unsigned char *r8712_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit) goto check_next_ie; *wpa_ie_len = *(pbuf + 1); return pbuf; - } else { - *wpa_ie_len = 0; - return NULL; } + *wpa_ie_len = 0; + return NULL; check_next_ie: limit = limit - (pbuf - pie) - 2 - len; if (limit <= 0) @@ -370,13 +368,12 @@ int r8712_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, int r8712_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, u8 *wpa_ie, u16 *wpa_len) { - u8 authmode, sec_idx; + u8 authmode; u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01}; uint cnt; /*Search required WPA or WPA2 IE and copy to sec_ie[ ]*/ cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_); - sec_idx = 0; while (cnt < in_len) { authmode = in_ie[cnt]; if ((authmode == _WPA_IE_ID_) && @@ -414,7 +411,7 @@ int r8712_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen) cnt += in_ie[cnt+1]+2; match = true; break; - } else + } cnt += in_ie[cnt+1]+2; /* goto next */ } return match; diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h index d7a357b8d2d1..5153ad9c2c75 100644 --- a/drivers/staging/rtl8712/osdep_service.h +++ b/drivers/staging/rtl8712/osdep_service.h @@ -88,17 +88,13 @@ static inline u32 _down_sema(struct semaphore *sema) { if (down_interruptible(sema)) return _FAIL; - else - return _SUCCESS; + return _SUCCESS; } static inline u32 end_of_queue_search(struct list_head *head, struct list_head *plist) { - if (head == plist) - return true; - else - return false; + return (head == plist); } static inline void sleep_schedulable(int ms) diff --git a/drivers/staging/rtl8712/recv_linux.c b/drivers/staging/rtl8712/recv_linux.c index 495ee1205e02..0631f3638257 100644 --- a/drivers/staging/rtl8712/recv_linux.c +++ b/drivers/staging/rtl8712/recv_linux.c @@ -146,7 +146,7 @@ void r8712_os_read_port(struct _adapter *padapter, struct recv_buf *precvbuf) dev_kfree_skb_any(precvbuf->pskb); precvbuf->pskb = NULL; precvbuf->reuse = false; - if (precvbuf->irp_pending == false) + if (!precvbuf->irp_pending) r8712_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); } diff --git a/drivers/staging/rtl8712/rtl8712_cmd.c b/drivers/staging/rtl8712/rtl8712_cmd.c index 720e8a15db96..62e53cc1d8b9 100644 --- a/drivers/staging/rtl8712/rtl8712_cmd.c +++ b/drivers/staging/rtl8712/rtl8712_cmd.c @@ -157,10 +157,8 @@ static u8 read_bbreg_hdl(struct _adapter *padapter, u8 *pbuf) { u32 val; void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd); - struct readBB_parm *prdbbparm; struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; - prdbbparm = (struct readBB_parm *)pcmd->parmbuf; if (pcmd->rsp && pcmd->rspsz > 0) memcpy(pcmd->rsp, (u8 *)&val, pcmd->rspsz); pcmd_callback = cmd_callback[pcmd->cmdcode].callback; @@ -174,10 +172,8 @@ static u8 read_bbreg_hdl(struct _adapter *padapter, u8 *pbuf) static u8 write_bbreg_hdl(struct _adapter *padapter, u8 *pbuf) { void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd); - struct writeBB_parm *pwritebbparm; struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; - pwritebbparm = (struct writeBB_parm *)pcmd->parmbuf; pcmd_callback = cmd_callback[pcmd->cmdcode].callback; if (pcmd_callback == NULL) r8712_free_cmd_obj(pcmd); @@ -190,10 +186,8 @@ static u8 read_rfreg_hdl(struct _adapter *padapter, u8 *pbuf) { u32 val; void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd); - struct readRF_parm *prdrfparm; struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; - prdrfparm = (struct readRF_parm *)pcmd->parmbuf; if (pcmd->rsp && pcmd->rspsz > 0) memcpy(pcmd->rsp, (u8 *)&val, pcmd->rspsz); pcmd_callback = cmd_callback[pcmd->cmdcode].callback; @@ -207,10 +201,8 @@ static u8 read_rfreg_hdl(struct _adapter *padapter, u8 *pbuf) static u8 write_rfreg_hdl(struct _adapter *padapter, u8 *pbuf) { void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd); - struct writeRF_parm *pwriterfparm; struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; - pwriterfparm = (struct writeRF_parm *)pcmd->parmbuf; pcmd_callback = cmd_callback[pcmd->cmdcode].callback; if (pcmd_callback == NULL) r8712_free_cmd_obj(pcmd); @@ -222,9 +214,7 @@ static u8 write_rfreg_hdl(struct _adapter *padapter, u8 *pbuf) static u8 sys_suspend_hdl(struct _adapter *padapter, u8 *pbuf) { struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; - struct usb_suspend_parm *psetusbsuspend; - psetusbsuspend = (struct usb_suspend_parm *)pcmd->parmbuf; r8712_free_cmd_obj(pcmd); return H2C_SUCCESS; } @@ -320,7 +310,7 @@ void r8712_fw_cmd_data(struct _adapter *pAdapter, u32 *value, u8 flag) int r8712_cmd_thread(void *context) { struct cmd_obj *pcmd; - unsigned int cmdsz, wr_sz, *pcmdbuf, *prspbuf; + unsigned int cmdsz, wr_sz, *pcmdbuf; struct tx_desc *pdesc; void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd); struct _adapter *padapter = (struct _adapter *)context; @@ -342,7 +332,6 @@ _next: continue; } pcmdbuf = (unsigned int *)pcmdpriv->cmd_buf; - prspbuf = (unsigned int *)pcmdpriv->rsp_buf; pdesc = (struct tx_desc *)pcmdbuf; memset(pdesc, 0, TXDESC_SIZE); pcmd = cmd_hdl_filter(padapter, pcmd); diff --git a/drivers/staging/rtl8712/rtl8712_efuse.c b/drivers/staging/rtl8712/rtl8712_efuse.c index c9eeb4270ab9..d95716999498 100644 --- a/drivers/staging/rtl8712/rtl8712_efuse.c +++ b/drivers/staging/rtl8712/rtl8712_efuse.c @@ -219,13 +219,12 @@ u16 r8712_efuse_get_current_size(struct _adapter *padapter) { int bContinual = true; u16 efuse_addr = 0; - u8 hoffset = 0, hworden = 0; + u8 hworden = 0; u8 efuse_data, word_cnts = 0; while (bContinual && efuse_one_byte_read(padapter, efuse_addr, &efuse_data) && (efuse_addr < efuse_available_max_size)) { if (efuse_data != 0xFF) { - hoffset = (efuse_data >> 4) & 0x0F; hworden = efuse_data & 0x0F; word_cnts = calculate_word_cnts(hworden); /* read next header */ @@ -414,19 +413,18 @@ u8 r8712_efuse_pg_packet_write(struct _adapter *padapter, const u8 offset, bResult = false; } break; - } else { /* write header fail */ - bResult = false; - if (0xFF == efuse_data) - return bResult; /* nothing damaged. */ - /* call rescue procedure */ - if (fix_header(padapter, efuse_data, efuse_addr) == - false) - return false; /* rescue fail */ - - if (++repeat_times > _REPEAT_THRESHOLD_) /* fail */ - break; - /* otherwise, take another risk... */ } + /* write header fail */ + bResult = false; + if (0xFF == efuse_data) + return bResult; /* nothing damaged. */ + /* call rescue procedure */ + if (!fix_header(padapter, efuse_data, efuse_addr)) + return false; /* rescue fail */ + + if (++repeat_times > _REPEAT_THRESHOLD_) /* fail */ + break; + /* otherwise, take another risk... */ } return bResult; } @@ -541,15 +539,16 @@ u8 r8712_efuse_map_write(struct _adapter *padapter, u16 addr, u16 cnts, } idx++; break; - } else { - if ((data[idx] != pktdata[i]) || (data[idx+1] != - pktdata[i+1])) { - word_en &= ~BIT(i >> 1); - newdata[j++] = data[idx]; - newdata[j++] = data[idx + 1]; - } - idx += 2; } + + if ((data[idx] != pktdata[i]) || (data[idx+1] != + pktdata[i+1])) { + word_en &= ~BIT(i >> 1); + newdata[j++] = data[idx]; + newdata[j++] = data[idx + 1]; + } + idx += 2; + if (idx == cnts) break; } diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c index b27806209268..cd8b444b255b 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.c +++ b/drivers/staging/rtl8712/rtl8712_recv.c @@ -158,8 +158,6 @@ int r8712_free_recvframe(union recv_frame *precvframe, static void update_recvframe_attrib_from_recvstat(struct rx_pkt_attrib *pattrib, struct recv_stat *prxstat) { - u32 *pphy_info; - struct phy_stat *pphy_stat; u16 drvinfo_sz = 0; drvinfo_sz = (le32_to_cpu(prxstat->rxdw0)&0x000f0000)>>16; @@ -189,10 +187,6 @@ static void update_recvframe_attrib_from_recvstat(struct rx_pkt_attrib *pattrib, /*Offset 16*/ /*Offset 20*/ /*phy_info*/ - if (drvinfo_sz) { - pphy_stat = (struct phy_stat *)(prxstat+1); - pphy_info = (u32 *)prxstat+1; - } } /*perform defrag*/ @@ -200,7 +194,7 @@ static union recv_frame *recvframe_defrag(struct _adapter *adapter, struct __queue *defrag_q) { struct list_head *plist, *phead; - u8 *data, wlanhdr_offset; + u8 wlanhdr_offset; u8 curfragnum; struct recv_frame_hdr *pfhdr, *pnfhdr; union recv_frame *prframe, *pnextrframe; @@ -223,7 +217,6 @@ static union recv_frame *recvframe_defrag(struct _adapter *adapter, curfragnum++; plist = &defrag_q->queue; plist = plist->next; - data = get_recvframe_data(prframe); while (end_of_queue_search(phead, plist) == false) { pnextrframe = LIST_CONTAINOR(plist, union recv_frame, u); pnfhdr = &pnextrframe->u.hdr; @@ -436,13 +429,11 @@ void r8712_rxcmd_event_hdl(struct _adapter *padapter, void *prxcmdbuf) { uint voffset; u8 *poffset; - u16 pkt_len, cmd_len, drvinfo_sz; - u8 eid, cmd_seq; + u16 cmd_len, drvinfo_sz; struct recv_stat *prxstat; poffset = (u8 *)prxcmdbuf; voffset = *(uint *)poffset; - pkt_len = le32_to_cpu(voffset) & 0x00003fff; prxstat = (struct recv_stat *)prxcmdbuf; drvinfo_sz = ((le32_to_cpu(prxstat->rxdw0) & 0x000f0000) >> 16); drvinfo_sz = drvinfo_sz << 3; @@ -450,8 +441,6 @@ void r8712_rxcmd_event_hdl(struct _adapter *padapter, void *prxcmdbuf) do { voffset = *(uint *)poffset; cmd_len = (u16)(le32_to_cpu(voffset) & 0xffff); - cmd_seq = (u8)((le32_to_cpu(voffset) >> 24) & 0x7f); - eid = (u8)((le32_to_cpu(voffset) >> 16) & 0xff); r8712_event_handle(padapter, (uint *)poffset); poffset += (cmd_len + 8);/*8 bytes alignment*/ } while (le32_to_cpu(voffset) & BIT(31)); @@ -533,11 +522,10 @@ int r8712_recv_indicatepkts_in_order(struct _adapter *padapter, if (bforced == true) { if (list_empty(phead)) return true; - else { - prframe = LIST_CONTAINOR(plist, union recv_frame, u); - pattrib = &prframe->u.hdr.attrib; - preorder_ctrl->indicate_seq = pattrib->seq_num; - } + + prframe = LIST_CONTAINOR(plist, union recv_frame, u); + pattrib = &prframe->u.hdr.attrib; + preorder_ctrl->indicate_seq = pattrib->seq_num; } /* Prepare indication list and indication. * Check if there is any packet need indicate. */ diff --git a/drivers/staging/rtl8712/rtl871x_cmd.c b/drivers/staging/rtl8712/rtl871x_cmd.c index d9c1561e3272..fe5e315319f7 100644 --- a/drivers/staging/rtl8712/rtl871x_cmd.c +++ b/drivers/staging/rtl8712/rtl871x_cmd.c @@ -205,12 +205,12 @@ void r8712_free_cmd_obj(struct cmd_obj *pcmd) { if ((pcmd->cmdcode != _JoinBss_CMD_) && (pcmd->cmdcode != _CreateBss_CMD_)) - kfree((unsigned char *)pcmd->parmbuf); + kfree(pcmd->parmbuf); if (pcmd->rsp != NULL) { if (pcmd->rspsz != 0) - kfree((unsigned char *)pcmd->rsp); + kfree(pcmd->rsp); } - kfree((unsigned char *)pcmd); + kfree(pcmd); } /* @@ -232,7 +232,7 @@ u8 r8712_sitesurvey_cmd(struct _adapter *padapter, return _FAIL; psurveyPara = kmalloc(sizeof(*psurveyPara), GFP_ATOMIC); if (psurveyPara == NULL) { - kfree((unsigned char *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, @@ -264,7 +264,7 @@ u8 r8712_setdatarate_cmd(struct _adapter *padapter, u8 *rateset) return _FAIL; pbsetdataratepara = kmalloc(sizeof(*pbsetdataratepara), GFP_ATOMIC); if (pbsetdataratepara == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara, @@ -286,7 +286,7 @@ u8 r8712_set_chplan_cmd(struct _adapter *padapter, int chplan) return _FAIL; psetchplanpara = kmalloc(sizeof(*psetchplanpara), GFP_ATOMIC); if (psetchplanpara == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, psetchplanpara, @@ -307,7 +307,7 @@ u8 r8712_setbasicrate_cmd(struct _adapter *padapter, u8 *rateset) return _FAIL; pssetbasicratepara = kmalloc(sizeof(*pssetbasicratepara), GFP_ATOMIC); if (pssetbasicratepara == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, pssetbasicratepara, @@ -329,7 +329,7 @@ u8 r8712_setptm_cmd(struct _adapter *padapter, u8 type) return _FAIL; pwriteptmparm = kmalloc(sizeof(*pwriteptmparm), GFP_ATOMIC); if (pwriteptmparm == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, pwriteptmparm, GEN_CMD_CODE(_SetPT)); @@ -349,7 +349,7 @@ u8 r8712_setfwdig_cmd(struct _adapter *padapter, u8 type) return _FAIL; pwriteptmparm = kmalloc(sizeof(*pwriteptmparm), GFP_ATOMIC); if (pwriteptmparm == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, pwriteptmparm, GEN_CMD_CODE(_SetDIG)); @@ -369,7 +369,7 @@ u8 r8712_setfwra_cmd(struct _adapter *padapter, u8 type) return _FAIL; pwriteptmparm = kmalloc(sizeof(*pwriteptmparm), GFP_ATOMIC); if (pwriteptmparm == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, pwriteptmparm, GEN_CMD_CODE(_SetRA)); @@ -389,7 +389,7 @@ u8 r8712_setrfreg_cmd(struct _adapter *padapter, u8 offset, u32 val) return _FAIL; pwriterfparm = kmalloc(sizeof(*pwriterfparm), GFP_ATOMIC); if (pwriterfparm == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, pwriterfparm, GEN_CMD_CODE(_SetRFReg)); @@ -410,7 +410,7 @@ u8 r8712_getrfreg_cmd(struct _adapter *padapter, u8 offset, u8 *pval) return _FAIL; prdrfparm = kmalloc(sizeof(*prdrfparm), GFP_ATOMIC); if (prdrfparm == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } INIT_LIST_HEAD(&ph2c->list); @@ -470,7 +470,6 @@ u8 r8712_createbss_cmd(struct _adapter *padapter) u8 r8712_joinbss_cmd(struct _adapter *padapter, struct wlan_network *pnetwork) { - u8 *auth; uint t_len = 0; struct ndis_wlan_bssid_ex *psecnetwork; struct cmd_obj *pcmd; @@ -517,7 +516,6 @@ u8 r8712_joinbss_cmd(struct _adapter *padapter, struct wlan_network *pnetwork) return _FAIL; } memcpy(psecnetwork, &pnetwork->network, t_len); - auth = &psecuritypriv->authenticator_ie[0]; psecuritypriv->authenticator_ie[0] = (unsigned char) psecnetwork->IELength; if ((psecnetwork->IELength-12) < (256 - 1)) @@ -527,7 +525,7 @@ u8 r8712_joinbss_cmd(struct _adapter *padapter, struct wlan_network *pnetwork) memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], (256-1)); psecnetwork->IELength = 0; - /* If the the driver wants to use the bssid to create the connection. + /* If the driver wants to use the bssid to create the connection. * If not, we copy the connecting AP's MAC address to it so that * the driver just has the bssid information for PMKIDList searching. */ @@ -626,7 +624,7 @@ u8 r8712_disassoc_cmd(struct _adapter *padapter) /* for sta_mode */ return _FAIL; pdisconnect = kmalloc(sizeof(*pdisconnect), GFP_ATOMIC); if (pdisconnect == NULL) { - kfree((u8 *)pdisconnect_cmd); + kfree(pdisconnect_cmd); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(pdisconnect_cmd, pdisconnect, @@ -648,7 +646,7 @@ u8 r8712_setopmode_cmd(struct _adapter *padapter, return _FAIL; psetop = kmalloc(sizeof(*psetop), GFP_ATOMIC); if (psetop == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_); @@ -672,13 +670,13 @@ u8 r8712_setstakey_cmd(struct _adapter *padapter, u8 *psta, u8 unicast_key) return _FAIL; psetstakey_para = kmalloc(sizeof(*psetstakey_para), GFP_ATOMIC); if (psetstakey_para == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } psetstakey_rsp = kmalloc(sizeof(*psetstakey_rsp), GFP_ATOMIC); if (psetstakey_rsp == NULL) { - kfree((u8 *) ph2c); - kfree((u8 *) psetstakey_para); + kfree(ph2c); + kfree(psetstakey_para); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); @@ -712,7 +710,7 @@ u8 r8712_setrfintfs_cmd(struct _adapter *padapter, u8 mode) return _FAIL; psetrfintfsparm = kmalloc(sizeof(*psetrfintfsparm), GFP_ATOMIC); if (psetrfintfsparm == NULL) { - kfree((unsigned char *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, psetrfintfsparm, @@ -734,7 +732,7 @@ u8 r8712_setrttbl_cmd(struct _adapter *padapter, return _FAIL; psetrttblparm = kmalloc(sizeof(*psetrttblparm), GFP_ATOMIC); if (psetrttblparm == NULL) { - kfree((unsigned char *)ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, @@ -755,7 +753,7 @@ u8 r8712_gettssi_cmd(struct _adapter *padapter, u8 offset, u8 *pval) return _FAIL; prdtssiparm = kmalloc(sizeof(*prdtssiparm), GFP_ATOMIC); if (prdtssiparm == NULL) { - kfree((unsigned char *) ph2c); + kfree(ph2c); return _FAIL; } INIT_LIST_HEAD(&ph2c->list); @@ -781,7 +779,7 @@ u8 r8712_setMacAddr_cmd(struct _adapter *padapter, u8 *mac_addr) return _FAIL; psetMacAddr_para = kmalloc(sizeof(*psetMacAddr_para), GFP_ATOMIC); if (psetMacAddr_para == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, psetMacAddr_para, @@ -803,13 +801,13 @@ u8 r8712_setassocsta_cmd(struct _adapter *padapter, u8 *mac_addr) return _FAIL; psetassocsta_para = kmalloc(sizeof(*psetassocsta_para), GFP_ATOMIC); if (psetassocsta_para == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } psetassocsta_rsp = kmalloc(sizeof(*psetassocsta_rsp), GFP_ATOMIC); if (psetassocsta_rsp == NULL) { - kfree((u8 *)ph2c); - kfree((u8 *)psetassocsta_para); + kfree(ph2c); + kfree(psetassocsta_para); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, psetassocsta_para, _SetAssocSta_CMD_); @@ -831,7 +829,7 @@ u8 r8712_addbareq_cmd(struct _adapter *padapter, u8 tid) return _FAIL; paddbareq_parm = kmalloc(sizeof(*paddbareq_parm), GFP_ATOMIC); if (paddbareq_parm == NULL) { - kfree((unsigned char *)ph2c); + kfree(ph2c); return _FAIL; } paddbareq_parm->tid = tid; @@ -852,7 +850,7 @@ u8 r8712_wdg_wk_cmd(struct _adapter *padapter) return _FAIL; pdrvintcmd_param = kmalloc(sizeof(*pdrvintcmd_param), GFP_ATOMIC); if (pdrvintcmd_param == NULL) { - kfree((unsigned char *)ph2c); + kfree(ph2c); return _FAIL; } pdrvintcmd_param->i_cid = WDG_WK_CID; @@ -1026,7 +1024,7 @@ u8 r8712_disconnectCtrlEx_cmd(struct _adapter *adapter, u32 enableDrvCtrl, return _FAIL; param = kzalloc(sizeof(*param), GFP_ATOMIC); if (param == NULL) { - kfree((unsigned char *) ph2c); + kfree(ph2c); return _FAIL; } diff --git a/drivers/staging/rtl8712/rtl871x_io.c b/drivers/staging/rtl8712/rtl871x_io.c index d7b63aedead7..e4e5b13cb927 100644 --- a/drivers/staging/rtl8712/rtl871x_io.c +++ b/drivers/staging/rtl8712/rtl871x_io.c @@ -93,7 +93,7 @@ static uint register_intf_hdl(u8 *dev, struct intf_hdl *pintfhdl) pintfhdl->intf_option = 0; pintfhdl->adapter = dev; pintfhdl->intf_dev = (u8 *)&(adapter->dvobjpriv); - if (_init_intf_hdl(adapter, pintfhdl) == false) + if (!_init_intf_hdl(adapter, pintfhdl)) goto register_intf_hdl_fail; return _SUCCESS; register_intf_hdl_fail: @@ -142,7 +142,7 @@ uint r8712_alloc_io_queue(struct _adapter *adapter) alloc_io_queue_fail: if (pio_queue) { kfree(pio_queue->pallocated_free_ioreqs_buf); - kfree((u8 *)pio_queue); + kfree(pio_queue); } adapter->pio_queue = NULL; return _FAIL; @@ -156,6 +156,6 @@ void r8712_free_io_queue(struct _adapter *adapter) kfree(pio_queue->pallocated_free_ioreqs_buf); adapter->pio_queue = NULL; unregister_intf_hdl(&pio_queue->intf); - kfree((u8 *)pio_queue); + kfree(pio_queue); } } diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index 8e42ce06e5d7..73b7d864ccbd 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -170,7 +170,7 @@ static inline char *translate_scan(struct _adapter *padapter, s8 *p; u32 i = 0, ht_ielen = 0; u16 cap, ht_cap = false, mcs_rate; - u8 rssi, bw_40MHz = 0, short_GI = 0; + u8 rssi; if ((pnetwork->network.Configuration.DSConfig < 1) || (pnetwork->network.Configuration.DSConfig > 14)) { @@ -197,10 +197,6 @@ static inline char *translate_scan(struct _adapter *padapter, ht_cap = true; pht_capie = (struct ieee80211_ht_cap *)(p + 2); memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2); - bw_40MHz = (pht_capie->cap_info&IEEE80211_HT_CAP_SUP_WIDTH) - ? 1 : 0; - short_GI = (pht_capie->cap_info&(IEEE80211_HT_CAP_SGI_20 | - IEEE80211_HT_CAP_SGI_40)) ? 1 : 0; } /* Add the protocol name */ iwe.cmd = SIOCGIWNAME; @@ -287,12 +283,10 @@ static inline char *translate_scan(struct _adapter *padapter, u8 wpa_ie[255], rsn_ie[255]; u16 wpa_len = 0, rsn_len = 0; int n; - sint out_len = 0; - out_len = r8712_get_sec_ie(pnetwork->network.IEs, - pnetwork->network. - IELength, rsn_ie, &rsn_len, - wpa_ie, &wpa_len); + r8712_get_sec_ie(pnetwork->network.IEs, + pnetwork->network.IELength, rsn_ie, &rsn_len, + wpa_ie, &wpa_len); if (wpa_len > 0) { memset(buf, 0, MAX_WPA_IE_LEN); n = sprintf(buf, "wpa_ie="); @@ -505,14 +499,14 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, } } exit: - kfree((u8 *)pwep); + kfree(pwep); return ret; } static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie, unsigned short ielen) { - u8 *buf = NULL, *pos = NULL; + u8 *buf = NULL; int group_cipher = 0, pairwise_cipher = 0; int ret = 0; @@ -522,7 +516,6 @@ static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie, buf = kmemdup(pie, ielen, GFP_ATOMIC); if (buf == NULL) return -ENOMEM; - pos = buf; if (ielen < RSN_HEADER_LEN) { ret = -EINVAL; goto exit; @@ -1133,13 +1126,11 @@ static int r871x_wx_set_mlme(struct net_device *dev, union iwreq_data *wrqu, char *extra) { int ret = 0; - u16 reason; struct _adapter *padapter = (struct _adapter *)netdev_priv(dev); struct iw_mlme *mlme = (struct iw_mlme *) extra; if (mlme == NULL) return -1; - reason = cpu_to_le16(mlme->reason_code); switch (mlme->cmd) { case IW_MLME_DEAUTH: if (!r8712_set_802_11_disassociate(padapter)) @@ -2216,7 +2207,7 @@ static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p) } if (ret == 0 && copy_to_user(p->pointer, param, p->length)) ret = -EFAULT; - kfree((u8 *)param); + kfree(param); return ret; } diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_set.c b/drivers/staging/rtl8712/rtl871x_ioctl_set.c index 9d47eb472837..6318a0e65e6e 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_set.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_set.c @@ -77,7 +77,7 @@ static u8 do_join(struct _adapter *padapter) /* when set_ssid/set_bssid for do_join(), but scanning queue * is empty we try to issue sitesurvey firstly */ - if (pmlmepriv->sitesurveyctrl.traffic_busy == false) + if (!pmlmepriv->sitesurveyctrl.traffic_busy) r8712_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid); return true; } else { @@ -143,8 +143,7 @@ u8 r8712_set_802_11_bssid(struct _adapter *padapter, u8 *bssid) _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true) { if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN)) { - if (check_fwstate(pmlmepriv, - WIFI_STATION_STATE) == false) + if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) goto _Abort_Set_BSSID; /* driver is in * WIFI_ADHOC_MASTER_STATE */ } else { @@ -177,7 +176,7 @@ void r8712_set_802_11_ssid(struct _adapter *padapter, struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_network *pnetwork = &pmlmepriv->cur_network; - if (padapter->hw_init_completed == false) + if (!padapter->hw_init_completed) return; spin_lock_irqsave(&pmlmepriv->lock, irqL); if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) { @@ -188,10 +187,9 @@ void r8712_set_802_11_ssid(struct _adapter *padapter, if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) && (!memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength))) { - if ((check_fwstate(pmlmepriv, - WIFI_STATION_STATE) == false)) { - if (r8712_is_same_ibss(padapter, - pnetwork) == false) { + if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { + if (!r8712_is_same_ibss(padapter, + pnetwork)) { /* if in WIFI_ADHOC_MASTER_STATE or * WIFI_ADHOC_STATE, create bss or * rejoin again @@ -227,7 +225,7 @@ void r8712_set_802_11_ssid(struct _adapter *padapter, } if (padapter->securitypriv.btkip_countermeasure == true) goto _Abort_Set_SSID; - if (validate_ssid(ssid) == false) + if (!validate_ssid(ssid)) goto _Abort_Set_SSID; memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid)); pmlmepriv->assoc_by_bssid = false; @@ -308,10 +306,10 @@ u8 r8712_set_802_11_bssid_list_scan(struct _adapter *padapter) unsigned long irqL; u8 ret = true; - if (padapter == NULL) + if (!padapter) return false; pmlmepriv = &padapter->mlmepriv; - if (padapter->hw_init_completed == false) + if (!padapter->hw_init_completed) return false; spin_lock_irqsave(&pmlmepriv->lock, irqL); if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) || @@ -345,13 +343,9 @@ u8 r8712_set_802_11_authentication_mode(struct _adapter *padapter, u8 r8712_set_802_11_add_wep(struct _adapter *padapter, struct NDIS_802_11_WEP *wep) { - u8 bdefaultkey; - u8 btransmitkey; sint keyid; struct security_priv *psecuritypriv = &padapter->securitypriv; - bdefaultkey = (wep->KeyIndex & 0x40000000) > 0 ? false : true; - btransmitkey = (wep->KeyIndex & 0x80000000) > 0 ? true : false; keyid = wep->KeyIndex & 0x3fffffff; if (keyid >= WEP_KEYS) return false; diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c index 00f2e0fc4ac5..b7462e8145d6 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.c +++ b/drivers/staging/rtl8712/rtl871x_mlme.c @@ -923,7 +923,7 @@ void r8712_joinbss_event_callback(struct _adapter *adapter, u8 *pbuf) ignore_joinbss_callback: spin_unlock_irqrestore(&pmlmepriv->lock, irqL); if (sizeof(struct list_head) == 4 * sizeof(u32)) - kfree((u8 *)pnetwork); + kfree(pnetwork); } void r8712_stassoc_event_callback(struct _adapter *adapter, u8 *pbuf) @@ -1218,7 +1218,7 @@ sint r8712_set_auth(struct _adapter *adapter, psetauthparm = kzalloc(sizeof(*psetauthparm), GFP_ATOMIC); if (psetauthparm == NULL) { - kfree((unsigned char *)pcmd); + kfree(pcmd); return _FAIL; } psetauthparm->mode = (u8)psecuritypriv->AuthAlgrthm; @@ -1372,7 +1372,7 @@ static int SecIsInPMKIDList(struct _adapter *Adapter, u8 *bssid) sint r8712_restruct_sec_ie(struct _adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len) { - u8 authmode = 0, securitytype, match; + u8 authmode = 0, match; u8 sec_ie[255], uncst_oui[4], bkup_ie[255]; u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01}; uint ielength, cnt, remove_cnt; @@ -1399,21 +1399,17 @@ sint r8712_restruct_sec_ie(struct _adapter *adapter, u8 *in_ie, switch (ndissecuritytype) { case Ndis802_11Encryption1Enabled: case Ndis802_11Encryption1KeyAbsent: - securitytype = _WEP40_; uncst_oui[3] = 0x1; break; case Ndis802_11Encryption2Enabled: case Ndis802_11Encryption2KeyAbsent: - securitytype = _TKIP_; uncst_oui[3] = 0x2; break; case Ndis802_11Encryption3Enabled: case Ndis802_11Encryption3KeyAbsent: - securitytype = _AES_; uncst_oui[3] = 0x4; break; default: - securitytype = _NO_PRIVACY_; break; } /*Search required WPA or WPA2 IE and copy to sec_ie[] */ @@ -1705,7 +1701,7 @@ unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len) { u32 ielen, out_len; - unsigned char *p, *pframe; + unsigned char *p; struct ieee80211_ht_cap ht_capie; unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00}; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -1717,10 +1713,8 @@ unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie, if (p && (ielen > 0)) { if (pqospriv->qos_option == 0) { out_len = *pout_len; - pframe = r8712_set_ie(out_ie+out_len, - _VENDOR_SPECIFIC_IE_, - _WMM_IE_Length_, - WMM_IE, pout_len); + r8712_set_ie(out_ie+out_len, _VENDOR_SPECIFIC_IE_, + _WMM_IE_Length_, WMM_IE, pout_len); pqospriv->qos_option = 1; } out_len = *pout_len; @@ -1733,9 +1727,9 @@ unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie, IEEE80211_HT_CAP_DSSSCCK40; ht_capie.ampdu_params_info = (IEEE80211_HT_CAP_AMPDU_FACTOR & 0x03) | (IEEE80211_HT_CAP_AMPDU_DENSITY & 0x00); - pframe = r8712_set_ie(out_ie+out_len, _HT_CAPABILITY_IE_, - sizeof(struct ieee80211_ht_cap), - (unsigned char *)&ht_capie, pout_len); + r8712_set_ie(out_ie+out_len, _HT_CAPABILITY_IE_, + sizeof(struct ieee80211_ht_cap), + (unsigned char *)&ht_capie, pout_len); phtpriv->ht_option = 1; } return phtpriv->ht_option; @@ -1748,7 +1742,6 @@ static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len) int i, len; struct sta_info *bmc_sta, *psta; struct ieee80211_ht_cap *pht_capie; - struct ieee80211_ht_addt_info *pht_addtinfo; struct recv_reorder_ctrl *preorder_ctrl; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct ht_priv *phtpriv = &pmlmepriv->htpriv; @@ -1801,8 +1794,6 @@ static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len) p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs), _HT_ADD_INFO_IE_, &len, ie_len-sizeof(struct NDIS_802_11_FIXED_IEs)); - if (p && len > 0) - pht_addtinfo = (struct ieee80211_ht_addt_info *)(p + 2); } void r8712_issue_addbareq_cmd(struct _adapter *padapter, int priority) diff --git a/drivers/staging/rtl8712/rtl871x_mp.c b/drivers/staging/rtl8712/rtl871x_mp.c index 2ec660ad78af..3d913b9701bb 100644 --- a/drivers/staging/rtl8712/rtl871x_mp.c +++ b/drivers/staging/rtl8712/rtl871x_mp.c @@ -56,7 +56,7 @@ static int init_mp_priv(struct mp_priv *pmp_priv) pmp_priv->pallocated_mp_xmitframe_buf = kmalloc(NR_MP_XMITFRAME * sizeof(struct mp_xmit_frame) + 4, GFP_ATOMIC); - if (pmp_priv->pallocated_mp_xmitframe_buf == NULL) { + if (!pmp_priv->pallocated_mp_xmitframe_buf) { res = _FAIL; goto _exit_init_mp_priv; } @@ -173,7 +173,7 @@ u8 r8712_bb_reg_write(struct _adapter *pAdapter, u16 offset, u32 value) oldValue = r8712_bb_reg_read(pAdapter, iocmd.value); oldValue &= (0xFFFFFFFF >> ((4 - shift) * 8)); value = oldValue | (newValue << (shift * 8)); - if (fw_iocmd_write(pAdapter, iocmd, value) == false) + if (!fw_iocmd_write(pAdapter, iocmd, value)) return false; iocmd.value += 4; oldValue = r8712_bb_reg_read(pAdapter, iocmd.value); diff --git a/drivers/staging/rtl8712/rtl871x_mp_ioctl.c b/drivers/staging/rtl8712/rtl871x_mp_ioctl.c index 9827ff8143b2..a16f15e91992 100644 --- a/drivers/staging/rtl8712/rtl871x_mp_ioctl.c +++ b/drivers/staging/rtl8712/rtl871x_mp_ioctl.c @@ -1431,11 +1431,8 @@ unsigned int mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv) /*-------------------------------------------------------------------------*/ uint oid_rt_set_power_down_hdl(struct oid_par_priv *poid_par_priv) { - u8 bpwrup; - if (poid_par_priv->type_of_oid != SET_OID) return RNDIS_STATUS_NOT_ACCEPTED; - bpwrup = *(u8 *)poid_par_priv->information_buf; /*CALL the power_down function*/ return RNDIS_STATUS_SUCCESS; } diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.c b/drivers/staging/rtl8712/rtl871x_pwrctrl.c index 51dcf5555b62..ed2844d2b02a 100644 --- a/drivers/staging/rtl8712/rtl871x_pwrctrl.c +++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.c @@ -156,11 +156,9 @@ static void rpwm_workitem_callback(struct work_struct *work) struct pwrctrl_priv, rpwm_workitem); struct _adapter *padapter = container_of(pwrpriv, struct _adapter, pwrctrlpriv); - u8 cpwm = pwrpriv->cpwm; - if (pwrpriv->cpwm != pwrpriv->rpwm) { _enter_pwrlock(&pwrpriv->lock); - cpwm = r8712_read8(padapter, SDIO_HCPWM); + r8712_read8(padapter, SDIO_HCPWM); pwrpriv->rpwm_retry = 1; r8712_set_rpwm(padapter, pwrpriv->rpwm); up(&pwrpriv->lock); diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c index 9b99a71670f3..06f15f81c4d8 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.c +++ b/drivers/staging/rtl8712/rtl871x_recv.c @@ -601,7 +601,7 @@ sint r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe) { /*remove the wlanhdr and add the eth_hdr*/ sint rmv_len; - u16 eth_type, len; + u16 len; u8 bsnaphdr; u8 *psnap_type; struct ieee80211_snap_hdr *psnap; @@ -635,7 +635,6 @@ sint r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe) ptr += rmv_len; *ptr = 0x87; *(ptr+1) = 0x12; - eth_type = 0x8712; /* append rx status for mp test packets */ ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + 2) - 24); @@ -658,27 +657,11 @@ s32 r8712_recv_entry(union recv_frame *precvframe) { struct _adapter *padapter; struct recv_priv *precvpriv; - struct mlme_priv *pmlmepriv; - struct recv_stat *prxstat; - struct dvobj_priv *pdev; - u8 *phead, *pdata, *ptail, *pend; - struct __queue *pfree_recv_queue, *ppending_recv_queue; s32 ret = _SUCCESS; - struct intf_hdl *pintfhdl; padapter = precvframe->u.hdr.adapter; - pintfhdl = &padapter->pio_queue->intf; - pmlmepriv = &padapter->mlmepriv; precvpriv = &(padapter->recvpriv); - pdev = &padapter->dvobjpriv; - pfree_recv_queue = &(precvpriv->free_recv_queue); - ppending_recv_queue = &(precvpriv->recv_pending_queue); - phead = precvframe->u.hdr.rx_head; - pdata = precvframe->u.hdr.rx_data; - ptail = precvframe->u.hdr.rx_tail; - pend = precvframe->u.hdr.rx_end; - prxstat = (struct recv_stat *)phead; padapter->ledpriv.LedControlHandler(padapter, LED_CTL_RX); diff --git a/drivers/staging/rtl8712/rtl871x_recv.h b/drivers/staging/rtl8712/rtl871x_recv.h index 92ca8997e5bc..77487bb9d3c0 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.h +++ b/drivers/staging/rtl8712/rtl871x_recv.h @@ -170,11 +170,8 @@ static inline u8 *recvframe_put(union recv_frame *precvframe, sint sz) /* used for append sz bytes from ptr to rx_tail, update rx_tail and * return the updated rx_tail to the caller * after putting, rx_tail must be still larger than rx_end. */ - unsigned char *prev_rx_tail; - if (precvframe == NULL) return NULL; - prev_rx_tail = precvframe->u.hdr.rx_tail; precvframe->u.hdr.rx_tail += sz; if (precvframe->u.hdr.rx_tail > precvframe->u.hdr.rx_end) { precvframe->u.hdr.rx_tail -= sz; diff --git a/drivers/staging/rtl8712/rtl871x_security.c b/drivers/staging/rtl8712/rtl871x_security.c index 8faf22bb7c90..c653ad6854b4 100644 --- a/drivers/staging/rtl8712/rtl871x_security.c +++ b/drivers/staging/rtl8712/rtl871x_security.c @@ -578,7 +578,7 @@ u32 r8712_tkip_encrypt(struct _adapter *padapter, u8 *pxmitframe) u8 ttkey[16]; u8 crc[4]; struct arc4context mycontext; - u32 curfragnum, length, prwskeylen; + u32 curfragnum, length; u8 *pframe, *payload, *iv, *prwskey; union pn48 txpn; @@ -600,7 +600,6 @@ u32 r8712_tkip_encrypt(struct _adapter *padapter, u8 *pxmitframe) &pattrib->ra[0]); if (stainfo != NULL) { prwskey = &stainfo->x_UncstKey.skey[0]; - prwskeylen = 16; for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { iv = pframe + pattrib->hdrlen; @@ -655,7 +654,7 @@ u32 r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe) u8 ttkey[16]; u8 crc[4]; struct arc4context mycontext; - u32 length, prwskeylen; + u32 length; u8 *pframe, *payload, *iv, *prwskey, idx = 0; union pn48 txpn; struct sta_info *stainfo; @@ -683,7 +682,6 @@ u32 r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe) return _FAIL; } else prwskey = &stainfo->x_UncstKey.skey[0]; - prwskeylen = 16; GET_TKIP_PN(iv, txpn); pnl = (u16)(txpn.val); pnh = (u32)(txpn.val >> 16); @@ -1154,7 +1152,6 @@ u32 r8712_aes_encrypt(struct _adapter *padapter, u8 *pxmitframe) { /* exclude ICV */ /* Intermediate Buffers */ sint curfragnum, length; - u32 prwskeylen; u8 *pframe, *prwskey; struct sta_info *stainfo; struct pkt_attrib *pattrib = &((struct xmit_frame *) @@ -1174,7 +1171,6 @@ u32 r8712_aes_encrypt(struct _adapter *padapter, u8 *pxmitframe) &pattrib->ra[0]); if (stainfo != NULL) { prwskey = &stainfo->x_UncstKey.skey[0]; - prwskeylen = 16; for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { if ((curfragnum + 1) == pattrib->nr_frags) { @@ -1363,7 +1359,6 @@ u32 r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe) { /* exclude ICV */ /* Intermediate Buffers */ sint length; - u32 prwskeylen; u8 *pframe, *prwskey, *iv, idx; struct sta_info *stainfo; struct rx_pkt_attrib *prxattrib = &((union recv_frame *) @@ -1387,7 +1382,6 @@ u32 r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe) } else prwskey = &stainfo->x_UncstKey.skey[0]; - prwskeylen = 16; length = ((union recv_frame *)precvframe)-> u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len; aes_decipher(prwskey, prxattrib->hdrlen, pframe, diff --git a/drivers/staging/rtl8712/rtl871x_sta_mgt.c b/drivers/staging/rtl8712/rtl871x_sta_mgt.c index e769bb5c5fb8..4c9b98e8210e 100644 --- a/drivers/staging/rtl8712/rtl871x_sta_mgt.c +++ b/drivers/staging/rtl8712/rtl871x_sta_mgt.c @@ -79,13 +79,11 @@ static void mfree_all_stainfo(struct sta_priv *pstapriv) { unsigned long irqL; struct list_head *plist, *phead; - struct sta_info *psta = NULL; spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); phead = &pstapriv->free_sta_queue.queue; plist = phead->next; while ((end_of_queue_search(phead, plist)) == false) { - psta = LIST_CONTAINOR(plist, struct sta_info, list); plist = plist->next; } @@ -109,7 +107,6 @@ u32 _r8712_free_sta_priv(struct sta_priv *pstapriv) struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) { - uint tmp_aid; s32 index; struct list_head *phash_list; struct sta_info *psta; @@ -127,7 +124,6 @@ struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) psta = LIST_CONTAINOR(pfree_sta_queue->queue.next, struct sta_info, list); list_del_init(&(psta->list)); - tmp_aid = psta->aid; _init_stainfo(psta); memcpy(psta->hwaddr, hwaddr, ETH_ALEN); index = wifi_mac_hash(hwaddr); @@ -267,15 +263,10 @@ struct sta_info *r8712_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) void r8712_init_bcmc_stainfo(struct _adapter *padapter) { - struct sta_info *psta; - struct tx_servq *ptxservq; unsigned char bcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; struct sta_priv *pstapriv = &padapter->stapriv; - psta = r8712_alloc_stainfo(pstapriv, bcast_addr); - if (psta == NULL) - return; - ptxservq = &(psta->sta_xmitpriv.be_q); + r8712_alloc_stainfo(pstapriv, bcast_addr); } struct sta_info *r8712_get_bcmc_stainfo(struct _adapter *padapter) diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c index f49acaf04076..62a377e7fdc7 100644 --- a/drivers/staging/rtl8712/rtl871x_xmit.c +++ b/drivers/staging/rtl8712/rtl871x_xmit.c @@ -184,7 +184,6 @@ void _free_xmit_priv(struct xmit_priv *pxmitpriv) sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, struct pkt_attrib *pattrib) { - uint i; struct pkt_file pktfile; struct sta_info *psta = NULL; struct ethhdr etherhdr; @@ -199,7 +198,7 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, _r8712_open_pktfile(pkt, &pktfile); - i = _r8712_pktfile_read(&pktfile, (unsigned char *)ðerhdr, ETH_HLEN); + _r8712_pktfile_read(&pktfile, (unsigned char *)ðerhdr, ETH_HLEN); pattrib->ether_type = ntohs(etherhdr.h_proto); @@ -236,7 +235,7 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, /* for mp storing the txcmd per packet, * according to the info of txcmd to update pattrib */ /*get MP_TXDESC_SIZE bytes txcmd per packet*/ - i = _r8712_pktfile_read(&pktfile, (u8 *)&txdesc, TXDESC_SIZE); + _r8712_pktfile_read(&pktfile, (u8 *)&txdesc, TXDESC_SIZE); memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); memcpy(pattrib->ta, pattrib->src, ETH_ALEN); pattrib->pctrl = 1; @@ -347,7 +346,7 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, static sint xmitframe_addmic(struct _adapter *padapter, struct xmit_frame *pxmitframe) { - u32 curfragnum, length, datalen; + u32 curfragnum, length; u8 *pframe, *payload, mic[8]; struct mic_data micdata; struct sta_info *stainfo; @@ -369,7 +368,6 @@ static sint xmitframe_addmic(struct _adapter *padapter, u8 null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; - datalen = pattrib->pktlen - pattrib->hdrlen; pframe = pxmitframe->buf_addr + TXDESC_OFFSET; if (bmcst) { if (!memcmp(psecuritypriv->XGrptxmickey @@ -486,7 +484,7 @@ static sint make_wlanhdr(struct _adapter *padapter , u8 *hdr, memset(hdr, 0, WLANHDR_OFFSET); SetFrameSubType(fctrl, pattrib->subtype); if (pattrib->subtype & WIFI_DATA_TYPE) { - if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)) { + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) { /* to_ds = 1, fr_ds = 0; */ SetToDs(fctrl); memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), @@ -825,16 +823,13 @@ void r8712_free_xmitframe(struct xmit_priv *pxmitpriv, unsigned long irqL; struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue; struct _adapter *padapter = pxmitpriv->adapter; - struct sk_buff *pndis_pkt = NULL; if (pxmitframe == NULL) return; spin_lock_irqsave(&pfree_xmit_queue->lock, irqL); list_del_init(&pxmitframe->list); - if (pxmitframe->pkt) { - pndis_pkt = pxmitframe->pkt; + if (pxmitframe->pkt) pxmitframe->pkt = NULL; - } list_add_tail(&pxmitframe->list, &pfree_xmit_queue->queue); pxmitpriv->free_xmitframe_cnt++; spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL); diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c index a3d733b145eb..7d0d1719b136 100644 --- a/drivers/staging/rtl8712/usb_intf.c +++ b/drivers/staging/rtl8712/usb_intf.c @@ -255,9 +255,6 @@ static struct drv_priv drvpriv = { static uint r8712_usb_dvobj_init(struct _adapter *padapter) { uint status = _SUCCESS; - struct usb_device_descriptor *pdev_desc; - struct usb_host_config *phost_conf; - struct usb_config_descriptor *pconf_desc; struct usb_host_interface *phost_iface; struct usb_interface_descriptor *piface_desc; struct dvobj_priv *pdvobjpriv = &padapter->dvobjpriv; @@ -265,9 +262,6 @@ static uint r8712_usb_dvobj_init(struct _adapter *padapter) pdvobjpriv->padapter = padapter; padapter->EepromAddressSize = 6; - pdev_desc = &pusbd->descriptor; - phost_conf = pusbd->actconfig; - pconf_desc = &phost_conf->desc; phost_iface = &pintf->altsetting[0]; piface_desc = &phost_iface->desc; pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints; @@ -292,13 +286,13 @@ static void r8712_usb_dvobj_deinit(struct _adapter *padapter) void rtl871x_intf_stop(struct _adapter *padapter) { /*disable_hw_interrupt*/ - if (padapter->bSurpriseRemoved == false) { + if (!padapter->bSurpriseRemoved) { /*device still exists, so driver can do i/o operation * TODO: */ } /* cancel in irp */ - if (padapter->dvobjpriv.inirp_deinit != NULL) + if (padapter->dvobjpriv.inirp_deinit) padapter->dvobjpriv.inirp_deinit(padapter); /* cancel out irp */ r8712_usb_write_port_cancel(padapter); @@ -318,7 +312,7 @@ void r871x_dev_unload(struct _adapter *padapter) r8712_stop_drv_threads(padapter); /*s5.*/ - if (padapter->bSurpriseRemoved == false) { + if (!padapter->bSurpriseRemoved) { padapter->hw_init_completed = false; rtl8712_hal_deinit(padapter); } @@ -402,7 +396,7 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf, /* step 3. * initialize the dvobj_priv */ - if (padapter->dvobj_init == NULL) + if (!padapter->dvobj_init) goto error; else { status = padapter->dvobj_init(padapter); @@ -568,7 +562,7 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf, ((mac[0] == 0x00) && (mac[1] == 0x00) && (mac[2] == 0x00) && (mac[3] == 0x00) && (mac[4] == 0x00) && (mac[5] == 0x00)) || - (AutoloadFail == false)) { + (!AutoloadFail)) { mac[0] = 0x00; mac[1] = 0xe0; mac[2] = 0x4c; diff --git a/drivers/staging/rtl8712/usb_ops_linux.c b/drivers/staging/rtl8712/usb_ops_linux.c index e89d2b07fcb9..c3a4e3f26b40 100644 --- a/drivers/staging/rtl8712/usb_ops_linux.c +++ b/drivers/staging/rtl8712/usb_ops_linux.c @@ -168,7 +168,6 @@ static void usb_write_mem_complete(struct urb *purb) void r8712_usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) { unsigned int pipe; - int status; struct _adapter *padapter = (struct _adapter *)pintfhdl->adapter; struct intf_priv *pintfpriv = pintfhdl->pintfpriv; struct io_queue *pio_queue = (struct io_queue *)padapter->pio_queue; @@ -186,7 +185,7 @@ void r8712_usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) usb_fill_bulk_urb(piorw_urb, pusbd, pipe, wmem, cnt, usb_write_mem_complete, pio_queue); - status = usb_submit_urb(piorw_urb, GFP_ATOMIC); + usb_submit_urb(piorw_urb, GFP_ATOMIC); _down_sema(&pintfpriv->io_retevt); } @@ -267,7 +266,7 @@ u32 r8712_usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) if (adapter->bDriverStopped || adapter->bSurpriseRemoved || adapter->pwrctrlpriv.pnp_bstop_trx) return _FAIL; - if ((precvbuf->reuse == false) || (precvbuf->pskb == NULL)) { + if (!precvbuf->reuse == false || !precvbuf->pskb) { precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue); if (NULL != precvbuf->pskb) precvbuf->reuse = true; @@ -275,10 +274,10 @@ u32 r8712_usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) if (precvbuf != NULL) { r8712_init_recvbuf(adapter, precvbuf); /* re-assign for linux based on skb */ - if ((precvbuf->reuse == false) || (precvbuf->pskb == NULL)) { + if (!precvbuf->reuse || !precvbuf->pskb) { precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); - if (precvbuf->pskb == NULL) + if (!precvbuf->pskb) return _FAIL; tmpaddr = (addr_t)precvbuf->pskb->data; alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1); diff --git a/drivers/staging/rtl8712/xmit_linux.c b/drivers/staging/rtl8712/xmit_linux.c index 0ac9130faf6c..039b598152bc 100644 --- a/drivers/staging/rtl8712/xmit_linux.c +++ b/drivers/staging/rtl8712/xmit_linux.c @@ -79,7 +79,6 @@ sint r8712_endofpktfile(struct pkt_file *pfile) void r8712_set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib) { - int i; struct ethhdr etherhdr; struct iphdr ip_hdr; u16 UserPriority = 0; @@ -89,8 +88,7 @@ void r8712_set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib) /* get UserPriority from IP hdr*/ if (pattrib->ether_type == 0x0800) { - i = _r8712_pktfile_read(ppktfile, (u8 *)&ip_hdr, - sizeof(ip_hdr)); + _r8712_pktfile_read(ppktfile, (u8 *)&ip_hdr, sizeof(ip_hdr)); /*UserPriority = (ntohs(ip_hdr.tos) >> 5) & 0x3 ;*/ UserPriority = ip_hdr.tos >> 5; } else { diff --git a/drivers/staging/rtl8723au/Makefile b/drivers/staging/rtl8723au/Makefile index a9aae2163639..3e8989018a88 100644 --- a/drivers/staging/rtl8723au/Makefile +++ b/drivers/staging/rtl8723au/Makefile @@ -2,7 +2,6 @@ r8723au-y := \ core/rtw_cmd.o \ core/rtw_efuse.o \ core/rtw_ieee80211.o \ - core/rtw_led.o \ core/rtw_mlme.o \ core/rtw_mlme_ext.o \ core/rtw_pwrctrl.o \ @@ -33,8 +32,6 @@ r8723au-y := \ hal/rtl8723a_rf6052.o \ hal/rtl8723a_rxdesc.o \ hal/rtl8723a_sreset.o \ - hal/rtl8723a_xmit.o \ - hal/rtl8723au_led.o \ hal/rtl8723au_recv.o \ hal/rtl8723au_xmit.o \ hal/usb_halinit.o \ diff --git a/drivers/staging/rtl8723au/core/rtw_ap.c b/drivers/staging/rtl8723au/core/rtw_ap.c index 6b4092f05da5..e394d12c36b0 100644 --- a/drivers/staging/rtl8723au/core/rtw_ap.c +++ b/drivers/staging/rtl8723au/core/rtw_ap.c @@ -231,12 +231,10 @@ void expire_timeout_chk23a(struct rtw_adapter *padapter) psta->expire_to--; } - if (psta->expire_to <= 0) - { + if (psta->expire_to <= 0) { struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - if (padapter->registrypriv.wifi_spec == 1) - { + if (padapter->registrypriv.wifi_spec == 1) { psta->expire_to = pstapriv->expire_to; continue; } @@ -308,15 +306,12 @@ void expire_timeout_chk23a(struct rtw_adapter *padapter) ret = issue_nulldata23a(padapter, psta->hwaddr, 0, 3, 50); psta->keep_alive_trycnt++; - if (ret == _SUCCESS) - { + if (ret == _SUCCESS) { DBG_8723A("asoc check, sta(" MAC_FMT ") is alive\n", MAC_ARG(psta->hwaddr)); psta->expire_to = pstapriv->expire_to; psta->keep_alive_trycnt = 0; continue; - } - else if (psta->keep_alive_trycnt <= 3) - { + } else if (psta->keep_alive_trycnt <= 3) { DBG_8723A("ack check for asoc expire, keep_alive_trycnt =%d\n", psta->keep_alive_trycnt); psta->expire_to = 1; continue; @@ -363,8 +358,7 @@ void add_RATid23a(struct rtw_adapter *padapter, struct sta_info *psta, u8 rssi_l return; /* b/g mode ra_bitmap */ - for (i = 0; i < sizeof(psta->bssrateset); i++) - { + for (i = 0; i < sizeof(psta->bssrateset); i++) { if (psta->bssrateset[i]) tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value23a(psta->bssrateset[i]&0x7f); } @@ -406,8 +400,7 @@ void add_RATid23a(struct rtw_adapter *padapter, struct sta_info *psta, u8 rssi_l raid = networktype_to_raid23a(sta_band); init_rate = get_highest_rate_idx23a(tx_ra_bitmap&0x0fffffff)&0x3f; - if (psta->aid < NUM_STA) - { + if (psta->aid < NUM_STA) { u8 arg = 0; arg = psta->mac_id&0x1f; @@ -436,11 +429,8 @@ void add_RATid23a(struct rtw_adapter *padapter, struct sta_info *psta, u8 rssi_l psta->raid = raid; psta->init_rate = init_rate; - } - else - { + } else DBG_8723A("station aid %d exceed the max number\n", psta->aid); - } } static void update_bmc_sta(struct rtw_adapter *padapter) @@ -453,8 +443,7 @@ static void update_bmc_sta(struct rtw_adapter *padapter) struct wlan_bssid_ex *pcur_network = &pmlmepriv->cur_network.network; struct sta_info *psta = rtw_get_bcmc_stainfo23a(padapter); - if (psta) - { + if (psta) { psta->aid = 0;/* default set to 0 */ psta->mac_id = psta->aid + 1; @@ -474,8 +463,7 @@ static void update_bmc_sta(struct rtw_adapter *padapter) psta->bssratelen = supportRateNum; /* b/g mode ra_bitmap */ - for (i = 0; i < supportRateNum; i++) - { + for (i = 0; i < supportRateNum; i++) { if (psta->bssrateset[i]) tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value23a(psta->bssrateset[i]&0x7f); } @@ -522,11 +510,8 @@ static void update_bmc_sta(struct rtw_adapter *padapter) psta->state = _FW_LINKED; spin_unlock_bh(&psta->lock); - } - else - { + } else DBG_8723A("add_RATid23a_bmc_sta error!\n"); - } } /* notes: */ @@ -561,8 +546,7 @@ void update_sta_info23a_apmode23a(struct rtw_adapter *padapter, struct sta_info /* ERP */ VCS_update23a(padapter, psta); /* HT related cap */ - if (phtpriv_sta->ht_option) - { + if (phtpriv_sta->ht_option) { /* check if sta supports rx ampdu */ phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable; @@ -580,9 +564,7 @@ void update_sta_info23a_apmode23a(struct rtw_adapter *padapter, struct sta_info psta->qos_option = true; - } - else - { + } else { phtpriv_sta->ampdu_enable = false; phtpriv_sta->sgi = false; @@ -654,7 +636,7 @@ static void start_bss_network(struct rtw_adapter *padapter, u8 *pbuf) bcn_interval = (u16)pnetwork->beacon_interval; cur_channel = pnetwork->DSConfig; - cur_bwmode = HT_CHANNEL_WIDTH_20;; + cur_bwmode = HT_CHANNEL_WIDTH_20; cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; /* check if there is wps ie, */ @@ -1122,7 +1104,6 @@ int rtw_acl_remove_sta23a(struct rtw_adapter *padapter, u8 *addr) struct sta_priv *pstapriv = &padapter->stapriv; struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; struct rtw_queue *pacl_node_q = &pacl_list->acl_node_q; - int ret = 0; DBG_8723A("%s(acl_num =%d) = %pM\n", __func__, pacl_list->num, addr); @@ -1148,7 +1129,7 @@ int rtw_acl_remove_sta23a(struct rtw_adapter *padapter, u8 *addr) DBG_8723A("%s, acl_num =%d\n", __func__, pacl_list->num); - return ret; + return 0; } static void update_bcn_fixed_ie(struct rtw_adapter *padapter) @@ -1217,8 +1198,6 @@ static void update_bcn_wmm_ie(struct rtw_adapter *padapter) static void update_bcn_wps_ie(struct rtw_adapter *padapter) { DBG_8723A("%s\n", __func__); - - return; } static void update_bcn_p2p_ie(struct rtw_adapter *padapter) @@ -1261,8 +1240,7 @@ void update_beacon23a(struct rtw_adapter *padapter, u8 ie_id, u8 *oui, u8 tx) spin_lock_bh(&pmlmepriv->bcn_update_lock); - switch (ie_id) - { + switch (ie_id) { case 0xFF: /* 8: TimeStamp, 2: Beacon Interval 2:Capability */ update_bcn_fixed_ie(padapter); @@ -1389,8 +1367,7 @@ static int rtw_ht_operation_update(struct rtw_adapter *padapter) void associated_clients_update23a(struct rtw_adapter *padapter, u8 updated) { /* update associated stations cap. */ - if (updated == true) - { + if (updated == true) { struct list_head *phead, *plist, *ptmp; struct sta_info *psta; struct sta_priv *pstapriv = &padapter->stapriv; @@ -1416,34 +1393,27 @@ void bss_cap_update_on_sta_join23a(struct rtw_adapter *padapter, struct sta_info struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - if (!(psta->flags & WLAN_STA_SHORT_PREAMBLE)) - { - if (!psta->no_short_preamble_set) - { + if (!(psta->flags & WLAN_STA_SHORT_PREAMBLE)) { + if (!psta->no_short_preamble_set) { psta->no_short_preamble_set = 1; pmlmepriv->num_sta_no_short_preamble++; if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && - (pmlmepriv->num_sta_no_short_preamble == 1)) - { + (pmlmepriv->num_sta_no_short_preamble == 1)) { beacon_updated = true; update_beacon23a(padapter, 0xFF, NULL, true); } } - } - else - { - if (psta->no_short_preamble_set) - { + } else { + if (psta->no_short_preamble_set) { psta->no_short_preamble_set = 0; pmlmepriv->num_sta_no_short_preamble--; if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && - (pmlmepriv->num_sta_no_short_preamble == 0)) - { + (pmlmepriv->num_sta_no_short_preamble == 0)) { beacon_updated = true; update_beacon23a(padapter, 0xFF, NULL, true); } @@ -1451,32 +1421,25 @@ void bss_cap_update_on_sta_join23a(struct rtw_adapter *padapter, struct sta_info } } - if (psta->flags & WLAN_STA_NONERP) - { - if (!psta->nonerp_set) - { + if (psta->flags & WLAN_STA_NONERP) { + if (!psta->nonerp_set) { psta->nonerp_set = 1; pmlmepriv->num_sta_non_erp++; - if (pmlmepriv->num_sta_non_erp == 1) - { + if (pmlmepriv->num_sta_non_erp == 1) { beacon_updated = true; update_beacon23a(padapter, WLAN_EID_ERP_INFO, NULL, true); } } - } - else - { - if (psta->nonerp_set) - { + } else { + if (psta->nonerp_set) { psta->nonerp_set = 0; pmlmepriv->num_sta_non_erp--; - if (pmlmepriv->num_sta_non_erp == 0) - { + if (pmlmepriv->num_sta_non_erp == 0) { beacon_updated = true; update_beacon23a(padapter, WLAN_EID_ERP_INFO, NULL, true); } @@ -1484,42 +1447,34 @@ void bss_cap_update_on_sta_join23a(struct rtw_adapter *padapter, struct sta_info } - if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)) - { - if (!psta->no_short_slot_time_set) - { + if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)) { + if (!psta->no_short_slot_time_set) { psta->no_short_slot_time_set = 1; pmlmepriv->num_sta_no_short_slot_time++; if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && - (pmlmepriv->num_sta_no_short_slot_time == 1)) - { + (pmlmepriv->num_sta_no_short_slot_time == 1)) { beacon_updated = true; update_beacon23a(padapter, 0xFF, NULL, true); } } - } - else - { - if (psta->no_short_slot_time_set) - { + } else { + if (psta->no_short_slot_time_set) { psta->no_short_slot_time_set = 0; pmlmepriv->num_sta_no_short_slot_time--; if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && - (pmlmepriv->num_sta_no_short_slot_time == 0)) - { + (pmlmepriv->num_sta_no_short_slot_time == 0)) { beacon_updated = true; update_beacon23a(padapter, 0xFF, NULL, true); } } } - if (psta->flags & WLAN_STA_HT) - { + if (psta->flags & WLAN_STA_HT) { u16 ht_capab = le16_to_cpu(psta->htpriv.ht_cap.cap_info); DBG_8723A("HT: STA " MAC_FMT " HT Capabilities " @@ -1552,9 +1507,7 @@ void bss_cap_update_on_sta_join23a(struct rtw_adapter *padapter, struct sta_info pmlmepriv->num_sta_ht_20mhz); } - } - else - { + } else { if (!psta->no_ht_set) { psta->no_ht_set = 1; pmlmepriv->num_sta_no_ht++; @@ -1567,8 +1520,7 @@ void bss_cap_update_on_sta_join23a(struct rtw_adapter *padapter, struct sta_info } } - if (rtw_ht_operation_update(padapter) > 0) - { + if (rtw_ht_operation_update(padapter) > 0) { update_beacon23a(padapter, WLAN_EID_HT_CAPABILITY, NULL, false); update_beacon23a(padapter, WLAN_EID_HT_OPERATION, NULL, true); } @@ -1592,8 +1544,7 @@ u8 bss_cap_update_on_sta_leave23a(struct rtw_adapter *padapter, struct sta_info psta->no_short_preamble_set = 0; pmlmepriv->num_sta_no_short_preamble--; if (pmlmeext->cur_wireless_mode > WIRELESS_11B - && pmlmepriv->num_sta_no_short_preamble == 0) - { + && pmlmepriv->num_sta_no_short_preamble == 0) { beacon_updated = true; update_beacon23a(padapter, 0xFF, NULL, true); } @@ -1602,8 +1553,7 @@ u8 bss_cap_update_on_sta_leave23a(struct rtw_adapter *padapter, struct sta_info if (psta->nonerp_set) { psta->nonerp_set = 0; pmlmepriv->num_sta_non_erp--; - if (pmlmepriv->num_sta_non_erp == 0) - { + if (pmlmepriv->num_sta_non_erp == 0) { beacon_updated = true; update_beacon23a(padapter, WLAN_EID_ERP_INFO, NULL, true); @@ -1614,8 +1564,7 @@ u8 bss_cap_update_on_sta_leave23a(struct rtw_adapter *padapter, struct sta_info psta->no_short_slot_time_set = 0; pmlmepriv->num_sta_no_short_slot_time--; if (pmlmeext->cur_wireless_mode > WIRELESS_11B - && pmlmepriv->num_sta_no_short_slot_time == 0) - { + && pmlmepriv->num_sta_no_short_slot_time == 0) { beacon_updated = true; update_beacon23a(padapter, 0xFF, NULL, true); } @@ -1636,8 +1585,7 @@ u8 bss_cap_update_on_sta_leave23a(struct rtw_adapter *padapter, struct sta_info pmlmepriv->num_sta_ht_20mhz--; } - if (rtw_ht_operation_update(padapter) > 0) - { + if (rtw_ht_operation_update(padapter) > 0) { update_beacon23a(padapter, WLAN_EID_HT_CAPABILITY, NULL, false); update_beacon23a(padapter, WLAN_EID_HT_OPERATION, NULL, true); } @@ -1657,8 +1605,7 @@ u8 ap_free_sta23a(struct rtw_adapter *padapter, struct sta_info *psta, bool acti if (!psta) return beacon_updated; - if (active == true) - { + if (active) { /* tear down Rx AMPDU */ send_delba23a(padapter, 0, psta->hwaddr);/* recipient */ @@ -1698,7 +1645,6 @@ u8 ap_free_sta23a(struct rtw_adapter *padapter, struct sta_info *psta, bool acti int rtw_ap_inform_ch_switch23a (struct rtw_adapter *padapter, u8 new_ch, u8 ch_offset) { struct list_head *phead, *plist; - int ret = 0; struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; @@ -1706,7 +1652,7 @@ int rtw_ap_inform_ch_switch23a (struct rtw_adapter *padapter, u8 new_ch, u8 ch_o u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; if ((pmlmeinfo->state&0x03) != MSR_AP) - return ret; + return 0; DBG_8723A("%s(%s): with ch:%u, offset:%u\n", __func__, padapter->pnetdev->name, new_ch, ch_offset); @@ -1724,13 +1670,12 @@ int rtw_ap_inform_ch_switch23a (struct rtw_adapter *padapter, u8 new_ch, u8 ch_o issue_action_spct_ch_switch23a (padapter, bc_addr, new_ch, ch_offset); - return ret; + return 0; } int rtw_sta_flush23a(struct rtw_adapter *padapter) { struct list_head *phead, *plist, *ptmp; - int ret = 0; struct sta_info *psta; struct sta_priv *pstapriv = &padapter->stapriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; @@ -1743,7 +1688,7 @@ int rtw_sta_flush23a(struct rtw_adapter *padapter) DBG_8723A("%s(%s)\n", __func__, padapter->pnetdev->name); if ((pmlmeinfo->state&0x03) != MSR_AP) - return ret; + return 0; spin_lock_bh(&pstapriv->asoc_list_lock); phead = &pstapriv->asoc_list; @@ -1769,7 +1714,7 @@ int rtw_sta_flush23a(struct rtw_adapter *padapter) associated_clients_update23a(padapter, true); - return ret; + return 0; } /* called > TSR LEVEL for USB or SDIO Interface*/ @@ -1788,13 +1733,10 @@ void sta_info_update23a(struct rtw_adapter *padapter, struct sta_info *psta) psta->qos_option = 0; /* update 802.11n ht cap. */ - if (WLAN_STA_HT&flags) - { + if (WLAN_STA_HT&flags) { psta->htpriv.ht_option = true; psta->qos_option = 1; - } - else - { + } else { psta->htpriv.ht_option = false; } @@ -1807,8 +1749,7 @@ void sta_info_update23a(struct rtw_adapter *padapter, struct sta_info *psta) /* called >= TSR LEVEL for USB or SDIO Interface*/ void ap_sta_info_defer_update23a(struct rtw_adapter *padapter, struct sta_info *psta) { - if (psta->state & _FW_LINKED) - { + if (psta->state & _FW_LINKED) { /* add ratid */ add_RATid23a(padapter, psta, 0);/* DM_RATR_STA_INIT */ } @@ -1819,7 +1760,7 @@ void rtw_ap_restore_network(struct rtw_adapter *padapter) { struct mlme_priv *mlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct sta_priv * pstapriv = &padapter->stapriv; + struct sta_priv *pstapriv = &padapter->stapriv; struct sta_info *psta; struct security_priv *psecuritypriv = &padapter->securitypriv; struct list_head *phead, *plist, *ptmp; diff --git a/drivers/staging/rtl8723au/core/rtw_cmd.c b/drivers/staging/rtl8723au/core/rtw_cmd.c index 4eaa50297b95..60e0ded8ae02 100644 --- a/drivers/staging/rtl8723au/core/rtw_cmd.c +++ b/drivers/staging/rtl8723au/core/rtw_cmd.c @@ -36,25 +36,25 @@ static struct cmd_hdl wlancmds[] = { GEN_MLME_EXT_HANDLER(0, NULL) GEN_MLME_EXT_HANDLER(0, NULL) GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(sizeof (struct wlan_bssid_ex), join_cmd_hdl23a) /*14*/ - GEN_MLME_EXT_HANDLER(sizeof (struct disconnect_parm), disconnect_hdl23a) - GEN_MLME_EXT_HANDLER(sizeof (struct wlan_bssid_ex), createbss_hdl23a) - GEN_MLME_EXT_HANDLER(sizeof (struct setopmode_parm), setopmode_hdl23a) - GEN_MLME_EXT_HANDLER(sizeof (struct sitesurvey_parm), sitesurvey_cmd_hdl23a) /*18*/ - GEN_MLME_EXT_HANDLER(sizeof (struct setauth_parm), setauth_hdl23a) - GEN_MLME_EXT_HANDLER(sizeof (struct setkey_parm), setkey_hdl23a) /*20*/ - GEN_MLME_EXT_HANDLER(sizeof (struct set_stakey_parm), set_stakey_hdl23a) - GEN_MLME_EXT_HANDLER(sizeof (struct set_assocsta_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof (struct del_assocsta_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof (struct setstapwrstate_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof (struct setbasicrate_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof (struct getbasicrate_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof (struct setdatarate_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof (struct getdatarate_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof (struct setphyinfo_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof (struct getphyinfo_parm), NULL) /*30*/ - GEN_MLME_EXT_HANDLER(sizeof (struct setphy_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof (struct getphy_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct wlan_bssid_ex), join_cmd_hdl23a) /*14*/ + GEN_MLME_EXT_HANDLER(sizeof(struct disconnect_parm), disconnect_hdl23a) + GEN_MLME_EXT_HANDLER(sizeof(struct wlan_bssid_ex), createbss_hdl23a) + GEN_MLME_EXT_HANDLER(sizeof(struct setopmode_parm), setopmode_hdl23a) + GEN_MLME_EXT_HANDLER(sizeof(struct sitesurvey_parm), sitesurvey_cmd_hdl23a) /*18*/ + GEN_MLME_EXT_HANDLER(sizeof(struct setauth_parm), setauth_hdl23a) + GEN_MLME_EXT_HANDLER(sizeof(struct setkey_parm), setkey_hdl23a) /*20*/ + GEN_MLME_EXT_HANDLER(sizeof(struct set_stakey_parm), set_stakey_hdl23a) + GEN_MLME_EXT_HANDLER(sizeof(struct set_assocsta_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct del_assocsta_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct setstapwrstate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct setbasicrate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct getbasicrate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct setdatarate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct getdatarate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct setphyinfo_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct getphyinfo_parm), NULL) /*30*/ + GEN_MLME_EXT_HANDLER(sizeof(struct setphy_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct getphy_parm), NULL) GEN_MLME_EXT_HANDLER(0, NULL) GEN_MLME_EXT_HANDLER(0, NULL) GEN_MLME_EXT_HANDLER(0, NULL) @@ -359,6 +359,7 @@ int rtw_sitesurvey_cmd23a(struct rtw_adapter *padapter, /* prepare ssid list */ if (ssid) { int i; + for (i = 0; i < ssid_num && i < RTW_SSID_SCAN_AMOUNT; i++) { if (ssid[i].ssid_len) { memcpy(&psurveyPara->ssid[i], &ssid[i], @@ -371,6 +372,7 @@ int rtw_sitesurvey_cmd23a(struct rtw_adapter *padapter, /* prepare channel list */ if (ch) { int i; + for (i = 0; i < ch_num && i < RTW_CHANNEL_SCAN_AMOUNT; i++) { if (ch[i].hw_value && !(ch[i].flags & IEEE80211_CHAN_DISABLED)) { @@ -389,8 +391,6 @@ int rtw_sitesurvey_cmd23a(struct rtw_adapter *padapter, mod_timer(&pmlmepriv->scan_to_timer, jiffies + msecs_to_jiffies(SCANNING_TIMEOUT)); - rtw_led_control(padapter, LED_CTL_SITE_SURVEY); - pmlmepriv->scan_interval = SCAN_INTERVAL;/* 30*2 sec = 60sec */ } else _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); @@ -415,8 +415,6 @@ int rtw_createbss_cmd23a(struct rtw_adapter *padapter) pdev_network = &padapter->registrypriv.dev_network; - rtw_led_control(padapter, LED_CTL_START_TO_LINK); - if (pmlmepriv->assoc_ssid.ssid_len == 0) { RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for Any SSid:%s\n", @@ -465,8 +463,6 @@ int rtw_joinbss_cmd23a(struct rtw_adapter *padapter, ifmode = pnetwork->network.ifmode; - rtw_led_control(padapter, LED_CTL_START_TO_LINK); - if (pmlmepriv->assoc_ssid.ssid_len == 0) { RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("+Join cmd: Any SSid\n")); @@ -599,7 +595,7 @@ exit: return res; } -int rtw_disassoc_cmd23a(struct rtw_adapter*padapter, u32 deauth_timeout_ms, +int rtw_disassoc_cmd23a(struct rtw_adapter *padapter, u32 deauth_timeout_ms, bool enqueue) { struct cmd_obj *cmdobj = NULL; @@ -719,6 +715,7 @@ int rtw_setstakey_cmd23a(struct rtw_adapter *padapter, u8 *psta, u8 unicast_key) memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16); } else { int idx = psecuritypriv->dot118021XGrpKeyid; + memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[idx].skey, 16); } @@ -786,7 +783,7 @@ exit: return res; } -int rtw_addbareq_cmd23a(struct rtw_adapter*padapter, u8 tid, u8 *addr) +int rtw_addbareq_cmd23a(struct rtw_adapter *padapter, u8 tid, u8 *addr) { struct cmd_priv *pcmdpriv = &padapter->cmdpriv; struct cmd_obj *ph2c; @@ -822,7 +819,7 @@ exit: return res; } -int rtw_dynamic_chk_wk_cmd23a(struct rtw_adapter*padapter) +int rtw_dynamic_chk_wk_cmd23a(struct rtw_adapter *padapter) { struct cmd_obj *ph2c; struct drvextra_cmd_parm *pdrvextra_cmd_parm; @@ -859,7 +856,7 @@ exit: * This is only ever called from on_action_spct23a_ch_switch () which isn't * called from anywhere itself */ -int rtw_set_ch_cmd23a(struct rtw_adapter*padapter, u8 ch, u8 bw, u8 ch_offset, +int rtw_set_ch_cmd23a(struct rtw_adapter *padapter, u8 ch, u8 bw, u8 ch_offset, u8 enqueue) { struct cmd_obj *pcmdobj; @@ -919,34 +916,34 @@ static void traffic_status_watchdog(struct rtw_adapter *padapter) u8 bHigherBusyTxTraffic = false; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; int BusyThreshold = 100; + struct rt_link_detect *ldi = &pmlmepriv->LinkDetectInfo; + /* */ /* Determine if our traffic is busy now */ /* */ if (check_fwstate(pmlmepriv, _FW_LINKED)) { if (rtl8723a_BT_coexist(padapter)) BusyThreshold = 50; - else if (pmlmepriv->LinkDetectInfo.bBusyTraffic) + else if (ldi->bBusyTraffic) BusyThreshold = 75; /* if we raise bBusyTraffic in last watchdog, using lower threshold. */ - if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > BusyThreshold || - pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > BusyThreshold) { + if (ldi->NumRxOkInPeriod > BusyThreshold || + ldi->NumTxOkInPeriod > BusyThreshold) { bBusyTraffic = true; - if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > - pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) + if (ldi->NumRxOkInPeriod > ldi->NumTxOkInPeriod) bRxBusyTraffic = true; else bTxBusyTraffic = true; } /* Higher Tx/Rx data. */ - if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 4000 || - pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 4000) { + if (ldi->NumRxOkInPeriod > 4000 || + ldi->NumTxOkInPeriod > 4000) { bHigherBusyTraffic = true; - if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > - pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) + if (ldi->NumRxOkInPeriod > ldi->NumTxOkInPeriod) bHigherBusyRxTraffic = true; else bHigherBusyTxTraffic = true; @@ -955,9 +952,9 @@ static void traffic_status_watchdog(struct rtw_adapter *padapter) if (!rtl8723a_BT_coexist(padapter) || !rtl8723a_BT_using_antenna_1(padapter)) { /* check traffic for powersaving. */ - if (((pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod + - pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) > 8) || - pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod >2) + if (((ldi->NumRxUnicastOkInPeriod + + ldi->NumTxOkInPeriod) > 8) || + ldi->NumRxUnicastOkInPeriod > 2) bEnterPS = false; else bEnterPS = true; @@ -971,15 +968,15 @@ static void traffic_status_watchdog(struct rtw_adapter *padapter) } else LPS_Leave23a(padapter); - pmlmepriv->LinkDetectInfo.NumRxOkInPeriod = 0; - pmlmepriv->LinkDetectInfo.NumTxOkInPeriod = 0; - pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod = 0; - pmlmepriv->LinkDetectInfo.bBusyTraffic = bBusyTraffic; - pmlmepriv->LinkDetectInfo.bTxBusyTraffic = bTxBusyTraffic; - pmlmepriv->LinkDetectInfo.bRxBusyTraffic = bRxBusyTraffic; - pmlmepriv->LinkDetectInfo.bHigherBusyTraffic = bHigherBusyTraffic; - pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic = bHigherBusyRxTraffic; - pmlmepriv->LinkDetectInfo.bHigherBusyTxTraffic = bHigherBusyTxTraffic; + ldi->NumRxOkInPeriod = 0; + ldi->NumTxOkInPeriod = 0; + ldi->NumRxUnicastOkInPeriod = 0; + ldi->bBusyTraffic = bBusyTraffic; + ldi->bTxBusyTraffic = bTxBusyTraffic; + ldi->bRxBusyTraffic = bRxBusyTraffic; + ldi->bHigherBusyTraffic = bHigherBusyTraffic; + ldi->bHigherBusyRxTraffic = bHigherBusyRxTraffic; + ldi->bHigherBusyTxTraffic = bHigherBusyTxTraffic; } static void dynamic_chk_wk_hdl(struct rtw_adapter *padapter, u8 *pbuf, int sz) @@ -1017,46 +1014,45 @@ static void lps_ctrl_wk_hdl(struct rtw_adapter *padapter, u8 lps_ctrl_type) check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) return; - switch (lps_ctrl_type) - { - case LPS_CTRL_SCAN: - rtl8723a_BT_wifiscan_notify(padapter, true); - if (!rtl8723a_BT_using_antenna_1(padapter)) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) - LPS_Leave23a(padapter); + switch (lps_ctrl_type) { + case LPS_CTRL_SCAN: + rtl8723a_BT_wifiscan_notify(padapter, true); + if (!rtl8723a_BT_using_antenna_1(padapter)) { + if (check_fwstate(pmlmepriv, _FW_LINKED)) + LPS_Leave23a(padapter); } - break; - case LPS_CTRL_JOINBSS: + break; + case LPS_CTRL_JOINBSS: + LPS_Leave23a(padapter); + break; + case LPS_CTRL_CONNECT: + mstatus = 1;/* connect */ + /* Reset LPS Setting */ + padapter->pwrctrlpriv.LpsIdleCount = 0; + rtl8723a_set_FwJoinBssReport_cmd(padapter, 1); + rtl8723a_BT_mediastatus_notify(padapter, mstatus); + break; + case LPS_CTRL_DISCONNECT: + mstatus = 0;/* disconnect */ + rtl8723a_BT_mediastatus_notify(padapter, mstatus); + if (!rtl8723a_BT_using_antenna_1(padapter)) LPS_Leave23a(padapter); - break; - case LPS_CTRL_CONNECT: - mstatus = 1;/* connect */ - /* Reset LPS Setting */ - padapter->pwrctrlpriv.LpsIdleCount = 0; - rtl8723a_set_FwJoinBssReport_cmd(padapter, 1); - rtl8723a_BT_mediastatus_notify(padapter, mstatus); - break; - case LPS_CTRL_DISCONNECT: - mstatus = 0;/* disconnect */ - rtl8723a_BT_mediastatus_notify(padapter, mstatus); - if (!rtl8723a_BT_using_antenna_1(padapter)) - LPS_Leave23a(padapter); - rtl8723a_set_FwJoinBssReport_cmd(padapter, 0); - break; - case LPS_CTRL_SPECIAL_PACKET: - pwrpriv->DelayLPSLastTimeStamp = jiffies; - rtl8723a_BT_specialpacket_notify(padapter); - if (!rtl8723a_BT_using_antenna_1(padapter)) - LPS_Leave23a(padapter); - break; - case LPS_CTRL_LEAVE: - rtl8723a_BT_lps_leave(padapter); - if (!rtl8723a_BT_using_antenna_1(padapter)) - LPS_Leave23a(padapter); - break; + rtl8723a_set_FwJoinBssReport_cmd(padapter, 0); + break; + case LPS_CTRL_SPECIAL_PACKET: + pwrpriv->DelayLPSLastTimeStamp = jiffies; + rtl8723a_BT_specialpacket_notify(padapter); + if (!rtl8723a_BT_using_antenna_1(padapter)) + LPS_Leave23a(padapter); + break; + case LPS_CTRL_LEAVE: + rtl8723a_BT_lps_leave(padapter); + if (!rtl8723a_BT_using_antenna_1(padapter)) + LPS_Leave23a(padapter); + break; - default: - break; + default: + break; } } @@ -1098,7 +1094,7 @@ exit: return res; } -int rtw_ps_cmd23a(struct rtw_adapter*padapter) +int rtw_ps_cmd23a(struct rtw_adapter *padapter) { struct cmd_obj *ppscmd; struct drvextra_cmd_parm *pdrvextra_cmd_parm; @@ -1147,12 +1143,12 @@ static void rtw_chk_hi_queue_hdl(struct rtw_adapter *padapter) val = rtl8723a_chk_hi_queue_empty(padapter); - while (val == false) { + while (!val) { msleep(100); cnt++; - if (cnt>10) + if (cnt > 10) break; val = rtl8723a_chk_hi_queue_empty(padapter); @@ -1168,7 +1164,7 @@ static void rtw_chk_hi_queue_hdl(struct rtw_adapter *padapter) } } -int rtw_chk_hi_queue_cmd23a(struct rtw_adapter*padapter) +int rtw_chk_hi_queue_cmd23a(struct rtw_adapter *padapter) { struct cmd_obj *ph2c; struct drvextra_cmd_parm *pdrvextra_cmd_parm; @@ -1305,8 +1301,7 @@ int rtw_drvextra_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf) pdrvextra_cmd = (struct drvextra_cmd_parm *)pbuf; - switch (pdrvextra_cmd->ec_id) - { + switch (pdrvextra_cmd->ec_id) { case DYNAMIC_CHK_WK_CID: dynamic_chk_wk_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size); diff --git a/drivers/staging/rtl8723au/core/rtw_efuse.c b/drivers/staging/rtl8723au/core/rtw_efuse.c index 9f6ce7d071cd..81960e788f89 100644 --- a/drivers/staging/rtl8723au/core/rtw_efuse.c +++ b/drivers/staging/rtl8723au/core/rtw_efuse.c @@ -117,12 +117,7 @@ Efuse_GetCurrentSize23a(struct rtw_adapter *pAdapter, u8 efuseType) u8 Efuse_CalculateWordCnts23a(u8 word_en) { - u8 word_cnts = 0; - if (!(word_en & BIT(0))) word_cnts++; /* 0 : write enable */ - if (!(word_en & BIT(1))) word_cnts++; - if (!(word_en & BIT(2))) word_cnts++; - if (!(word_en & BIT(3))) word_cnts++; - return word_cnts; + return hweight8((~word_en) & 0xf); } /* */ @@ -181,7 +176,7 @@ EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType, switch (type) { case TYPE_EFUSE_MAX_SECTION: - pMax_section = (u8 *) pOut; + pMax_section = pOut; if (efuseType == EFUSE_WIFI) *pMax_section = EFUSE_MAX_SECTION_8723A; @@ -190,7 +185,7 @@ EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType, break; case TYPE_EFUSE_REAL_CONTENT_LEN: - pu2Tmp = (u16 *) pOut; + pu2Tmp = pOut; if (efuseType == EFUSE_WIFI) *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723A; @@ -199,7 +194,7 @@ EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType, break; case TYPE_AVAILABLE_EFUSE_BYTES_BANK: - pu2Tmp = (u16 *) pOut; + pu2Tmp = pOut; if (efuseType == EFUSE_WIFI) *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723A - @@ -210,7 +205,7 @@ EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType, break; case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL: - pu2Tmp = (u16 *) pOut; + pu2Tmp = pOut; if (efuseType == EFUSE_WIFI) *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723A - @@ -221,7 +216,7 @@ EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType, break; case TYPE_EFUSE_MAP_LEN: - pu2Tmp = (u16 *) pOut; + pu2Tmp = pOut; if (efuseType == EFUSE_WIFI) *pu2Tmp = EFUSE_MAP_LEN_8723A; @@ -230,7 +225,7 @@ EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType, break; case TYPE_EFUSE_PROTECT_BYTES_BANK: - pu1Tmp = (u8 *) pOut; + pu1Tmp = pOut; if (efuseType == EFUSE_WIFI) *pu1Tmp = EFUSE_OOB_PROTECT_BYTES; @@ -239,7 +234,7 @@ EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType, break; case TYPE_EFUSE_CONTENT_LEN_BANK: - pu2Tmp = (u16 *) pOut; + pu2Tmp = pOut; if (efuseType == EFUSE_WIFI) *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723A; @@ -248,7 +243,7 @@ EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType, break; default: - pu1Tmp = (u8 *) pOut; + pu1Tmp = pOut; *pu1Tmp = 0; break; } diff --git a/drivers/staging/rtl8723au/core/rtw_ieee80211.c b/drivers/staging/rtl8723au/core/rtw_ieee80211.c index 6274cb397c92..bbbcfc8257da 100644 --- a/drivers/staging/rtl8723au/core/rtw_ieee80211.c +++ b/drivers/staging/rtl8723au/core/rtw_ieee80211.c @@ -69,6 +69,7 @@ int rtw_get_bit_value_from_ieee_value23a(u8 val) {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 0}; int i = 0; + while (dot11_rate_table[i] != 0) { if (dot11_rate_table[i] == val) return BIT(i); @@ -301,8 +302,7 @@ void rtw_set_supported_rate23a(u8 *SupportedRates, uint mode) memset(SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX); - switch (mode) - { + switch (mode) { case WIRELESS_11B: memcpy(SupportedRates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN); break; diff --git a/drivers/staging/rtl8723au/core/rtw_led.c b/drivers/staging/rtl8723au/core/rtw_led.c deleted file mode 100644 index 989cda29a57e..000000000000 --- a/drivers/staging/rtl8723au/core/rtw_led.c +++ /dev/null @@ -1,1893 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - ******************************************************************************/ - -#include <drv_types.h> -#include <rtl8723a_led.h> - -/* */ -/* Description: */ -/* Callback function of LED BlinkTimer, */ -/* it just schedules to corresponding BlinkWorkItem/led_blink_hdl23a */ -/* */ -static void BlinkTimerCallback(unsigned long data) -{ - struct led_8723a *pLed = (struct led_8723a *)data; - struct rtw_adapter *padapter = pLed->padapter; - - /* DBG_8723A("%s\n", __func__); */ - - if ((padapter->bSurpriseRemoved == true) || (padapter->bDriverStopped == true)) - { - /* DBG_8723A("%s bSurpriseRemoved:%d, bDriverStopped:%d\n", __func__, padapter->bSurpriseRemoved, padapter->bDriverStopped); */ - return; - } - schedule_work(&pLed->BlinkWorkItem); -} - -/* */ -/* Description: */ -/* Callback function of LED BlinkWorkItem. */ -/* We dispatch acture LED blink action according to LedStrategy. */ -/* */ -void BlinkWorkItemCallback23a(struct work_struct *work) -{ - struct led_8723a *pLed = container_of(work, struct led_8723a, BlinkWorkItem); - BlinkHandler23a(pLed); -} - -/* */ -/* Description: */ -/* Reset status of led_8723a object. */ -/* */ -void ResetLedStatus23a(struct led_8723a * pLed) { - - pLed->CurrLedState = RTW_LED_OFF; /* Current LED state. */ - pLed->bLedOn = false; /* true if LED is ON, false if LED is OFF. */ - - pLed->bLedBlinkInProgress = false; /* true if it is blinking, false o.w.. */ - pLed->bLedWPSBlinkInProgress = false; - - pLed->BlinkTimes = 0; /* Number of times to toggle led state for blinking. */ - pLed->BlinkingLedState = LED_UNKNOWN; /* Next state for blinking, either RTW_LED_ON or RTW_LED_OFF are. */ - - pLed->bLedNoLinkBlinkInProgress = false; - pLed->bLedLinkBlinkInProgress = false; - pLed->bLedStartToLinkBlinkInProgress = false; - pLed->bLedScanBlinkInProgress = false; -} - - /* */ -/* Description: */ -/* Initialize an led_8723a object. */ -/* */ -void -InitLed871x23a(struct rtw_adapter *padapter, struct led_8723a *pLed, enum led_pin_8723a LedPin) -{ - pLed->padapter = padapter; - pLed->LedPin = LedPin; - - ResetLedStatus23a(pLed); - - setup_timer(&pLed->BlinkTimer, BlinkTimerCallback, (unsigned long)pLed); - - INIT_WORK(&pLed->BlinkWorkItem, BlinkWorkItemCallback23a); -} - -/* */ -/* Description: */ -/* DeInitialize an led_8723a object. */ -/* */ -void -DeInitLed871x23a(struct led_8723a *pLed) -{ - cancel_work_sync(&pLed->BlinkWorkItem); - del_timer_sync(&pLed->BlinkTimer); - ResetLedStatus23a(pLed); -} - -/* Description: */ -/* Implementation of LED blinking behavior. */ -/* It toggle off LED and schedule corresponding timer if necessary. */ - -static void SwLedBlink(struct led_8723a *pLed) -{ - struct rtw_adapter *padapter = pLed->padapter; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - u8 bStopBlinking = false; - - /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == RTW_LED_ON) { - SwLedOn23a(padapter, pLed); - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); - } else { - SwLedOff23a(padapter, pLed); - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); - } - - /* Determine if we shall change LED state again. */ - pLed->BlinkTimes--; - switch (pLed->CurrLedState) { - - case LED_BLINK_NORMAL: - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - break; - case LED_BLINK_StartToBlink: - if (check_fwstate(pmlmepriv, _FW_LINKED) && - check_fwstate(pmlmepriv, WIFI_STATION_STATE)) - bStopBlinking = true; - if (check_fwstate(pmlmepriv, _FW_LINKED) && - (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || - check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) - bStopBlinking = true; - else if (pLed->BlinkTimes == 0) - bStopBlinking = true; - break; - case LED_BLINK_WPS: - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - break; - default: - bStopBlinking = true; - break; - } - - if (bStopBlinking) { - if ((check_fwstate(pmlmepriv, _FW_LINKED)) && !pLed->bLedOn) - SwLedOn23a(padapter, pLed); - else if ((check_fwstate(pmlmepriv, _FW_LINKED)) && pLed->bLedOn) - SwLedOff23a(padapter, pLed); - - pLed->BlinkTimes = 0; - pLed->bLedBlinkInProgress = false; - } else { - /* Assign LED state to toggle. */ - if (pLed->BlinkingLedState == RTW_LED_ON) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - - /* Schedule a timer to toggle LED state. */ - switch (pLed->CurrLedState) { - case LED_BLINK_NORMAL: - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - break; - case LED_BLINK_SLOWLY: - case LED_BLINK_StartToBlink: - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL)); - break; - case LED_BLINK_WPS: - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_LONG_INTERVAL)); - break; - default: - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL)); - break; - } - } -} - -static void SwLedBlink1(struct led_8723a *pLed) -{ - struct rtw_adapter *padapter = pLed->padapter; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - unsigned long delay = 0; - u8 bStopBlinking = false; - - /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == RTW_LED_ON) { - SwLedOn23a(padapter, pLed); - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, - ("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); - } else { - SwLedOff23a(padapter, pLed); - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, - ("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); - } - - if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { - SwLedOff23a(padapter, pLed); - ResetLedStatus23a(pLed); - return; - } - switch (pLed->CurrLedState) { - case LED_BLINK_SLOWLY: - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_NO_LINK_INTERVAL_ALPHA; - break; - case LED_BLINK_NORMAL: - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_LINK_INTERVAL_ALPHA; - break; - case LED_BLINK_SCAN: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->bLedLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_NORMAL; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_LINK_INTERVAL_ALPHA; - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState)); - } else { - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_NO_LINK_INTERVAL_ALPHA; - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState)); - } - pLed->bLedScanBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_SCAN_INTERVAL_ALPHA; - } - break; - case LED_BLINK_TXRX: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->bLedLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_NORMAL; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_LINK_INTERVAL_ALPHA; - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState)); - } else { - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_NO_LINK_INTERVAL_ALPHA; - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState)); - } - pLed->BlinkTimes = 0; - pLed->bLedBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_FASTER_INTERVAL_ALPHA; - } - break; - case LED_BLINK_WPS: - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_SCAN_INTERVAL_ALPHA; - break; - case LED_BLINK_WPS_STOP: /* WPS success */ - if (pLed->BlinkingLedState == RTW_LED_ON) - bStopBlinking = false; - else - bStopBlinking = true; - if (bStopBlinking) { - pLed->bLedLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_NORMAL; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_LINK_INTERVAL_ALPHA; - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState)); - - pLed->bLedWPSBlinkInProgress = false; - } else { - pLed->BlinkingLedState = RTW_LED_OFF; - delay = LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA; - } - break; - default: - break; - } - if (delay) - mod_timer(&pLed->BlinkTimer, jiffies + msecs_to_jiffies(delay)); -} - -static void SwLedBlink2(struct led_8723a *pLed) -{ - struct rtw_adapter *padapter = pLed->padapter; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - u8 bStopBlinking = false; - - /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == RTW_LED_ON) { - SwLedOn23a(padapter, pLed); - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, - ("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); - } else { - SwLedOff23a(padapter, pLed); - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, - ("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); - } - switch (pLed->CurrLedState) { - case LED_BLINK_SCAN: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { - SwLedOff23a(padapter, pLed); - } else if (check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->CurrLedState = RTW_LED_ON; - pLed->BlinkingLedState = RTW_LED_ON; - SwLedOn23a(padapter, pLed); - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, - ("stop scan blink CurrLedState %d\n", - pLed->CurrLedState)); - } else { - pLed->CurrLedState = RTW_LED_OFF; - pLed->BlinkingLedState = RTW_LED_OFF; - SwLedOff23a(padapter, pLed); - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, - ("stop scan blink CurrLedState %d\n", - pLed->CurrLedState)); - } - pLed->bLedScanBlinkInProgress = false; - } else { - if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { - SwLedOff23a(padapter, pLed); - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - } - break; - case LED_BLINK_TXRX: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { - SwLedOff23a(padapter, pLed); - } else if (check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->CurrLedState = RTW_LED_ON; - pLed->BlinkingLedState = RTW_LED_ON; - SwLedOn23a(padapter, pLed); - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, - ("stop CurrLedState %d\n", pLed->CurrLedState)); - - } else { - pLed->CurrLedState = RTW_LED_OFF; - pLed->BlinkingLedState = RTW_LED_OFF; - SwLedOff23a(padapter, pLed); - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, - ("stop CurrLedState %d\n", pLed->CurrLedState)); - } - pLed->bLedBlinkInProgress = false; - } else { - if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { - SwLedOff23a(padapter, pLed); - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - } - break; - default: - break; - } -} - -static void SwLedBlink3(struct led_8723a *pLed) -{ - struct rtw_adapter *padapter = pLed->padapter; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - u8 bStopBlinking = false; - - /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == RTW_LED_ON) - { - SwLedOn23a(padapter, pLed); - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); - } - else - { - if (pLed->CurrLedState != LED_BLINK_WPS_STOP) - SwLedOff23a(padapter, pLed); - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); - } - - switch (pLed->CurrLedState) - { - case LED_BLINK_SCAN: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - { - bStopBlinking = true; - } - - if (bStopBlinking) - { - if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) - { - SwLedOff23a(padapter, pLed); - } - else if (check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->CurrLedState = RTW_LED_ON; - pLed->BlinkingLedState = RTW_LED_ON; - if (!pLed->bLedOn) - SwLedOn23a(padapter, pLed); - - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState)); - } else { - pLed->CurrLedState = RTW_LED_OFF; - pLed->BlinkingLedState = RTW_LED_OFF; - if (pLed->bLedOn) - SwLedOff23a(padapter, pLed); - - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState)); - } - pLed->bLedScanBlinkInProgress = false; - } - else - { - if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) - { - SwLedOff23a(padapter, pLed); - } - else - { - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - } - break; - - case LED_BLINK_TXRX: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - { - bStopBlinking = true; - } - if (bStopBlinking) - { - if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) - { - SwLedOff23a(padapter, pLed); - } else if (check_fwstate(pmlmepriv, - _FW_LINKED)) { - pLed->CurrLedState = RTW_LED_ON; - pLed->BlinkingLedState = RTW_LED_ON; - - if (!pLed->bLedOn) - SwLedOn23a(padapter, pLed); - - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState)); - } else { - pLed->CurrLedState = RTW_LED_OFF; - pLed->BlinkingLedState = RTW_LED_OFF; - - if (pLed->bLedOn) - SwLedOff23a(padapter, pLed); - - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState)); - } - pLed->bLedBlinkInProgress = false; - } - else - { - if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) - { - SwLedOff23a(padapter, pLed); - } - else - { - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - } - break; - - case LED_BLINK_WPS: - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - break; - - case LED_BLINK_WPS_STOP: /* WPS success */ - if (pLed->BlinkingLedState == RTW_LED_ON) - { - pLed->BlinkingLedState = RTW_LED_OFF; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA)); - bStopBlinking = false; - } else { - bStopBlinking = true; - } - - if (bStopBlinking) - { - if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) - { - SwLedOff23a(padapter, pLed); - } - else - { - pLed->CurrLedState = RTW_LED_ON; - pLed->BlinkingLedState = RTW_LED_ON; - SwLedOn23a(padapter, pLed); - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState)); - } - pLed->bLedWPSBlinkInProgress = false; - } - break; - - default: - break; - } -} - -static void SwLedBlink4(struct led_8723a *pLed) -{ - struct rtw_adapter *padapter = pLed->padapter; - struct led_priv *ledpriv = &padapter->ledpriv; - struct led_8723a *pLed1 = &ledpriv->SwLed1; - u8 bStopBlinking = false; - unsigned long delay = 0; - - /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == RTW_LED_ON) - { - SwLedOn23a(padapter, pLed); - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); - } else { - SwLedOff23a(padapter, pLed); - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); - } - - if (!pLed1->bLedWPSBlinkInProgress && pLed1->BlinkingLedState == LED_UNKNOWN) - { - pLed1->BlinkingLedState = RTW_LED_OFF; - pLed1->CurrLedState = RTW_LED_OFF; - SwLedOff23a(padapter, pLed1); - } - - switch (pLed->CurrLedState) - { - case LED_BLINK_SLOWLY: - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_NO_LINK_INTERVAL_ALPHA; - break; - - case LED_BLINK_StartToBlink: - if (pLed->bLedOn) { - pLed->BlinkingLedState = RTW_LED_OFF; - delay = LED_BLINK_SLOWLY_INTERVAL; - } else { - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_NORMAL_INTERVAL; - } - break; - - case LED_BLINK_SCAN: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) { - bStopBlinking = false; - } - - if (bStopBlinking) { - if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { - SwLedOff23a(padapter, pLed); - } else { - pLed->bLedNoLinkBlinkInProgress = false; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_NO_LINK_INTERVAL_ALPHA; - } - pLed->bLedScanBlinkInProgress = false; - } else { - if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { - SwLedOff23a(padapter, pLed); - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_SCAN_INTERVAL_ALPHA; - } - } - break; - - case LED_BLINK_TXRX: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) { - bStopBlinking = true; - } - if (bStopBlinking) { - if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { - SwLedOff23a(padapter, pLed); - } else { - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_NO_LINK_INTERVAL_ALPHA; - } - pLed->bLedBlinkInProgress = false; - } else { - if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { - SwLedOff23a(padapter, pLed); - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_FASTER_INTERVAL_ALPHA; - } - } - break; - - case LED_BLINK_WPS: - if (pLed->bLedOn) { - pLed->BlinkingLedState = RTW_LED_OFF; - delay = LED_BLINK_SLOWLY_INTERVAL; - } else { - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_NORMAL_INTERVAL; - } - break; - - case LED_BLINK_WPS_STOP: /* WPS authentication fail */ - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - - delay = LED_BLINK_NORMAL_INTERVAL; - break; - - case LED_BLINK_WPS_STOP_OVERLAP: /* WPS session overlap */ - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) { - if (pLed->bLedOn) { - pLed->BlinkTimes = 1; - } else { - bStopBlinking = true; - } - } - - if (bStopBlinking) { - pLed->BlinkTimes = 10; - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_LINK_INTERVAL_ALPHA; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - - delay = LED_BLINK_NORMAL_INTERVAL; - } - break; - - default: - break; - } - if (delay) - mod_timer(&pLed->BlinkTimer, jiffies + msecs_to_jiffies(delay)); - - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("SwLedBlink4 CurrLedState %d\n", pLed->CurrLedState)); -} - -static void SwLedBlink5(struct led_8723a *pLed) -{ - struct rtw_adapter *padapter = pLed->padapter; - u8 bStopBlinking = false; - unsigned long delay = 0; - - /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == RTW_LED_ON) { - SwLedOn23a(padapter, pLed); - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); - } else { - SwLedOff23a(padapter, pLed); - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); - } - - switch (pLed->CurrLedState) - { - case LED_BLINK_SCAN: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) { - bStopBlinking = true; - } - - if (bStopBlinking) { - if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { - pLed->CurrLedState = RTW_LED_OFF; - pLed->BlinkingLedState = RTW_LED_OFF; - if (pLed->bLedOn) - SwLedOff23a(padapter, pLed); - } else { - pLed->CurrLedState = RTW_LED_ON; - pLed->BlinkingLedState = RTW_LED_ON; - if (!pLed->bLedOn) - delay = LED_BLINK_FASTER_INTERVAL_ALPHA; - } - - pLed->bLedScanBlinkInProgress = false; - } else { - if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { - SwLedOff23a(padapter, pLed); - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_SCAN_INTERVAL_ALPHA; - } - } - break; - - case LED_BLINK_TXRX: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) { - bStopBlinking = true; - } - - if (bStopBlinking) { - if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { - pLed->CurrLedState = RTW_LED_OFF; - pLed->BlinkingLedState = RTW_LED_OFF; - if (pLed->bLedOn) - SwLedOff23a(padapter, pLed); - } else { - pLed->CurrLedState = RTW_LED_ON; - pLed->BlinkingLedState = RTW_LED_ON; - if (!pLed->bLedOn) - delay = LED_BLINK_FASTER_INTERVAL_ALPHA; - } - - pLed->bLedBlinkInProgress = false; - } else { - if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { - SwLedOff23a(padapter, pLed); - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_FASTER_INTERVAL_ALPHA; - } - } - break; - - default: - break; - } - - if (delay) - mod_timer(&pLed->BlinkTimer, jiffies + msecs_to_jiffies(delay)); - - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("SwLedBlink5 CurrLedState %d\n", pLed->CurrLedState)); -} - -static void SwLedBlink6(struct led_8723a *pLed) -{ - struct rtw_adapter *padapter = pLed->padapter; - - /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == RTW_LED_ON) { - SwLedOn23a(padapter, pLed); - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); - } else { - SwLedOff23a(padapter, pLed); - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); - } - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("<==== blink6\n")); -} - -/* ALPHA, added by chiyoko, 20090106 */ -static void -SwLedControlMode1(struct rtw_adapter *padapter, enum led_ctl_mode LedAction) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - struct led_8723a *pLed = &ledpriv->SwLed0; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - long delay = -1; - - switch (LedAction) - { - case LED_CTL_POWER_ON: - case LED_CTL_START_TO_LINK: - case LED_CTL_NO_LINK: - if (pLed->bLedNoLinkBlinkInProgress == false) { - if (pLed->CurrLedState == LED_BLINK_SCAN || - IS_LED_WPS_BLINKING(pLed)) { - return; - } - if (pLed->bLedLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_NO_LINK_INTERVAL_ALPHA; - } - break; - - case LED_CTL_LINK: - if (pLed->bLedLinkBlinkInProgress == false) { - if (pLed->CurrLedState == LED_BLINK_SCAN || - IS_LED_WPS_BLINKING(pLed)) { - return; - } - if (pLed->bLedNoLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_NORMAL; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_LINK_INTERVAL_ALPHA; - } - break; - - case LED_CTL_SITE_SURVEY: - if (pmlmepriv->LinkDetectInfo.bBusyTraffic && - check_fwstate(pmlmepriv, _FW_LINKED)) - ; - else if (pLed->bLedScanBlinkInProgress == false) { - if (IS_LED_WPS_BLINKING(pLed)) - return; - - if (pLed->bLedNoLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedScanBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SCAN; - pLed->BlinkTimes = 24; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_SCAN_INTERVAL_ALPHA; - } - break; - - case LED_CTL_TX: - case LED_CTL_RX: - if (pLed->bLedBlinkInProgress == false) { - if (pLed->CurrLedState == LED_BLINK_SCAN || - IS_LED_WPS_BLINKING(pLed)) { - return; - } - if (pLed->bLedNoLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; - } - pLed->bLedBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_TXRX; - pLed->BlinkTimes = 2; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_FASTER_INTERVAL_ALPHA; - } - break; - - case LED_CTL_START_WPS: /* wait until xinpin finish */ - case LED_CTL_START_WPS_BOTTON: - if (pLed->bLedWPSBlinkInProgress == false) { - if (pLed->bLedNoLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - pLed->bLedWPSBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_WPS; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_SCAN_INTERVAL_ALPHA; - } - break; - - case LED_CTL_STOP_WPS: - if (pLed->bLedNoLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - } else { - pLed->bLedWPSBlinkInProgress = true; - } - - pLed->CurrLedState = LED_BLINK_WPS_STOP; - if (pLed->bLedOn) { - pLed->BlinkingLedState = RTW_LED_OFF; - delay = LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA; - } else { - pLed->BlinkingLedState = RTW_LED_ON; - delay = 0; - } - break; - - case LED_CTL_STOP_WPS_FAIL: - if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_NO_LINK_INTERVAL_ALPHA; - break; - - case LED_CTL_POWER_OFF: - pLed->CurrLedState = RTW_LED_OFF; - pLed->BlinkingLedState = RTW_LED_OFF; - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedLinkBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - - SwLedOff23a(padapter, pLed); - break; - - default: - break; - - } - - if (delay != -1) - mod_timer(&pLed->BlinkTimer, jiffies + msecs_to_jiffies(delay)); - - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Led %d\n", pLed->CurrLedState)); -} - - /* Arcadyan/Sitecom , added by chiyoko, 20090216 */ -static void -SwLedControlMode2(struct rtw_adapter *padapter, enum led_ctl_mode LedAction) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct led_8723a *pLed = &ledpriv->SwLed0; - long delay = -1; - - switch (LedAction) { - case LED_CTL_SITE_SURVEY: - if (pmlmepriv->LinkDetectInfo.bBusyTraffic) - ; - else if (pLed->bLedScanBlinkInProgress == false) { - if (IS_LED_WPS_BLINKING(pLed)) - return; - - if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedScanBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SCAN; - pLed->BlinkTimes = 24; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_SCAN_INTERVAL_ALPHA; - } - break; - case LED_CTL_TX: - case LED_CTL_RX: - if (pLed->bLedBlinkInProgress == false && - check_fwstate(pmlmepriv, _FW_LINKED)) { - if (pLed->CurrLedState == LED_BLINK_SCAN || - IS_LED_WPS_BLINKING(pLed)) { - return; - } - - pLed->bLedBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_TXRX; - pLed->BlinkTimes = 2; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_FASTER_INTERVAL_ALPHA; - } - break; - case LED_CTL_LINK: - pLed->CurrLedState = RTW_LED_ON; - pLed->BlinkingLedState = RTW_LED_ON; - if (pLed->bLedBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - - delay = 0; - break; - case LED_CTL_START_WPS: /* wait until xinpin finish */ - case LED_CTL_START_WPS_BOTTON: - if (pLed->bLedWPSBlinkInProgress == false) { - if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - pLed->bLedWPSBlinkInProgress = true; - pLed->CurrLedState = RTW_LED_ON; - pLed->BlinkingLedState = RTW_LED_ON; - delay = 0; - } - break; - case LED_CTL_STOP_WPS: - pLed->bLedWPSBlinkInProgress = false; - if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { - SwLedOff23a(padapter, pLed); - } else { - pLed->CurrLedState = RTW_LED_ON; - pLed->BlinkingLedState = RTW_LED_ON; - delay = 0; - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState)); - } - break; - case LED_CTL_STOP_WPS_FAIL: - pLed->bLedWPSBlinkInProgress = false; - if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { - SwLedOff23a(padapter, pLed); - } else { - pLed->CurrLedState = RTW_LED_OFF; - pLed->BlinkingLedState = RTW_LED_OFF; - delay = 0; - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState)); - } - break; - case LED_CTL_START_TO_LINK: - case LED_CTL_NO_LINK: - if (!IS_LED_BLINKING(pLed)) - { - pLed->CurrLedState = RTW_LED_OFF; - pLed->BlinkingLedState = RTW_LED_OFF; - delay = 0; - } - break; - case LED_CTL_POWER_OFF: - pLed->CurrLedState = RTW_LED_OFF; - pLed->BlinkingLedState = RTW_LED_OFF; - if (pLed->bLedBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - - delay = 0; - break; - default: - break; - - } - - if (delay != -1) - mod_timer(&pLed->BlinkTimer, jiffies + msecs_to_jiffies(delay)); - - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState)); -} - - /* COREGA, added by chiyoko, 20090316 */ -static void -SwLedControlMode3(struct rtw_adapter *padapter, enum led_ctl_mode LedAction) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct led_8723a *pLed = &ledpriv->SwLed0; - long delay = -1; - - switch (LedAction) - { - case LED_CTL_SITE_SURVEY: - if (pmlmepriv->LinkDetectInfo.bBusyTraffic) - ; - else if (pLed->bLedScanBlinkInProgress == false) { - if (IS_LED_WPS_BLINKING(pLed)) - return; - - if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedScanBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SCAN; - pLed->BlinkTimes = 24; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_SCAN_INTERVAL_ALPHA; - } - break; - - case LED_CTL_TX: - case LED_CTL_RX: - if (pLed->bLedBlinkInProgress == false && - check_fwstate(pmlmepriv, _FW_LINKED)) { - if (pLed->CurrLedState == LED_BLINK_SCAN || - IS_LED_WPS_BLINKING(pLed)) { - return; - } - - pLed->bLedBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_TXRX; - pLed->BlinkTimes = 2; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_FASTER_INTERVAL_ALPHA; - } - break; - - case LED_CTL_LINK: - if (IS_LED_WPS_BLINKING(pLed)) - return; - - pLed->CurrLedState = RTW_LED_ON; - pLed->BlinkingLedState = RTW_LED_ON; - if (pLed->bLedBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - - delay = 0; - break; - - case LED_CTL_START_WPS: /* wait until xinpin finish */ - case LED_CTL_START_WPS_BOTTON: - if (pLed->bLedWPSBlinkInProgress == false) { - if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - pLed->bLedWPSBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_WPS; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - delay = LED_BLINK_SCAN_INTERVAL_ALPHA; - } - break; - - case LED_CTL_STOP_WPS: - if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } else { - pLed->bLedWPSBlinkInProgress = true; - } - - pLed->CurrLedState = LED_BLINK_WPS_STOP; - if (pLed->bLedOn) { - pLed->BlinkingLedState = RTW_LED_OFF; - delay = LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA; - } else { - pLed->BlinkingLedState = RTW_LED_ON; - delay = 0; - } - - break; - - case LED_CTL_STOP_WPS_FAIL: - if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - - pLed->CurrLedState = RTW_LED_OFF; - pLed->BlinkingLedState = RTW_LED_OFF; - delay = 0; - break; - - case LED_CTL_START_TO_LINK: - case LED_CTL_NO_LINK: - if (!IS_LED_BLINKING(pLed)) - { - pLed->CurrLedState = RTW_LED_OFF; - pLed->BlinkingLedState = RTW_LED_OFF; - delay = 0; - } - break; - - case LED_CTL_POWER_OFF: - pLed->CurrLedState = RTW_LED_OFF; - pLed->BlinkingLedState = RTW_LED_OFF; - if (pLed->bLedBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - - delay = 0; - break; - - default: - break; - - } - - if (delay != -1) - mod_timer(&pLed->BlinkTimer, jiffies + msecs_to_jiffies(delay)); - - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState)); -} - - /* Edimax-Belkin, added by chiyoko, 20090413 */ -static void -SwLedControlMode4(struct rtw_adapter *padapter, enum led_ctl_mode LedAction) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct led_8723a *pLed = &ledpriv->SwLed0; - struct led_8723a *pLed1 = &ledpriv->SwLed1; - - switch (LedAction) - { - case LED_CTL_START_TO_LINK: - if (pLed1->bLedWPSBlinkInProgress) { - pLed1->bLedWPSBlinkInProgress = false; - del_timer_sync(&pLed1->BlinkTimer); - - pLed1->BlinkingLedState = RTW_LED_OFF; - pLed1->CurrLedState = RTW_LED_OFF; - - if (pLed1->bLedOn) - mod_timer(&pLed->BlinkTimer, jiffies); - } - - if (pLed->bLedStartToLinkBlinkInProgress == false) { - if (pLed->CurrLedState == LED_BLINK_SCAN || - IS_LED_WPS_BLINKING(pLed)) { - return; - } - if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedNoLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - - pLed->bLedStartToLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_StartToBlink; - if (pLed->bLedOn) { - pLed->BlinkingLedState = RTW_LED_OFF; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL)); - } else { - pLed->BlinkingLedState = RTW_LED_ON; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - } - } - break; - - case LED_CTL_LINK: - case LED_CTL_NO_LINK: - /* LED1 settings */ - if (LedAction == LED_CTL_LINK) { - if (pLed1->bLedWPSBlinkInProgress) { - pLed1->bLedWPSBlinkInProgress = false; - del_timer_sync(&pLed1->BlinkTimer); - - pLed1->BlinkingLedState = RTW_LED_OFF; - pLed1->CurrLedState = RTW_LED_OFF; - - if (pLed1->bLedOn) - mod_timer(&pLed->BlinkTimer, jiffies); - } - } - - if (pLed->bLedNoLinkBlinkInProgress == false) { - if (pLed->CurrLedState == LED_BLINK_SCAN || - IS_LED_WPS_BLINKING(pLed)) { - return; - } - if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - } - break; - - case LED_CTL_SITE_SURVEY: - if (pmlmepriv->LinkDetectInfo.bBusyTraffic && - check_fwstate(pmlmepriv, _FW_LINKED)) - ; - else if (pLed->bLedScanBlinkInProgress == false) { - if (IS_LED_WPS_BLINKING(pLed)) - return; - - if (pLed->bLedNoLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedScanBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SCAN; - pLed->BlinkTimes = 24; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - - case LED_CTL_TX: - case LED_CTL_RX: - if (pLed->bLedBlinkInProgress == false) { - if (pLed->CurrLedState == LED_BLINK_SCAN || - IS_LED_WPS_BLINKING(pLed)) { - return; - } - if (pLed->bLedNoLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - pLed->bLedBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_TXRX; - pLed->BlinkTimes = 2; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - - case LED_CTL_START_WPS: /* wait until xinpin finish */ - case LED_CTL_START_WPS_BOTTON: - if (pLed1->bLedWPSBlinkInProgress) { - pLed1->bLedWPSBlinkInProgress = false; - del_timer_sync(&pLed1->BlinkTimer); - - pLed1->BlinkingLedState = RTW_LED_OFF; - pLed1->CurrLedState = RTW_LED_OFF; - - if (pLed1->bLedOn) - mod_timer(&pLed->BlinkTimer, jiffies); - } - - if (pLed->bLedWPSBlinkInProgress == false) { - if (pLed->bLedNoLinkBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress == true) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - pLed->bLedWPSBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_WPS; - if (pLed->bLedOn) - { - pLed->BlinkingLedState = RTW_LED_OFF; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL)); - } else { - pLed->BlinkingLedState = RTW_LED_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - } - } - break; - - case LED_CTL_STOP_WPS: /* WPS connect success */ - if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - break; - - case LED_CTL_STOP_WPS_FAIL: /* WPS authentication fail */ - if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - - /* LED1 settings */ - if (pLed1->bLedWPSBlinkInProgress) - del_timer_sync(&pLed1->BlinkTimer); - else - pLed1->bLedWPSBlinkInProgress = true; - - pLed1->CurrLedState = LED_BLINK_WPS_STOP; - if (pLed1->bLedOn) - pLed1->BlinkingLedState = RTW_LED_OFF; - else - pLed1->BlinkingLedState = RTW_LED_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - - break; - - case LED_CTL_STOP_WPS_FAIL_OVERLAP: /* WPS session overlap */ - if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - - /* LED1 settings */ - if (pLed1->bLedWPSBlinkInProgress) - del_timer_sync(&pLed1->BlinkTimer); - else - pLed1->bLedWPSBlinkInProgress = true; - - pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP; - pLed1->BlinkTimes = 10; - if (pLed1->bLedOn) - pLed1->BlinkingLedState = RTW_LED_OFF; - else - pLed1->BlinkingLedState = RTW_LED_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - - break; - - case LED_CTL_POWER_OFF: - pLed->CurrLedState = RTW_LED_OFF; - pLed->BlinkingLedState = RTW_LED_OFF; - - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedLinkBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - if (pLed->bLedStartToLinkBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedStartToLinkBlinkInProgress = false; - } - - if (pLed1->bLedWPSBlinkInProgress) { - del_timer_sync(&pLed1->BlinkTimer); - pLed1->bLedWPSBlinkInProgress = false; - } - - pLed1->BlinkingLedState = LED_UNKNOWN; - SwLedOff23a(padapter, pLed); - SwLedOff23a(padapter, pLed1); - break; - - default: - break; - - } - - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Led %d\n", pLed->CurrLedState)); -} - - /* Sercomm-Belkin, added by chiyoko, 20090415 */ -static void -SwLedControlMode5(struct rtw_adapter *padapter, enum led_ctl_mode LedAction) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct led_8723a *pLed = &ledpriv->SwLed0; - - switch (LedAction) - { - case LED_CTL_POWER_ON: - case LED_CTL_NO_LINK: - case LED_CTL_LINK: /* solid blue */ - pLed->CurrLedState = RTW_LED_ON; - pLed->BlinkingLedState = RTW_LED_ON; - - mod_timer(&pLed->BlinkTimer, jiffies); - break; - - case LED_CTL_SITE_SURVEY: - if (pmlmepriv->LinkDetectInfo.bBusyTraffic && - check_fwstate(pmlmepriv, _FW_LINKED)) - ; - else if (pLed->bLedScanBlinkInProgress == false) - { - if (pLed->bLedBlinkInProgress == true) - { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedScanBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SCAN; - pLed->BlinkTimes = 24; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - - case LED_CTL_TX: - case LED_CTL_RX: - if (pLed->bLedBlinkInProgress == false) { - if (pLed->CurrLedState == LED_BLINK_SCAN) { - return; - } - pLed->bLedBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_TXRX; - pLed->BlinkTimes = 2; - if (pLed->bLedOn) - pLed->BlinkingLedState = RTW_LED_OFF; - else - pLed->BlinkingLedState = RTW_LED_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - - case LED_CTL_POWER_OFF: - pLed->CurrLedState = RTW_LED_OFF; - pLed->BlinkingLedState = RTW_LED_OFF; - - if (pLed->bLedBlinkInProgress) { - del_timer_sync(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - - SwLedOff23a(padapter, pLed); - break; - - default: - break; - - } - - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Led %d\n", pLed->CurrLedState)); -} - - /* WNC-Corega, added by chiyoko, 20090902 */ -static void SwLedControlMode6(struct rtw_adapter *padapter, - enum led_ctl_mode LedAction) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - struct led_8723a *pLed0 = &ledpriv->SwLed0; - - switch (LedAction) { - case LED_CTL_POWER_ON: - case LED_CTL_LINK: - case LED_CTL_NO_LINK: - del_timer_sync(&pLed0->BlinkTimer); - pLed0->CurrLedState = RTW_LED_ON; - pLed0->BlinkingLedState = RTW_LED_ON; - mod_timer(&pLed0->BlinkTimer, jiffies); - break; - case LED_CTL_POWER_OFF: - SwLedOff23a(padapter, pLed0); - break; - default: - break; - } - - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("ledcontrol 6 Led %d\n", pLed0->CurrLedState)); -} - -/* */ -/* Description: */ -/* Handler function of LED Blinking. */ -/* We dispatch acture LED blink action according to LedStrategy. */ -/* */ -void BlinkHandler23a(struct led_8723a *pLed) -{ - struct rtw_adapter *padapter = pLed->padapter; - struct led_priv *ledpriv = &padapter->ledpriv; - - /* DBG_8723A("%s (%s:%d)\n", __func__, current->comm, current->pid); */ - - if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped)) - return; - - switch (ledpriv->LedStrategy) { - case SW_LED_MODE0: - SwLedBlink(pLed); - break; - case SW_LED_MODE1: - SwLedBlink1(pLed); - break; - case SW_LED_MODE2: - SwLedBlink2(pLed); - break; - case SW_LED_MODE3: - SwLedBlink3(pLed); - break; - case SW_LED_MODE4: - SwLedBlink4(pLed); - break; - case SW_LED_MODE5: - SwLedBlink5(pLed); - break; - case SW_LED_MODE6: - SwLedBlink6(pLed); - break; - default: - break; - } -} - -void -LedControl871x23a(struct rtw_adapter *padapter, enum led_ctl_mode LedAction) { - struct led_priv *ledpriv = &padapter->ledpriv; - - if ((padapter->bSurpriseRemoved == true) || - (padapter->bDriverStopped == true) || - (padapter->hw_init_completed == false)) { - return; - } - - if (ledpriv->bRegUseLed == false) - return; - - /* if (!priv->up) */ - /* return; */ - - /* if (priv->bInHctTest) */ - /* return; */ - - if ((padapter->pwrctrlpriv.rf_pwrstate != rf_on && - padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) && - (LedAction == LED_CTL_TX || LedAction == LED_CTL_RX || - LedAction == LED_CTL_SITE_SURVEY || - LedAction == LED_CTL_LINK || - LedAction == LED_CTL_NO_LINK || - LedAction == LED_CTL_POWER_ON)) { - return; - } - - switch (ledpriv->LedStrategy) { - case SW_LED_MODE0: - break; - case SW_LED_MODE1: - SwLedControlMode1(padapter, LedAction); - break; - case SW_LED_MODE2: - SwLedControlMode2(padapter, LedAction); - break; - case SW_LED_MODE3: - SwLedControlMode3(padapter, LedAction); - break; - case SW_LED_MODE4: - SwLedControlMode4(padapter, LedAction); - break; - case SW_LED_MODE5: - SwLedControlMode5(padapter, LedAction); - break; - case SW_LED_MODE6: - SwLedControlMode6(padapter, LedAction); - break; - default: - break; - } - - RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("LedStrategy:%d, LedAction %d\n", ledpriv->LedStrategy, LedAction)); -} diff --git a/drivers/staging/rtl8723au/core/rtw_mlme.c b/drivers/staging/rtl8723au/core/rtw_mlme.c index 1f6006439bbb..7299ef0a2e54 100644 --- a/drivers/staging/rtl8723au/core/rtw_mlme.c +++ b/drivers/staging/rtl8723au/core/rtw_mlme.c @@ -50,7 +50,6 @@ static void rtw_init_mlme_timer(struct rtw_adapter *padapter) int rtw_init_mlme_priv23a(struct rtw_adapter *padapter) { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - int res = _SUCCESS; pmlmepriv->nic_hdl = padapter; @@ -68,7 +67,7 @@ int rtw_init_mlme_priv23a(struct rtw_adapter *padapter) rtw_clear_scan_deny(padapter); rtw_init_mlme_timer(padapter); - return res; + return _SUCCESS; } #ifdef CONFIG_8723AU_AP_MODE @@ -110,7 +109,6 @@ struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv, gfp_t gfp) pnetwork->network_type = 0; pnetwork->fixed = false; pnetwork->last_scanned = jiffies; - pnetwork->aid = 0; pnetwork->join_res = 0; } @@ -218,8 +216,6 @@ void rtw_generate_random_ibss23a(u8 *pibss) pibss[3] = curtime & 0xff;/* p[0]; */ pibss[4] = (curtime >> 8) & 0xff;/* p[1]; */ pibss[5] = (curtime >> 16) & 0xff;/* p[2]; */ - - return; } void rtw_set_roaming(struct rtw_adapter *adapter, u8 to_roaming) @@ -356,12 +352,12 @@ rtw_get_oldest_wlan_network23a(struct rtw_queue *scanned_queue) void update_network23a(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src, struct rtw_adapter *padapter, bool update_ie) { - u8 ss_ori = dst->PhyInfo.SignalStrength; - u8 sq_ori = dst->PhyInfo.SignalQuality; + u8 ss_ori = dst->SignalStrength; + u8 sq_ori = dst->SignalQuality; long rssi_ori = dst->Rssi; - u8 ss_smp = src->PhyInfo.SignalStrength; - u8 sq_smp = src->PhyInfo.SignalQuality; + u8 ss_smp = src->SignalStrength; + u8 sq_smp = src->SignalQuality; long rssi_smp = src->Rssi; u8 ss_final; @@ -389,16 +385,16 @@ void update_network23a(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src, rssi_final = rssi_ori; } else { if (sq_smp != 101) { /* from the right channel */ - ss_final = ((u32)src->PhyInfo.SignalStrength + - (u32)dst->PhyInfo.SignalStrength * 4) / 5; - sq_final = ((u32)src->PhyInfo.SignalQuality + - (u32)dst->PhyInfo.SignalQuality * 4) / 5; + ss_final = ((u32)src->SignalStrength + + (u32)dst->SignalStrength * 4) / 5; + sq_final = ((u32)src->SignalQuality + + (u32)dst->SignalQuality * 4) / 5; rssi_final = src->Rssi+dst->Rssi * 4 / 5; } else { /* bss info not receiving from the right channel, use the original RX signal infos */ - ss_final = dst->PhyInfo.SignalStrength; - sq_final = dst->PhyInfo.SignalQuality; + ss_final = dst->SignalStrength; + sq_final = dst->SignalQuality; rssi_final = dst->Rssi; } @@ -407,14 +403,13 @@ void update_network23a(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src, if (update_ie) memcpy(dst, src, get_wlan_bssid_ex_sz(src)); - dst->PhyInfo.SignalStrength = ss_final; - dst->PhyInfo.SignalQuality = sq_final; + dst->SignalStrength = ss_final; + dst->SignalQuality = sq_final; dst->Rssi = rssi_final; DBG_8723A("%s %s(%pM), SignalStrength:%u, SignalQuality:%u, " "RawRSSI:%ld\n", __func__, dst->Ssid.ssid, dst->MacAddress, - dst->PhyInfo.SignalStrength, - dst->PhyInfo.SignalQuality, dst->Rssi); + dst->SignalStrength, dst->SignalQuality, dst->Rssi); } static void update_current_network(struct rtw_adapter *adapter, @@ -487,12 +482,11 @@ static void rtw_update_scanned_network(struct rtw_adapter *adapter, pnetwork->last_scanned = jiffies; pnetwork->network_type = 0; - pnetwork->aid = 0; pnetwork->join_res = 0; /* bss info not receiving from the right channel */ - if (pnetwork->network.PhyInfo.SignalQuality == 101) - pnetwork->network.PhyInfo.SignalQuality = 0; + if (pnetwork->network.SignalQuality == 101) + pnetwork->network.SignalQuality = 0; } else { /* * we have an entry and we are going to update it. But @@ -579,8 +573,6 @@ void rtw_atimdone_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf) { RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("receive atimdone_evet\n")); - - return; } void rtw_survey_event_cb23a(struct rtw_adapter *adapter, const u8 *pbuf) @@ -650,8 +642,6 @@ exit: kfree(survey->bss); survey->bss = NULL; - - return; } void @@ -825,8 +815,6 @@ void rtw_indicate_connect23a(struct rtw_adapter *padapter) if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { set_fwstate(pmlmepriv, _FW_LINKED); - rtw_led_control(padapter, LED_CTL_LINK); - rtw_cfg80211_indicate_connect(padapter); netif_carrier_on(padapter->pnetdev); @@ -871,10 +859,7 @@ void rtw_indicate_disconnect23a(struct rtw_adapter *padapter) _clr_fwstate_(pmlmepriv, _FW_LINKED); - rtw_led_control(padapter, LED_CTL_NO_LINK); - rtw_clear_scan_deny(padapter); - } rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_DISCONNECT, 1); @@ -1028,22 +1013,18 @@ rtw_joinbss_update_network23a(struct rtw_adapter *padapter, cur_network->network.beacon_interval = ptarget_wlan->network.beacon_interval; cur_network->network.tsf = ptarget_wlan->network.tsf; - cur_network->aid = pnetwork->join_res; rtw_set_signal_stat_timer(&padapter->recvpriv); padapter->recvpriv.signal_strength = - ptarget_wlan->network.PhyInfo.SignalStrength; - padapter->recvpriv.signal_qual = - ptarget_wlan->network.PhyInfo.SignalQuality; + ptarget_wlan->network.SignalStrength; + padapter->recvpriv.signal_qual = ptarget_wlan->network.SignalQuality; /* * the ptarget_wlan->network.Rssi is raw data, we use - * ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled) + * ptarget_wlan->network.SignalStrength instead (has scaled) */ - padapter->recvpriv.rssi = translate_percentage_to_dbm( - ptarget_wlan->network.PhyInfo.SignalStrength); - DBG_8723A("%s signal_strength:%3u, rssi:%3d, signal_qual:%3u\n", + DBG_8723A("%s signal_strength:%3u, signal_qual:%3u\n", __func__, padapter->recvpriv.signal_strength, - padapter->recvpriv.rssi, padapter->recvpriv.signal_qual); + padapter->recvpriv.signal_qual); rtw_set_signal_stat_timer(&padapter->recvpriv); /* update fw_state will clr _FW_UNDER_LINKING here indirectly */ @@ -1132,7 +1113,7 @@ void rtw_joinbss_event_prehandle23a(struct rtw_adapter *adapter, u8 *pbuf) if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { /* s1. find ptarget_wlan */ if (check_fwstate(pmlmepriv, _FW_LINKED)) { - if (the_same_macaddr == true) { + if (the_same_macaddr) { ptarget_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, cur_network->network.MacAddress); } else { pcur_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, cur_network->network.MacAddress); @@ -1515,18 +1496,21 @@ out: inline bool rtw_is_scan_deny(struct rtw_adapter *adapter) { struct mlme_priv *mlmepriv = &adapter->mlmepriv; + return (atomic_read(&mlmepriv->set_scan_deny) != 0) ? true : false; } void rtw_clear_scan_deny(struct rtw_adapter *adapter) { struct mlme_priv *mlmepriv = &adapter->mlmepriv; + atomic_set(&mlmepriv->set_scan_deny, 0); } void rtw_set_scan_deny_timer_hdl(unsigned long data) { struct rtw_adapter *adapter = (struct rtw_adapter *)data; + rtw_clear_scan_deny(adapter); } @@ -1540,7 +1524,8 @@ void rtw_set_scan_deny(struct rtw_adapter *adapter, u32 ms) } #if defined(IEEE80211_SCAN_RESULT_EXPIRE) -#define RTW_SCAN_RESULT_EXPIRE IEEE80211_SCAN_RESULT_EXPIRE/HZ*1000 -1000 /* 3000 -1000 */ +#define RTW_SCAN_RESULT_EXPIRE \ + ((IEEE80211_SCAN_RESULT_EXPIRE / (HZ*1000)) - 1000) /* 3000 -1000 */ #else #define RTW_SCAN_RESULT_EXPIRE 2000 #endif @@ -1766,7 +1751,7 @@ exit: return ret; } -int rtw_set_auth23a(struct rtw_adapter * adapter, +int rtw_set_auth23a(struct rtw_adapter *adapter, struct security_priv *psecuritypriv) { struct cmd_obj *pcmd; @@ -2151,6 +2136,7 @@ bool rtw_restructure_ht_ie23a(struct rtw_adapter *padapter, u8 *in_ie, if (p && p[1] > 0) { u32 rx_packet_offset, max_recvbuf_sz; + if (pmlmepriv->qos_option == 0) { out_len = *pout_len; pframe = rtw_set_ie23a(out_ie + out_len, @@ -2165,9 +2151,9 @@ bool rtw_restructure_ht_ie23a(struct rtw_adapter *padapter, u8 *in_ie, memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap)); - ht_capie.cap_info = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | + ht_capie.cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | - IEEE80211_HT_CAP_TX_STBC | IEEE80211_HT_CAP_DSSSCCK40; + IEEE80211_HT_CAP_TX_STBC | IEEE80211_HT_CAP_DSSSCCK40); GetHalDefVar8192CUsb(padapter, HAL_DEF_RX_PACKET_OFFSET, &rx_packet_offset); diff --git a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c index 3eb77de17e3a..0e0f73c86e53 100644 --- a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c @@ -331,6 +331,7 @@ rtw_update_TSF(struct mlme_ext_priv *pmlmeext, struct ieee80211_mgmt *mgmt) int rtw_ch_set_search_ch23a(struct rt_channel_info *ch_set, const u32 ch) { int i; + for (i = 0; ch_set[i]. ChannelNum != 0; i++) { if (ch == ch_set[i].ChannelNum) break; @@ -566,7 +567,6 @@ static u8 init_channel_set(struct rtw_adapter *padapter, u8 cplan, int init_mlme_ext_priv23a(struct rtw_adapter *padapter) { - int res = _SUCCESS; struct registry_priv *pregistrypriv = &padapter->registrypriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -593,7 +593,7 @@ int init_mlme_ext_priv23a(struct rtw_adapter *padapter) pmlmeext->mlmeext_init = true; pmlmeext->active_keep_alive_check = true; - return res; + return _SUCCESS; } void free_mlme_ext_priv23a (struct mlme_ext_priv *pmlmeext) @@ -680,8 +680,7 @@ void mgt_dispatcher23a(struct rtw_adapter *padapter, } #ifdef CONFIG_8723AU_AP_MODE - switch (stype) - { + switch (stype) { case IEEE80211_STYPE_AUTH: if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) ptable->func = &OnAuth23a; @@ -1572,6 +1571,7 @@ OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame) pstat->uapsd_bk = 0; if (pmlmepriv->qos_option) { const u8 *end = pos + left; + p = pos; for (;;) { @@ -2335,12 +2335,9 @@ static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode) __func__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */ if (ssid_ie && ssid_len_ori > 0) { - switch (hidden_ssid_mode) - { + switch (hidden_ssid_mode) { case 1: next_ie = ssid_ie + 2 + ssid_len_ori; - remain_len = 0; - remain_len = ies_len -(next_ie-ies); ssid_ie[1] = 0; @@ -2599,7 +2596,9 @@ static void issue_probersp(struct rtw_adapter *padapter, unsigned char *da, if (ssid_ie && cur_network->Ssid.ssid_len) { uint remainder_ielen; u8 *remainder_ie; + remainder_ie = ssid_ie + 2; + remainder_ielen = pframe - remainder_ie; DBG_8723A_LEVEL(_drv_warning_, "%s(%s): " @@ -2862,6 +2861,7 @@ static void issue_auth(struct rtw_adapter *padapter, struct sta_info *psta, if (psta) { /* for AP mode */ #ifdef CONFIG_8723AU_AP_MODE unsigned short val16; + ether_addr_copy(mgmt->da, psta->hwaddr); ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv)); ether_addr_copy(mgmt->bssid, myid(&padapter->eeprompriv)); @@ -3306,6 +3306,7 @@ static void issue_assocreq(struct rtw_adapter *padapter) !memcmp(p + 2, WMM_OUI23A, 4) || !memcmp(p + 2, WPS_OUI23A, 4)) { u8 plen = p[1]; + if (!padapter->registrypriv.wifi_spec) { /* Commented by Kurt 20110629 */ /* In some older APs, WPS handshake */ @@ -3997,7 +3998,7 @@ int send_beacon23a(struct rtw_adapter *padapter) yield(); bxmitok = rtl8723a_get_bcn_valid(padapter); poll++; - } while ((poll % 10) != 0 && bxmitok == false && + } while ((poll % 10) != 0 && !bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped); @@ -4070,6 +4071,7 @@ static void rtw_site_survey(struct rtw_adapter *padapter) if (ScanType == SCAN_ACTIVE) /* obey the channel plan setting... */ { int i; + for (i = 0;i<RTW_SSID_SCAN_AMOUNT;i++) { if (pmlmeext->sitesurvey_res.ssid[i].ssid_len) { /* todo: to issue two probe req??? */ @@ -4197,9 +4199,9 @@ static struct wlan_bssid_ex *collect_bss_info(struct rtw_adapter *padapter, /* get the signal strength */ /* in dBM.raw data */ bssid->Rssi = precv_frame->attrib.phy_info.RecvSignalPower; - bssid->PhyInfo.SignalQuality = + bssid->SignalQuality = precv_frame->attrib.phy_info.SignalQuality;/* in percentage */ - bssid->PhyInfo.SignalStrength = + bssid->SignalStrength = precv_frame->attrib.phy_info.SignalStrength;/* in percentage */ /* checking SSID */ @@ -4293,6 +4295,7 @@ static struct wlan_bssid_ex *collect_bss_info(struct rtw_adapter *padapter, bssid->IELength); if (p && p[1] > 0) { struct ieee80211_ht_cap *pHT_caps; + pHT_caps = (struct ieee80211_ht_cap *)(p + 2); if (pHT_caps->cap_info & @@ -4305,7 +4308,7 @@ static struct wlan_bssid_ex *collect_bss_info(struct rtw_adapter *padapter, /* mark bss info receiving from nearby channel as SignalQuality 101 */ if (bssid->DSConfig != rtw_get_oper_ch23a(padapter)) - bssid->PhyInfo.SignalQuality = 101; + bssid->SignalQuality = 101; return bssid; fail: @@ -4319,6 +4322,7 @@ static void start_create_ibss(struct rtw_adapter *padapter) struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; + pmlmeext->cur_channel = (u8)pnetwork->DSConfig; pmlmeinfo->bcn_interval = pnetwork->beacon_interval; @@ -4354,9 +4358,7 @@ static void start_create_ibss(struct rtw_adapter *padapter) report_join_res23a(padapter, 1); pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; } - } - else - { + } else { DBG_8723A("%s: invalid cap:%x\n", __func__, caps); return; } @@ -4414,9 +4416,7 @@ static void start_clnt_join(struct rtw_adapter *padapter) pmlmeinfo->state = MSR_ADHOC; report_join_res23a(padapter, 1); - } - else - { + } else { /* DBG_8723A("marc: invalid cap:%x\n", caps); */ return; } @@ -4480,16 +4480,12 @@ int receive_disconnect23a(struct rtw_adapter *padapter, DBG_8723A("%s\n", __func__); - if ((pmlmeinfo->state&0x03) == MSR_INFRA) - { - if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) - { + if ((pmlmeinfo->state&0x03) == MSR_INFRA) { + if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) { pmlmeinfo->state = MSR_NOLINK; report_del_sta_event23a(padapter, MacAddr, reason); - } - else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) - { + } else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) { pmlmeinfo->state = MSR_NOLINK; report_join_res23a(padapter, -2); } @@ -4866,7 +4862,7 @@ void report_join_res23a(struct rtw_adapter *padapter, int res) pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header)); memcpy((unsigned char *)&pjoinbss_evt->network.network, &pmlmeinfo->network, sizeof(struct wlan_bssid_ex)); - pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res; + pjoinbss_evt->network.join_res = res; DBG_8723A("report_join_res23a(%d)\n", res); @@ -4995,8 +4991,7 @@ void update_sta_info23a(struct rtw_adapter *padapter, struct sta_info *psta) VCS_update23a(padapter, psta); /* HT */ - if (pmlmepriv->htpriv.ht_option) - { + if (pmlmepriv->htpriv.ht_option) { psta->htpriv.ht_option = true; psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable; @@ -5006,9 +5001,7 @@ void update_sta_info23a(struct rtw_adapter *padapter, struct sta_info *psta) psta->qos_option = true; - } - else - { + } else { psta->htpriv.ht_option = false; psta->htpriv.ampdu_enable = false; @@ -5050,12 +5043,10 @@ void mlmeext_joinbss_event_callback23a(struct rtw_adapter *padapter, goto exit_mlmeext_joinbss_event_callback23a; } - if ((pmlmeinfo->state&0x03) == MSR_ADHOC) - { + if ((pmlmeinfo->state&0x03) == MSR_ADHOC) { /* for bc/mc */ psta_bmc = rtw_get_bcmc_stainfo23a(padapter); - if (psta_bmc) - { + if (psta_bmc) { pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc; update_bmc_sta_support_rate23a(padapter, psta_bmc->mac_id); Update_RA_Entry23a(padapter, psta_bmc); @@ -5086,8 +5077,7 @@ void mlmeext_joinbss_event_callback23a(struct rtw_adapter *padapter, set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress); - if (psta) /* only for infra. mode */ - { + if (psta) { /* only for infra. mode */ pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta; /* DBG_8723A("set_sta_rate23a\n"); */ @@ -5123,8 +5113,7 @@ void mlmeext_sta_add_event_callback23a(struct rtw_adapter *padapter, if ((pmlmeinfo->state & 0x03) == MSR_ADHOC) { /* adhoc master or sta_count>1 */ - if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) - { + if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) { /* nothing to do */ } else { /* adhoc client */ /* correcting TSF */ diff --git a/drivers/staging/rtl8723au/core/rtw_pwrctrl.c b/drivers/staging/rtl8723au/core/rtw_pwrctrl.c index 1b2af7381d82..e2d51afe522c 100644 --- a/drivers/staging/rtl8723au/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8723au/core/rtw_pwrctrl.c @@ -159,7 +159,7 @@ void rtw_ps_processor23a(struct rtw_adapter *padapter) if (pwrpriv->ips_mode_req == IPS_NONE) goto exit; - if (rtw_pwr_unassociated_idle(padapter) == false) + if (!rtw_pwr_unassociated_idle(padapter)) goto exit; if (pwrpriv->rf_pwrstate == rf_on && @@ -172,12 +172,12 @@ void rtw_ps_processor23a(struct rtw_adapter *padapter) exit: rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv); pwrpriv->ps_processing = false; - return; } static void pwr_state_check_handler(unsigned long data) { struct rtw_adapter *padapter = (struct rtw_adapter *)data; + rtw_ps_cmd23a(padapter); } @@ -338,8 +338,7 @@ s32 LPS_RF_ON_check23a(struct rtw_adapter *padapter, u32 delay_ms) start_time = jiffies; end_time = start_time + msecs_to_jiffies(delay_ms); - while (1) - { + while (1) { bAwake = rtl8723a_get_fwlps_rf_on(padapter); if (bAwake == true) break; @@ -470,6 +469,7 @@ void rtw_free_pwrctrl_priv(struct rtw_adapter *adapter) inline void rtw_set_ips_deny23a(struct rtw_adapter *padapter, u32 ms) { struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + pwrpriv->ips_deny_time = jiffies + msecs_to_jiffies(ms); } diff --git a/drivers/staging/rtl8723au/core/rtw_recv.c b/drivers/staging/rtl8723au/core/rtw_recv.c index 5bc7734d9a72..559dddee2648 100644 --- a/drivers/staging/rtl8723au/core/rtw_recv.c +++ b/drivers/staging/rtl8723au/core/rtw_recv.c @@ -215,6 +215,7 @@ u32 rtw_free_uc_swdec_pending_queue23a(struct rtw_adapter *adapter) { u32 cnt = 0; struct recv_frame *pending_frame; + while ((pending_frame = rtw_alloc_recvframe23a(&adapter->recvpriv.uc_swdec_pending_queue))) { rtw_free_recvframe23a(pending_frame); DBG_8723A("%s: dequeue uc_swdec_pending_queue\n", __func__); @@ -239,6 +240,7 @@ int rtw_enqueue_recvbuf23a_to_head(struct recv_buf *precvbuf, struct rtw_queue * int rtw_enqueue_recvbuf23a(struct recv_buf *precvbuf, struct rtw_queue *queue) { unsigned long irqL; + spin_lock_irqsave(&queue->lock, irqL); list_del_init(&precvbuf->list); @@ -364,6 +366,7 @@ int recvframe_chkmic(struct rtw_adapter *adapter, if (bmic_err == true) { int i; + RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n *(pframemic-8)-*(pframemic-1) =" "0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:" @@ -483,6 +486,7 @@ struct recv_frame *decryptor(struct rtw_adapter *padapter, if (prxattrib->encrypt > 0) { u8 *iv = precv_frame->pkt->data + prxattrib->hdrlen; + prxattrib->key_index = (((iv[3]) >> 6) & 0x3); if (prxattrib->key_index > WEP_KEYS) { @@ -564,59 +568,27 @@ static struct recv_frame *portctrl(struct rtw_adapter *adapter, ("########portctrl:adapter->securitypriv.dot11AuthAlgrthm =" "%d\n", adapter->securitypriv.dot11AuthAlgrthm)); + prtnframe = precv_frame; + if (auth_alg == dot11AuthAlgrthm_8021X) { /* get ether_type */ ptr = pfhdr->pkt->data + pfhdr->attrib.hdrlen; ether_type = (ptr[6] << 8) | ptr[7]; - if ((psta != NULL) && (psta->ieee8021x_blocked)) { + if (psta && psta->ieee8021x_blocked) { /* blocked */ /* only accept EAPOL frame */ RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:psta->ieee8021x_blocked ==" "1\n")); - if (ether_type == eapol_type) { - prtnframe = precv_frame; - } else { + if (ether_type != eapol_type) { /* free this frame */ rtw_free_recvframe23a(precv_frame); prtnframe = NULL; } - } else { - /* allowed */ - /* check decryption status, and decrypt the frame if needed */ - RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, - ("########portctrl:psta->ieee8021x_blocked ==" - "0\n")); - RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, - ("portctrl:precv_frame->hdr.attrib.privacy =" - "%x\n", precv_frame->attrib.privacy)); - - if (pattrib->bdecrypted == 0) { - RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, - ("portctrl:prxstat->decrypted =%x\n", - pattrib->bdecrypted)); - } - - prtnframe = precv_frame; - /* check is the EAPOL frame or not (Rekey) */ - if (ether_type == eapol_type) { - RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, - ("########portctrl:ether_type == " - "0x888e\n")); - /* check Rekey */ - - prtnframe = precv_frame; - } else { - RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, - ("########portctrl:ether_type = 0x%04x" - "\n", ether_type)); - } } - } else { - prtnframe = precv_frame; } return prtnframe; @@ -1066,6 +1038,7 @@ int sta2ap_data_frame(struct rtw_adapter *adapter, } } else { u8 *myhwaddr = myid(&adapter->eeprompriv); + if (!ether_addr_equal(pattrib->ra, myhwaddr)) { ret = RTW_RX_HANDLED; goto exit; @@ -1405,8 +1378,7 @@ static int validate_recv_data_frame(struct rtw_adapter *adapter, RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n pattrib->encrypt =%d\n", pattrib->encrypt)); - switch (pattrib->encrypt) - { + switch (pattrib->encrypt) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: pattrib->iv_len = IEEE80211_WEP_IV_LEN; @@ -1505,8 +1477,7 @@ static int validate_recv_frame(struct rtw_adapter *adapter, if (unlikely(bDumpRxPkt == 1)) dump_rx_pkt(skb, type, bDumpRxPkt); - switch (type) - { + switch (type) { case IEEE80211_FTYPE_MGMT: retval = validate_recv_mgnt_frame(adapter, precv_frame); if (retval == _FAIL) { @@ -1524,7 +1495,6 @@ static int validate_recv_frame(struct rtw_adapter *adapter, retval = _FAIL; /* only data frame return _SUCCESS */ break; case IEEE80211_FTYPE_DATA: - rtw_led_control(adapter, LED_CTL_RX); pattrib->qos = (subtype & IEEE80211_STYPE_QOS_DATA) ? 1 : 0; retval = validate_recv_data_frame(adapter, precv_frame); if (retval == _FAIL) { @@ -1551,8 +1521,6 @@ static int wlanhdr_to_ethhdr (struct recv_frame *precvframe) u16 eth_type, len, hdrlen; u8 bsnaphdr; u8 *psnap; - - int ret = _SUCCESS; struct rtw_adapter *adapter = precvframe->adapter; struct mlme_priv *pmlmepriv = &adapter->mlmepriv; @@ -1613,7 +1581,7 @@ static int wlanhdr_to_ethhdr (struct recv_frame *precvframe) } - return ret; + return _SUCCESS; } /* perform defrag */ @@ -1691,7 +1659,7 @@ struct recv_frame *recvframe_defrag(struct rtw_adapter *adapter, skb_put(skb, pnfhdr->pkt->len); prframe->attrib.icv_len = pnfhdr->attrib.icv_len; - }; + } /* free the defrag_q queue and return the prframe */ rtw_free_recvframe23a_queue(defrag_q); @@ -2177,8 +2145,7 @@ int process_recv_indicatepkts(struct rtw_adapter *padapter, return retval; } } - } else /* B/G mode */ - { + } else { /* B/G mode */ retval = wlanhdr_to_ethhdr(prframe); if (retval != _SUCCESS) { RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, @@ -2238,8 +2205,6 @@ static int recv_func_posthandle(struct rtw_adapter *padapter, struct recv_priv *precvpriv = &padapter->recvpriv; /* DATA FRAME */ - rtw_led_control(padapter, LED_CTL_RX); - prframe = decryptor(padapter, prframe); if (prframe == NULL) { RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, @@ -2349,66 +2314,52 @@ void rtw_signal_stat_timer_hdl23a(unsigned long data) u8 _alpha = 3; /* this value is based on converging_constant = 5000 */ /* and sampling_interval = 1000 */ - if (adapter->recvpriv.is_signal_dbg) { - /* update the user specific value, signal_strength_dbg, */ - /* to signal_strength, rssi */ - adapter->recvpriv.signal_strength = - adapter->recvpriv.signal_strength_dbg; - adapter->recvpriv.rssi = - (s8)translate_percentage_to_dbm((u8)adapter->recvpriv.signal_strength_dbg); - } else { - if (recvpriv->signal_strength_data.update_req == 0) { - /* update_req is clear, means we got rx */ - avg_signal_strength = - recvpriv->signal_strength_data.avg_val; - num_signal_strength = - recvpriv->signal_strength_data.total_num; - /* after avg_vals are acquired, we can re-stat */ - /* the signal values */ - recvpriv->signal_strength_data.update_req = 1; - } + if (recvpriv->signal_strength_data.update_req == 0) { + /* update_req is clear, means we got rx */ + avg_signal_strength = recvpriv->signal_strength_data.avg_val; + num_signal_strength = recvpriv->signal_strength_data.total_num; + /* after avg_vals are acquired, we can re-stat */ + /* the signal values */ + recvpriv->signal_strength_data.update_req = 1; + } + + if (recvpriv->signal_qual_data.update_req == 0) { + /* update_req is clear, means we got rx */ + avg_signal_qual = recvpriv->signal_qual_data.avg_val; + num_signal_qual = recvpriv->signal_qual_data.total_num; + /* after avg_vals are acquired, we can re-stat */ + /*the signal values */ + recvpriv->signal_qual_data.update_req = 1; + } + + /* update value of signal_strength, rssi, signal_qual */ + if (!check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY)) { + tmp_s = (avg_signal_strength + (_alpha - 1) * + recvpriv->signal_strength); + if (tmp_s %_alpha) + tmp_s = tmp_s / _alpha + 1; + else + tmp_s = tmp_s / _alpha; + if (tmp_s > 100) + tmp_s = 100; - if (recvpriv->signal_qual_data.update_req == 0) { - /* update_req is clear, means we got rx */ - avg_signal_qual = recvpriv->signal_qual_data.avg_val; - num_signal_qual = recvpriv->signal_qual_data.total_num; - /* after avg_vals are acquired, we can re-stat */ - /*the signal values */ - recvpriv->signal_qual_data.update_req = 1; - } + tmp_q = avg_signal_qual + (_alpha - 1) * recvpriv->signal_qual; + if (tmp_q %_alpha) + tmp_q = tmp_q / _alpha + 1; + else + tmp_q = tmp_q / _alpha; + if (tmp_q > 100) + tmp_q = 100; - /* update value of signal_strength, rssi, signal_qual */ - if (!check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY)) { - tmp_s = (avg_signal_strength + (_alpha - 1) * - recvpriv->signal_strength); - if (tmp_s %_alpha) - tmp_s = tmp_s / _alpha + 1; - else - tmp_s = tmp_s / _alpha; - if (tmp_s > 100) - tmp_s = 100; - - tmp_q = (avg_signal_qual + (_alpha - 1) * - recvpriv->signal_qual); - if (tmp_q %_alpha) - tmp_q = tmp_q / _alpha + 1; - else - tmp_q = tmp_q / _alpha; - if (tmp_q > 100) - tmp_q = 100; - - recvpriv->signal_strength = tmp_s; - recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s); - recvpriv->signal_qual = tmp_q; - - DBG_8723A("%s signal_strength:%3u, rssi:%3d, " - "signal_qual:%3u, num_signal_strength:%u, " - "num_signal_qual:%u\n", - __func__, recvpriv->signal_strength, - recvpriv->rssi, recvpriv->signal_qual, - num_signal_strength, num_signal_qual - ); - } + recvpriv->signal_strength = tmp_s; + recvpriv->signal_qual = tmp_q; + + DBG_8723A("%s signal_strength:%3u, signal_qual:%3u, " + "num_signal_strength:%u, num_signal_qual:%u\n", + __func__, recvpriv->signal_strength, + recvpriv->signal_qual, num_signal_strength, + num_signal_qual); } + rtw_set_signal_stat_timer(recvpriv); } diff --git a/drivers/staging/rtl8723au/core/rtw_security.c b/drivers/staging/rtl8723au/core/rtw_security.c index 76371ae69377..715a47414bdd 100644 --- a/drivers/staging/rtl8723au/core/rtw_security.c +++ b/drivers/staging/rtl8723au/core/rtw_security.c @@ -23,19 +23,18 @@ #define CRC32_POLY 0x04c11db7 -struct arc4context -{ +struct arc4context { u32 x; u32 y; u8 state[256]; }; -static void arcfour_init(struct arc4context *parc4ctx, u8 * key, u32 key_len) +static void arcfour_init(struct arc4context *parc4ctx, u8 *key, u32 key_len) { u32 t, u; u32 keyindex; u32 stateindex; - u8 * state; + u8 *state; u32 counter; state = parc4ctx->state; @@ -45,8 +44,7 @@ static void arcfour_init(struct arc4context *parc4ctx, u8 * key, u32 key_len) state[counter] = (u8)counter; keyindex = 0; stateindex = 0; - for (counter = 0; counter < 256; counter++) - { + for (counter = 0; counter < 256; counter++) { t = state[counter]; stateindex = (stateindex + key[keyindex] + t) & 0xff; u = state[stateindex]; @@ -62,7 +60,7 @@ static u32 arcfour_byte( struct arc4context *parc4ctx) u32 x; u32 y; u32 sx, sy; - u8 * state; + u8 *state; state = parc4ctx->state; x = (parc4ctx->x + 1) & 0xff; @@ -78,8 +76,8 @@ static u32 arcfour_byte( struct arc4context *parc4ctx) } static void arcfour_encrypt( struct arc4context *parc4ctx, - u8 * dest, - u8 * src, + u8 *dest, + u8 *src, u32 len) { u32 i; @@ -114,8 +112,7 @@ static void crc32_init(void) c = 0x12340000; - for (i = 0; i < 256; ++i) - { + for (i = 0; i < 256; ++i) { k = crc32_reverseBit((u8)i); for (c = ((u32)k) << 24, j = 8; j > 0; --j) { c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1); @@ -221,7 +218,7 @@ void rtw_wep_decrypt23a(struct rtw_adapter *padapter, u8 keyindex; struct rx_pkt_attrib *prxattrib = &precvframe->attrib; struct security_priv *psecuritypriv = &padapter->securitypriv; - struct sk_buff * skb = precvframe->pkt; + struct sk_buff *skb = precvframe->pkt; pframe = skb->data; @@ -260,33 +257,29 @@ void rtw_wep_decrypt23a(struct rtw_adapter *padapter, crc[1], payload[length - 3], crc[0], payload[length - 4])); } - - return; } /* 3 ===== TKIP related ===== */ -static u32 secmicgetuint32(u8 * p) +static u32 secmicgetuint32(u8 *p) /* Convert from Byte[] to u32 in a portable way */ { s32 i; u32 res = 0; - for (i = 0; i<4; i++) - { + for (i = 0; i<4; i++) { res |= ((u32)(*p++)) << (8*i); } return res; } -static void secmicputuint32(u8 * p, u32 val) +static void secmicputuint32(u8 *p, u32 val) /* Convert from long to Byte[] in a portable way */ { long i; - for (i = 0; i<4; i++) - { + for (i = 0; i<4; i++) { *p++ = (u8) (val & 0xff); val >>= 8; } @@ -304,7 +297,7 @@ static void secmicclear(struct mic_data *pmicdata) } -void rtw_secmicsetkey23a(struct mic_data *pmicdata, u8 * key) +void rtw_secmicsetkey23a(struct mic_data *pmicdata, u8 *key) { /* Set the key */ @@ -322,8 +315,7 @@ void rtw_secmicappend23abyte23a(struct mic_data *pmicdata, u8 b) pmicdata->M |= ((unsigned long)b) << (8*pmicdata->nBytesInM); pmicdata->nBytesInM++; /* Process the word if it is full. */ - if (pmicdata->nBytesInM >= 4) - { + if (pmicdata->nBytesInM >= 4) { pmicdata->L ^= pmicdata->M; pmicdata->R ^= ROL32(pmicdata->L, 17); pmicdata->L += pmicdata->R; @@ -340,19 +332,18 @@ void rtw_secmicappend23abyte23a(struct mic_data *pmicdata, u8 b) } -void rtw_secmicappend23a(struct mic_data *pmicdata, u8 * src, u32 nbytes) +void rtw_secmicappend23a(struct mic_data *pmicdata, u8 *src, u32 nbytes) { /* This is simple */ - while(nbytes > 0) - { + while(nbytes > 0) { rtw_secmicappend23abyte23a(pmicdata, *src++); nbytes--; } } -void rtw_secgetmic23a(struct mic_data *pmicdata, u8 * dst) +void rtw_secgetmic23a(struct mic_data *pmicdata, u8 *dst) { /* Append the minimum padding */ @@ -362,8 +353,7 @@ void rtw_secgetmic23a(struct mic_data *pmicdata, u8 * dst) rtw_secmicappend23abyte23a(pmicdata, 0); rtw_secmicappend23abyte23a(pmicdata, 0); /* and then zeroes until the length is a multiple of 4 */ - while(pmicdata->nBytesInM != 0) - { + while(pmicdata->nBytesInM != 0) { rtw_secmicappend23abyte23a(pmicdata, 0); } /* The appendByte function has already computed the result. */ @@ -374,7 +364,8 @@ void rtw_secgetmic23a(struct mic_data *pmicdata, u8 * dst) } -void rtw_seccalctkipmic23a(u8 * key, u8 *header, u8 *data, u32 data_len, u8 *mic_code, u8 pri) +void rtw_seccalctkipmic23a(u8 *key, u8 *header, u8 *data, u32 data_len, + u8 *mic_code, u8 pri) { struct mic_data micdata; @@ -531,8 +522,8 @@ static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32) /* Now compute an unbalanced Feistel cipher with 80-bit block */ /* size on the 80-bit block P1K[], using the 128-bit key TK[] */ - for (i = 0; i < PHASE1_LOOP_CNT ;i++) - { /* Each add operation here is mod 2**16 */ + for (i = 0; i < PHASE1_LOOP_CNT ;i++) { + /* Each add operation here is mod 2**16 */ p1k[0] += _S_(p1k[4] ^ TK16((i&1)+0)); p1k[1] += _S_(p1k[0] ^ TK16((i&1)+2)); p1k[2] += _S_(p1k[1] ^ TK16((i&1)+4)); @@ -602,8 +593,7 @@ static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16) rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1); /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */ - for (i = 0;i<6;i++) - { + for (i = 0;i<6;i++) { rc4key[4+2*i] = Lo8(PPK[i]); rc4key[5+2*i] = Hi8(PPK[i]); } @@ -649,8 +639,7 @@ int rtw_tkip_encrypt23a(struct rtw_adapter *padapter, if (stainfo!= NULL) { - if (!(stainfo->state &_FW_LINKED)) - { + if (!(stainfo->state &_FW_LINKED)) { DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state); return _FAIL; } @@ -728,7 +717,7 @@ int rtw_tkip_decrypt23a(struct rtw_adapter *padapter, struct sta_info *stainfo; struct rx_pkt_attrib *prxattrib = &precvframe->attrib; struct security_priv *psecuritypriv = &padapter->securitypriv; - struct sk_buff * skb = precvframe->pkt; + struct sk_buff *skb = precvframe->pkt; int res = _SUCCESS; pframe = skb->data; @@ -887,8 +876,7 @@ static void byte_sub(u8 *in, u8 *out) { int i; - for (i = 0; i< 16; i++) - { + for (i = 0; i< 16; i++) { out[i] = sbox(in[i]); } @@ -928,8 +916,7 @@ static void mix_column(u8 *in, u8 *out) u8 temp[4]; u8 tempb[4]; - for (i = 0 ; i<4; i++) - { + for (i = 0 ; i<4; i++) { if ((in[i] & 0x80) == 0x80) add1b[i] = 0x1b; else @@ -951,11 +938,9 @@ static void mix_column(u8 *in, u8 *out) andf7[2] = in[2] & 0x7f; andf7[3] = in[3] & 0x7f; - for (i = 3; i>0; i--) /* logical shift left 1 bit */ - { + for (i = 3; i>0; i--) { /* logical shift left 1 bit */ andf7[i] = andf7[i] << 1; - if ((andf7[i-1] & 0x80) == 0x80) - { + if ((andf7[i-1] & 0x80) == 0x80) { andf7[i] = (andf7[i] | 0x01); } } @@ -988,21 +973,15 @@ static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext) for (i = 0; i<16; i++) round_key[i] = key[i]; - for (round = 0; round < 11; round++) - { - if (round == 0) - { + for (round = 0; round < 11; round++) { + if (round == 0) { xor_128(round_key, data, ciphertext); next_key(round_key, round); - } - else if (round == 10) - { + } else if (round == 10) { byte_sub(ciphertext, intermediatea); shift_row(intermediatea, intermediateb); xor_128(intermediateb, round_key, ciphertext); - } - else /* 1 - 9 */ - { + } else { /* 1 - 9 */ byte_sub(ciphertext, intermediatea); shift_row(intermediatea, intermediateb); mix_column(&intermediateb[0], &intermediatea[0]); @@ -1088,20 +1067,17 @@ static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists, mic_header2[6] = 0x00; mic_header2[7] = 0x00; /* mpdu[23]; */ - if (!qc_exists && a4_exists) - { + if (!qc_exists && a4_exists) { for (i = 0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */ } - if (qc_exists && !a4_exists) - { + if (qc_exists && !a4_exists) { mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */ mic_header2[9] = mpdu[25] & 0x00; } - if (qc_exists && a4_exists) - { + if (qc_exists && a4_exists) { for (i = 0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */ mic_header2[14] = mpdu[30] & 0x0f; diff --git a/drivers/staging/rtl8723au/core/rtw_sreset.c b/drivers/staging/rtl8723au/core/rtw_sreset.c index 58ed980795a6..29a29d92a6ac 100644 --- a/drivers/staging/rtl8723au/core/rtw_sreset.c +++ b/drivers/staging/rtl8723au/core/rtw_sreset.c @@ -107,7 +107,7 @@ static void sreset_restore_network_station(struct rtw_adapter *padapter) mlmeext_joinbss_event_callback23a(padapter, 1); /* restore Sequence No. */ - rtl8723au_write8(padapter, 0x4dc, padapter->xmitpriv.nqos_ssn); + rtl8723au_write8(padapter, REG_NQOS_SEQ, padapter->xmitpriv.nqos_ssn); sreset_restore_security_station(padapter); } diff --git a/drivers/staging/rtl8723au/core/rtw_wlan_util.c b/drivers/staging/rtl8723au/core/rtw_wlan_util.c index 09c44a55d4a6..69d9e0f17fd8 100644 --- a/drivers/staging/rtl8723au/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8723au/core/rtw_wlan_util.c @@ -608,8 +608,6 @@ void WMMOnAssocRsp23a(struct rtw_adapter *padapter) DBG_8723A("wmm_para_seq(%d): %d\n", i, pxmitpriv->wmm_para_seq[i]); } - - return; } static void bwmode_update_check(struct rtw_adapter *padapter, const u8 *p) @@ -750,7 +748,6 @@ void HT_caps_handler23a(struct rtw_adapter *padapter, const u8 *p) else cap->mcs.rx_mask[i] &= MCS_rate_2R23A[i]; } - return; } void HT_info_handler23a(struct rtw_adapter *padapter, const u8 *p) @@ -771,7 +768,6 @@ void HT_info_handler23a(struct rtw_adapter *padapter, const u8 *p) pmlmeinfo->HT_info_enable = 1; memcpy(&pmlmeinfo->HT_info, p + 2, p[1]); - return; } void HTOnAssocRsp23a(struct rtw_adapter *padapter) @@ -833,7 +829,7 @@ void VCS_update23a(struct rtw_adapter *padapter, struct sta_info *psta) psta->cts2self = 0; break; case 1: /* on */ - if (pregpriv->vcs_type == 1) { /* 1:RTS/CTS 2:CTS to self */ + if (pregpriv->vcs_type == RTS_CTS) { psta->rtsen = 1; psta->cts2self = 0; } else { @@ -844,7 +840,7 @@ void VCS_update23a(struct rtw_adapter *padapter, struct sta_info *psta) case 2: /* auto */ default: if (pmlmeinfo->ERP_enable && pmlmeinfo->ERP_IE & BIT(1)) { - if (pregpriv->vcs_type == 1) { + if (pregpriv->vcs_type == RTS_CTS) { psta->rtsen = 1; psta->cts2self = 0; } else { @@ -870,7 +866,7 @@ int rtw_check_bcn_info23a(struct rtw_adapter *Adapter, int pie_len, ssid_len, privacy; const u8 *p, *ssid; - if (is_client_associated_to_ap23a(Adapter) == false) + if (!is_client_associated_to_ap23a(Adapter)) return _SUCCESS; if (unlikely(!ieee80211_is_beacon(mgmt->frame_control))) { @@ -1080,7 +1076,7 @@ bool is_ap_in_tkip23a(struct rtw_adapter *padapter) return false; } -bool should_forbid_n_rate23a(struct rtw_adapter * padapter) +bool should_forbid_n_rate23a(struct rtw_adapter *padapter) { u32 i; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -1153,6 +1149,7 @@ bool is_ap_in_wep23a(struct rtw_adapter *padapter) static int wifirate2_ratetbl_inx23a(unsigned char rate) { int inx = 0; + rate = rate & 0x7f; switch (rate) { @@ -1311,6 +1308,7 @@ unsigned char check_assoc_AP23a(u8 *pframe, uint len) u8 epigram_vendor_flag; u8 ralink_vendor_flag; const u8 *p; + epigram_vendor_flag = 0; ralink_vendor_flag = 0; @@ -1324,7 +1322,6 @@ unsigned char check_assoc_AP23a(u8 *pframe, uint len) DBG_8723A("link to Artheros AP\n"); return HT_IOT_PEER_ATHEROS; } else if (!memcmp(p + 2, BROADCOM_OUI1, 3) || - !memcmp(p + 2, BROADCOM_OUI2, 3) || !memcmp(p + 2, BROADCOM_OUI2, 3)) { DBG_8723A("link to Broadcom AP\n"); return HT_IOT_PEER_BROADCOM; diff --git a/drivers/staging/rtl8723au/core/rtw_xmit.c b/drivers/staging/rtl8723au/core/rtw_xmit.c index 7a8038156cea..7a5e6bf0d1ae 100644 --- a/drivers/staging/rtl8723au/core/rtw_xmit.c +++ b/drivers/staging/rtl8723au/core/rtw_xmit.c @@ -22,9 +22,6 @@ #include <usb_ops.h> #include <rtl8723a_xmit.h> -static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; -static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; - static void _init_txservq(struct tx_servq *ptxservq) { @@ -180,16 +177,8 @@ int _rtw_init_xmit_priv23a(struct xmit_priv *pxmitpriv, for (i = 0; i < 4; i ++) pxmitpriv->wmm_para_seq[i] = i; - pxmitpriv->txirp_cnt = 1; - sema_init(&pxmitpriv->tx_retevt, 0); - /* per AC pending irp */ - pxmitpriv->beq_cnt = 0; - pxmitpriv->bkq_cnt = 0; - pxmitpriv->viq_cnt = 0; - pxmitpriv->voq_cnt = 0; - pxmitpriv->ack_tx = false; mutex_init(&pxmitpriv->ack_tx_mutex); rtw_sctx_init23a(&pxmitpriv->ack_tx_ops, 0); @@ -315,6 +304,7 @@ static void update_attrib_vcs_info(struct rtw_adapter *padapter, struct xmit_fra /* check HT op mode */ if (pattrib->ht_en) { u8 HTOpMode = pmlmeinfo->HT_protection; + if ((pmlmeext->cur_bwmode && (HTOpMode == 2 || HTOpMode == 3)) || (!pmlmeext->cur_bwmode && HTOpMode == 3)) { pattrib->vcs_mode = RTS_CTS; @@ -464,6 +454,7 @@ static int update_attrib(struct rtw_adapter *padapter, if (pattrib->pktlen > 282 + 24) { if (pattrib->ether_type == ETH_P_IP) {/* IP header */ u8 *pframe = skb->data; + pframe += ETH_HLEN; if ((pframe[21] == 68 && pframe[23] == 67) || @@ -1048,21 +1039,23 @@ s32 rtw_txframes_sta_ac_pending23a(struct rtw_adapter *padapter, return ptxservq->qcnt; } -/* - * Calculate wlan 802.11 packet MAX size from pkt_attrib - * This function doesn't consider fragment case +/* Logical Link Control(LLC) SubNetwork Attachment Point(SNAP) header + * IEEE LLC/SNAP header contains 8 octets + * First 3 octets comprise the LLC portion + * SNAP portion, 5 octets, is divided into two fields: + * Organizationally Unique Identifier(OUI), 3 octets, + * type, defined by that organization, 2 octets. */ -u32 rtw_calculate_wlan_pkt_size_by_attribue23a(struct pkt_attrib *pattrib) +static int rtw_put_snap(u8 *data, u16 h_proto) { - u32 len = 0; - - len = pattrib->hdrlen + pattrib->iv_len; /* WLAN Header and IV */ - len += SNAP_SIZE + sizeof(u16); /* LLC */ - len += pattrib->pktlen; - if (pattrib->encrypt == WLAN_CIPHER_SUITE_TKIP) len += 8; /* MIC */ - len += ((pattrib->bswenc) ? pattrib->icv_len : 0); /* ICV */ + if (h_proto == ETH_P_IPX || h_proto == ETH_P_AARP) + ether_addr_copy(data, bridge_tunnel_header); + else + ether_addr_copy(data, rfc1042_header); - return len; + data += ETH_ALEN; + put_unaligned_be16(h_proto, data); + return ETH_ALEN + sizeof(u16); } /* @@ -1188,7 +1181,7 @@ int rtw_xmitframe_coalesce23a(struct rtw_adapter *padapter, struct sk_buff *skb, mpdu_len -= pattrib->iv_len; } if (frg_inx == 0) { - llc_sz = rtw_put_snap23a(pframe, pattrib->ether_type); + llc_sz = rtw_put_snap(pframe, pattrib->ether_type); pframe += llc_sz; mpdu_len -= llc_sz; } @@ -1258,34 +1251,6 @@ exit: return res; } -/* Logical Link Control(LLC) SubNetwork Attachment Point(SNAP) header - * IEEE LLC/SNAP header contains 8 octets - * First 3 octets comprise the LLC portion - * SNAP portion, 5 octets, is divided into two fields: - * Organizationally Unique Identifier(OUI), 3 octets, - * type, defined by that organization, 2 octets. - */ -s32 rtw_put_snap23a(u8 *data, u16 h_proto) -{ - struct ieee80211_snap_hdr *snap; - u8 *oui; - - snap = (struct ieee80211_snap_hdr *)data; - snap->dsap = 0xaa; - snap->ssap = 0xaa; - snap->ctrl = 0x03; - - if (h_proto == 0x8137 || h_proto == 0x80f3) - oui = P802_1H_OUI; - else - oui = RFC1042_OUI; - snap->oui[0] = oui[0]; - snap->oui[1] = oui[1]; - snap->oui[2] = oui[2]; - *(u16 *)(data + SNAP_SIZE) = htons(h_proto); - return SNAP_SIZE + sizeof(u16); -} - void rtw_update_protection23a(struct rtw_adapter *padapter, u8 *ie, uint ie_len) { struct xmit_priv *pxmitpriv = &padapter->xmitpriv; @@ -1293,7 +1258,7 @@ void rtw_update_protection23a(struct rtw_adapter *padapter, u8 *ie, uint ie_len) uint protection; const u8 *p; - switch (pxmitpriv->vcs_setting) { + switch (pregistrypriv->vrtl_carrier_sense) { case DISABLE_VCS: pxmitpriv->vcs = NONE_VCS; break; @@ -1326,7 +1291,7 @@ void rtw_count_tx_stats23a(struct rtw_adapter *padapter, struct xmit_frame *pxmi struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - if ((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) { + if (pxmitframe->frame_tag == DATA_FRAMETAG) { pxmitpriv->tx_bytes += sz; pmlmepriv->LinkDetectInfo.NumTxOkInPeriod++; @@ -1893,18 +1858,6 @@ u32 rtw_get_ff_hwaddr23a(struct xmit_frame *pxmitframe) return addr; } -static void do_queue_select(struct rtw_adapter *padapter, struct pkt_attrib *pattrib) -{ - u8 qsel; - - qsel = pattrib->priority; - RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, - ("### do_queue_select priority =%d , qsel = %d\n", - pattrib->priority, qsel)); - - pattrib->qsel = qsel; -} - /* * The main transmit(tx) entry * @@ -1936,9 +1889,7 @@ int rtw_xmit23a(struct rtw_adapter *padapter, struct sk_buff *skb) } pxmitframe->pkt = skb; - rtw_led_control(padapter, LED_CTL_TX); - - do_queue_select(padapter, &pxmitframe->attrib); + pxmitframe->attrib.qsel = pxmitframe->attrib.priority; #ifdef CONFIG_8723AU_AP_MODE spin_lock_bh(&pxmitpriv->lock); @@ -2411,11 +2362,6 @@ void rtw23a_sctx_done_err(struct submit_ctx **sctx, int status) } } -void rtw_sctx_done23a(struct submit_ctx **sctx) -{ - rtw23a_sctx_done_err(sctx, RTW_SCTX_DONE_SUCCESS); -} - int rtw_ack_tx_wait23a(struct xmit_priv *pxmitpriv, u32 timeout_ms) { struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops; diff --git a/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c b/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c index 4b41bc4ce1e6..179a1ba03029 100644 --- a/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c +++ b/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c @@ -612,7 +612,7 @@ static void _PHY_PathADDAOn(struct rtw_adapter *pAdapter, u32 *ADDAReg, bool isP u32 i; pathOn = isPathAOn ? 0x04db25a4 : 0x0b1b25a4; - if (false == is2T) { + if (!is2T) { pathOn = 0x0bdb25a0; PHY_SetBBReg(pAdapter, ADDAReg[0], bMaskDWord, 0x0b1b25a0); } else { diff --git a/drivers/staging/rtl8723au/hal/hal_com.c b/drivers/staging/rtl8723au/hal/hal_com.c index bf919f6e4128..bf4cae20bd12 100644 --- a/drivers/staging/rtl8723au/hal/hal_com.c +++ b/drivers/staging/rtl8723au/hal/hal_com.c @@ -463,7 +463,7 @@ void rtl8723a_set_ampdu_factor(struct rtw_adapter *padapter, u8 FactorToSet) MaxAggNum = 0xF; if (FactorToSet <= 3) { - FactorToSet = (1 << (FactorToSet + 2)); + FactorToSet = 1 << (FactorToSet + 2); if (FactorToSet > MaxAggNum) FactorToSet = MaxAggNum; @@ -727,7 +727,7 @@ void rtl8723a_fifo_cleanup(struct rtw_adapter *padapter) rtl8723au_write8(padapter, REG_TXPAUSE, 0xff); /* keep sn */ - padapter->xmitpriv.nqos_ssn = rtl8723au_read16(padapter, REG_NQOS_SEQ); + padapter->xmitpriv.nqos_ssn = rtl8723au_read8(padapter, REG_NQOS_SEQ); if (pwrpriv->bkeepfwalive != true) { u32 v32; diff --git a/drivers/staging/rtl8723au/hal/odm_HWConfig.c b/drivers/staging/rtl8723au/hal/odm_HWConfig.c index 29d844d66cae..fb3cc872f205 100644 --- a/drivers/staging/rtl8723au/hal/odm_HWConfig.c +++ b/drivers/staging/rtl8723au/hal/odm_HWConfig.c @@ -391,20 +391,11 @@ static void odm_Process_RSSIForDM(struct dm_odm_t *pDM_Odm, } } -/* Endianness before calling this API */ -static void ODM_PhyStatusQuery23a_92CSeries(struct dm_odm_t *pDM_Odm, - struct phy_info *pPhyInfo, - u8 *pPhyStatus, - struct odm_packet_info *pPktinfo) +void ODM_PhyStatusQuery23a(struct dm_odm_t *pDM_Odm, struct phy_info *pPhyInfo, + u8 *pPhyStatus, struct odm_packet_info *pPktinfo) { odm_RxPhyStatus92CSeries_Parsing(pDM_Odm, pPhyInfo, pPhyStatus, pPktinfo); odm_Process_RSSIForDM(pDM_Odm, pPhyInfo, pPktinfo); } - -void ODM_PhyStatusQuery23a(struct dm_odm_t *pDM_Odm, struct phy_info *pPhyInfo, - u8 *pPhyStatus, struct odm_packet_info *pPktinfo) -{ - ODM_PhyStatusQuery23a_92CSeries(pDM_Odm, pPhyInfo, pPhyStatus, pPktinfo); -} diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c b/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c index 9054a987f06b..86a83975f4f0 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c @@ -340,7 +340,7 @@ static u8 bthci_GetAssocInfo(struct rtw_adapter *padapter, u8 EntryNum) tempBuf, TotalLen-BaseMemoryShift); pAmpAsoc = (struct amp_assoc_structure *)tempBuf; - pAmpAsoc->Length = le16_to_cpu(pAmpAsoc->Length); + le16_to_cpus(&pAmpAsoc->Length); BaseMemoryShift += 3 + pAmpAsoc->Length; RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("TypeID = 0x%x, ", pAmpAsoc->TypeID)); @@ -1759,18 +1759,6 @@ static enum hci_status bthci_CmdReadConnectionAcceptTimeout(struct rtw_adapter * return status; } -/* 7.3.3 */ -static enum hci_status -bthci_CmdSetEventFilter( - struct rtw_adapter *padapter, - struct packet_irp_hcicmd_data *pHciCmd - ) -{ - enum hci_status status = HCI_STATUS_SUCCESS; - - return status; -} - /* 7.3.14 */ static enum hci_status bthci_CmdWriteConnectionAcceptTimeout( @@ -2982,19 +2970,12 @@ bthci_CmdReadLinkQuality( return status; } -static enum hci_status bthci_CmdReadRSSI(struct rtw_adapter *padapter) -{ - enum hci_status status = HCI_STATUS_SUCCESS; - return status; -} - static enum hci_status bthci_CmdCreateLogicalLink( struct rtw_adapter *padapter, struct packet_irp_hcicmd_data *pHciCmd ) { - enum hci_status status = HCI_STATUS_SUCCESS; struct bt_30info *pBTInfo = GET_BT_INFO(padapter); struct bt_dgb *pBtDbg = &pBTInfo->BtDbg; @@ -3003,7 +2984,7 @@ bthci_CmdCreateLogicalLink( bthci_BuildLogicalLink(padapter, pHciCmd, HCI_CREATE_LOGICAL_LINK); - return status; + return HCI_STATUS_SUCCESS; } static enum hci_status @@ -3012,7 +2993,6 @@ bthci_CmdAcceptLogicalLink( struct packet_irp_hcicmd_data *pHciCmd ) { - enum hci_status status = HCI_STATUS_SUCCESS; struct bt_30info *pBTInfo = GET_BT_INFO(padapter); struct bt_dgb *pBtDbg = &pBTInfo->BtDbg; @@ -3021,7 +3001,7 @@ bthci_CmdAcceptLogicalLink( bthci_BuildLogicalLink(padapter, pHciCmd, HCI_ACCEPT_LOGICAL_LINK); - return status; + return HCI_STATUS_SUCCESS; } static enum hci_status @@ -4138,15 +4118,6 @@ bthci_CmdHostBufferSize(struct rtw_adapter *padapter, } static enum hci_status -bthci_CmdHostNumberOfCompletedPackets(struct rtw_adapter *padapter, - struct packet_irp_hcicmd_data *pHciCmd) -{ - enum hci_status status = HCI_STATUS_SUCCESS; - - return status; -} - -static enum hci_status bthci_UnknownCMD(struct rtw_adapter *padapter, struct packet_irp_hcicmd_data *pHciCmd) { enum hci_status status = HCI_STATUS_UNKNOW_HCI_CMD; @@ -4219,7 +4190,6 @@ bthci_HandleOGFSetEventMaskCMD(struct rtw_adapter *padapter, break; case HCI_SET_EVENT_FILTER: RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_SET_EVENT_FILTER\n")); - status = bthci_CmdSetEventFilter(padapter, pHciCmd); break; case HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT: RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT\n")); @@ -4235,7 +4205,6 @@ bthci_HandleOGFSetEventMaskCMD(struct rtw_adapter *padapter, break; case HCI_HOST_NUMBER_OF_COMPLETED_PACKETS: RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_HOST_NUMBER_OF_COMPLETED_PACKETS\n")); - status = bthci_CmdHostNumberOfCompletedPackets(padapter, pHciCmd); break; case HCI_READ_LINK_SUPERVISION_TIMEOUT: RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LINK_SUPERVISION_TIMEOUT\n")); @@ -4323,7 +4292,6 @@ bthci_HandleOGFStatusParameters(struct rtw_adapter *padapter, break; case HCI_READ_RSSI: RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_RSSI\n")); - status = bthci_CmdReadRSSI(padapter); break; case HCI_READ_LOCAL_AMP_INFO: RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOCAL_AMP_INFO\n")); @@ -10671,7 +10639,7 @@ void BTDM_BBBackOffLevel(struct rtw_adapter *padapter, u8 type) void BTDM_FWCoexAllOff(struct rtw_adapter *padapter) { - struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);; + struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); RTPRINT(FBT, BT_TRACE, ("BTDM_FWCoexAllOff()\n")); if (pHalData->bt_coexist.bFWCoexistAllOff) @@ -10685,7 +10653,7 @@ void BTDM_FWCoexAllOff(struct rtw_adapter *padapter) void BTDM_SWCoexAllOff(struct rtw_adapter *padapter) { - struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);; + struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); RTPRINT(FBT, BT_TRACE, ("BTDM_SWCoexAllOff()\n")); if (pHalData->bt_coexist.bSWCoexistAllOff) @@ -10698,7 +10666,7 @@ void BTDM_SWCoexAllOff(struct rtw_adapter *padapter) void BTDM_HWCoexAllOff(struct rtw_adapter *padapter) { - struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);; + struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); RTPRINT(FBT, BT_TRACE, ("BTDM_HWCoexAllOff()\n")); if (pHalData->bt_coexist.bHWCoexistAllOff) diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c b/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c index 271c33d6ca5a..7b56411cc3c8 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c @@ -115,19 +115,16 @@ exit: int rtl8723a_set_rssi_cmd(struct rtw_adapter *padapter, u8 *param) { - int res = _SUCCESS; - *((u32 *)param) = cpu_to_le32(*((u32 *)param)); FillH2CCmd(padapter, RSSI_SETTING_EID, 3, param); - return res; + return _SUCCESS; } int rtl8723a_set_raid_cmd(struct rtw_adapter *padapter, u32 mask, u8 arg) { u8 buf[5]; - int res = _SUCCESS; memset(buf, 0, 5); mask = cpu_to_le32(mask); @@ -136,7 +133,7 @@ int rtl8723a_set_raid_cmd(struct rtw_adapter *padapter, u32 mask, u8 arg) FillH2CCmd(padapter, MACID_CONFIG_EID, 5, buf); - return res; + return _SUCCESS; } /* bitmap[0:27] = tx_rate_bitmap */ diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c index 8523908d5e5f..a5eadd4e2580 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c @@ -47,29 +47,19 @@ static void _FWDownloadEnable(struct rtw_adapter *padapter, bool enable) } } -static int _BlockWrite(struct rtw_adapter *padapter, void *buffer, u32 buffSize) -{ - int ret; - - if (buffSize > MAX_PAGE_SIZE) - return _FAIL; - - ret = rtl8723au_writeN(padapter, FW_8723A_START_ADDRESS, - buffSize, buffer); - - return ret; -} - static int _PageWrite(struct rtw_adapter *padapter, u32 page, void *buffer, u32 size) { u8 value8; u8 u8Page = (u8) (page & 0x07); + if (size > MAX_PAGE_SIZE) + return _FAIL; + value8 = (rtl8723au_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page; rtl8723au_write8(padapter, REG_MCUFWDL + 2, value8); - return _BlockWrite(padapter, buffer, size); + return rtl8723au_writeN(padapter, FW_8723A_START_ADDRESS, size, buffer); } static int _WriteFW(struct rtw_adapter *padapter, void *buffer, u32 size) @@ -743,84 +733,6 @@ u16 rtl8723a_EfuseGetCurrentSize_BT(struct rtw_adapter *padapter) return retU2; } -bool -rtl8723a_EfusePgPacketRead(struct rtw_adapter *padapter, u8 offset, u8 *data) -{ - u8 efuse_data, word_cnts = 0; - u16 efuse_addr = 0; - u8 hoffset = 0, hworden = 0; - u8 i; - u8 max_section = 0; - s32 ret; - - if (data == NULL) - return false; - - EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, - &max_section); - if (offset > max_section) { - DBG_8723A("%s: Packet offset(%d) is illegal(>%d)!\n", - __func__, offset, max_section); - return false; - } - - memset(data, 0xFF, PGPKT_DATA_SIZE); - ret = true; - - /* */ - /* <Roger_TODO> Efuse has been pre-programmed dummy 5Bytes at the - end of Efuse by CP. */ - /* Skip dummy parts to prevent unexpected data read from Efuse. */ - /* By pass right now. 2009.02.19. */ - /* */ - while (AVAILABLE_EFUSE_ADDR(efuse_addr)) { - if (efuse_OneByteRead23a(padapter, efuse_addr++, &efuse_data) == - _FAIL) { - ret = false; - break; - } - - if (efuse_data == 0xFF) - break; - - if (EXT_HEADER(efuse_data)) { - hoffset = GET_HDR_OFFSET_2_0(efuse_data); - efuse_OneByteRead23a(padapter, efuse_addr++, &efuse_data); - if (ALL_WORDS_DISABLED(efuse_data)) { - DBG_8723A("%s: Error!! All words disabled!\n", - __func__); - continue; - } - - hoffset |= ((efuse_data & 0xF0) >> 1); - hworden = efuse_data & 0x0F; - } else { - hoffset = (efuse_data >> 4) & 0x0F; - hworden = efuse_data & 0x0F; - } - - if (hoffset == offset) { - for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { - /* Check word enable condition in the section */ - if (!(hworden & (0x01 << i))) { - ReadEFuseByte23a(padapter, efuse_addr++, - &efuse_data); - data[i * 2] = efuse_data; - - ReadEFuseByte23a(padapter, efuse_addr++, - &efuse_data); - data[(i * 2) + 1] = efuse_data; - } - } - } else { - word_cnts = Efuse_CalculateWordCnts23a(hworden); - efuse_addr += word_cnts * 2; - } - } - - return ret; -} - void rtl8723a_read_chip_version(struct rtw_adapter *padapter) { u32 value32; @@ -1126,6 +1038,21 @@ exit: return ret; } +void handle_txrpt_ccx_8723a(struct rtw_adapter *adapter, void *buf) +{ + struct txrpt_ccx_8723a *txrpt_ccx = buf; + struct submit_ctx *pack_tx_ops = &adapter->xmitpriv.ack_tx_ops; + + if (txrpt_ccx->int_ccx && adapter->xmitpriv.ack_tx) { + if (txrpt_ccx->pkt_ok) + rtw23a_sctx_done_err(&pack_tx_ops, + RTW_SCTX_DONE_SUCCESS); + else + rtw23a_sctx_done_err(&pack_tx_ops, + RTW_SCTX_DONE_CCX_PKT_FAIL); + } +} + void rtl8723a_InitAntenna_Selection(struct rtw_adapter *padapter) { u8 val; @@ -1326,18 +1253,17 @@ c. APSD_CTRL 0x600[7:0] = 0x40 d. SYS_FUNC_EN 0x02[7:0] = 0x16 reset BB state machine e. SYS_FUNC_EN 0x02[7:0] = 0x14 reset BB state machine ***************************************/ - u8 eRFPath = 0, value8 = 0; + u8 value8; rtl8723au_write8(padapter, REG_TXPAUSE, 0xFF); - PHY_SetRFReg(padapter, (enum RF_RADIO_PATH) eRFPath, 0x0, bMaskByte0, 0x0); + PHY_SetRFReg(padapter, RF_PATH_A, 0x0, bMaskByte0, 0x0); - value8 |= APSDOFF; + value8 = APSDOFF; rtl8723au_write8(padapter, REG_APSD_CTRL, value8); /* 0x40 */ /* Set BB reset at first */ - value8 = 0; - value8 |= (FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn); + value8 = FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn; rtl8723au_write8(padapter, REG_SYS_FUNC_EN, value8); /* 0x16 */ /* Set global reset. */ @@ -1350,11 +1276,6 @@ e. SYS_FUNC_EN 0x02[7:0] = 0x14 reset BB state machine /* RT_TRACE(COMP_INIT, DBG_LOUD, ("======> RF off and reset BB.\n")); */ } -static void _DisableRFAFEAndResetBB(struct rtw_adapter *padapter) -{ - _DisableRFAFEAndResetBB8192C(padapter); -} - static void _ResetDigitalProcedure1_92C(struct rtw_adapter *padapter, bool bWithoutHWSM) { @@ -1368,18 +1289,18 @@ static void _ResetDigitalProcedure1_92C(struct rtw_adapter *padapter, i. SYS_FUNC_EN 0x02[10]= 1 enable MCU register, (8051 enable) ******************************/ - u16 valu16 = 0; + u16 valu16; rtl8723au_write8(padapter, REG_MCUFWDL, 0); valu16 = rtl8723au_read16(padapter, REG_SYS_FUNC_EN); /* reset MCU , 8051 */ rtl8723au_write16(padapter, REG_SYS_FUNC_EN, - valu16 & (~FEN_CPUEN)); + valu16 & ~FEN_CPUEN); valu16 = rtl8723au_read16(padapter, REG_SYS_FUNC_EN) & 0x0FFF; /* reset MAC */ rtl8723au_write16(padapter, REG_SYS_FUNC_EN, - valu16 | (FEN_HWPDN | FEN_ELDR)); + valu16 | FEN_HWPDN | FEN_ELDR); valu16 = rtl8723au_read16(padapter, REG_SYS_FUNC_EN); /* enable MCU , 8051 */ @@ -1387,43 +1308,41 @@ static void _ResetDigitalProcedure1_92C(struct rtw_adapter *padapter, valu16 | FEN_CPUEN); } else { u8 retry_cnts = 0; + u8 val8; + + val8 = rtl8723au_read8(padapter, REG_MCUFWDL); /* 2010/08/12 MH For USB SS, we can not stop 8051 when we are trying to enter IPS/HW&SW radio off. For S3/S4/S5/Disable, we can stop 8051 because */ /* we will init FW when power on again. */ /* If we want to SS mode, we can not reset 8051. */ - if (rtl8723au_read8(padapter, REG_MCUFWDL) & BIT(1)) { + if ((val8 & BIT(1)) && padapter->bFWReady) { /* IF fw in RAM code, do reset */ - if (padapter->bFWReady) { - /* 2010/08/25 MH Accordign to RD alfred's - suggestion, we need to disable other */ - /* HRCV INT to influence 8051 reset. */ - rtl8723au_write8(padapter, REG_FWIMR, 0x20); - /* 2011/02/15 MH According to Alex's - suggestion, close mask to prevent - incorrect FW write operation. */ - rtl8723au_write8(padapter, REG_FTIMR, 0x00); - rtl8723au_write8(padapter, REG_FSIMR, 0x00); - - /* 8051 reset by self */ - rtl8723au_write8(padapter, REG_HMETFR + 3, - 0x20); - - while ((retry_cnts++ < 100) && - (FEN_CPUEN & - rtl8723au_read16(padapter, - REG_SYS_FUNC_EN))) { - udelay(50); /* us */ - } + /* 2010/08/25 MH Accordign to RD alfred's + suggestion, we need to disable other */ + /* HRCV INT to influence 8051 reset. */ + rtl8723au_write8(padapter, REG_FWIMR, 0x20); + /* 2011/02/15 MH According to Alex's + suggestion, close mask to prevent + incorrect FW write operation. */ + rtl8723au_write8(padapter, REG_FTIMR, 0x00); + rtl8723au_write8(padapter, REG_FSIMR, 0x00); + + /* 8051 reset by self */ + rtl8723au_write8(padapter, REG_HMETFR + 3, 0x20); + + while ((retry_cnts++ < 100) && + (rtl8723au_read16(padapter, REG_SYS_FUNC_EN) & + FEN_CPUEN)) { + udelay(50); /* us */ + } - if (retry_cnts >= 100) { - /* Reset MAC and Enable 8051 */ - rtl8723au_write8(padapter, - REG_SYS_FUNC_EN + 1, - 0x50); - mdelay(10); - } + if (retry_cnts >= 100) { + /* Reset MAC and Enable 8051 */ + rtl8723au_write8(padapter, + REG_SYS_FUNC_EN + 1, 0x50); + mdelay(10); } } /* Reset MAC and Enable 8051 */ @@ -1450,12 +1369,6 @@ static void _ResetDigitalProcedure1_92C(struct rtw_adapter *padapter, } } -static void _ResetDigitalProcedure1(struct rtw_adapter *padapter, - bool bWithoutHWSM) -{ - _ResetDigitalProcedure1_92C(padapter, bWithoutHWSM); -} - static void _ResetDigitalProcedure2(struct rtw_adapter *padapter) { /***************************** @@ -1472,8 +1385,8 @@ m. SYS_ISO_CTRL 0x01[7:0] = 0x83 isolated ELDR to PON static void _DisableAnalog(struct rtw_adapter *padapter, bool bWithoutHWSM) { struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); - u16 value16 = 0; - u8 value8 = 0; + u16 value16; + u8 value8; if (bWithoutHWSM) { /***************************** @@ -1487,7 +1400,7 @@ static void _DisableAnalog(struct rtw_adapter *padapter, bool bWithoutHWSM) /* rtl8723au_write8(padapter, REG_LDOV12D_CTRL, 0x54); */ value8 = rtl8723au_read8(padapter, REG_LDOV12D_CTRL); - value8 &= (~LDV12_EN); + value8 &= ~LDV12_EN; rtl8723au_write8(padapter, REG_LDOV12D_CTRL, value8); /* RT_TRACE(COMP_INIT, DBG_LOUD, (" REG_LDOV12D_CTRL Reg0x21:0x%02x.\n", value8)); */ @@ -1509,9 +1422,9 @@ static void _DisableAnalog(struct rtw_adapter *padapter, bool bWithoutHWSM) use HW to shut down 8051 automatically. */ /* Becasue suspend operatione need the asistance of 8051 to wait for 3ms. */ - value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN); + value16 = APDM_HOST | AFSM_HSUS | PFM_ALDN; } else { - value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN); + value16 = APDM_HOST | AFSM_HSUS | PFM_ALDN; } rtl8723au_write16(padapter, REG_APS_FSMCO, value16); /* 0x4802 */ @@ -1522,16 +1435,14 @@ static void _DisableAnalog(struct rtw_adapter *padapter, bool bWithoutHWSM) /* HW Auto state machine */ int CardDisableHWSM(struct rtw_adapter *padapter, u8 resetMCU) { - int rtStatus = _SUCCESS; - if (padapter->bSurpriseRemoved) { - return rtStatus; + return _SUCCESS; } /* RF Off Sequence ==== */ - _DisableRFAFEAndResetBB(padapter); + _DisableRFAFEAndResetBB8192C(padapter); /* ==== Reset digital sequence ====== */ - _ResetDigitalProcedure1(padapter, false); + _ResetDigitalProcedure1_92C(padapter, false); /* ==== Pull GPIO PIN to balance level and LED control ====== */ _DisableGPIO(padapter); @@ -1542,25 +1453,21 @@ int CardDisableHWSM(struct rtw_adapter *padapter, u8 resetMCU) RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("======> Card disable finished.\n")); - return rtStatus; + return _SUCCESS; } /* without HW Auto state machine */ int CardDisableWithoutHWSM(struct rtw_adapter *padapter) { - int rtStatus = _SUCCESS; - - /* RT_TRACE(COMP_INIT, DBG_LOUD, - ("======> Card Disable Without HWSM .\n")); */ if (padapter->bSurpriseRemoved) { - return rtStatus; + return _SUCCESS; } /* RF Off Sequence ==== */ - _DisableRFAFEAndResetBB(padapter); + _DisableRFAFEAndResetBB8192C(padapter); /* ==== Reset digital sequence ====== */ - _ResetDigitalProcedure1(padapter, true); + _ResetDigitalProcedure1_92C(padapter, true); /* ==== Pull GPIO PIN to balance level and LED control ====== */ _DisableGPIO(padapter); @@ -1573,29 +1480,27 @@ int CardDisableWithoutHWSM(struct rtw_adapter *padapter) /* RT_TRACE(COMP_INIT, DBG_LOUD, ("<====== Card Disable Without HWSM .\n")); */ - return rtStatus; + return _SUCCESS; } void Hal_InitPGData(struct rtw_adapter *padapter, u8 *PROMContent) { struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter); - if (false == pEEPROM->bautoload_fail_flag) { /* autoload OK. */ + if (!pEEPROM->bautoload_fail_flag) { /* autoload OK. */ if (!pEEPROM->EepromOrEfuse) { /* Read EFUSE real map to shadow. */ EFUSE_ShadowMapUpdate23a(padapter, EFUSE_WIFI); - memcpy((void *)PROMContent, - (void *)pEEPROM->efuse_eeprom_data, + memcpy(PROMContent, pEEPROM->efuse_eeprom_data, HWSET_MAX_SIZE); } - } else { /* autoload fail */ + } else { RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("AutoLoad Fail reported from CR9346!!\n")); -/* pHalData->AutoloadFailFlag = true; */ /* update to default value 0xFF */ - if (false == pEEPROM->EepromOrEfuse) + if (!pEEPROM->EepromOrEfuse) EFUSE_ShadowMapUpdate23a(padapter, EFUSE_WIFI); - memcpy((void *)PROMContent, (void *)pEEPROM->efuse_eeprom_data, + memcpy(PROMContent, pEEPROM->efuse_eeprom_data, HWSET_MAX_SIZE); } } @@ -1945,13 +1850,13 @@ Hal_EfuseParseThermalMeter_8723A(struct rtw_adapter *padapter, /* */ /* ThermalMeter from EEPROM */ /* */ - if (AutoloadFail == false) + if (!AutoloadFail) pHalData->EEPROMThermalMeter = PROMContent[EEPROM_THERMAL_METER_8723A]; else pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter; - if ((pHalData->EEPROMThermalMeter == 0xff) || (AutoloadFail == true)) { + if ((pHalData->EEPROMThermalMeter == 0xff) || AutoloadFail) { pHalData->bAPKThermalMeterIgnore = true; pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter; } @@ -1960,10 +1865,6 @@ Hal_EfuseParseThermalMeter_8723A(struct rtw_adapter *padapter, pHalData->EEPROMThermalMeter); } -void Hal_InitChannelPlan23a(struct rtw_adapter *padapter) -{ -} - static void rtl8723a_cal_txdesc_chksum(struct tx_desc *ptxdesc) { u16 *usPtr = (u16 *) ptxdesc; @@ -1981,254 +1882,6 @@ static void rtl8723a_cal_txdesc_chksum(struct tx_desc *ptxdesc) ptxdesc->txdw7 |= cpu_to_le32(checksum & 0x0000ffff); } -static void fill_txdesc_sectype(struct pkt_attrib *pattrib, - struct txdesc_8723a *ptxdesc) -{ - if ((pattrib->encrypt > 0) && !pattrib->bswenc) { - switch (pattrib->encrypt) { - /* SEC_TYPE */ - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - case WLAN_CIPHER_SUITE_TKIP: - ptxdesc->sectype = 1; - break; - - case WLAN_CIPHER_SUITE_CCMP: - ptxdesc->sectype = 3; - break; - - case 0: - default: - break; - } - } -} - -static void fill_txdesc_vcs(struct pkt_attrib *pattrib, - struct txdesc_8723a *ptxdesc) -{ - /* DBG_8723A("cvs_mode =%d\n", pattrib->vcs_mode); */ - - switch (pattrib->vcs_mode) { - case RTS_CTS: - ptxdesc->rtsen = 1; - break; - - case CTS_TO_SELF: - ptxdesc->cts2self = 1; - break; - - case NONE_VCS: - default: - break; - } - - if (pattrib->vcs_mode) { - ptxdesc->hw_rts_en = 1; /* ENABLE HW RTS */ - - /* Set RTS BW */ - if (pattrib->ht_en) { - if (pattrib->bwmode & HT_CHANNEL_WIDTH_40) - ptxdesc->rts_bw = 1; - - switch (pattrib->ch_offset) { - case HAL_PRIME_CHNL_OFFSET_DONT_CARE: - ptxdesc->rts_sc = 0; - break; - - case HAL_PRIME_CHNL_OFFSET_LOWER: - ptxdesc->rts_sc = 1; - break; - - case HAL_PRIME_CHNL_OFFSET_UPPER: - ptxdesc->rts_sc = 2; - break; - - default: - ptxdesc->rts_sc = 3; /* Duplicate */ - break; - } - } - } -} - -static void fill_txdesc_phy(struct pkt_attrib *pattrib, - struct txdesc_8723a *ptxdesc) -{ - if (pattrib->ht_en) { - if (pattrib->bwmode & HT_CHANNEL_WIDTH_40) - ptxdesc->data_bw = 1; - - switch (pattrib->ch_offset) { - case HAL_PRIME_CHNL_OFFSET_DONT_CARE: - ptxdesc->data_sc = 0; - break; - - case HAL_PRIME_CHNL_OFFSET_LOWER: - ptxdesc->data_sc = 1; - break; - - case HAL_PRIME_CHNL_OFFSET_UPPER: - ptxdesc->data_sc = 2; - break; - - default: - ptxdesc->data_sc = 3; /* Duplicate */ - break; - } - } -} - -static void rtl8723a_fill_default_txdesc(struct xmit_frame *pxmitframe, - u8 *pbuf) -{ - struct rtw_adapter *padapter; - struct hal_data_8723a *pHalData; - struct dm_priv *pdmpriv; - struct mlme_ext_priv *pmlmeext; - struct mlme_ext_info *pmlmeinfo; - struct pkt_attrib *pattrib; - struct txdesc_8723a *ptxdesc; - s32 bmcst; - - padapter = pxmitframe->padapter; - pHalData = GET_HAL_DATA(padapter); - pdmpriv = &pHalData->dmpriv; - pmlmeext = &padapter->mlmeextpriv; - pmlmeinfo = &pmlmeext->mlmext_info; - - pattrib = &pxmitframe->attrib; - bmcst = is_multicast_ether_addr(pattrib->ra); - - ptxdesc = (struct txdesc_8723a *)pbuf; - - if (pxmitframe->frame_tag == DATA_FRAMETAG) { - ptxdesc->macid = pattrib->mac_id; /* CAM_ID(MAC_ID) */ - - if (pattrib->ampdu_en == true) - ptxdesc->agg_en = 1; /* AGG EN */ - else - ptxdesc->bk = 1; /* AGG BK */ - - ptxdesc->qsel = pattrib->qsel; - ptxdesc->rate_id = pattrib->raid; - - fill_txdesc_sectype(pattrib, ptxdesc); - - ptxdesc->seq = pattrib->seqnum; - - if ((pattrib->ether_type != 0x888e) && - (pattrib->ether_type != 0x0806) && - (pattrib->dhcp_pkt != 1)) { - /* Non EAP & ARP & DHCP type data packet */ - - fill_txdesc_vcs(pattrib, ptxdesc); - fill_txdesc_phy(pattrib, ptxdesc); - - ptxdesc->rtsrate = 8; /* RTS Rate = 24M */ - ptxdesc->data_ratefb_lmt = 0x1F; - ptxdesc->rts_ratefb_lmt = 0xF; - - /* use REG_INIDATA_RATE_SEL value */ - ptxdesc->datarate = - pdmpriv->INIDATA_RATE[pattrib->mac_id]; - - } else { - /* EAP data packet and ARP packet. */ - /* Use the 1M data rate to send the EAP/ARP packet. */ - /* This will maybe make the handshake smooth. */ - - ptxdesc->bk = 1; /* AGG BK */ - ptxdesc->userate = 1; /* driver uses rate */ - if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT) - ptxdesc->data_short = 1; - ptxdesc->datarate = MRateToHwRate23a(pmlmeext->tx_rate); - } - } else if (pxmitframe->frame_tag == MGNT_FRAMETAG) { -/* RT_TRACE(_module_hal_xmit_c_, _drv_notice_, - ("%s: MGNT_FRAMETAG\n", __func__)); */ - - ptxdesc->macid = pattrib->mac_id; /* CAM_ID(MAC_ID) */ - ptxdesc->qsel = pattrib->qsel; - ptxdesc->rate_id = pattrib->raid; /* Rate ID */ - ptxdesc->seq = pattrib->seqnum; - ptxdesc->userate = 1; /* driver uses rate, 1M */ - ptxdesc->rty_lmt_en = 1; /* retry limit enable */ - ptxdesc->data_rt_lmt = 6; /* retry limit = 6 */ - - /* CCX-TXRPT ack for xmit mgmt frames. */ - if (pxmitframe->ack_report) - ptxdesc->ccx = 1; - - ptxdesc->datarate = MRateToHwRate23a(pmlmeext->tx_rate); - } else if (pxmitframe->frame_tag == TXAGG_FRAMETAG) { - RT_TRACE(_module_hal_xmit_c_, _drv_warning_, - ("%s: TXAGG_FRAMETAG\n", __func__)); - } else { - RT_TRACE(_module_hal_xmit_c_, _drv_warning_, - ("%s: frame_tag = 0x%x\n", __func__, - pxmitframe->frame_tag)); - - ptxdesc->macid = 4; /* CAM_ID(MAC_ID) */ - ptxdesc->rate_id = 6; /* Rate ID */ - ptxdesc->seq = pattrib->seqnum; - ptxdesc->userate = 1; /* driver uses rate */ - ptxdesc->datarate = MRateToHwRate23a(pmlmeext->tx_rate); - } - - ptxdesc->pktlen = pattrib->last_txcmdsz; - ptxdesc->offset = TXDESC_SIZE + OFFSET_SZ; - if (bmcst) - ptxdesc->bmc = 1; - ptxdesc->ls = 1; - ptxdesc->fs = 1; - ptxdesc->own = 1; - - /* 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS. */ - /* (1) The sequence number of each non-Qos frame / broadcast / - * multicast / mgnt frame should be controled by Hw because Fw - * will also send null data which we cannot control when Fw LPS enable. - * --> default enable non-Qos data sequense number. - 2010.06.23. by tynli. */ - /* (2) Enable HW SEQ control for beacon packet, - * because we use Hw beacon. */ - /* (3) Use HW Qos SEQ to control the seq num of Ext port - * non-Qos packets. */ - /* 2010.06.23. Added by tynli. */ - if (!pattrib->qos_en) { - /* Hw set sequence number */ - ptxdesc->hwseq_en = 1; /* HWSEQ_EN */ - ptxdesc->hwseq_sel = 0; /* HWSEQ_SEL */ - } -} - -/* - * Description: - * - * Parameters: - * pxmitframe xmitframe - * pbuf where to fill tx desc - */ -void rtl8723a_update_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf) -{ - struct tx_desc *pdesc; - - pdesc = (struct tx_desc *)pbuf; - memset(pdesc, 0, sizeof(struct tx_desc)); - - rtl8723a_fill_default_txdesc(pxmitframe, pbuf); - - pdesc->txdw0 = cpu_to_le32(pdesc->txdw0); - pdesc->txdw1 = cpu_to_le32(pdesc->txdw1); - pdesc->txdw2 = cpu_to_le32(pdesc->txdw2); - pdesc->txdw3 = cpu_to_le32(pdesc->txdw3); - pdesc->txdw4 = cpu_to_le32(pdesc->txdw4); - pdesc->txdw5 = cpu_to_le32(pdesc->txdw5); - pdesc->txdw6 = cpu_to_le32(pdesc->txdw6); - pdesc->txdw7 = cpu_to_le32(pdesc->txdw7); - rtl8723a_cal_txdesc_chksum(pdesc); -} - /* * Description: In normal chip, we should send some packet to Hw which * will be used by Fw in FW LPS mode. The function is to fill the Tx diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c b/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c index 3d4d7ec27509..88e91cd8ebb9 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c @@ -418,7 +418,6 @@ PHY_SetRFReg(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath, *---------------------------------------------------------------------------*/ int PHY_MACConfig8723A(struct rtw_adapter *Adapter) { - int rtStatus = _SUCCESS; struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); bool is92C = IS_92C_SERIAL(pHalData->VersionID); @@ -433,7 +432,7 @@ int PHY_MACConfig8723A(struct rtw_adapter *Adapter) if (is92C && (BOARD_USB_DONGLE == pHalData->BoardType)) rtl8723au_write8(Adapter, 0x40, 0x04); - return rtStatus; + return _SUCCESS; } /** diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c b/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c index 2dc0886e5f90..1aad4384471c 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c @@ -42,21 +42,6 @@ #include <rtl8723a_hal.h> #include <usb_ops_linux.h> -/*---------------------------Define Local Constant---------------------------*/ -/* Define local structure for debug!!!!! */ -struct rf_shadow_compare_map { - /* Shadow register value */ - u32 Value; - /* Compare or not flag */ - u8 Compare; - /* Record If it had ever modified unpredicted */ - u8 ErrorOrNot; - /* Recorver Flag */ - u8 Recorver; - /* */ - u8 Driver_Write; -}; - /*----------------------------------------------------------------------------- * Function: PHY_RF6052SetBandwidth() * @@ -71,20 +56,23 @@ struct rf_shadow_compare_map { * * Note: For RF type 0222D *---------------------------------------------------------------------------*/ -void rtl8723a_phy_rf6052set_bw( - struct rtw_adapter *Adapter, - enum ht_channel_width Bandwidth) /* 20M or 40M */ +void rtl8723a_phy_rf6052set_bw(struct rtw_adapter *Adapter, + enum ht_channel_width Bandwidth) /* 20M or 40M */ { - struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); + struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); switch (Bandwidth) { case HT_CHANNEL_WIDTH_20: - pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff3ff) | 0x0400); - PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, pHalData->RfRegChnlVal[0]); + pHalData->RfRegChnlVal[0] = + (pHalData->RfRegChnlVal[0] & 0xfffff3ff) | 0x0400; + PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, + pHalData->RfRegChnlVal[0]); break; case HT_CHANNEL_WIDTH_40: - pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff3ff)); - PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, pHalData->RfRegChnlVal[0]); + pHalData->RfRegChnlVal[0] = + (pHalData->RfRegChnlVal[0] & 0xfffff3ff); + PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, + pHalData->RfRegChnlVal[0]); break; default: break; @@ -108,7 +96,8 @@ void rtl8723a_phy_rf6052set_bw( * *---------------------------------------------------------------------------*/ -void rtl823a_phy_rf6052setccktxpower(struct rtw_adapter *Adapter, u8 *pPowerlevel) +void rtl823a_phy_rf6052setccktxpower(struct rtw_adapter *Adapter, + u8 *pPowerlevel) { struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); struct dm_priv *pdmpriv = &pHalData->dmpriv; @@ -118,7 +107,8 @@ void rtl823a_phy_rf6052setccktxpower(struct rtw_adapter *Adapter, u8 *pPowerleve u8 idx1, idx2; u8 *ptr; - /* According to SD3 eechou's suggestion, we need to disable turbo scan for RU. */ + /* According to SD3 eechou's suggestion, we need to disable + turbo scan for RU. */ /* Otherwise, external PA will be broken if power index > 0x20. */ if (pHalData->EEPROMRegulatory != 0 || pHalData->ExternalPA) TurboScanOff = true; @@ -131,29 +121,37 @@ void rtl823a_phy_rf6052setccktxpower(struct rtw_adapter *Adapter, u8 *pPowerleve if (TurboScanOff) { for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) { - TxAGC[idx1] = - pPowerlevel[idx1] | (pPowerlevel[idx1]<<8) | - (pPowerlevel[idx1]<<16) | (pPowerlevel[idx1]<<24); - /* 2010/10/18 MH For external PA module. We need to limit power index to be less than 0x20. */ + TxAGC[idx1] = pPowerlevel[idx1] | + (pPowerlevel[idx1] << 8) | + (pPowerlevel[idx1] << 16) | + (pPowerlevel[idx1] << 24); + /* 2010/10/18 MH For external PA module. + We need to limit power index to be less + than 0x20. */ if (TxAGC[idx1] > 0x20 && pHalData->ExternalPA) TxAGC[idx1] = 0x20; } } } else { -/* 20100427 Joseph: Driver dynamic Tx power shall not affect Tx power. It shall be determined by power training mechanism. */ -/* Currently, we cannot fully disable driver dynamic tx power mechanism because it is referenced by BT coexist mechanism. */ -/* In the future, two mechanism shall be separated from each other and maintained independantly. Thanks for Lanhsin's reminder. */ +/* 20100427 Joseph: Driver dynamic Tx power shall not affect Tx + * power. It shall be determined by power training mechanism. */ +/* Currently, we cannot fully disable driver dynamic tx power + * mechanism because it is referenced by BT coexist mechanism. */ +/* In the future, two mechanism shall be separated from each other + * and maintained independantly. Thanks for Lanhsin's reminder. */ if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1) { TxAGC[RF_PATH_A] = 0x10101010; TxAGC[RF_PATH_B] = 0x10101010; - } else if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level2) { + } else if (pdmpriv->DynamicTxHighPowerLvl == + TxHighPwrLevel_Level2) { TxAGC[RF_PATH_A] = 0x00000000; TxAGC[RF_PATH_B] = 0x00000000; } else { for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) { - TxAGC[idx1] = - pPowerlevel[idx1] | (pPowerlevel[idx1]<<8) | - (pPowerlevel[idx1]<<16) | (pPowerlevel[idx1]<<24); + TxAGC[idx1] = pPowerlevel[idx1] | + (pPowerlevel[idx1] << 8) | + (pPowerlevel[idx1] << 16) | + (pPowerlevel[idx1] << 24); } if (pHalData->EEPROMRegulatory == 0) { @@ -178,29 +176,24 @@ void rtl823a_phy_rf6052setccktxpower(struct rtw_adapter *Adapter, u8 *pPowerleve } /* rf-A cck tx power */ - tmpval = TxAGC[RF_PATH_A]&0xff; + tmpval = TxAGC[RF_PATH_A] & 0xff; PHY_SetBBReg(Adapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, tmpval); - tmpval = TxAGC[RF_PATH_A]>>8; + tmpval = TxAGC[RF_PATH_A] >> 8; PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); /* rf-B cck tx power */ - tmpval = TxAGC[RF_PATH_B]>>24; + tmpval = TxAGC[RF_PATH_B] >> 24; PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte0, tmpval); - tmpval = TxAGC[RF_PATH_B]&0x00ffffff; + tmpval = TxAGC[RF_PATH_B] & 0x00ffffff; PHY_SetBBReg(Adapter, rTxAGC_B_CCK1_55_Mcs32, 0xffffff00, tmpval); } /* PHY_RF6052SetCckTxPower */ /* powerbase0 for OFDM rates */ /* powerbase1 for HT MCS rates */ -static void getPowerBase( - struct rtw_adapter *Adapter, - u8 *pPowerLevel, - u8 Channel, - u32 *OfdmBase, - u32 *MCSBase - ) +static void getPowerBase(struct rtw_adapter *Adapter, u8 *pPowerLevel, + u8 Channel, u32 *OfdmBase, u32 *MCSBase) { - struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); + struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); u32 powerBase0, powerBase1; u8 Legacy_pwrdiff = 0; s8 HT20_pwrdiff = 0; @@ -211,8 +204,9 @@ static void getPowerBase( Legacy_pwrdiff = pHalData->TxPwrLegacyHtDiff[i][Channel-1]; powerBase0 = powerlevel[i] + Legacy_pwrdiff; - powerBase0 = (powerBase0<<24) | (powerBase0<<16) | (powerBase0<<8) | powerBase0; - *(OfdmBase+i) = powerBase0; + powerBase0 = powerBase0 << 24 | powerBase0 << 16 | + powerBase0 << 8 | powerBase0; + *(OfdmBase + i) = powerBase0; } for (i = 0; i < 2; i++) { @@ -222,36 +216,35 @@ static void getPowerBase( powerlevel[i] += HT20_pwrdiff; } powerBase1 = powerlevel[i]; - powerBase1 = (powerBase1<<24) | (powerBase1<<16) | (powerBase1<<8) | powerBase1; - *(MCSBase+i) = powerBase1; + powerBase1 = powerBase1 << 24 | powerBase1 << 16 | + powerBase1 << 8 | powerBase1; + *(MCSBase + i) = powerBase1; } } -static void getTxPowerWriteValByRegulatory( - struct rtw_adapter *Adapter, - u8 Channel, - u8 index, - u32 *powerBase0, - u32 *powerBase1, - u32 *pOutWriteVal - ) +static void +getTxPowerWriteValByRegulatory(struct rtw_adapter *Adapter, u8 Channel, + u8 index, u32 *powerBase0, u32 *powerBase1, + u32 *pOutWriteVal) { - struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); + struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); struct dm_priv *pdmpriv = &pHalData->dmpriv; - u8 i, chnlGroup = 0, pwr_diff_limit[4]; - u32 writeVal, customer_limit, rf; + u8 i, chnlGroup = 0, pwr_diff_limit[4]; + u32 writeVal, customer_limit, rf; /* Index 0 & 1 = legacy OFDM, 2-5 = HT_MCS rate */ for (rf = 0; rf < 2; rf++) { switch (pHalData->EEPROMRegulatory) { case 0: /* Realtek better performance */ - /* increase power diff defined by Realtek for large power */ + /* increase power diff defined by Realtek for + * large power */ chnlGroup = 0; writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)] + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); break; case 1: /* Realtek regulatory */ - /* increase power diff defined by Realtek for regulatory */ + /* increase power diff defined by Realtek for + * regulatory */ if (pHalData->pwrGroupCnt == 1) chnlGroup = 0; if (pHalData->pwrGroupCnt >= 3) { @@ -262,17 +255,20 @@ static void getTxPowerWriteValByRegulatory( else if (Channel > 9) chnlGroup = 2; - if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_20) + if (pHalData->CurrentChannelBW == + HT_CHANNEL_WIDTH_20) chnlGroup++; else chnlGroup += 4; } writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)] + - ((index < 2) ? powerBase0[rf] : powerBase1[rf]); + ((index < 2) ? powerBase0[rf] : + powerBase1[rf]); break; case 2: /* Better regulatory */ - /* don't increase any power diff */ - writeVal = ((index < 2) ? powerBase0[rf] : powerBase1[rf]); + /* don't increase any power diff */ + writeVal = ((index < 2) ? powerBase0[rf] : + powerBase1[rf]); break; case 3: /* Customer defined power diff. */ chnlGroup = 0; @@ -299,28 +295,34 @@ static void getTxPowerWriteValByRegulatory( break; } -/* 20100427 Joseph: Driver dynamic Tx power shall not affect Tx power. It shall be determined by power training mechanism. */ -/* Currently, we cannot fully disable driver dynamic tx power mechanism because it is referenced by BT coexist mechanism. */ -/* In the future, two mechanism shall be separated from each other and maintained independantly. Thanks for Lanhsin's reminder. */ +/* 20100427 Joseph: Driver dynamic Tx power shall not affect Tx power. + It shall be determined by power training mechanism. */ +/* Currently, we cannot fully disable driver dynamic tx power mechanism + because it is referenced by BT coexist mechanism. */ +/* In the future, two mechanism shall be separated from each other and + maintained independantly. Thanks for Lanhsin's reminder. */ if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1) writeVal = 0x14141414; - else if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level2) + else if (pdmpriv->DynamicTxHighPowerLvl == + TxHighPwrLevel_Level2) writeVal = 0x00000000; - /* 20100628 Joseph: High power mode for BT-Coexist mechanism. */ - /* This mechanism is only applied when Driver-Highpower-Mechanism is OFF. */ + /* 20100628 Joseph: High power mode for BT-Coexist mechanism. */ + /* This mechanism is only applied when + Driver-Highpower-Mechanism is OFF. */ if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_BT1) writeVal = writeVal - 0x06060606; else if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_BT2) writeVal = writeVal; - *(pOutWriteVal+rf) = writeVal; + *(pOutWriteVal + rf) = writeVal; } } -static void writeOFDMPowerReg(struct rtw_adapter *Adapter, u8 index, u32 *pValue) +static void writeOFDMPowerReg(struct rtw_adapter *Adapter, u8 index, + u32 *pValue) { - struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); + struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); u16 RegOffset_A[6] = { rTxAGC_A_Rate18_06, rTxAGC_A_Rate54_24, rTxAGC_A_Mcs03_Mcs00, rTxAGC_A_Mcs07_Mcs04, @@ -338,12 +340,13 @@ static void writeOFDMPowerReg(struct rtw_adapter *Adapter, u8 index, u32 *pValue for (rf = 0; rf < 2; rf++) { writeVal = pValue[rf]; for (i = 0; i < 4; i++) { - pwr_val[i] = (u8)((writeVal & (0x7f<<(i*8)))>>(i*8)); - if (pwr_val[i] > RF6052_MAX_TX_PWR) + pwr_val[i] = (u8)((writeVal & + (0x7f << (i * 8))) >> (i * 8)); + if (pwr_val[i] > RF6052_MAX_TX_PWR) pwr_val[i] = RF6052_MAX_TX_PWR; } - writeVal = (pwr_val[3]<<24) | (pwr_val[2]<<16) | - (pwr_val[1]<<8) | pwr_val[0]; + writeVal = pwr_val[3] << 24 | pwr_val[2] << 16 | + pwr_val[1] << 8 | pwr_val[0]; if (rf == 0) RegOffset = RegOffset_A[index]; @@ -352,7 +355,8 @@ static void writeOFDMPowerReg(struct rtw_adapter *Adapter, u8 index, u32 *pValue PHY_SetBBReg(Adapter, RegOffset, bMaskDWord, writeVal); - /* 201005115 Joseph: Set Tx Power diff for Tx power training mechanism. */ + /* 201005115 Joseph: Set Tx Power diff for Tx power + training mechanism. */ if (((pHalData->rf_type == RF_2T2R) && (RegOffset == rTxAGC_A_Mcs15_Mcs12 || RegOffset == rTxAGC_B_Mcs15_Mcs12)) || @@ -360,15 +364,19 @@ static void writeOFDMPowerReg(struct rtw_adapter *Adapter, u8 index, u32 *pValue (RegOffset == rTxAGC_A_Mcs07_Mcs04 || RegOffset == rTxAGC_B_Mcs07_Mcs04))) { writeVal = pwr_val[3]; - if (RegOffset == rTxAGC_A_Mcs15_Mcs12 || RegOffset == rTxAGC_A_Mcs07_Mcs04) + if (RegOffset == rTxAGC_A_Mcs15_Mcs12 || + RegOffset == rTxAGC_A_Mcs07_Mcs04) RegOffset = 0xc90; - if (RegOffset == rTxAGC_B_Mcs15_Mcs12 || RegOffset == rTxAGC_B_Mcs07_Mcs04) + if (RegOffset == rTxAGC_B_Mcs15_Mcs12 || + RegOffset == rTxAGC_B_Mcs07_Mcs04) RegOffset = 0xc98; for (i = 0; i < 3; i++) { if (i != 2) - writeVal = (writeVal > 8) ? (writeVal-8) : 0; + writeVal = (writeVal > 8) ? + (writeVal - 8) : 0; else - writeVal = (writeVal > 6) ? (writeVal-6) : 0; + writeVal = (writeVal > 6) ? + (writeVal - 6) : 0; rtl8723au_write8(Adapter, RegOffset + i, (u8)writeVal); } @@ -379,8 +387,9 @@ static void writeOFDMPowerReg(struct rtw_adapter *Adapter, u8 index, u32 *pValue * Function: PHY_RF6052SetOFDMTxPower * * Overview: For legacy and HY OFDM, we must read EEPROM TX power index for - * different channel and read original value in TX power register area from - * 0xe00. We increase offset and original value to be correct tx pwr. + * different channel and read original value in TX power + * register area from 0xe00. We increase offset and + * original value to be correct tx pwr. * * Input: NONE * @@ -389,20 +398,23 @@ static void writeOFDMPowerReg(struct rtw_adapter *Adapter, u8 index, u32 *pValue * Return: NONE * * Revised History: - * When Who Remark - * 11/05/2008 MHC Simulate 8192 series method. - * 01/06/2009 MHC 1. Prevent Path B tx power overflow or underflow dure to - * A/B pwr difference or legacy/HT pwr diff. - * 2. We concern with path B legacy/HT OFDM difference. - * 01/22/2009 MHC Support new EPRO format from SD3. + * When Remark + * 11/05/2008 MHC Simulate 8192 series method. + * 01/06/2009 MHC 1. Prevent Path B tx power overflow or + * underflow dure to A/B pwr difference or + * legacy/HT pwr diff. + * 2. We concern with path B legacy/HT OFDM difference. + * 01/22/2009 MHC Support new EPRO format from SD3. * *---------------------------------------------------------------------------*/ -void rtl8723a_PHY_RF6052SetOFDMTxPower(struct rtw_adapter *Adapter, u8 *pPowerLevel, u8 Channel) +void rtl8723a_PHY_RF6052SetOFDMTxPower(struct rtw_adapter *Adapter, + u8 *pPowerLevel, u8 Channel) { u32 writeVal[2], powerBase0[2], powerBase1[2]; u8 index = 0; - getPowerBase(Adapter, pPowerLevel, Channel, &powerBase0[0], &powerBase1[0]); + getPowerBase(Adapter, pPowerLevel, Channel, + &powerBase0[0], &powerBase1[0]); for (index = 0; index < 6; index++) { getTxPowerWriteValByRegulatory(Adapter, Channel, index, @@ -416,7 +428,7 @@ static int phy_RF6052_Config_ParaFile(struct rtw_adapter *Adapter) { u32 u4RegValue = 0; u8 eRFPath; - struct bb_reg_define *pPhyReg; + struct bb_reg_define *pPhyReg; int rtStatus = _SUCCESS; struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); @@ -430,15 +442,17 @@ static int phy_RF6052_Config_ParaFile(struct rtw_adapter *Adapter) /*----Store original RFENV control type----*/ switch (eRFPath) { case RF_PATH_A: - u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV); + u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs, + bRFSI_RFENV); break; case RF_PATH_B: - u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV<<16); + u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs, + bRFSI_RFENV << 16); break; } /*----Set RF_ENV enable----*/ - PHY_SetBBReg(Adapter, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1); + PHY_SetBBReg(Adapter, pPhyReg->rfintfe, bRFSI_RFENV << 16, 0x1); udelay(1);/* PlatformStallExecution(1); */ /*----Set RF_ENV output high----*/ @@ -446,10 +460,12 @@ static int phy_RF6052_Config_ParaFile(struct rtw_adapter *Adapter) udelay(1);/* PlatformStallExecution(1); */ /* Set bit number of Address and Data for RF register */ - PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); /* Set 1 to 4 bits for 8255 */ + PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireAddressLength, + 0x0); /* Set 1 to 4 bits for 8255 */ udelay(1);/* PlatformStallExecution(1); */ - PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); /* Set 0 to 12 bits for 8255 */ + PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireDataLength, + 0x0); /* Set 0 to 12 bits for 8255 */ udelay(1);/* PlatformStallExecution(1); */ /*----Initialize RF fom connfiguration file----*/ @@ -464,15 +480,16 @@ static int phy_RF6052_Config_ParaFile(struct rtw_adapter *Adapter) /*----Restore RFENV control type----*/; switch (eRFPath) { case RF_PATH_A: - PHY_SetBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue); + PHY_SetBBReg(Adapter, pPhyReg->rfintfs, + bRFSI_RFENV, u4RegValue); break; case RF_PATH_B: - PHY_SetBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue); + PHY_SetBBReg(Adapter, pPhyReg->rfintfs, + bRFSI_RFENV << 16, u4RegValue); break; } if (rtStatus != _SUCCESS) { - /* RT_TRACE(COMP_FPGA, DBG_LOUD, ("phy_RF6052_Config_ParaFile():Radio[%d] Fail!!", eRFPath)); */ goto phy_RF6052_Config_ParaFile_Fail; } } diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_xmit.c b/drivers/staging/rtl8723au/hal/rtl8723a_xmit.c deleted file mode 100644 index 6ea2f9efef64..000000000000 --- a/drivers/staging/rtl8723au/hal/rtl8723a_xmit.c +++ /dev/null @@ -1,31 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - ******************************************************************************/ -#define _RTL8723A_XMIT_C_ - -#include <osdep_service.h> -#include <drv_types.h> -#include <rtl8723a_hal.h> - -void handle_txrpt_ccx_8723a(struct rtw_adapter *adapter, void *buf) -{ - struct txrpt_ccx_8723a *txrpt_ccx = buf; - - if (txrpt_ccx->int_ccx) { - if (txrpt_ccx->pkt_ok) - rtw_ack_tx_done23a(&adapter->xmitpriv, RTW_SCTX_DONE_SUCCESS); - else - rtw_ack_tx_done23a(&adapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL); - } -} diff --git a/drivers/staging/rtl8723au/hal/rtl8723au_led.c b/drivers/staging/rtl8723au/hal/rtl8723au_led.c deleted file mode 100644 index b946636af9b3..000000000000 --- a/drivers/staging/rtl8723au/hal/rtl8723au_led.c +++ /dev/null @@ -1,124 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - ******************************************************************************/ - -#include "drv_types.h" -#include "rtl8723a_hal.h" -#include "rtl8723a_led.h" -#include "usb_ops_linux.h" - -/* */ -/* LED object. */ -/* */ - -/* */ -/* Prototype of protected function. */ -/* */ - -/* */ -/* LED_819xUsb routines. */ -/* */ - -/* Description: */ -/* Turn on LED according to LedPin specified. */ -void SwLedOn23a(struct rtw_adapter *padapter, struct led_8723a *pLed) -{ - u8 LedCfg = 0; - - if ((padapter->bSurpriseRemoved == true) || (padapter->bDriverStopped == true)) - return; - switch (pLed->LedPin) { - case LED_PIN_GPIO0: - break; - case LED_PIN_LED0: - /* SW control led0 on. */ - rtl8723au_write8(padapter, REG_LEDCFG0, - (LedCfg&0xf0)|BIT(5)|BIT(6)); - break; - case LED_PIN_LED1: - /* SW control led1 on. */ - rtl8723au_write8(padapter, REG_LEDCFG1, (LedCfg&0x00)|BIT(6)); - break; - case LED_PIN_LED2: - LedCfg = rtl8723au_read8(padapter, REG_LEDCFG2); - /* SW control led1 on. */ - rtl8723au_write8(padapter, REG_LEDCFG2, (LedCfg&0x80)|BIT(5)); - break; - default: - break; - } - pLed->bLedOn = true; -} - -/* Description: */ -/* Turn off LED according to LedPin specified. */ -void SwLedOff23a(struct rtw_adapter *padapter, struct led_8723a *pLed) -{ - u8 LedCfg = 0; - /* struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); */ - - if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped)) - goto exit; - - switch (pLed->LedPin) { - case LED_PIN_GPIO0: - break; - case LED_PIN_LED0: - /* SW control led0 on. */ - rtl8723au_write8(padapter, REG_LEDCFG0, - (LedCfg&0xf0)|BIT(5)|BIT(6)); - break; - case LED_PIN_LED1: - /* SW control led1 on. */ - rtl8723au_write8(padapter, REG_LEDCFG1, - (LedCfg&0x00)|BIT(5)|BIT(6)); - break; - case LED_PIN_LED2: - LedCfg = rtl8723au_read8(padapter, REG_LEDCFG2); - /* SW control led1 on. */ - rtl8723au_write8(padapter, REG_LEDCFG2, - (LedCfg&0x80)|BIT(3)|BIT(5)); - break; - default: - break; - } -exit: - pLed->bLedOn = false; -} - -/* Interface to manipulate LED objects. */ - -/* Description: */ -/* Initialize all LED_871x objects. */ -void -rtl8723au_InitSwLeds(struct rtw_adapter *padapter) -{ - struct led_priv *pledpriv = &padapter->ledpriv; - - pledpriv->LedControlHandler = LedControl871x23a; - /* 8723as-vau wifi used led2 */ - InitLed871x23a(padapter, &pledpriv->SwLed0, LED_PIN_LED2); - -/* InitLed871x23a(padapter,&pledpriv->SwLed1, LED_PIN_LED2); */ -} - -/* Description: */ -/* DeInitialize all LED_819xUsb objects. */ -void -rtl8723au_DeInitSwLeds(struct rtw_adapter *padapter) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - - DeInitLed871x23a(&ledpriv->SwLed0); -} diff --git a/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c b/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c index a67850fe6e5d..6070510bb470 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c +++ b/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c @@ -21,18 +21,6 @@ /* include <rtl8192c_hal.h> */ #include <rtl8723a_hal.h> -static void do_queue_select(struct rtw_adapter *padapter, struct pkt_attrib *pattrib) -{ - u8 qsel; - - qsel = pattrib->priority; - RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, - ("### do_queue_select priority =%d , qsel = %d\n", - pattrib->priority, qsel)); - - pattrib->qsel = qsel; -} - static int urb_zero_packet_chk(struct rtw_adapter *padapter, int sz) { int blnSetTxDescOffset; @@ -163,7 +151,7 @@ static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bag memset(ptxdesc, 0, sizeof(struct tx_desc)); - if ((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) { + if (pxmitframe->frame_tag == DATA_FRAMETAG) { /* offset 4 */ ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x1f); @@ -215,7 +203,7 @@ static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bag ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate23a(pmlmeext->tx_rate)); } - } else if ((pxmitframe->frame_tag&0x0f) == MGNT_FRAMETAG) { + } else if (pxmitframe->frame_tag == MGNT_FRAMETAG) { /* offset 4 */ ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x1f); @@ -240,10 +228,11 @@ static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bag ptxdesc->txdw5 |= cpu_to_le32(0x00180000);/* retry limit = 6 */ ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate23a(pmlmeext->tx_rate)); - } else if ((pxmitframe->frame_tag&0x0f) == TXAGG_FRAMETAG) { + } else if (pxmitframe->frame_tag == TXAGG_FRAMETAG) { DBG_8723A("pxmitframe->frame_tag == TXAGG_FRAMETAG\n"); } else { - DBG_8723A("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag); + DBG_8723A("pxmitframe->frame_tag = %d\n", + pxmitframe->frame_tag); /* offset 4 */ ptxdesc->txdw1 |= cpu_to_le32((4)&0x1f);/* CAM_ID(MAC_ID) */ @@ -306,10 +295,10 @@ static int rtw_dump_xframe(struct rtw_adapter *padapter, struct pkt_attrib *pattrib = &pxmitframe->attrib; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - if ((pxmitframe->frame_tag == DATA_FRAMETAG) && - (pxmitframe->attrib.ether_type != 0x0806) && - (pxmitframe->attrib.ether_type != 0x888e) && - (pxmitframe->attrib.dhcp_pkt != 1)) + if (pxmitframe->frame_tag == DATA_FRAMETAG && + pxmitframe->attrib.ether_type != ETH_P_ARP && + pxmitframe->attrib.ether_type != ETH_P_PAE && + pxmitframe->attrib.dhcp_pkt != 1) rtw_issue_addbareq_cmd23a(padapter, pxmitframe); mem_addr = pxmitframe->buf_addr; @@ -392,7 +381,7 @@ bool rtl8723au_xmitframe_complete(struct rtw_adapter *padapter, pxmitbuf->priv_data = pxmitframe; - if ((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) { + if (pxmitframe->frame_tag == DATA_FRAMETAG) { if (pxmitframe->attrib.priority <= 15)/* TID0~15 */ res = rtw_xmitframe_coalesce23a(padapter, pxmitframe->pkt, pxmitframe); @@ -440,7 +429,7 @@ bool rtl8723au_hal_xmit(struct rtw_adapter *padapter, struct pkt_attrib *pattrib = &pxmitframe->attrib; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - do_queue_select(padapter, pattrib); + pattrib->qsel = pattrib->priority; spin_lock_bh(&pxmitpriv->lock); #ifdef CONFIG_8723AU_AP_MODE diff --git a/drivers/staging/rtl8723au/hal/usb_halinit.c b/drivers/staging/rtl8723au/hal/usb_halinit.c index a5de03d45aa9..febe5cedef8f 100644 --- a/drivers/staging/rtl8723au/hal/usb_halinit.c +++ b/drivers/staging/rtl8723au/hal/usb_halinit.c @@ -21,11 +21,13 @@ #include <HalPwrSeqCmd.h> #include <Hal8723PwrSeq.h> #include <rtl8723a_hal.h> -#include <rtl8723a_led.h> #include <linux/ieee80211.h> #include <usb_ops.h> +static void phy_SsPwrSwitch92CU(struct rtw_adapter *Adapter, + enum rt_rf_power_state eRFPowerState); + static void _ConfigChipOutEP(struct rtw_adapter *pAdapter, u8 NumOutPipe) { @@ -61,42 +63,28 @@ _ConfigChipOutEP(struct rtw_adapter *pAdapter, u8 NumOutPipe) (u32)NumOutPipe, (u32)pHalData->OutEpNumber)); */ } -static bool rtl8723au_set_queue_pipe_mapping(struct rtw_adapter *pAdapter, - u8 NumInPipe, u8 NumOutPipe) +bool rtl8723au_chip_configure(struct rtw_adapter *padapter) { - struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); - bool result = false; + struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + u8 NumInPipe = pdvobjpriv->RtNumInPipes; + u8 NumOutPipe = pdvobjpriv->RtNumOutPipes; - _ConfigChipOutEP(pAdapter, NumOutPipe); + _ConfigChipOutEP(padapter, NumOutPipe); /* Normal chip with one IN and one OUT doesn't have interrupt IN EP. */ if (pHalData->OutEpNumber == 1) { if (NumInPipe != 1) - return result; + return false; } - result = Hal_MappingOutPipe23a(pAdapter, NumOutPipe); - - return result; -} - -void rtl8723au_chip_configure(struct rtw_adapter *padapter) -{ - struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); - struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); - - pHalData->interfaceIndex = pdvobjpriv->InterfaceNumber; - - rtl8723au_set_queue_pipe_mapping(padapter, - pdvobjpriv->RtNumInPipes, - pdvobjpriv->RtNumOutPipes); + return Hal_MappingOutPipe23a(padapter, NumOutPipe); } static int _InitPowerOn(struct rtw_adapter *padapter) { - int status = _SUCCESS; - u16 value16 = 0; - u8 value8 = 0; + u16 value16; + u8 value8; /* RSV_CTRL 0x1C[7:0] = 0x00 unlock ISO/CLK/Power control register */ @@ -123,7 +111,7 @@ static int _InitPowerOn(struct rtw_adapter *padapter) /* for Efuse PG, suggest by Jackie 2011.11.23 */ PHY_SetBBReg(padapter, REG_EFUSE_CTRL, BIT(28)|BIT(29)|BIT(30), 0x06); - return status; + return _SUCCESS; } /* Shall USB interface init this? */ @@ -313,7 +301,7 @@ static void _InitNormalChipThreeOutEpPriority(struct rtw_adapter *Adapter) _InitNormalChipRegPriority(Adapter, beQ, bkQ, viQ, voQ, mgtQ, hiQ); } -static void _InitNormalChipQueuePriority(struct rtw_adapter *Adapter) +static void _InitQueuePriority(struct rtw_adapter *Adapter) { struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); @@ -333,11 +321,6 @@ static void _InitNormalChipQueuePriority(struct rtw_adapter *Adapter) } } -static void _InitQueuePriority(struct rtw_adapter *Adapter) -{ - _InitNormalChipQueuePriority(Adapter); -} - static void _InitTransferPageSize(struct rtw_adapter *Adapter) { /* Tx page size is always 128. */ @@ -442,18 +425,6 @@ static void _InitEDCA(struct rtw_adapter *Adapter) rtl8723au_write32(Adapter, REG_EDCA_VO_PARAM, 0x002FA226); } -static void _InitHWLed(struct rtw_adapter *Adapter) -{ - struct led_priv *pledpriv = &Adapter->ledpriv; - - if (pledpriv->LedStrategy != HW_LED) - return; - -/* HW led control */ -/* to do .... */ -/* must consider cases of antenna diversity/ commbo card/solo card/mini card */ -} - static void _InitRDGSetting(struct rtw_adapter *Adapter) { rtl8723au_write8(Adapter, REG_RD_CTRL, 0xFF); @@ -480,7 +451,7 @@ static void _InitRFType(struct rtw_adapter *Adapter) pHalData->rf_chip = RF_6052; - if (is92CU == false) { + if (!is92CU) { pHalData->rf_type = RF_1T1R; DBG_8723A("Set RF Chip ID to RF_6052 and RF type to 1T1R.\n"); return; @@ -527,23 +498,22 @@ enum rt_rf_power_state RfOnOffDetect23a(struct rtw_adapter *pAdapter) return rfpowerstate; } -void _ps_open_RF23a(struct rtw_adapter *padapter); - int rtl8723au_hal_init(struct rtw_adapter *Adapter) { - u8 val8 = 0; - u32 boundary; - int status = _SUCCESS; struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv; struct registry_priv *pregistrypriv = &Adapter->registrypriv; + u8 val8 = 0; + u32 boundary; + int status = _SUCCESS; + bool mac_on; unsigned long init_start_time = jiffies; Adapter->hw_init_completed = false; if (Adapter->pwrctrlpriv.bkeepfwalive) { - _ps_open_RF23a(Adapter); + phy_SsPwrSwitch92CU(Adapter, rf_on); if (pHalData->bIQKInitialized) { rtl8723a_phy_iq_calibrate(Adapter, true); @@ -566,9 +536,9 @@ int rtl8723au_hal_init(struct rtw_adapter *Adapter) /* 0x100 value of first mac is 0xEA while 0x100 value of secondary is 0x00 */ if (val8 == 0xEA) { - pHalData->bMACFuncEnable = false; + mac_on = false; } else { - pHalData->bMACFuncEnable = true; + mac_on = true; RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("%s: MAC has already power on\n", __func__)); } @@ -587,7 +557,7 @@ int rtl8723au_hal_init(struct rtw_adapter *Adapter) boundary = WMM_NORMAL_TX_PAGE_BOUNDARY; } - if (!pHalData->bMACFuncEnable) { + if (!mac_on) { status = InitLLTTable23a(Adapter, boundary); if (status == _FAIL) { RT_TRACE(_module_hci_hal_init_c_, _drv_err_, @@ -673,7 +643,7 @@ int rtl8723au_hal_init(struct rtw_adapter *Adapter) pHalData->RfRegChnlVal[0] = PHY_QueryRFReg(Adapter, (enum RF_RADIO_PATH)0, RF_CHNLBW, bRFRegOffsetMask); pHalData->RfRegChnlVal[1] = PHY_QueryRFReg(Adapter, (enum RF_RADIO_PATH)1, RF_CHNLBW, bRFRegOffsetMask); - if (!pHalData->bMACFuncEnable) { + if (!mac_on) { _InitQueueReservedPage(Adapter); _InitTxBufferBoundary(Adapter); } @@ -694,8 +664,6 @@ int rtl8723au_hal_init(struct rtw_adapter *Adapter) _InitRetryFunction(Adapter); rtl8723a_InitBeaconParameters(Adapter); - _InitHWLed(Adapter); - _BBTurnOnBlock(Adapter); /* NicIFSetMacAddress(padapter, padapter->PermanentAddress); */ @@ -806,266 +774,108 @@ exit: } static void phy_SsPwrSwitch92CU(struct rtw_adapter *Adapter, - enum rt_rf_power_state eRFPowerState, - int bRegSSPwrLvl) + enum rt_rf_power_state eRFPowerState) { struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); - u8 value8; - u8 bytetmp; + u8 sps0; + + sps0 = rtl8723au_read8(Adapter, REG_SPS0_CTRL); switch (eRFPowerState) { case rf_on: - if (bRegSSPwrLvl == 1) { - /* 1. Enable MAC Clock. Can not be enabled now. */ - /* WriteXBYTE(REG_SYS_CLKR+1, - ReadXBYTE(REG_SYS_CLKR+1) | BIT(3)); */ - - /* 2. Force PWM, Enable SPS18_LDO_Marco_Block */ - rtl8723au_write8(Adapter, REG_SPS0_CTRL, - rtl8723au_read8(Adapter, REG_SPS0_CTRL) | - BIT(0) | BIT(3)); - - /* 3. restore BB, AFE control register. */ - /* RF */ - if (pHalData->rf_type == RF_2T2R) - PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, - 0x380038, 1); - else - PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, - 0x38, 1); - PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 1); - PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(1), 0); - - /* AFE */ - if (pHalData->rf_type == RF_2T2R) - PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord, - 0x63DB25A0); - else if (pHalData->rf_type == RF_1T1R) - PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord, - 0x631B25A0); - - /* 4. issue 3-wire command that RF set to Rx idle - mode. This is used to re-write the RX idle mode. */ - /* We can only prvide a usual value instead and then - HW will modify the value by itself. */ - PHY_SetRFReg(Adapter, RF_PATH_A, 0, - bRFRegOffsetMask, 0x32D95); - if (pHalData->rf_type == RF_2T2R) { - PHY_SetRFReg(Adapter, RF_PATH_B, 0, - bRFRegOffsetMask, 0x32D95); - } - } else { /* Level 2 or others. */ - /* h. AFE_PLL_CTRL 0x28[7:0] = 0x80 - disable AFE PLL */ - rtl8723au_write8(Adapter, REG_AFE_PLL_CTRL, 0x81); - - /* i. AFE_XTAL_CTRL 0x24[15:0] = 0x880F - gated AFE DIG_CLOCK */ - rtl8723au_write16(Adapter, REG_AFE_XTAL_CTRL, 0x800F); - mdelay(1); - - /* 2. Force PWM, Enable SPS18_LDO_Marco_Block */ - rtl8723au_write8(Adapter, REG_SPS0_CTRL, - rtl8723au_read8(Adapter, REG_SPS0_CTRL) | - BIT(0) | BIT(3)); - - /* 3. restore BB, AFE control register. */ - /* RF */ - if (pHalData->rf_type == RF_2T2R) - PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, - 0x380038, 1); - else - PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, - 0x38, 1); - PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 1); - PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(1), 0); - - /* AFE */ - if (pHalData->rf_type == RF_2T2R) - PHY_SetBBReg(Adapter, rRx_Wait_CCA, - bMaskDWord, 0x63DB25A0); - else if (pHalData->rf_type == RF_1T1R) - PHY_SetBBReg(Adapter, rRx_Wait_CCA, - bMaskDWord, 0x631B25A0); - - /* 4. issue 3-wire command that RF set to Rx idle - mode. This is used to re-write the RX idle mode. */ - /* We can only prvide a usual value instead and - then HW will modify the value by itself. */ - PHY_SetRFReg(Adapter, RF_PATH_A, 0, + /* 1. Enable MAC Clock. Can not be enabled now. */ + /* WriteXBYTE(REG_SYS_CLKR+1, + ReadXBYTE(REG_SYS_CLKR+1) | BIT(3)); */ + + /* 2. Force PWM, Enable SPS18_LDO_Marco_Block */ + rtl8723au_write8(Adapter, REG_SPS0_CTRL, + sps0 | BIT(0) | BIT(3)); + + /* 3. restore BB, AFE control register. */ + /* RF */ + if (pHalData->rf_type == RF_2T2R) + PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, + 0x380038, 1); + else + PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, + 0x38, 1); + PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 1); + PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(1), 0); + + /* AFE */ + if (pHalData->rf_type == RF_2T2R) + PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord, + 0x63DB25A0); + else if (pHalData->rf_type == RF_1T1R) + PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord, + 0x631B25A0); + + /* 4. issue 3-wire command that RF set to Rx idle + mode. This is used to re-write the RX idle mode. */ + /* We can only prvide a usual value instead and then + HW will modify the value by itself. */ + PHY_SetRFReg(Adapter, RF_PATH_A, 0, bRFRegOffsetMask, 0x32D95); + if (pHalData->rf_type == RF_2T2R) { + PHY_SetRFReg(Adapter, RF_PATH_B, 0, bRFRegOffsetMask, 0x32D95); - if (pHalData->rf_type == RF_2T2R) { - PHY_SetRFReg(Adapter, RF_PATH_B, 0, - bRFRegOffsetMask, 0x32D95); - } - - /* 5. gated MAC Clock */ - bytetmp = rtl8723au_read8(Adapter, REG_APSD_CTRL); - rtl8723au_write8(Adapter, REG_APSD_CTRL, - bytetmp & ~BIT(6)); - - mdelay(10); - - /* Set BB reset at first */ - /* 0x16 */ - rtl8723au_write8(Adapter, REG_SYS_FUNC_EN, 0x17); - - /* Enable TX */ - rtl8723au_write8(Adapter, REG_TXPAUSE, 0x0); } break; case rf_sleep: case rf_off: - value8 = rtl8723au_read8(Adapter, REG_SPS0_CTRL); if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID)) - value8 &= ~BIT(0); + sps0 &= ~BIT(0); else - value8 &= ~(BIT(0) | BIT(3)); - if (bRegSSPwrLvl == 1) { - RT_TRACE(_module_hal_init_c_, _drv_err_, ("SS LVL1\n")); - /* Disable RF and BB only for SelectSuspend. */ - - /* 1. Set BB/RF to shutdown. */ - /* (1) Reg878[5:3]= 0 RF rx_code for - preamble power saving */ - /* (2)Reg878[21:19]= 0 Turn off RF-B */ - /* (3) RegC04[7:4]= 0 Turn off all paths - for packet detection */ - /* (4) Reg800[1] = 1 enable preamble power - saving */ - Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF0] = - PHY_QueryBBReg(Adapter, rFPGA0_XAB_RFParameter, - bMaskDWord); - Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF1] = - PHY_QueryBBReg(Adapter, rOFDM0_TRxPathEnable, - bMaskDWord); - Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF2] = - PHY_QueryBBReg(Adapter, rFPGA0_RFMOD, - bMaskDWord); - if (pHalData->rf_type == RF_2T2R) { - PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, - 0x380038, 0); - } else if (pHalData->rf_type == RF_1T1R) { - PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, - 0x38, 0); - } - PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 0); - PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(1), 1); - - /* 2 .AFE control register to power down. bit[30:22] */ - Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_AFE0] = - PHY_QueryBBReg(Adapter, rRx_Wait_CCA, - bMaskDWord); - if (pHalData->rf_type == RF_2T2R) - PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord, - 0x00DB25A0); - else if (pHalData->rf_type == RF_1T1R) - PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord, - 0x001B25A0); - - /* 3. issue 3-wire command that RF set to power down.*/ - PHY_SetRFReg(Adapter, RF_PATH_A, 0, bRFRegOffsetMask, 0); - if (pHalData->rf_type == RF_2T2R) - PHY_SetRFReg(Adapter, RF_PATH_B, 0, - bRFRegOffsetMask, 0); - - /* 4. Force PFM , disable SPS18_LDO_Marco_Block */ - rtl8723au_write8(Adapter, REG_SPS0_CTRL, value8); - } else { /* Level 2 or others. */ - RT_TRACE(_module_hal_init_c_, _drv_err_, ("SS LVL2\n")); - { - u8 eRFPath = RF_PATH_A, value8 = 0; - rtl8723au_write8(Adapter, REG_TXPAUSE, 0xFF); - PHY_SetRFReg(Adapter, - (enum RF_RADIO_PATH)eRFPath, - 0x0, bMaskByte0, 0x0); - value8 |= APSDOFF; - /* 0x40 */ - rtl8723au_write8(Adapter, REG_APSD_CTRL, - value8); - - /* After switch APSD, we need to delay - for stability */ - mdelay(10); - - /* Set BB reset at first */ - value8 = 0; - value8 |= (FEN_USBD | FEN_USBA | - FEN_BB_GLB_RSTn); - /* 0x16 */ - rtl8723au_write8(Adapter, REG_SYS_FUNC_EN, - value8); - } - - /* Disable RF and BB only for SelectSuspend. */ - - /* 1. Set BB/RF to shutdown. */ - /* (1) Reg878[5:3]= 0 RF rx_code for - preamble power saving */ - /* (2)Reg878[21:19]= 0 Turn off RF-B */ - /* (3) RegC04[7:4]= 0 Turn off all paths for - packet detection */ - /* (4) Reg800[1] = 1 enable preamble power - saving */ - Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF0] = - PHY_QueryBBReg(Adapter, rFPGA0_XAB_RFParameter, - bMaskDWord); - Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF1] = - PHY_QueryBBReg(Adapter, rOFDM0_TRxPathEnable, - bMaskDWord); - Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF2] = - PHY_QueryBBReg(Adapter, rFPGA0_RFMOD, - bMaskDWord); - if (pHalData->rf_type == RF_2T2R) - PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, - 0x380038, 0); - else if (pHalData->rf_type == RF_1T1R) - PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, - 0x38, 0); - PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 0); - PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(1), 1); - - /* 2 .AFE control register to power down. bit[30:22] */ - Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_AFE0] = - PHY_QueryBBReg(Adapter, rRx_Wait_CCA, - bMaskDWord); - if (pHalData->rf_type == RF_2T2R) - PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord, - 0x00DB25A0); - else if (pHalData->rf_type == RF_1T1R) - PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord, - 0x001B25A0); - - /* 3. issue 3-wire command that RF set to power down. */ - PHY_SetRFReg(Adapter, RF_PATH_A, 0, bRFRegOffsetMask, 0); - if (pHalData->rf_type == RF_2T2R) - PHY_SetRFReg(Adapter, RF_PATH_B, 0, - bRFRegOffsetMask, 0); - - /* 4. Force PFM , disable SPS18_LDO_Marco_Block */ - rtl8723au_write8(Adapter, REG_SPS0_CTRL, value8); - - /* 2010/10/13 MH/Isaachsu exchange sequence. */ - /* h. AFE_PLL_CTRL 0x28[7:0] = 0x80 - disable AFE PLL */ - rtl8723au_write8(Adapter, REG_AFE_PLL_CTRL, 0x80); - mdelay(1); - - /* i. AFE_XTAL_CTRL 0x24[15:0] = 0x880F - gated AFE DIG_CLOCK */ - rtl8723au_write16(Adapter, REG_AFE_XTAL_CTRL, 0xA80F); + sps0 &= ~(BIT(0) | BIT(3)); + + RT_TRACE(_module_hal_init_c_, _drv_err_, ("SS LVL1\n")); + /* Disable RF and BB only for SelectSuspend. */ + + /* 1. Set BB/RF to shutdown. */ + /* (1) Reg878[5:3]= 0 RF rx_code for + preamble power saving */ + /* (2)Reg878[21:19]= 0 Turn off RF-B */ + /* (3) RegC04[7:4]= 0 Turn off all paths + for packet detection */ + /* (4) Reg800[1] = 1 enable preamble power saving */ + Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF0] = + PHY_QueryBBReg(Adapter, rFPGA0_XAB_RFParameter, + bMaskDWord); + Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF1] = + PHY_QueryBBReg(Adapter, rOFDM0_TRxPathEnable, + bMaskDWord); + Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF2] = + PHY_QueryBBReg(Adapter, rFPGA0_RFMOD, bMaskDWord); + if (pHalData->rf_type == RF_2T2R) { + PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, + 0x380038, 0); + } else if (pHalData->rf_type == RF_1T1R) { + PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, 0x38, 0); } + PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 0); + PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(1), 1); + + /* 2 .AFE control register to power down. bit[30:22] */ + Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_AFE0] = + PHY_QueryBBReg(Adapter, rRx_Wait_CCA, bMaskDWord); + if (pHalData->rf_type == RF_2T2R) + PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord, + 0x00DB25A0); + else if (pHalData->rf_type == RF_1T1R) + PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord, + 0x001B25A0); + + /* 3. issue 3-wire command that RF set to power down.*/ + PHY_SetRFReg(Adapter, RF_PATH_A, 0, bRFRegOffsetMask, 0); + if (pHalData->rf_type == RF_2T2R) + PHY_SetRFReg(Adapter, RF_PATH_B, 0, + bRFRegOffsetMask, 0); + + /* 4. Force PFM , disable SPS18_LDO_Marco_Block */ + rtl8723au_write8(Adapter, REG_SPS0_CTRL, sps0); break; default: break; } - -} /* phy_PowerSwitch92CU */ - -void _ps_open_RF23a(struct rtw_adapter *padapter) -{ - /* here call with bRegSSPwrLvl 1, bRegSSPwrLvl 2 needs to be verified */ - phy_SsPwrSwitch92CU(padapter, rf_on, 1); } static void CardDisableRTL8723U(struct rtw_adapter *Adapter) @@ -1142,8 +952,7 @@ int rtl8723au_inirp_init(struct rtw_adapter *Adapter) /* issue Rx irp to receive data */ precvbuf = (struct recv_buf *)precvpriv->precv_buf; for (i = 0; i < NR_RECVBUFF; i++) { - if (rtl8723au_read_port(Adapter, RECV_BULK_IN_ADDR, 0, - precvbuf) == _FAIL) { + if (rtl8723au_read_port(Adapter, 0, precvbuf) == _FAIL) { RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("usb_rx_init: usb_read_port error\n")); status = _FAIL; @@ -1151,9 +960,9 @@ int rtl8723au_inirp_init(struct rtw_adapter *Adapter) } precvbuf++; } - if (rtl8723au_read_interrupt(Adapter, RECV_INT_IN_ADDR) == _FAIL) { + if (rtl8723au_read_interrupt(Adapter) == _FAIL) { RT_TRACE(_module_hci_hal_init_c_, _drv_err_, - ("usb_rx_init: usb_read_interrupt error\n")); + ("%s: usb_read_interrupt error\n", __func__)); status = _FAIL; } pHalData->IntrMask[0] = rtl8723au_read32(Adapter, REG_USB_HIMR); @@ -1209,14 +1018,6 @@ static void _ReadBoardType(struct rtw_adapter *Adapter, u8 *PROMContent, pHalData->ExternalPA = 1; } -static void _ReadLEDSetting(struct rtw_adapter *Adapter, u8 *PROMContent, - bool AutoloadFail) -{ - struct led_priv *pledpriv = &Adapter->ledpriv; - - pledpriv->LedStrategy = HW_LED; -} - static void Hal_EfuseParseMACAddr_8723AU(struct rtw_adapter *padapter, u8 *hwinfo, bool AutoLoadFail) { @@ -1263,7 +1064,6 @@ static void readAdapterInfo(struct rtw_adapter *padapter) pEEPROM->bautoload_fail_flag); Hal_EfuseParseThermalMeter_8723A(padapter, hwinfo, pEEPROM->bautoload_fail_flag); - _ReadLEDSetting(padapter, hwinfo, pEEPROM->bautoload_fail_flag); /* _ReadRFSetting(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); */ /* _ReadPSSetting(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); */ Hal_EfuseParseAntennaDiversity(padapter, hwinfo, @@ -1276,10 +1076,6 @@ static void readAdapterInfo(struct rtw_adapter *padapter) pEEPROM->bautoload_fail_flag); Hal_EfuseParseXtal_8723A(padapter, hwinfo, pEEPROM->bautoload_fail_flag); - /* */ - /* The following part initialize some vars by PG info. */ - /* */ - Hal_InitChannelPlan23a(padapter); /* hal_CustomizedBehavior_8723U(Adapter); */ @@ -1311,13 +1107,6 @@ static void _ReadRFType(struct rtw_adapter *Adapter) pHalData->rf_chip = RF_6052; } -static void _ReadSilmComboMode(struct rtw_adapter *Adapter) -{ - struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); - - pHalData->SlimComboDbg = false; /* Default is not debug mode. */ -} - /* */ /* Description: */ /* We should set Efuse cell selection to WiFi cell in default. */ @@ -1350,10 +1139,6 @@ void rtl8723a_read_adapter_info(struct rtw_adapter *Adapter) _ReadRFType(Adapter);/* rf_chip -> _InitRFType() */ _ReadPROMContent(Adapter); - /* 2010/10/25 MH THe function must be called after - borad_type & IC-Version recognize. */ - _ReadSilmComboMode(Adapter); - /* MSG_8723A("%s()(done), rf_chip = 0x%x, rf_type = 0x%x\n", __func__, pHalData->rf_chip, pHalData->rf_type); */ @@ -1417,17 +1202,17 @@ int GetHalDefVar8192CUsb(struct rtw_adapter *Adapter, void rtl8723a_update_ramask(struct rtw_adapter *padapter, u32 mac_id, u8 rssi_level) { - u8 init_rate = 0; - u8 networkType, raid; - u32 mask, rate_bitmap; - u8 shortGIrate = false; - int supportRateNum = 0; struct sta_info *psta; - struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); - struct dm_priv *pdmpriv = &pHalData->dmpriv; + struct FW_Sta_Info *fw_sta; + struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; + u8 init_rate, networkType, raid; + u32 mask, rate_bitmap; + u8 shortGIrate = false; + int supportRateNum; if (mac_id >= NUM_STA) /* CAM_SIZE */ return; @@ -1456,8 +1241,8 @@ void rtl8723a_update_ramask(struct rtw_adapter *padapter, break; case 1:/* for broadcast/multicast */ - supportRateNum = rtw_get_rateset_len23a( - pmlmeinfo->FW_sta_info[mac_id].SupportedRates); + fw_sta = &pmlmeinfo->FW_sta_info[mac_id]; + supportRateNum = rtw_get_rateset_len23a(fw_sta->SupportedRates); if (pmlmeext->cur_wireless_mode & WIRELESS_11B) networkType = WIRELESS_11B; else @@ -1469,23 +1254,22 @@ void rtl8723a_update_ramask(struct rtw_adapter *padapter, break; default: /* for each sta in IBSS */ - supportRateNum = rtw_get_rateset_len23a( - pmlmeinfo->FW_sta_info[mac_id].SupportedRates); + fw_sta = &pmlmeinfo->FW_sta_info[mac_id]; + supportRateNum = rtw_get_rateset_len23a(fw_sta->SupportedRates); networkType = judge_network_type23a(padapter, - pmlmeinfo->FW_sta_info[mac_id].SupportedRates, - supportRateNum) & 0xf; + fw_sta->SupportedRates, + supportRateNum) & 0xf; /* pmlmeext->cur_wireless_mode = networkType; */ raid = networktype_to_raid23a(networkType); mask = update_supported_rate23a(cur_network->SupportedRates, - supportRateNum); + supportRateNum); /* todo: support HT in IBSS */ break; } /* mask &= 0x0fffffff; */ - rate_bitmap = 0x0fffffff; rate_bitmap = ODM_Get_Rate_Bitmap23a(pHalData, mac_id, mask, rssi_level); DBG_8723A("%s => mac_id:%d, networkType:0x%02x, " @@ -1493,15 +1277,14 @@ void rtl8723a_update_ramask(struct rtw_adapter *padapter, __func__, mac_id, networkType, mask, rssi_level, rate_bitmap); mask &= rate_bitmap; - mask |= ((raid<<28)&0xf0000000); + mask |= ((raid << 28) & 0xf0000000); - init_rate = get_highest_rate_idx23a(mask)&0x3f; + init_rate = get_highest_rate_idx23a(mask) & 0x3f; if (pHalData->fw_ractrl == true) { u8 arg = 0; - /* arg = (cam_idx-4)&0x1f;MACID */ - arg = mac_id&0x1f;/* MACID */ + arg = mac_id & 0x1f;/* MACID */ arg |= BIT(7); @@ -1516,7 +1299,7 @@ void rtl8723a_update_ramask(struct rtw_adapter *padapter, if (shortGIrate == true) init_rate |= BIT(6); - rtl8723au_write8(padapter, (REG_INIDATA_RATE_SEL+mac_id), + rtl8723au_write8(padapter, (REG_INIDATA_RATE_SEL + mac_id), init_rate); } diff --git a/drivers/staging/rtl8723au/hal/usb_ops_linux.c b/drivers/staging/rtl8723au/hal/usb_ops_linux.c index c1b04c13c392..a6d16adce107 100644 --- a/drivers/staging/rtl8723au/hal/usb_ops_linux.c +++ b/drivers/staging/rtl8723au/hal/usb_ops_linux.c @@ -317,7 +317,7 @@ urb_submit: } } -int rtl8723au_read_interrupt(struct rtw_adapter *adapter, u32 addr) +int rtl8723au_read_interrupt(struct rtw_adapter *adapter) { int err; unsigned int pipe; @@ -545,8 +545,7 @@ static void usb_read_port_complete(struct urb *purb) ("usb_read_port_complete: (purb->actual_" "length > MAX_RECVBUF_SZ) || (purb->actual_" "length < RXDESC_SIZE)\n")); - rtl8723au_read_port(padapter, RECV_BULK_IN_ADDR, 0, - precvbuf); + rtl8723au_read_port(padapter, 0, precvbuf); DBG_8723A("%s()-%d: RX Warning!\n", __func__, __LINE__); } else { @@ -561,8 +560,7 @@ static void usb_read_port_complete(struct urb *purb) tasklet_schedule(&precvpriv->recv_tasklet); precvbuf->pskb = NULL; - rtl8723au_read_port(padapter, RECV_BULK_IN_ADDR, 0, - precvbuf); + rtl8723au_read_port(padapter, 0, precvbuf); } } else { RT_TRACE(_module_hci_ops_os_c_, _drv_err_, @@ -596,8 +594,7 @@ static void usb_read_port_complete(struct urb *purb) break; case -EPROTO: case -EOVERFLOW: - rtl8723au_read_port(padapter, RECV_BULK_IN_ADDR, 0, - precvbuf); + rtl8723au_read_port(padapter, 0, precvbuf); break; case -EINPROGRESS: DBG_8723A("ERROR: URB IS IN PROGRESS!\n"); @@ -608,18 +605,18 @@ static void usb_read_port_complete(struct urb *purb) } } -int rtl8723au_read_port(struct rtw_adapter *adapter, u32 addr, u32 cnt, +int rtl8723au_read_port(struct rtw_adapter *adapter, u32 cnt, struct recv_buf *precvbuf) { + struct urb *purb; + struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter); + struct recv_priv *precvpriv = &adapter->recvpriv; + struct usb_device *pusbd = pdvobj->pusbdev; int err; unsigned int pipe; unsigned long tmpaddr; unsigned long alignment; int ret = _SUCCESS; - struct urb *purb; - struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter); - struct recv_priv *precvpriv = &adapter->recvpriv; - struct usb_device *pusbd = pdvobj->pusbdev; if (adapter->bDriverStopped || adapter->bSurpriseRemoved) { RT_TRACE(_module_hci_ops_os_c_, _drv_err_, diff --git a/drivers/staging/rtl8723au/include/Hal8723UHWImg_CE.h b/drivers/staging/rtl8723au/include/Hal8723UHWImg_CE.h index bbeaab48057a..c834b3a738d7 100644 --- a/drivers/staging/rtl8723au/include/Hal8723UHWImg_CE.h +++ b/drivers/staging/rtl8723au/include/Hal8723UHWImg_CE.h @@ -19,7 +19,7 @@ extern u8 Rtl8723UFwUMCBCutImgArrayWithoutBT[Rtl8723UUMCBCutImgArrayWithoutBTLen extern const u8 Rtl8723SFwUMCBCutMPImgArray[Rtl8723SUMCBCutMPImgArrayLength]; #define Rtl8723EBTImgArrayLength 15276 -extern u8 Rtl8723EFwBTImgArray[Rtl8723EBTImgArrayLength] ; +extern u8 Rtl8723EFwBTImgArray[Rtl8723EBTImgArrayLength]; #define Rtl8723UPHY_REG_Array_PGLength 336 extern u32 Rtl8723UPHY_REG_Array_PG[Rtl8723UPHY_REG_Array_PGLength]; diff --git a/drivers/staging/rtl8723au/include/drv_types.h b/drivers/staging/rtl8723au/include/drv_types.h index 9870f87bdc70..e83463aeb9b1 100644 --- a/drivers/staging/rtl8723au/include/drv_types.h +++ b/drivers/staging/rtl8723au/include/drv_types.h @@ -51,7 +51,6 @@ enum _NIC_VERSION { #include <rtw_debug.h> #include <rtw_rf.h> #include <rtw_event.h> -#include <rtw_led.h> #include <rtw_mlme_ext.h> #include <rtw_ap.h> @@ -228,7 +227,6 @@ struct rtw_adapter { struct registry_priv registrypriv; struct pwrctrl_priv pwrctrlpriv; struct eeprom_priv eeprompriv; - struct led_priv ledpriv; u32 setband; diff --git a/drivers/staging/rtl8723au/include/odm_debug.h b/drivers/staging/rtl8723au/include/odm_debug.h index 4d935a33ccb3..83be5bab9e09 100644 --- a/drivers/staging/rtl8723au/include/odm_debug.h +++ b/drivers/staging/rtl8723au/include/odm_debug.h @@ -91,8 +91,7 @@ #define ODM_COMP_INIT BIT(31) /*------------------------Export Macro Definition---------------------------*/ - #define DbgPrint printk - #define RT_PRINTK(fmt, args...) DbgPrint("%s(): " fmt, __func__, ## args); + #define RT_PRINTK(fmt, args...) printk("%s(): " fmt, __func__, ## args); #ifndef ASSERT #define ASSERT(expr) @@ -101,38 +100,17 @@ #define ODM_RT_TRACE(pDM_Odm, comp, level, fmt) \ if(((comp) & pDM_Odm->DebugComponents) && (level <= pDM_Odm->DebugLevel)) \ { \ - DbgPrint("[ODM-8723A] "); \ - RT_PRINTK fmt; \ - } - -#define ODM_RT_TRACE_F(pDM_Odm, comp, level, fmt) \ - if(((comp) & pDM_Odm->DebugComponents) && (level <= pDM_Odm->DebugLevel)) \ - { \ + printk("[ODM-8723A] "); \ RT_PRINTK fmt; \ } #define ODM_RT_ASSERT(pDM_Odm, expr, fmt) \ if(!(expr)) { \ - DbgPrint("Assertion failed! %s at ......\n", #expr); \ - DbgPrint(" ......%s,%s,line=%d\n", __FILE__, __func__, __LINE__);\ + printk("Assertion failed! %s at ......\n", #expr); \ + printk(" ......%s,%s,line=%d\n", __FILE__, __func__, __LINE__);\ RT_PRINTK fmt; \ ASSERT(false); \ } -#define ODM_dbg_enter() { DbgPrint("==> %s\n", __func__); } -#define ODM_dbg_exit() { DbgPrint("<== %s\n", __func__); } -#define ODM_dbg_trace(str) { DbgPrint("%s:%s\n", __func__, str); } - -#define ODM_PRINT_ADDR(pDM_Odm, comp, level, title_str, ptr) \ - if(((comp) & pDM_Odm->DebugComponents) && (level <= pDM_Odm->DebugLevel){ \ - int __i; \ - u8 * __ptr = (u8 *)ptr; \ - DbgPrint("[ODM] "); \ - DbgPrint(title_str); \ - DbgPrint(" "); \ - for (__i=0; __i < 6; __i++) \ - DbgPrint("%02X%s", __ptr[__i], (__i == 5) ? "" : "-"); \ - DbgPrint("\n"); \ - } void ODM_InitDebugSetting23a(struct dm_odm_t *pDM_Odm); diff --git a/drivers/staging/rtl8723au/include/rtl8723a_dm.h b/drivers/staging/rtl8723au/include/rtl8723a_dm.h index 18112225e53f..bf236e8e47a2 100644 --- a/drivers/staging/rtl8723au/include/rtl8723a_dm.h +++ b/drivers/staging/rtl8723au/include/rtl8723a_dm.h @@ -37,8 +37,7 @@ enum{ #define IQK_BB_REG_NUM 9 #define HP_THERMAL_NUM 8 /* duplicate code,will move to ODM ######### */ -struct dm_priv -{ +struct dm_priv { u32 InitODMFlag; /* Upper and Lower Signal threshold for Rate Adaptive*/ diff --git a/drivers/staging/rtl8723au/include/rtl8723a_hal.h b/drivers/staging/rtl8723au/include/rtl8723a_hal.h index ee203a572cb7..e14633678b52 100644 --- a/drivers/staging/rtl8723au/include/rtl8723a_hal.h +++ b/drivers/staging/rtl8723au/include/rtl8723a_hal.h @@ -372,16 +372,9 @@ struct hal_data_8723a { /* 2010/08/09 MH Add CU power down mode. */ u8 pwrdown; - /* Add for dual MAC 0--Mac0 1--Mac1 */ - u32 interfaceIndex; - u8 OutEpQueueSel; u8 OutEpNumber; - /* 2010/11/22 MH Add for slim combo debug mode selective. */ - /* This is used for fix the drawback of CU TSMC-A/UMC-A cut. HW auto suspend ability. Close BT clock. */ - bool SlimComboDbg; - /* */ /* Add For EEPROM Efuse switch and Efuse Shadow map Setting */ /* */ @@ -405,8 +398,6 @@ struct hal_data_8723a { * 2011/02/23 MH Add for 8723 mylti function definition. The define should be moved to an */ /* independent file in the future. */ - bool bMACFuncEnable; - /* Interrupt related register information. */ u32 IntArray[2]; u32 IntrMask[2]; @@ -518,8 +509,6 @@ void Hal_EfuseParseRateIndicationOption(struct rtw_adapter *padapter, u8 *hwinfo void Hal_EfuseParseXtal_8723A(struct rtw_adapter *pAdapter, u8 *hwinfo, u8 AutoLoadFail); void Hal_EfuseParseThermalMeter_8723A(struct rtw_adapter *padapter, u8 *hwinfo, bool AutoLoadFail); -void Hal_InitChannelPlan23a(struct rtw_adapter *padapter); - /* register */ void SetBcnCtrlReg23a(struct rtw_adapter *padapter, u8 SetBits, u8 ClearBits); void rtl8723a_InitBeaconParameters(struct rtw_adapter *padapter); diff --git a/drivers/staging/rtl8723au/include/rtl8723a_led.h b/drivers/staging/rtl8723au/include/rtl8723a_led.h deleted file mode 100644 index 1623d186feb4..000000000000 --- a/drivers/staging/rtl8723au/include/rtl8723a_led.h +++ /dev/null @@ -1,30 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - ******************************************************************************/ -#ifndef __RTL8723A_LED_H__ -#define __RTL8723A_LED_H__ - -#include <osdep_service.h> -#include <drv_types.h> - - -/* */ -/* Interface to manipulate LED objects. */ -/* */ -void rtl8723au_InitSwLeds(struct rtw_adapter *padapter); -void rtl8723au_DeInitSwLeds(struct rtw_adapter *padapter); -void SwLedOn23a(struct rtw_adapter *padapter, struct led_8723a * pLed); -void SwLedOff23a(struct rtw_adapter *padapter, struct led_8723a * pLed); - -#endif diff --git a/drivers/staging/rtl8723au/include/rtl8723a_recv.h b/drivers/staging/rtl8723au/include/rtl8723a_recv.h index 885d4d3859f8..0177bbc1c1cf 100644 --- a/drivers/staging/rtl8723au/include/rtl8723a_recv.h +++ b/drivers/staging/rtl8723au/include/rtl8723a_recv.h @@ -28,15 +28,11 @@ #define MAX_RECVBUF_SZ 15360 /* 15k < 16k */ -#define RECV_BULK_IN_ADDR 0x80 -#define RECV_INT_IN_ADDR 0x81 - #define PHY_RSSI_SLID_WIN_MAX 100 #define PHY_LINKQUALITY_SLID_WIN_MAX 20 -struct phy_stat -{ +struct phy_stat { unsigned int phydw0; unsigned int phydw1; unsigned int phydw2; diff --git a/drivers/staging/rtl8723au/include/rtl8723a_xmit.h b/drivers/staging/rtl8723au/include/rtl8723a_xmit.h index 815560c6e1d7..7db29f40ab70 100644 --- a/drivers/staging/rtl8723au/include/rtl8723a_xmit.h +++ b/drivers/staging/rtl8723au/include/rtl8723a_xmit.h @@ -212,7 +212,6 @@ struct txrpt_ccx_8723a { #define txrpt_ccx_qtime_8723a(txrpt_ccx) ((txrpt_ccx)->ccx_qtime0+((txrpt_ccx)->ccx_qtime1<<8)) void handle_txrpt_ccx_8723a(struct rtw_adapter *adapter, void *buf); -void rtl8723a_update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem); void rtl8723a_fill_fake_txdesc(struct rtw_adapter *padapter, u8 *pDesc, u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull); int rtl8723au_hal_xmitframe_enqueue(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe); diff --git a/drivers/staging/rtl8723au/include/rtw_cmd.h b/drivers/staging/rtl8723au/include/rtw_cmd.h index ef67068a5fe3..71044107d13b 100644 --- a/drivers/staging/rtl8723au/include/rtw_cmd.h +++ b/drivers/staging/rtl8723au/include/rtw_cmd.h @@ -17,7 +17,6 @@ #include <wlan_bssdef.h> #include <rtw_rf.h> -#include <rtw_led.h> #define C2H_MEM_SZ (16*1024) @@ -450,8 +449,7 @@ struct getrfintfs_parm { u8 rfintfs; }; -struct Tx_Beacon_param -{ +struct Tx_Beacon_param { struct wlan_bssid_ex network; }; diff --git a/drivers/staging/rtl8723au/include/rtw_ht.h b/drivers/staging/rtl8723au/include/rtw_ht.h index cfc947daf08b..780eb8944118 100644 --- a/drivers/staging/rtl8723au/include/rtw_ht.h +++ b/drivers/staging/rtl8723au/include/rtw_ht.h @@ -19,8 +19,7 @@ #include "linux/ieee80211.h" #include "wifi.h" -struct ht_priv -{ +struct ht_priv { bool ht_option; bool ampdu_enable;/* for enable Tx A-MPDU */ /* u8 baddbareq_issued[16]; */ diff --git a/drivers/staging/rtl8723au/include/rtw_led.h b/drivers/staging/rtl8723au/include/rtw_led.h deleted file mode 100644 index c071da587efd..000000000000 --- a/drivers/staging/rtl8723au/include/rtw_led.h +++ /dev/null @@ -1,181 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - ******************************************************************************/ -#ifndef __RTW_LED_H_ -#define __RTW_LED_H_ - -#include <osdep_service.h> -#include <drv_types.h> - -#define MSECS(t) (HZ * ((t) / 1000) + (HZ * ((t) % 1000)) / 1000) - -#define LED_BLINK_NORMAL_INTERVAL 100 -#define LED_BLINK_SLOWLY_INTERVAL 200 -#define LED_BLINK_LONG_INTERVAL 400 - -#define LED_BLINK_NO_LINK_INTERVAL_ALPHA 1000 -#define LED_BLINK_LINK_INTERVAL_ALPHA 500 /* 500 */ -#define LED_BLINK_SCAN_INTERVAL_ALPHA 180 /* 150 */ -#define LED_BLINK_FASTER_INTERVAL_ALPHA 50 -#define LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA 5000 - -#define LED_BLINK_NORMAL_INTERVAL_NETTRONIX 100 -#define LED_BLINK_SLOWLY_INTERVAL_NETTRONIX 2000 - -#define LED_BLINK_SLOWLY_INTERVAL_PORNET 1000 -#define LED_BLINK_NORMAL_INTERVAL_PORNET 100 - -#define LED_BLINK_FAST_INTERVAL_BITLAND 30 - -/* 060403, rcnjko: Customized for AzWave. */ -#define LED_CM2_BLINK_ON_INTERVAL 250 -#define LED_CM2_BLINK_OFF_INTERVAL 4750 - -#define LED_CM8_BLINK_INTERVAL 500 /* for QMI */ -#define LED_CM8_BLINK_OFF_INTERVAL 3750 /* for QMI */ - -/* 080124, lanhsin: Customized for RunTop */ -#define LED_RunTop_BLINK_INTERVAL 300 - -/* 060421, rcnjko: Customized for Sercomm Printer Server case. */ -#define LED_CM3_BLINK_INTERVAL 1500 - -enum led_ctl_mode { - LED_CTL_POWER_ON = 1, - LED_CTL_LINK = 2, - LED_CTL_NO_LINK = 3, - LED_CTL_TX = 4, - LED_CTL_RX = 5, - LED_CTL_SITE_SURVEY = 6, - LED_CTL_POWER_OFF = 7, - LED_CTL_START_TO_LINK = 8, - LED_CTL_START_WPS = 9, - LED_CTL_STOP_WPS = 10, - LED_CTL_START_WPS_BOTTON = 11, /* added for runtop */ - LED_CTL_STOP_WPS_FAIL = 12, /* added for ALPHA */ - LED_CTL_STOP_WPS_FAIL_OVERLAP = 13, /* added for BELKIN */ - LED_CTL_CONNECTION_NO_TRANSFER = 14, -}; - -enum led_state_872x { - LED_UNKNOWN = 0, - RTW_LED_ON = 1, - RTW_LED_OFF = 2, - LED_BLINK_NORMAL = 3, - LED_BLINK_SLOWLY = 4, - LED_BLINK_POWER_ON = 5, - LED_BLINK_SCAN = 6, /* LED is blinking during scanning period, the # of times to blink is depend on time for scanning. */ - LED_BLINK_NO_LINK = 7, /* LED is blinking during no link state. */ - LED_BLINK_StartToBlink = 8,/* Customzied for Sercomm Printer Server case */ - LED_BLINK_TXRX = 9, - LED_BLINK_WPS = 10, /* LED is blinkg during WPS communication */ - LED_BLINK_WPS_STOP = 11, /* for ALPHA */ - LED_BLINK_WPS_STOP_OVERLAP = 12, /* for BELKIN */ - LED_BLINK_RUNTOP = 13, /* Customized for RunTop */ - LED_BLINK_CAMEO = 14, - LED_BLINK_XAVI = 15, - LED_BLINK_ALWAYS_ON = 16, -}; - -enum led_pin_8723a { - LED_PIN_NULL = 0, - LED_PIN_LED0 = 1, - LED_PIN_LED1 = 2, - LED_PIN_LED2 = 3, - LED_PIN_GPIO0 = 4, -}; - -struct led_8723a { - struct rtw_adapter *padapter; - - enum led_pin_8723a LedPin; /* Identify how to implement this SW led. */ - enum led_state_872x CurrLedState; /* Current LED state. */ - enum led_state_872x BlinkingLedState; /* Next state for blinking, either RTW_LED_ON or RTW_LED_OFF are. */ - - u8 bLedOn; /* true if LED is ON, false if LED is OFF. */ - - u8 bLedBlinkInProgress; /* true if it is blinking, false o.w.. */ - - u8 bLedWPSBlinkInProgress; - - u32 BlinkTimes; /* Number of times to toggle led state for blinking. */ - - struct timer_list BlinkTimer; /* Timer object for led blinking. */ - - u8 bSWLedCtrl; - - /* ALPHA, added by chiyoko, 20090106 */ - u8 bLedNoLinkBlinkInProgress; - u8 bLedLinkBlinkInProgress; - u8 bLedStartToLinkBlinkInProgress; - u8 bLedScanBlinkInProgress; - - struct work_struct BlinkWorkItem; /* Workitem used by BlinkTimer to manipulate H/W to blink LED. */ -}; - -#define IS_LED_WPS_BLINKING(_LED_871x) (((struct led_8723a *)_LED_871x)->CurrLedState==LED_BLINK_WPS \ - || ((struct led_8723a *)_LED_871x)->CurrLedState==LED_BLINK_WPS_STOP \ - || ((struct led_8723a *)_LED_871x)->bLedWPSBlinkInProgress) - -#define IS_LED_BLINKING(_LED_871x) (((struct led_8723a *)_LED_871x)->bLedWPSBlinkInProgress \ - ||((struct led_8723a *)_LED_871x)->bLedScanBlinkInProgress) - -/* */ -/* LED customization. */ -/* */ - -enum led_strategy_8723a { - SW_LED_MODE0 = 0, /* SW control 1 LED via GPIO0. It is default option. */ - SW_LED_MODE1= 1, /* 2 LEDs, through LED0 and LED1. For ALPHA. */ - SW_LED_MODE2 = 2, /* SW control 1 LED via GPIO0, customized for AzWave 8187 minicard. */ - SW_LED_MODE3 = 3, /* SW control 1 LED via GPIO0, customized for Sercomm Printer Server case. */ - SW_LED_MODE4 = 4, /* for Edimax / Belkin */ - SW_LED_MODE5 = 5, /* for Sercomm / Belkin */ - SW_LED_MODE6 = 6, /* for 88CU minicard, porting from ce SW_LED_MODE7 */ - HW_LED = 50, /* HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes, see MAC.CONFIG1 for details.) */ - LED_ST_NONE = 99, -}; - -void LedControl871x23a(struct rtw_adapter *padapter, enum led_ctl_mode LedAction); - -struct led_priv{ - /* add for led controll */ - struct led_8723a SwLed0; - struct led_8723a SwLed1; - enum led_strategy_8723a LedStrategy; - u8 bRegUseLed; - void (*LedControlHandler)(struct rtw_adapter *padapter, enum led_ctl_mode LedAction); - /* add for led controll */ -}; - -#define rtw_led_control(adapter, LedAction) - -void BlinkWorkItemCallback23a(struct work_struct *work); - -void ResetLedStatus23a(struct led_8723a *pLed); - -void -InitLed871x23a( - struct rtw_adapter *padapter, - struct led_8723a *pLed, - enum led_pin_8723a LedPin -); - -void -DeInitLed871x23a(struct led_8723a *pLed); - -/* hal... */ -void BlinkHandler23a(struct led_8723a *pLed); - -#endif /* __RTW_LED_H_ */ diff --git a/drivers/staging/rtl8723au/include/rtw_mlme.h b/drivers/staging/rtl8723au/include/rtw_mlme.h index 2ff01eb8fc0c..a6751f138336 100644 --- a/drivers/staging/rtl8723au/include/rtw_mlme.h +++ b/drivers/staging/rtl8723au/include/rtw_mlme.h @@ -270,7 +270,7 @@ static inline void _clr_fwstate_(struct mlme_priv *pmlmepriv, int state) static inline void clr_fwstate(struct mlme_priv *pmlmepriv, int state) { spin_lock_bh(&pmlmepriv->lock); - if (check_fwstate(pmlmepriv, state) == true) + if (check_fwstate(pmlmepriv, state)) pmlmepriv->fw_state ^= state; spin_unlock_bh(&pmlmepriv->lock); } diff --git a/drivers/staging/rtl8723au/include/rtw_mlme_ext.h b/drivers/staging/rtl8723au/include/rtw_mlme_ext.h index 97c3c4478f29..51dba1fa4c5d 100644 --- a/drivers/staging/rtl8723au/include/rtw_mlme_ext.h +++ b/drivers/staging/rtl8723au/include/rtw_mlme_ext.h @@ -270,8 +270,7 @@ struct action_handler { int (*func)(struct rtw_adapter *padapter, struct recv_frame *precv_frame); }; -struct ss_res -{ +struct ss_res { int state; int bss_cnt; int channel_idx; @@ -318,8 +317,7 @@ struct FW_Sta_Info { * 5. ... and so on, till survey done. */ -struct mlme_ext_info -{ +struct mlme_ext_info { u32 state; u32 reauth_count; u32 reassoc_count; diff --git a/drivers/staging/rtl8723au/include/rtw_recv.h b/drivers/staging/rtl8723au/include/rtw_recv.h index f846bb5e7ab7..dc784be3ddd9 100644 --- a/drivers/staging/rtl8723au/include/rtw_recv.h +++ b/drivers/staging/rtl8723au/include/rtw_recv.h @@ -200,9 +200,6 @@ struct recv_priv { u8 *precv_buf; /* For display the phy informatiom */ - u8 is_signal_dbg; /* for debug */ - u8 signal_strength_dbg; /* for debug */ - s8 rssi; s8 rxpwdb; u8 signal_strength; u8 signal_qual; diff --git a/drivers/staging/rtl8723au/include/rtw_xmit.h b/drivers/staging/rtl8723au/include/rtw_xmit.h index 32a844170327..2b7d6d08238b 100644 --- a/drivers/staging/rtl8723au/include/rtw_xmit.h +++ b/drivers/staging/rtl8723au/include/rtw_xmit.h @@ -196,7 +196,6 @@ enum { void rtw_sctx_init23a(struct submit_ctx *sctx, int timeout_ms); int rtw_sctx_wait23a(struct submit_ctx *sctx); void rtw23a_sctx_done_err(struct submit_ctx **sctx, int status); -void rtw_sctx_done23a(struct submit_ctx **sctx); struct xmit_buf { struct list_head list, list2; @@ -295,10 +294,6 @@ struct xmit_priv { struct rtw_adapter *adapter; - u8 vcs_setting; - u8 vcs; - u8 vcs_type; - u64 tx_bytes; u64 tx_pkts; u64 tx_drop; @@ -307,6 +302,8 @@ struct xmit_priv { struct hw_xmit *hwxmits; u8 hwxmit_entry; + u8 vcs; + u8 nqos_ssn; u8 wmm_para_seq[4];/* sequence for wmm ac parameter strength from * large to small. it's value is 0->vo, 1->vi, @@ -314,14 +311,8 @@ struct xmit_priv { */ struct semaphore tx_retevt;/* all tx return event; */ - u8 txirp_cnt;/* */ struct tasklet_struct xmit_tasklet; - /* per AC pending irp */ - int beq_cnt; - int bkq_cnt; - int viq_cnt; - int voq_cnt; struct rtw_queue free_xmitbuf_queue; struct list_head xmitbuf_list; /* track buffers for cleanup */ @@ -332,7 +323,6 @@ struct xmit_priv { struct list_head xmitextbuf_list; /* track buffers for cleanup */ uint free_xmit_extbuf_cnt; - u16 nqos_ssn; int ack_tx; struct mutex ack_tx_mutex; struct submit_ctx ack_tx_ops; @@ -349,7 +339,6 @@ s32 rtw_free_xmitbuf23a(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); void rtw_count_tx_stats23a(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe, int sz); void rtw_update_protection23a(struct rtw_adapter *padapter, u8 *ie, uint ie_len); -s32 rtw_put_snap23a(u8 *data, u16 h_proto); struct xmit_frame *rtw_alloc_xmitframe23a_ext(struct xmit_priv *pxmitpriv); struct xmit_frame *rtw_alloc_xmitframe23a_once(struct xmit_priv *pxmitpriv); s32 rtw_free_xmitframe23a(struct xmit_priv *pxmitpriv, @@ -363,8 +352,6 @@ struct xmit_frame *rtw_dequeue_xframe23a(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, int entry); s32 rtw_xmit23a_classifier(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe); -u32 rtw_calculate_wlan_pkt_size_by_attribue23a(struct pkt_attrib *pattrib); -#define rtw_wlan_pkt_size(f) rtw_calculate_wlan_pkt_size_by_attribue23a(&f->attrib) s32 rtw_xmitframe_coalesce23a(struct rtw_adapter *padapter, struct sk_buff *pkt, struct xmit_frame *pxmitframe); s32 _rtw_init_hw_txqueue(struct hw_txqueue *phw_txqueue, u8 ac_tag); @@ -391,7 +378,6 @@ void xmit_delivery_enabled_frames23a(struct rtw_adapter *padapter, u8 qos_acm23a(u8 acm_mask, u8 priority); u32 rtw_get_ff_hwaddr23a(struct xmit_frame *pxmitframe); int rtw_ack_tx_wait23a(struct xmit_priv *pxmitpriv, u32 timeout_ms); -void rtw_ack_tx_done23a(struct xmit_priv *pxmitpriv, int status); /* include after declaring struct xmit_buf, in order to avoid warning */ #include <xmit_osdep.h> diff --git a/drivers/staging/rtl8723au/include/usb_ops.h b/drivers/staging/rtl8723au/include/usb_ops.h index ade8bc71572a..ff11e13b24a8 100644 --- a/drivers/staging/rtl8723au/include/usb_ops.h +++ b/drivers/staging/rtl8723au/include/usb_ops.h @@ -63,6 +63,6 @@ static inline void rtw_reset_continual_urb_error(struct dvobj_priv *dvobj) atomic_set(&dvobj->continual_urb_error, 0); } -void rtl8723au_chip_configure(struct rtw_adapter *padapter); +bool rtl8723au_chip_configure(struct rtw_adapter *padapter); #endif /* __USB_OPS_H_ */ diff --git a/drivers/staging/rtl8723au/include/usb_ops_linux.h b/drivers/staging/rtl8723au/include/usb_ops_linux.h index bf68bbb41f9c..af2f14b8b360 100644 --- a/drivers/staging/rtl8723au/include/usb_ops_linux.h +++ b/drivers/staging/rtl8723au/include/usb_ops_linux.h @@ -21,13 +21,13 @@ #define MAX_USBCTRL_VENDORREQ_TIMES 10 -int rtl8723au_read_port(struct rtw_adapter *adapter, u32 addr, u32 cnt, +int rtl8723au_read_port(struct rtw_adapter *adapter, u32 cnt, struct recv_buf *precvbuf); void rtl8723au_read_port_cancel(struct rtw_adapter *padapter); int rtl8723au_write_port(struct rtw_adapter *padapter, u32 addr, u32 cnt, struct xmit_buf *pxmitbuf); void rtl8723au_write_port_cancel(struct rtw_adapter *padapter); -int rtl8723au_read_interrupt(struct rtw_adapter *adapter, u32 addr); +int rtl8723au_read_interrupt(struct rtw_adapter *adapter); u8 rtl8723au_read8(struct rtw_adapter *padapter, u16 addr); u16 rtl8723au_read16(struct rtw_adapter *padapter, u16 addr); diff --git a/drivers/staging/rtl8723au/include/wlan_bssdef.h b/drivers/staging/rtl8723au/include/wlan_bssdef.h index 96e8074a7c18..95b32e15a4d0 100644 --- a/drivers/staging/rtl8723au/include/wlan_bssdef.h +++ b/drivers/staging/rtl8723au/include/wlan_bssdef.h @@ -57,23 +57,6 @@ enum { Ndis802_11Encryption3KeyAbsent, }; -/* Key mapping keys require a BSSID */ -struct ndis_802_11_key { - u32 Length; /* Length of this structure */ - u32 KeyIndex; - u32 KeyLength; /* length of key in bytes */ - unsigned char BSSID[6]; - unsigned long long KeyRSC; - u8 KeyMaterial[32]; /* variable length depending on above field */ -}; - -struct wlan_phy_info { - u8 SignalStrength;/* in percentage) */ - u8 SignalQuality;/* in percentage) */ - u8 Optimum_antenna; /* for Antenna diversity */ - u8 Reserved_0; -}; - struct wlan_bcn_info { /* these infor get from rtw_get_encrypt_info when * * translate scan to UI */ @@ -99,7 +82,8 @@ struct wlan_bssid_ex { u32 DSConfig; /* Frequency, units are kHz */ enum nl80211_iftype ifmode; unsigned char SupportedRates[NDIS_802_11_LENGTH_RATES_EX]; - struct wlan_phy_info PhyInfo; + u8 SignalStrength;/* in percentage */ + u8 SignalQuality;/* in percentage */ u32 IELength; u8 IEs[MAX_IE_SZ]; /* timestamp, beacon interval, and capability info*/ } __packed; @@ -115,7 +99,6 @@ struct wlan_network { /* set to fixed when not to be removed as site-surveying */ int fixed; unsigned long last_scanned; /* timestamp for the network */ - int aid; /* will only be valid when a BSS is joined. */ int join_res; struct wlan_bssid_ex network; /* must be the last item */ struct wlan_bcn_info BcnInfo; diff --git a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c index 3d26955da724..82a8c06ab347 100644 --- a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c @@ -275,7 +275,8 @@ static int rtw_cfg80211_inform_bss(struct rtw_adapter *padapter, &pnetwork->network)) { notify_signal = 100 * translate_percentage_to_dbm(padapter->recvpriv.signal_strength); /* dbm */ } else { - notify_signal = 100 * translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength); /* dbm */ + notify_signal = 100 * translate_percentage_to_dbm( + pnetwork->network.SignalStrength); /* dbm */ } bss = cfg80211_inform_bss(wiphy, notify_channel, @@ -471,7 +472,6 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, u8 key_index, int set_tx, const u8 *sta_addr, struct key_params *keyparms) { - int ret = 0; int key_len; struct sta_info *psta = NULL, *pbcmc_sta = NULL; struct rtw_adapter *padapter = netdev_priv(dev); @@ -708,7 +708,7 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, u8 key_index, exit: - return ret; + return 0; } #endif @@ -850,7 +850,6 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, u8 key_index, dot11PrivacyAlgrthm; } } - } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { /* adhoc mode */ } } @@ -2364,7 +2363,6 @@ void rtw_cfg80211_indicate_sta_assoc(struct rtw_adapter *padapter, ie_offset = offsetof(struct ieee80211_mgmt, u.reassoc_req.variable); - sinfo.filled = 0; sinfo.filled = STATION_INFO_ASSOC_REQ_IES; sinfo.assoc_req_ies = pmgmt_frame + ie_offset; sinfo.assoc_req_ies_len = frame_len - ie_offset; @@ -2432,20 +2430,16 @@ void rtw_cfg80211_indicate_sta_disassoc(struct rtw_adapter *padapter, static int rtw_cfg80211_monitor_if_open(struct net_device *ndev) { - int ret = 0; - DBG_8723A("%s\n", __func__); - return ret; + return 0; } static int rtw_cfg80211_monitor_if_close(struct net_device *ndev) { - int ret = 0; - DBG_8723A("%s\n", __func__); - return ret; + return 0; } static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, @@ -2574,11 +2568,9 @@ fail: static int rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr) { - int ret = 0; - DBG_8723A("%s\n", __func__); - return ret; + return 0; } static const struct net_device_ops rtw_cfg80211_monitor_if_ops = { diff --git a/drivers/staging/rtl8723au/os_dep/os_intfs.c b/drivers/staging/rtl8723au/os_dep/os_intfs.c index b34eaec9dd48..9966d16342b3 100644 --- a/drivers/staging/rtl8723au/os_dep/os_intfs.c +++ b/drivers/staging/rtl8723au/os_dep/os_intfs.c @@ -175,7 +175,6 @@ static int netdev_close(struct net_device *pnetdev); static int loadparam(struct rtw_adapter *padapter, struct net_device *pnetdev) { struct registry_priv *registry_par = &padapter->registrypriv; - int status = _SUCCESS; GlobalDebugLevel23A = rtw_debug; registry_par->chip_version = (u8)rtw_chip_version; @@ -234,7 +233,7 @@ static int loadparam(struct rtw_adapter *padapter, struct net_device *pnetdev) snprintf(registry_par->if2name, 16, "%s", if2name); registry_par->notch_filter = (u8)rtw_notch_filter; registry_par->regulatory_tid = (u8)rtw_regulatory_id; - return status; + return _SUCCESS; } static int rtw_net_set_mac_address(struct net_device *pnetdev, void *p) @@ -384,12 +383,9 @@ static int rtw_init_default_value(struct rtw_adapter *padapter) struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct security_priv *psecuritypriv = &padapter->securitypriv; - int ret = _SUCCESS; /* xmit_priv */ - pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense; pxmitpriv->vcs = pregistrypriv->vcs_type; - pxmitpriv->vcs_type = pregistrypriv->vcs_type; /* pxmitpriv->rts_thresh = pregistrypriv->rts_thresh; */ pxmitpriv->frag_len = pregistrypriv->frag_thresh; @@ -425,7 +421,7 @@ static int rtw_init_default_value(struct rtw_adapter *padapter) /* misc. */ padapter->bReadPortCancel = false; padapter->bWritePortCancel = false; - return ret; + return _SUCCESS; } int rtw_reset_drv_sw23a(struct rtw_adapter *padapter) @@ -546,9 +542,6 @@ void rtw_cancel_all_timer23a(struct rtw_adapter *padapter) RT_TRACE(_module_os_intfs_c_, _drv_info_, ("%s:cancel dynamic_chk_timer!\n", __func__)); - RT_TRACE(_module_os_intfs_c_, _drv_info_, - ("%s:cancel DeInitSwLeds!\n", __func__)); - del_timer_sync(&padapter->pwrctrlpriv.pwr_state_check_timer); del_timer_sync(&padapter->mlmepriv.set_scan_deny_timer); @@ -685,8 +678,6 @@ int netdev_open23a(struct net_device *pnetdev) rtw_cfg80211_init_wiphy(padapter); - rtw_led_control(padapter, LED_CTL_NO_LINK); - padapter->bup = true; } padapter->net_closed = false; @@ -768,8 +759,6 @@ int rtw_ips_pwr_up23a(struct rtw_adapter *padapter) result = ips_netdrv_open(padapter); - rtw_led_control(padapter, LED_CTL_NO_LINK); - DBG_8723A("<=== rtw_ips_pwr_up23a.............. in %dms\n", jiffies_to_msecs(jiffies - start_time)); return result; @@ -784,8 +773,6 @@ void rtw_ips_pwr_down23a(struct rtw_adapter *padapter) padapter->bCardDisableWOHSM = true; padapter->net_closed = true; - rtw_led_control(padapter, LED_CTL_POWER_OFF); - rtw_ips_dev_unload23a(padapter); padapter->bCardDisableWOHSM = false; DBG_8723A("<=== rtw_ips_pwr_down23a..................... in %dms\n", @@ -844,8 +831,6 @@ static int netdev_close(struct net_device *pnetdev) rtw_free_assoc_resources23a(padapter, 1); /* s2-4. */ rtw_free_network_queue23a(padapter); - /* Close LED */ - rtw_led_control(padapter, LED_CTL_POWER_OFF); } rtw_scan_abort23a(padapter); diff --git a/drivers/staging/rtl8723au/os_dep/usb_intf.c b/drivers/staging/rtl8723au/os_dep/usb_intf.c index 865743ecd855..373a617ace54 100644 --- a/drivers/staging/rtl8723au/os_dep/usb_intf.c +++ b/drivers/staging/rtl8723au/os_dep/usb_intf.c @@ -59,21 +59,6 @@ static struct usb_driver rtl8723a_usb_drv = { static struct usb_driver *usb_drv = &rtl8723a_usb_drv; -static inline int RT_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd) -{ - return usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_in(epd); -} - -static inline int RT_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd) -{ - return usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_out(epd); -} - -static inline int RT_usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd) -{ - return usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd); -} - static int rtw_init_intf_priv(struct dvobj_priv *dvobj) { mutex_init(&dvobj->usb_vendor_req_mutex); @@ -143,21 +128,21 @@ static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf) le16_to_cpu(pendp_desc->wMaxPacketSize)); DBG_8723A("bInterval =%x\n", pendp_desc->bInterval); - if (RT_usb_endpoint_is_bulk_in(pendp_desc)) { - DBG_8723A("RT_usb_endpoint_is_bulk_in = %x\n", + if (usb_endpoint_is_bulk_in(pendp_desc)) { + DBG_8723A("usb_endpoint_is_bulk_in = %x\n", usb_endpoint_num(pendp_desc)); pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = usb_endpoint_num(pendp_desc); pdvobjpriv->RtNumInPipes++; - } else if (RT_usb_endpoint_is_int_in(pendp_desc)) { - DBG_8723A("RT_usb_endpoint_is_int_in = %x, Interval = %x\n", + } else if (usb_endpoint_is_int_in(pendp_desc)) { + DBG_8723A("usb_endpoint_is_int_in = %x, Interval = %x\n", usb_endpoint_num(pendp_desc), pendp_desc->bInterval); pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = usb_endpoint_num(pendp_desc); pdvobjpriv->RtNumInPipes++; - } else if (RT_usb_endpoint_is_bulk_out(pendp_desc)) { - DBG_8723A("RT_usb_endpoint_is_bulk_out = %x\n", + } else if (usb_endpoint_is_bulk_out(pendp_desc)) { + DBG_8723A("usb_endpoint_is_bulk_out = %x\n", usb_endpoint_num(pendp_desc)); pdvobjpriv->RtOutPipe[pdvobjpriv->RtNumOutPipes] = usb_endpoint_num(pendp_desc); @@ -257,6 +242,7 @@ void rtl8723a_usb_intf_stop(struct rtw_adapter *padapter) static void rtw_dev_unload(struct rtw_adapter *padapter) { + struct submit_ctx *pack_tx_ops = &padapter->xmitpriv.ack_tx_ops; RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_dev_unload\n")); if (padapter->bup) { @@ -264,8 +250,8 @@ static void rtw_dev_unload(struct rtw_adapter *padapter) padapter->bDriverStopped = true; if (padapter->xmitpriv.ack_tx) - rtw_ack_tx_done23a(&padapter->xmitpriv, - RTW_SCTX_DONE_DRV_STOP); + rtw23a_sctx_done_err(&pack_tx_ops, + RTW_SCTX_DONE_DRV_STOP); /* s3. */ rtl8723a_usb_intf_stop(padapter); @@ -322,8 +308,6 @@ int rtw_hw_suspend23a(struct rtw_adapter *padapter) if (check_fwstate(pmlmepriv, _FW_LINKED)) { _clr_fwstate_(pmlmepriv, _FW_LINKED); - rtw_led_control(padapter, LED_CTL_NO_LINK); - rtw_os_indicate_disconnect23a(padapter); /* donnot enqueue cmd */ @@ -546,7 +530,8 @@ static struct rtw_adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj, rtl8723a_read_chip_version(padapter); /* step usb endpoint mapping */ - rtl8723au_chip_configure(padapter); + if (!rtl8723au_chip_configure(padapter)) + goto free_hal_data; /* step read efuse/eeprom data and get mac_addr */ rtl8723a_read_adapter_info(padapter); diff --git a/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c b/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c index a3349ac57bae..3e19b3b2c1c2 100644 --- a/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c +++ b/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c @@ -18,13 +18,6 @@ #include <usb_ops_linux.h> #include <rtw_sreset.h> -struct zero_bulkout_context { - void *pbuf; - void *purb; - void *pirp; - void *padapter; -}; - void rtl8723au_read_port_cancel(struct rtw_adapter *padapter) { struct recv_buf *precvbuf; @@ -53,18 +46,6 @@ static void usb_write_port23a_complete(struct urb *purb) unsigned long irqL; switch (pxmitbuf->flags) { - case VO_QUEUE_INX: - pxmitpriv->voq_cnt--; - break; - case VI_QUEUE_INX: - pxmitpriv->viq_cnt--; - break; - case BE_QUEUE_INX: - pxmitpriv->beq_cnt--; - break; - case BK_QUEUE_INX: - pxmitpriv->bkq_cnt--; - break; case HIGH_QUEUE_INX: #ifdef CONFIG_8723AU_AP_MODE rtw_chk_hi_queue_cmd23a(padapter); @@ -166,19 +147,15 @@ int rtl8723au_write_port(struct rtw_adapter *padapter, u32 addr, u32 cnt, switch (addr) { case VO_QUEUE_INX: - pxmitpriv->voq_cnt++; pxmitbuf->flags = VO_QUEUE_INX; break; case VI_QUEUE_INX: - pxmitpriv->viq_cnt++; pxmitbuf->flags = VI_QUEUE_INX; break; case BE_QUEUE_INX: - pxmitpriv->beq_cnt++; pxmitbuf->flags = BE_QUEUE_INX; break; case BK_QUEUE_INX: - pxmitpriv->bkq_cnt++; pxmitbuf->flags = BK_QUEUE_INX; break; case HIGH_QUEUE_INX: diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c index 228e48339b9e..b4612fb615f6 100644 --- a/drivers/staging/rts5208/ms.c +++ b/drivers/staging/rts5208/ms.c @@ -2599,9 +2599,9 @@ static int mspro_rw_multi_sector(struct scsi_cmnd *srb, if (count > sector_cnt) { if (mode_2k) - ms_card->seq_mode |= MODE_2K_SEQ; + ms_card->seq_mode = MODE_2K_SEQ; else - ms_card->seq_mode |= MODE_512_SEQ; + ms_card->seq_mode = MODE_512_SEQ; } } else { count = sector_cnt; diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c index 2d2527c3aea2..c74f1b8108f6 100644 --- a/drivers/staging/rts5208/rtsx.c +++ b/drivers/staging/rts5208/rtsx.c @@ -418,7 +418,7 @@ static void rtsx_shutdown(struct pci_dev *pci) static int rtsx_control_thread(void *__dev) { - struct rtsx_dev *dev = (struct rtsx_dev *)__dev; + struct rtsx_dev *dev = __dev; struct rtsx_chip *chip = dev->chip; struct Scsi_Host *host = rtsx_to_host(dev); @@ -527,7 +527,7 @@ SkipForAbort: static int rtsx_polling_thread(void *__dev) { - struct rtsx_dev *dev = (struct rtsx_dev *)__dev; + struct rtsx_dev *dev = __dev; struct rtsx_chip *chip = dev->chip; struct sd_info *sd_card = &(chip->sd_card); struct xd_info *xd_card = &(chip->xd_card); diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c index a7ade8b4e7f2..9593d8132938 100644 --- a/drivers/staging/rts5208/rtsx_chip.c +++ b/drivers/staging/rts5208/rtsx_chip.c @@ -126,10 +126,11 @@ static int rtsx_pre_handle_sdio_old(struct rtsx_chip *chip) if (chip->ignore_sd && CHK_SDIO_EXIST(chip)) { if (chip->asic_code) { RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PU | SD_CD_PU | SD_CMD_PU); + MS_INS_PU | SD_WP_PU | + SD_CD_PU | SD_CMD_PU); } else { RTSX_WRITE_REG(chip, FPGA_PULL_CTL, 0xFF, - FPGA_SD_PULL_CTL_EN); + FPGA_SD_PULL_CTL_EN); } RTSX_WRITE_REG(chip, CARD_SHARE_MODE, 0xFF, CARD_SHARE_48_SD); @@ -137,7 +138,7 @@ static int rtsx_pre_handle_sdio_old(struct rtsx_chip *chip) RTSX_WRITE_REG(chip, 0xFF2C, 0x01, 0x01); RTSX_WRITE_REG(chip, SDIO_CTRL, 0xFF, - SDIO_BUS_CTRL | SDIO_CD_CTRL); + SDIO_BUS_CTRL | SDIO_CD_CTRL); chip->sd_int = 1; chip->sd_io = 1; @@ -201,7 +202,7 @@ static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip) TRACE_RET(chip, STATUS_FAIL); } else { RTSX_WRITE_REG(chip, FPGA_PULL_CTL, - FPGA_SD_PULL_CTL_BIT | 0x20, 0); + FPGA_SD_PULL_CTL_BIT | 0x20, 0); } retval = card_share_mode(chip, SD_CARD); if (retval != STATUS_SUCCESS) @@ -226,6 +227,87 @@ static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip) } #endif +static int rtsx_reset_aspm(struct rtsx_chip *chip) +{ + int ret; + + if (chip->dynamic_aspm) { + if (!CHK_SDIO_EXIST(chip) || !CHECK_PID(chip, 0x5288)) + return STATUS_SUCCESS; + + ret = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, + chip->aspm_l0s_l1_en); + if (ret != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; + } + + if (CHECK_PID(chip, 0x5208)) + RTSX_WRITE_REG(chip, ASPM_FORCE_CTL, 0xFF, 0x3F); + ret = rtsx_write_config_byte(chip, LCTLR, chip->aspm_l0s_l1_en); + if (ret != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + chip->aspm_level[0] = chip->aspm_l0s_l1_en; + if (CHK_SDIO_EXIST(chip)) { + chip->aspm_level[1] = chip->aspm_l0s_l1_en; + ret = rtsx_write_cfg_dw(chip, CHECK_PID(chip, 0x5288) ? 2 : 1, + 0xC0, 0xFF, chip->aspm_l0s_l1_en); + if (ret != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + chip->aspm_enabled = 1; + + return STATUS_SUCCESS; +} + +static int rtsx_enable_pcie_intr(struct rtsx_chip *chip) +{ + int ret; + + if (!chip->asic_code || !CHECK_PID(chip, 0x5208)) { + rtsx_enable_bus_int(chip); + return STATUS_SUCCESS; + } + + if (chip->phy_debug_mode) { + RTSX_WRITE_REG(chip, CDRESUMECTL, 0x77, 0); + rtsx_disable_bus_int(chip); + } else { + rtsx_enable_bus_int(chip); + } + + if (chip->ic_version >= IC_VER_D) { + u16 reg; + + ret = rtsx_read_phy_register(chip, 0x00, ®); + if (ret != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + reg &= 0xFE7F; + reg |= 0x80; + ret = rtsx_write_phy_register(chip, 0x00, reg); + if (ret != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + ret = rtsx_read_phy_register(chip, 0x1C, ®); + if (ret != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + reg &= 0xFFF7; + ret = rtsx_write_phy_register(chip, 0x1C, reg); + if (ret != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + if (chip->driver_first_load && (chip->ic_version < IC_VER_C)) + rtsx_calibration(chip); + + return STATUS_SUCCESS; +} + int rtsx_reset_chip(struct rtsx_chip *chip) { int retval; @@ -268,7 +350,7 @@ int rtsx_reset_chip(struct rtsx_chip *chip) #ifdef LED_AUTO_BLINK RTSX_WRITE_REG(chip, CARD_AUTO_BLINK, 0xFF, - LED_BLINK_SPEED | BLINK_EN | LED_GPIO0); + LED_BLINK_SPEED | BLINK_EN | LED_GPIO0); #endif if (chip->asic_code) { @@ -288,39 +370,9 @@ int rtsx_reset_chip(struct rtsx_chip *chip) /* Enable ASPM */ if (chip->aspm_l0s_l1_en) { - if (chip->dynamic_aspm) { - if (CHK_SDIO_EXIST(chip)) { - if (CHECK_PID(chip, 0x5288)) { - retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, chip->aspm_l0s_l1_en); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - } - } else { - if (CHECK_PID(chip, 0x5208)) - RTSX_WRITE_REG(chip, ASPM_FORCE_CTL, - 0xFF, 0x3F); - - retval = rtsx_write_config_byte(chip, LCTLR, - chip->aspm_l0s_l1_en); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - chip->aspm_level[0] = chip->aspm_l0s_l1_en; - if (CHK_SDIO_EXIST(chip)) { - chip->aspm_level[1] = chip->aspm_l0s_l1_en; - if (CHECK_PID(chip, 0x5288)) - retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, chip->aspm_l0s_l1_en); - else - retval = rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF, chip->aspm_l0s_l1_en); - - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - } - - chip->aspm_enabled = 1; - } + retval = rtsx_reset_aspm(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); } else { if (chip->asic_code && CHECK_PID(chip, 0x5208)) { retval = rtsx_write_phy_register(chip, 0x07, 0x0129); @@ -338,91 +390,38 @@ int rtsx_reset_chip(struct rtsx_chip *chip) TRACE_RET(chip, STATUS_FAIL); if (CHK_SDIO_EXIST(chip)) { - if (CHECK_PID(chip, 0x5288)) - retval = rtsx_write_cfg_dw(chip, 2, 0xC0, - 0xFF00, 0x0100); - else - retval = rtsx_write_cfg_dw(chip, 1, 0xC0, - 0xFF00, 0x0100); + retval = rtsx_write_cfg_dw(chip, + CHECK_PID(chip, 0x5288) ? 2 : 1, + 0xC0, 0xFF00, 0x0100); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } - if (CHECK_PID(chip, 0x5288)) { - if (!CHK_SDIO_EXIST(chip)) { - retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFFFF, - 0x0103); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = rtsx_write_cfg_dw(chip, 2, 0x84, 0xFF, 0x03); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); + if (CHECK_PID(chip, 0x5288) && !CHK_SDIO_EXIST(chip)) { + retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFFFF, 0x0103); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); - } + retval = rtsx_write_cfg_dw(chip, 2, 0x84, 0xFF, 0x03); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); } RTSX_WRITE_REG(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT); RTSX_WRITE_REG(chip, PERST_GLITCH_WIDTH, 0xFF, 0x80); - /* Enable PCIE interrupt */ - if (chip->asic_code) { - if (CHECK_PID(chip, 0x5208)) { - if (chip->phy_debug_mode) { - RTSX_WRITE_REG(chip, CDRESUMECTL, 0x77, 0); - rtsx_disable_bus_int(chip); - } else { - rtsx_enable_bus_int(chip); - } - - if (chip->ic_version >= IC_VER_D) { - u16 reg; - - retval = rtsx_read_phy_register(chip, 0x00, - ®); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - reg &= 0xFE7F; - reg |= 0x80; - retval = rtsx_write_phy_register(chip, 0x00, - reg); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = rtsx_read_phy_register(chip, 0x1C, - ®); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - reg &= 0xFFF7; - retval = rtsx_write_phy_register(chip, 0x1C, - reg); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - } - - if (chip->driver_first_load && - (chip->ic_version < IC_VER_C)) - rtsx_calibration(chip); - - } else { - rtsx_enable_bus_int(chip); - } - } else { - rtsx_enable_bus_int(chip); - } + retval = rtsx_enable_pcie_intr(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); chip->need_reset = 0; chip->int_reg = rtsx_readl(chip, RTSX_BIPR); if (chip->hw_bypass_sd) - goto NextCard; + goto nextcard; dev_dbg(rtsx_dev(chip), "In %s, chip->int_reg = 0x%x\n", __func__, chip->int_reg); if (chip->int_reg & SD_EXIST) { @@ -443,10 +442,10 @@ int rtsx_reset_chip(struct rtsx_chip *chip) } else { chip->sd_io = 0; RTSX_WRITE_REG(chip, SDIO_CTRL, SDIO_BUS_CTRL | SDIO_CD_CTRL, - 0); + 0); } -NextCard: +nextcard: if (chip->int_reg & XD_EXIST) chip->need_reset |= XD_CARD; if (chip->int_reg & MS_EXIST) @@ -484,10 +483,10 @@ NextCard: if (chip->ft2_fast_mode) { RTSX_WRITE_REG(chip, CARD_PWR_CTL, 0xFF, - MS_PARTIAL_POWER_ON | SD_PARTIAL_POWER_ON); + MS_PARTIAL_POWER_ON | SD_PARTIAL_POWER_ON); udelay(chip->pmos_pwr_on_interval); RTSX_WRITE_REG(chip, CARD_PWR_CTL, 0xFF, - MS_POWER_ON | SD_POWER_ON); + MS_POWER_ON | SD_POWER_ON); wait_timeout(200); } @@ -540,10 +539,7 @@ static int rts5208_init(struct rtsx_chip *chip) RTSX_WRITE_REG(chip, CLK_SEL, 0x03, 0x03); RTSX_READ_REG(chip, CLK_SEL, &val); - if (val == 0) - chip->asic_code = 1; - else - chip->asic_code = 0; + chip->asic_code = val == 0 ? 1 : 0; if (chip->asic_code) { retval = rtsx_read_phy_register(chip, 0x1C, ®); @@ -553,10 +549,7 @@ static int rts5208_init(struct rtsx_chip *chip) dev_dbg(rtsx_dev(chip), "Value of phy register 0x1C is 0x%x\n", reg); chip->ic_version = (reg >> 4) & 0x07; - if (reg & PHY_DEBUG_MODE) - chip->phy_debug_mode = 1; - else - chip->phy_debug_mode = 0; + chip->phy_debug_mode = reg & PHY_DEBUG_MODE ? 1 : 0; } else { RTSX_READ_REG(chip, 0xFE80, &val); @@ -566,16 +559,10 @@ static int rts5208_init(struct rtsx_chip *chip) RTSX_READ_REG(chip, PDINFO, &val); dev_dbg(rtsx_dev(chip), "PDINFO: 0x%x\n", val); - if (val & AUX_PWR_DETECTED) - chip->aux_pwr_exist = 1; - else - chip->aux_pwr_exist = 0; + chip->aux_pwr_exist = val & AUX_PWR_DETECTED ? 1 : 0; RTSX_READ_REG(chip, 0xFE50, &val); - if (val & 0x01) - chip->hw_bypass_sd = 1; - else - chip->hw_bypass_sd = 0; + chip->hw_bypass_sd = val & 0x01 ? 1 : 0; rtsx_read_config_byte(chip, 0x0E, &val); if (val & 0x80) @@ -585,10 +572,7 @@ static int rts5208_init(struct rtsx_chip *chip) if (chip->use_hw_setting) { RTSX_READ_REG(chip, CHANGE_LINK_STATE, &val); - if (val & 0x80) - chip->auto_delink_en = 1; - else - chip->auto_delink_en = 0; + chip->auto_delink_en = val & 0x80 ? 1 : 0; } return STATUS_SUCCESS; @@ -602,33 +586,21 @@ static int rts5288_init(struct rtsx_chip *chip) RTSX_WRITE_REG(chip, CLK_SEL, 0x03, 0x03); RTSX_READ_REG(chip, CLK_SEL, &val); - if (val == 0) - chip->asic_code = 1; - else - chip->asic_code = 0; + chip->asic_code = val == 0 ? 1 : 0; chip->ic_version = 0; chip->phy_debug_mode = 0; RTSX_READ_REG(chip, PDINFO, &val); dev_dbg(rtsx_dev(chip), "PDINFO: 0x%x\n", val); - if (val & AUX_PWR_DETECTED) - chip->aux_pwr_exist = 1; - else - chip->aux_pwr_exist = 0; + chip->aux_pwr_exist = val & AUX_PWR_DETECTED ? 1 : 0; RTSX_READ_REG(chip, CARD_SHARE_MODE, &val); dev_dbg(rtsx_dev(chip), "CARD_SHARE_MODE: 0x%x\n", val); - if (val & 0x04) - chip->baro_pkg = QFN; - else - chip->baro_pkg = LQFP; + chip->baro_pkg = val & 0x04 ? QFN : LQFP; RTSX_READ_REG(chip, 0xFE5A, &val); - if (val & 0x10) - chip->hw_bypass_sd = 1; - else - chip->hw_bypass_sd = 0; + chip->hw_bypass_sd = val & 0x10 ? 1 : 0; retval = rtsx_read_cfg_dw(chip, 0, 0x718, &lval); if (retval != STATUS_SUCCESS) @@ -643,16 +615,12 @@ static int rts5288_init(struct rtsx_chip *chip) if (chip->use_hw_setting) { RTSX_READ_REG(chip, CHANGE_LINK_STATE, &val); - if (val & 0x80) - chip->auto_delink_en = 1; - else - chip->auto_delink_en = 0; + chip->auto_delink_en = val & 0x80 ? 1 : 0; if (CHECK_BARO_PKG(chip, LQFP)) chip->lun_mode = SD_MS_1LUN; else chip->lun_mode = DEFAULT_SINGLE; - } return STATUS_SUCCESS; @@ -660,9 +628,9 @@ static int rts5288_init(struct rtsx_chip *chip) int rtsx_init_chip(struct rtsx_chip *chip) { - struct sd_info *sd_card = &(chip->sd_card); - struct xd_info *xd_card = &(chip->xd_card); - struct ms_info *ms_card = &(chip->ms_card); + struct sd_info *sd_card = &chip->sd_card; + struct xd_info *xd_card = &chip->xd_card; + struct ms_info *ms_card = &chip->ms_card; int retval; unsigned int i; @@ -740,7 +708,6 @@ int rtsx_init_chip(struct rtsx_chip *chip) retval = rts5288_init(chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (chip->ss_en == 2) @@ -842,7 +809,6 @@ static void rtsx_monitor_aspm_config(struct rtsx_chip *chip) } else { if (reg0 & 0x03) maybe_support_aspm = 1; - } if (reg_changed) { @@ -859,15 +825,15 @@ static void rtsx_monitor_aspm_config(struct rtsx_chip *chip) chip->sdio_aspm = 0; } rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFF, - 0x30 | chip->aspm_level[0] | - (chip->aspm_level[1] << 2)); + 0x30 | chip->aspm_level[0] | + (chip->aspm_level[1] << 2)); } } void rtsx_polling_func(struct rtsx_chip *chip) { #ifdef SUPPORT_SD_LOCK - struct sd_info *sd_card = &(chip->sd_card); + struct sd_info *sd_card = &chip->sd_card; #endif int ss_allowed; @@ -875,7 +841,7 @@ void rtsx_polling_func(struct rtsx_chip *chip) return; if (rtsx_chk_stat(chip, RTSX_STAT_DELINK)) - goto Delink_Stage; + goto delink_stage; if (chip->polling_config) { u8 val; @@ -888,7 +854,7 @@ void rtsx_polling_func(struct rtsx_chip *chip) #ifdef SUPPORT_OCP if (chip->ocp_int) { - rtsx_read_register(chip, OCPSTAT, &(chip->ocp_stat)); + rtsx_read_register(chip, OCPSTAT, &chip->ocp_stat); if (chip->card_exist & SD_CARD) sd_power_off_card3v3(chip); @@ -932,7 +898,6 @@ void rtsx_polling_func(struct rtsx_chip *chip) rtsx_read_cfg_dw(chip, 1, 0x04, &val); if (val & 0x07) ss_allowed = 0; - } } } else { @@ -958,7 +923,7 @@ void rtsx_polling_func(struct rtsx_chip *chip) #ifdef SUPPORT_SDIO_ASPM if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip) && - chip->aspm_l0s_l1_en && chip->dynamic_aspm) { + chip->aspm_l0s_l1_en && chip->dynamic_aspm) { if (chip->sd_io) { dynamic_configure_sdio_aspm(chip); } else { @@ -966,7 +931,8 @@ void rtsx_polling_func(struct rtsx_chip *chip) dev_dbg(rtsx_dev(chip), "SDIO enter ASPM!\n"); rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, - 0x30 | (chip->aspm_level[1] << 2)); + 0x30 | + (chip->aspm_level[1] << 2)); chip->sdio_aspm = 1; } } @@ -988,9 +954,10 @@ void rtsx_polling_func(struct rtsx_chip *chip) turn_off_led(chip, LED_GPIO); - if (chip->auto_power_down && !chip->card_ready && !chip->sd_io) - rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); - + if (chip->auto_power_down && !chip->card_ready && + !chip->sd_io) + rtsx_force_power_down(chip, + SSC_PDCTL | OC_PDCTL); } } @@ -1013,7 +980,6 @@ void rtsx_polling_func(struct rtsx_chip *chip) break; } - #ifdef SUPPORT_OCP if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { if (chip->ocp_stat & @@ -1024,7 +990,7 @@ void rtsx_polling_func(struct rtsx_chip *chip) if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { if (chip->card_exist & SD_CARD) { rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, - 0); + 0); card_power_off(chip, SD_CARD); chip->card_fail |= SD_CARD; } @@ -1032,7 +998,7 @@ void rtsx_polling_func(struct rtsx_chip *chip) if (chip->ocp_stat & (MS_OC_NOW | MS_OC_EVER)) { if (chip->card_exist & MS_CARD) { rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, - 0); + 0); card_power_off(chip, MS_CARD); chip->card_fail |= MS_CARD; } @@ -1043,15 +1009,15 @@ void rtsx_polling_func(struct rtsx_chip *chip) chip->ocp_stat); if (chip->card_exist & SD_CARD) { rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, - 0); + 0); chip->card_fail |= SD_CARD; } else if (chip->card_exist & MS_CARD) { rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, - 0); + 0); chip->card_fail |= MS_CARD; } else if (chip->card_exist & XD_CARD) { rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN, - 0); + 0); chip->card_fail |= XD_CARD; } card_power_off(chip, SD_CARD); @@ -1059,9 +1025,9 @@ void rtsx_polling_func(struct rtsx_chip *chip) } #endif -Delink_Stage: +delink_stage: if (chip->auto_delink_en && chip->auto_delink_allowed && - !chip->card_ready && !chip->card_ejected && !chip->sd_io) { + !chip->card_ready && !chip->card_ejected && !chip->sd_io) { int enter_L1 = chip->auto_delink_in_L1 && ( chip->aspm_l0s_l1_en || chip->ss_en); int delink_stage1_cnt = chip->delink_stage1_step; @@ -1081,27 +1047,33 @@ Delink_Stage: dev_dbg(rtsx_dev(chip), "False card inserted, do force delink\n"); if (enter_L1) - rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1); + rtsx_write_register(chip, + HOST_SLEEP_STATE, + 0x03, 1); rtsx_write_register(chip, - CHANGE_LINK_STATE, 0x0A, - 0x0A); + CHANGE_LINK_STATE, + 0x0A, 0x0A); if (enter_L1) rtsx_enter_L1(chip); - chip->auto_delink_cnt = delink_stage3_cnt + 1; + chip->auto_delink_cnt = + delink_stage3_cnt + 1; } else { dev_dbg(rtsx_dev(chip), "No card inserted, do delink\n"); if (enter_L1) - rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1); + rtsx_write_register(chip, + HOST_SLEEP_STATE, + 0x03, 1); - rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 0x02); + rtsx_write_register(chip, + CHANGE_LINK_STATE, + 0x02, 0x02); if (enter_L1) rtsx_enter_L1(chip); - } } @@ -1115,7 +1087,7 @@ Delink_Stage: rtsx_set_phy_reg_bit(chip, 0x1C, 2); rtsx_write_register(chip, CHANGE_LINK_STATE, - 0x0A, 0x0A); + 0x0A, 0x0A); } chip->auto_delink_cnt++; @@ -1219,7 +1191,7 @@ int rtsx_read_register(struct rtsx_chip *chip, u16 addr, u8 *data) } int rtsx_write_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 mask, - u32 val) + u32 val) { u8 mode = 0, tmp; int i; @@ -1279,7 +1251,7 @@ int rtsx_read_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 *val) } int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, - int len) + int len) { u32 *data, *mask; u16 offset = addr % 4; @@ -1324,7 +1296,7 @@ int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, for (i = 0; i < dw_len; i++) { retval = rtsx_write_cfg_dw(chip, func, aligned_addr + i * 4, - mask[i], data[i]); + mask[i], data[i]); if (retval != STATUS_SUCCESS) { vfree(data); vfree(mask); @@ -1339,7 +1311,7 @@ int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, } int rtsx_read_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, - int len) + int len) { u32 *data; u16 offset = addr % 4; @@ -1360,7 +1332,7 @@ int rtsx_read_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, for (i = 0; i < dw_len; i++) { retval = rtsx_read_cfg_dw(chip, func, aligned_addr + i * 4, - data + i); + data + i); if (retval != STATUS_SUCCESS) { vfree(data); TRACE_RET(chip, STATUS_FAIL); @@ -1522,7 +1494,7 @@ int rtsx_set_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit) if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - if (0 == (value & (1 << bit))) { + if ((value & (1 << bit)) == 0) { value |= (1 << bit); retval = rtsx_write_phy_register(chip, reg, value); if (retval != STATUS_SUCCESS) @@ -1595,12 +1567,9 @@ void rtsx_enter_ss(struct rtsx_chip *chip) rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); } - if (CHK_SDIO_EXIST(chip)) { - if (CHECK_PID(chip, 0x5288)) - rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF00, 0x0100); - else - rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF00, 0x0100); - } + if (CHK_SDIO_EXIST(chip)) + rtsx_write_cfg_dw(chip, CHECK_PID(chip, 0x5288) ? 2 : 1, + 0xC0, 0xFF00, 0x0100); if (chip->auto_delink_en) { rtsx_write_register(chip, HOST_SLEEP_STATE, 0x01, 0x01); @@ -1666,7 +1635,7 @@ int rtsx_pre_handle_interrupt(struct rtsx_chip *chip) chip->int_reg = rtsx_readl(chip, RTSX_BIPR); if (((chip->int_reg & int_enable) == 0) || - (chip->int_reg == 0xFFFFFFFF)) + (chip->int_reg == 0xFFFFFFFF)) return STATUS_FAIL; status = chip->int_reg &= (int_enable | 0x7FFFFF); @@ -1676,12 +1645,12 @@ int rtsx_pre_handle_interrupt(struct rtsx_chip *chip) if (status & SD_INT) { if (status & SD_EXIST) { - set_bit(SD_NR, &(chip->need_reset)); + set_bit(SD_NR, &chip->need_reset); } else { - set_bit(SD_NR, &(chip->need_release)); + set_bit(SD_NR, &chip->need_release); chip->sd_reset_counter = 0; chip->sd_show_cnt = 0; - clear_bit(SD_NR, &(chip->need_reset)); + clear_bit(SD_NR, &chip->need_reset); } } else { /* If multi-luns, it's possible that @@ -1691,35 +1660,35 @@ int rtsx_pre_handle_interrupt(struct rtsx_chip *chip) all existed cards should be reset. */ if (exit_ss && (status & SD_EXIST)) - set_bit(SD_NR, &(chip->need_reinit)); + set_bit(SD_NR, &chip->need_reinit); } if (!CHECK_PID(chip, 0x5288) || CHECK_BARO_PKG(chip, QFN)) { if (status & XD_INT) { if (status & XD_EXIST) { - set_bit(XD_NR, &(chip->need_reset)); + set_bit(XD_NR, &chip->need_reset); } else { - set_bit(XD_NR, &(chip->need_release)); + set_bit(XD_NR, &chip->need_release); chip->xd_reset_counter = 0; chip->xd_show_cnt = 0; - clear_bit(XD_NR, &(chip->need_reset)); + clear_bit(XD_NR, &chip->need_reset); } } else { if (exit_ss && (status & XD_EXIST)) - set_bit(XD_NR, &(chip->need_reinit)); + set_bit(XD_NR, &chip->need_reinit); } } if (status & MS_INT) { if (status & MS_EXIST) { - set_bit(MS_NR, &(chip->need_reset)); + set_bit(MS_NR, &chip->need_reset); } else { - set_bit(MS_NR, &(chip->need_release)); + set_bit(MS_NR, &chip->need_release); chip->ms_reset_counter = 0; chip->ms_show_cnt = 0; - clear_bit(MS_NR, &(chip->need_reset)); + clear_bit(MS_NR, &chip->need_reset); } } else { if (exit_ss && (status & MS_EXIST)) - set_bit(MS_NR, &(chip->need_reinit)); + set_bit(MS_NR, &chip->need_reinit); } } @@ -1727,10 +1696,8 @@ int rtsx_pre_handle_interrupt(struct rtsx_chip *chip) chip->ocp_int = ocp_int & status; #endif - if (chip->sd_io) { - if (chip->int_reg & DATA_DONE_INT) - chip->int_reg &= ~(u32)DATA_DONE_INT; - } + if (chip->sd_io && (chip->int_reg & DATA_DONE_INT)) + chip->int_reg &= ~(u32)DATA_DONE_INT; return STATUS_SUCCESS; } @@ -1774,14 +1741,14 @@ void rtsx_do_before_power_down(struct rtsx_chip *chip, int pm_stat) if (pm_stat == PM_S1) { dev_dbg(rtsx_dev(chip), "Host enter S1\n"); rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, - HOST_ENTER_S1); + HOST_ENTER_S1); } else if (pm_stat == PM_S3) { if (chip->s3_pwr_off_delay > 0) wait_timeout(chip->s3_pwr_off_delay); dev_dbg(rtsx_dev(chip), "Host enter S3\n"); rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, - HOST_ENTER_S3); + HOST_ENTER_S3); } if (chip->do_delink_before_power_down && chip->auto_delink_en) @@ -1796,31 +1763,25 @@ void rtsx_do_before_power_down(struct rtsx_chip *chip, int pm_stat) void rtsx_enable_aspm(struct rtsx_chip *chip) { - if (chip->aspm_l0s_l1_en && chip->dynamic_aspm) { - if (!chip->aspm_enabled) { - dev_dbg(rtsx_dev(chip), "Try to enable ASPM\n"); - chip->aspm_enabled = 1; + if (chip->aspm_l0s_l1_en && chip->dynamic_aspm && !chip->aspm_enabled) { + dev_dbg(rtsx_dev(chip), "Try to enable ASPM\n"); + chip->aspm_enabled = 1; - if (chip->asic_code && CHECK_PID(chip, 0x5208)) - rtsx_write_phy_register(chip, 0x07, 0); - if (CHECK_PID(chip, 0x5208)) { - rtsx_write_register(chip, ASPM_FORCE_CTL, 0xF3, - 0x30 | chip->aspm_level[0]); - } else { - rtsx_write_config_byte(chip, LCTLR, - chip->aspm_l0s_l1_en); - } + if (chip->asic_code && CHECK_PID(chip, 0x5208)) + rtsx_write_phy_register(chip, 0x07, 0); + if (CHECK_PID(chip, 0x5208)) { + rtsx_write_register(chip, ASPM_FORCE_CTL, 0xF3, + 0x30 | chip->aspm_level[0]); + } else { + rtsx_write_config_byte(chip, LCTLR, + chip->aspm_l0s_l1_en); + } - if (CHK_SDIO_EXIST(chip)) { - u16 val = chip->aspm_l0s_l1_en | 0x0100; + if (CHK_SDIO_EXIST(chip)) { + u16 val = chip->aspm_l0s_l1_en | 0x0100; - if (CHECK_PID(chip, 0x5288)) - rtsx_write_cfg_dw(chip, 2, 0xC0, - 0xFFFF, val); - else - rtsx_write_cfg_dw(chip, 1, 0xC0, - 0xFFFF, val); - } + rtsx_write_cfg_dw(chip, CHECK_PID(chip, 0x5288) ? 2 : 1, + 0xC0, 0xFFF, val); } } } @@ -1830,21 +1791,19 @@ void rtsx_disable_aspm(struct rtsx_chip *chip) if (CHECK_PID(chip, 0x5208)) rtsx_monitor_aspm_config(chip); - if (chip->aspm_l0s_l1_en && chip->dynamic_aspm) { - if (chip->aspm_enabled) { - dev_dbg(rtsx_dev(chip), "Try to disable ASPM\n"); - chip->aspm_enabled = 0; + if (chip->aspm_l0s_l1_en && chip->dynamic_aspm && chip->aspm_enabled) { + dev_dbg(rtsx_dev(chip), "Try to disable ASPM\n"); + chip->aspm_enabled = 0; - if (chip->asic_code && CHECK_PID(chip, 0x5208)) - rtsx_write_phy_register(chip, 0x07, 0x0129); - if (CHECK_PID(chip, 0x5208)) - rtsx_write_register(chip, ASPM_FORCE_CTL, - 0xF3, 0x30); - else - rtsx_write_config_byte(chip, LCTLR, 0x00); + if (chip->asic_code && CHECK_PID(chip, 0x5208)) + rtsx_write_phy_register(chip, 0x07, 0x0129); + if (CHECK_PID(chip, 0x5208)) + rtsx_write_register(chip, ASPM_FORCE_CTL, + 0xF3, 0x30); + else + rtsx_write_config_byte(chip, LCTLR, 0x00); - wait_timeout(1); - } + wait_timeout(1); } } @@ -1907,7 +1866,7 @@ int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len) for (j = 0; j < 256; j++) { rtsx_add_cmd(chip, WRITE_REG_CMD, reg_addr++, 0xFF, - *ptr); + *ptr); ptr++; } @@ -1921,7 +1880,7 @@ int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len) for (j = 0; j < buf_len%256; j++) { rtsx_add_cmd(chip, WRITE_REG_CMD, reg_addr++, 0xFF, - *ptr); + *ptr); ptr++; } diff --git a/drivers/staging/rts5208/rtsx_scsi.c b/drivers/staging/rts5208/rtsx_scsi.c index bbbf7968a0b6..11610826acf1 100644 --- a/drivers/staging/rts5208/rtsx_scsi.c +++ b/drivers/staging/rts5208/rtsx_scsi.c @@ -584,9 +584,8 @@ static int start_stop_unit(struct scsi_cmnd *srb, struct rtsx_chip *chip) case MAKE_MEDIUM_READY: case LOAD_MEDIUM: - if (check_card_ready(chip, lun)) { + if (check_card_ready(chip, lun)) return TRANSPORT_GOOD; - } set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, TRANSPORT_FAILED); diff --git a/drivers/staging/rts5208/rtsx_transport.c b/drivers/staging/rts5208/rtsx_transport.c index 0a67dca72dff..756a9687c293 100644 --- a/drivers/staging/rts5208/rtsx_transport.c +++ b/drivers/staging/rts5208/rtsx_transport.c @@ -539,7 +539,7 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, if (i == buf_cnt / (HOST_SG_TBL_BUF_LEN / 8)) sg_cnt = buf_cnt % (HOST_SG_TBL_BUF_LEN / 8); else - sg_cnt = (HOST_SG_TBL_BUF_LEN / 8); + sg_cnt = HOST_SG_TBL_BUF_LEN / 8; chip->sgi = 0; for (j = 0; j < sg_cnt; j++) { @@ -728,15 +728,13 @@ int rtsx_transfer_data_partial(struct rtsx_chip *chip, u8 card, if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) return -EIO; - if (use_sg) { + if (use_sg) err = rtsx_transfer_sglist_adma_partial(chip, card, (struct scatterlist *)buf, use_sg, index, offset, (int)len, dma_dir, timeout); - } else { + else err = rtsx_transfer_buf(chip, card, buf, len, dma_dir, timeout); - } - if (err < 0) { if (RTSX_TST_DELINK(chip)) { RTSX_CLR_DELINK(chip); diff --git a/drivers/staging/rts5208/rtsx_transport.h b/drivers/staging/rts5208/rtsx_transport.h index b4b112372776..899bc2079dbe 100644 --- a/drivers/staging/rts5208/rtsx_transport.h +++ b/drivers/staging/rts5208/rtsx_transport.h @@ -46,7 +46,7 @@ void rtsx_add_cmd(struct rtsx_chip *chip, void rtsx_send_cmd_no_wait(struct rtsx_chip *chip); int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout); -extern inline u8 *rtsx_get_cmd_data(struct rtsx_chip *chip) +static inline u8 *rtsx_get_cmd_data(struct rtsx_chip *chip) { #ifdef CMD_USING_SG return (u8 *)(chip->host_sg_tbl_ptr); diff --git a/drivers/staging/skein/Kconfig b/drivers/staging/skein/Kconfig index b9172bfcdc1b..012a8233376e 100644 --- a/drivers/staging/skein/Kconfig +++ b/drivers/staging/skein/Kconfig @@ -1,8 +1,8 @@ config CRYPTO_SKEIN - bool "Skein digest algorithm" + tristate "Skein digest algorithm" depends on (X86 || UML_X86) && 64BIT && CRYPTO - select CRYPTO_THREEFISH select CRYPTO_HASH + select CRYPTO_ALGAPI help Skein secure hash algorithm is one of 5 finalists from the NIST SHA3 competition. @@ -12,21 +12,5 @@ config CRYPTO_SKEIN http://www.skein-hash.info/sites/default/files/skein1.3.pdf - for more information. This module depends on the threefish block - cipher module. - -config CRYPTO_THREEFISH - bool "Threefish tweakable block cipher" - depends on (X86 || UML_X86) && 64BIT && CRYPTO - select CRYPTO_ALGAPI - help - Threefish cipher algorithm is the tweakable block cipher underneath - the Skein family of secure hash algorithms. Skein is one of 5 - finalists from the NIST SHA3 competition. - - Skein is optimized for modern, 64bit processors and is highly - customizable. See: - - http://www.skein-hash.info/sites/default/files/skein1.3.pdf - - for more information. + for more information. This module also contains the threefish block + cipher algorithm. diff --git a/drivers/staging/skein/Makefile b/drivers/staging/skein/Makefile index a14aaddd829c..b7f947fb98f0 100644 --- a/drivers/staging/skein/Makefile +++ b/drivers/staging/skein/Makefile @@ -1,9 +1,10 @@ # # Makefile for the skein secure hash algorithm # -obj-$(CONFIG_CRYPTO_SKEIN) += skein.o \ - skein_api.o \ - skein_block.o - -obj-$(CONFIG_CRYPTO_THREEFISH) += threefish_block.o \ - threefish_api.o +obj-$(CONFIG_CRYPTO_SKEIN) += skein.o +skein-y := skein_base.o \ + skein_api.o \ + skein_block.o \ + threefish_block.o \ + threefish_api.o \ + skein_generic.o diff --git a/drivers/staging/skein/skein_api.c b/drivers/staging/skein/skein_api.c index 6e700eefc00c..5bfce076f7c8 100644 --- a/drivers/staging/skein/skein_api.c +++ b/drivers/staging/skein/skein_api.c @@ -31,7 +31,7 @@ int skein_ctx_prepare(struct skein_ctx *ctx, enum skein_size size) { skein_assert_ret(ctx && size, SKEIN_FAIL); - memset(ctx , 0, sizeof(struct skein_ctx)); + memset(ctx, 0, sizeof(struct skein_ctx)); ctx->skein_size = size; return SKEIN_SUCCESS; diff --git a/drivers/staging/skein/skein_api.h b/drivers/staging/skein/skein_api.h index e02fa19d9458..171b87549548 100644 --- a/drivers/staging/skein/skein_api.h +++ b/drivers/staging/skein/skein_api.h @@ -79,7 +79,7 @@ OTHER DEALINGS IN THE SOFTWARE. */ #include <linux/types.h> -#include "skein.h" +#include "skein_base.h" /** * Which Skein size to use diff --git a/drivers/staging/skein/skein.c b/drivers/staging/skein/skein_base.c index 8cc83587b1f1..7e700a6b5788 100644 --- a/drivers/staging/skein/skein.c +++ b/drivers/staging/skein/skein_base.c @@ -8,10 +8,9 @@ ** ************************************************************************/ -#define SKEIN_PORT_CODE /* instantiate any code in skein_port.h */ - #include <linux/string.h> /* get the memcpy/memset functions */ -#include "skein.h" /* get the Skein API definitions */ +#include <linux/export.h> +#include "skein_base.h" /* get the Skein API definitions */ #include "skein_iv.h" /* get precomputed IVs */ #include "skein_block.h" @@ -125,8 +124,6 @@ int skein_256_init_ext(struct skein_256_ctx *ctx, size_t hash_bit_len, /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */ cfg.w[2] = skein_swap64(tree_info); - skein_show_key(256, &ctx->h, key, key_bytes); - /* compute the initial chaining values from config block */ skein_256_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN); @@ -233,8 +230,6 @@ int skein_256_final(struct skein_256_ctx *ctx, u8 *hash_val) /* "output" the ctr mode bytes */ skein_put64_lsb_first(hash_val+i*SKEIN_256_BLOCK_BYTES, ctx->x, n); - skein_show_final(256, &ctx->h, n, - hash_val+i*SKEIN_256_BLOCK_BYTES); /* restore the counter mode key for next time */ memcpy(ctx->x, x, sizeof(x)); } @@ -354,8 +349,6 @@ int skein_512_init_ext(struct skein_512_ctx *ctx, size_t hash_bit_len, /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */ cfg.w[2] = skein_swap64(tree_info); - skein_show_key(512, &ctx->h, key, key_bytes); - /* compute the initial chaining values from config block */ skein_512_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN); @@ -462,8 +455,6 @@ int skein_512_final(struct skein_512_ctx *ctx, u8 *hash_val) /* "output" the ctr mode bytes */ skein_put64_lsb_first(hash_val+i*SKEIN_512_BLOCK_BYTES, ctx->x, n); - skein_show_final(512, &ctx->h, n, - hash_val+i*SKEIN_512_BLOCK_BYTES); /* restore the counter mode key for next time */ memcpy(ctx->x, x, sizeof(x)); } @@ -578,8 +569,6 @@ int skein_1024_init_ext(struct skein_1024_ctx *ctx, size_t hash_bit_len, /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */ cfg.w[2] = skein_swap64(tree_info); - skein_show_key(1024, &ctx->h, key, key_bytes); - /* compute the initial chaining values from config block */ skein_1024_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN); @@ -686,8 +675,6 @@ int skein_1024_final(struct skein_1024_ctx *ctx, u8 *hash_val) /* "output" the ctr mode bytes */ skein_put64_lsb_first(hash_val+i*SKEIN_1024_BLOCK_BYTES, ctx->x, n); - skein_show_final(1024, &ctx->h, n, - hash_val+i*SKEIN_1024_BLOCK_BYTES); /* restore the counter mode key for next time */ memcpy(ctx->x, x, sizeof(x)); } @@ -795,8 +782,6 @@ int skein_256_output(struct skein_256_ctx *ctx, u8 *hash_val) /* "output" the ctr mode bytes */ skein_put64_lsb_first(hash_val+i*SKEIN_256_BLOCK_BYTES, ctx->x, n); - skein_show_final(256, &ctx->h, n, - hash_val+i*SKEIN_256_BLOCK_BYTES); /* restore the counter mode key for next time */ memcpy(ctx->x, x, sizeof(x)); } @@ -834,8 +819,6 @@ int skein_512_output(struct skein_512_ctx *ctx, u8 *hash_val) /* "output" the ctr mode bytes */ skein_put64_lsb_first(hash_val+i*SKEIN_512_BLOCK_BYTES, ctx->x, n); - skein_show_final(256, &ctx->h, n, - hash_val+i*SKEIN_512_BLOCK_BYTES); /* restore the counter mode key for next time */ memcpy(ctx->x, x, sizeof(x)); } @@ -873,8 +856,6 @@ int skein_1024_output(struct skein_1024_ctx *ctx, u8 *hash_val) /* "output" the ctr mode bytes */ skein_put64_lsb_first(hash_val+i*SKEIN_1024_BLOCK_BYTES, ctx->x, n); - skein_show_final(256, &ctx->h, n, - hash_val+i*SKEIN_1024_BLOCK_BYTES); /* restore the counter mode key for next time */ memcpy(ctx->x, x, sizeof(x)); } diff --git a/drivers/staging/skein/skein.h b/drivers/staging/skein/skein_base.h index e6669f196e5d..3c7f8ad3627d 100644 --- a/drivers/staging/skein/skein.h +++ b/drivers/staging/skein/skein_base.h @@ -15,10 +15,6 @@ ** ** The "default" note explains what happens when the switch is not defined. ** -** SKEIN_DEBUG -- make callouts from inside Skein code -** to examine/display intermediate values. -** [default: no callouts (no overhead)] -** ** SKEIN_ERR_CHECK -- how error checking is handled inside Skein ** code. If not defined, most error checking ** is disabled (for performance). Otherwise, @@ -28,9 +24,10 @@ ** ***************************************************************************/ -#ifndef rotl_64 -#define rotl_64(x, N) (((x) << (N)) | ((x) >> (64-(N)))) -#endif +/*Skein digest sizes for crypto api*/ +#define SKEIN256_DIGEST_BIT_SIZE 256 +#define SKEIN512_DIGEST_BIT_SIZE 512 +#define SKEIN1024_DIGEST_BIT_SIZE 1024 /* below two prototype assume we are handed aligned data */ #define skein_put64_lsb_first(dst08, src64, b_cnt) memcpy(dst08, src64, b_cnt) @@ -44,12 +41,12 @@ enum { SKEIN_BAD_HASHLEN = 2 }; -#define SKEIN_MODIFIER_WORDS (2) /* number of modifier (tweak) words */ +#define SKEIN_MODIFIER_WORDS 2 /* number of modifier (tweak) words */ -#define SKEIN_256_STATE_WORDS (4) -#define SKEIN_512_STATE_WORDS (8) -#define SKEIN_1024_STATE_WORDS (16) -#define SKEIN_MAX_STATE_WORDS (16) +#define SKEIN_256_STATE_WORDS 4 +#define SKEIN_512_STATE_WORDS 8 +#define SKEIN_1024_STATE_WORDS 16 +#define SKEIN_MAX_STATE_WORDS 16 #define SKEIN_256_STATE_BYTES (8*SKEIN_256_STATE_WORDS) #define SKEIN_512_STATE_BYTES (8*SKEIN_512_STATE_WORDS) @@ -87,6 +84,11 @@ struct skein_1024_ctx { /* 1024-bit Skein hash context structure */ u8 b[SKEIN_1024_BLOCK_BYTES]; /* partial block buf (8-byte aligned) */ }; +static inline u64 rotl_64(u64 x, u8 N) +{ + return (x << N) | (x >> (64 - N)); +} + /* Skein APIs for (incremental) "straight hashing" */ int skein_256_init(struct skein_256_ctx *ctx, size_t hash_bit_len); int skein_512_init(struct skein_512_ctx *ctx, size_t hash_bit_len); @@ -273,19 +275,6 @@ int skein_1024_output(struct skein_1024_ctx *ctx, u8 *hash_val); (hdr).tweak[1] |= SKEIN_T1_TREE_LEVEL(height); \ } -/***************************************************************** -** "Internal" Skein definitions for debugging and error checking -******************************************************************/ -#ifdef SKEIN_DEBUG /* examine/display intermediate values? */ -#include "skein_debug.h" -#else /* default is no callouts */ -#define skein_show_block(bits, ctx, x, blk_ptr, w_ptr, ks_event_ptr, ks_odd_ptr) -#define skein_show_round(bits, ctx, r, x) -#define skein_show_r_ptr(bits, ctx, r, x_ptr) -#define skein_show_final(bits, ctx, cnt, out_ptr) -#define skein_show_key(bits, ctx, key, key_bytes) -#endif - /* ignore all asserts, for performance */ #define skein_assert_ret(x, ret_code) #define skein_assert(x) diff --git a/drivers/staging/skein/skein_block.c b/drivers/staging/skein/skein_block.c index 616364faf92e..66261ab25c88 100644 --- a/drivers/staging/skein/skein_block.c +++ b/drivers/staging/skein/skein_block.c @@ -15,7 +15,7 @@ ************************************************************************/ #include <linux/string.h> -#include "skein.h" +#include "skein_base.h" #include "skein_block.h" #ifndef SKEIN_USE_ASM @@ -26,32 +26,27 @@ #define SKEIN_LOOP 001 /* default: unroll 256 and 512, but not 1024 */ #endif -#define BLK_BITS (WCNT*64) /* some useful definitions for code here */ +#define BLK_BITS (WCNT * 64) /* some useful definitions for code here */ #define KW_TWK_BASE (0) #define KW_KEY_BASE (3) #define ks (kw + KW_KEY_BASE) #define ts (kw + KW_TWK_BASE) #ifdef SKEIN_DEBUG -#define debug_save_tweak(ctx) { \ - ctx->h.tweak[0] = ts[0]; ctx->h.tweak[1] = ts[1]; } +#define debug_save_tweak(ctx) \ +{ \ + ctx->h.tweak[0] = ts[0]; \ + ctx->h.tweak[1] = ts[1]; \ +} #else #define debug_save_tweak(ctx) #endif -/***************************** SKEIN_256 ******************************/ #if !(SKEIN_USE_ASM & 256) -void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr, - size_t blk_cnt, size_t byte_cnt_add) - { /* do it in C */ - enum { - WCNT = SKEIN_256_STATE_WORDS - }; #undef RCNT -#define RCNT (SKEIN_256_ROUNDS_TOTAL/8) - +#define RCNT (SKEIN_256_ROUNDS_TOTAL / 8) #ifdef SKEIN_LOOP /* configure how much to unroll the loop */ -#define SKEIN_UNROLL_256 (((SKEIN_LOOP)/100)%10) +#define SKEIN_UNROLL_256 (((SKEIN_LOOP) / 100) % 10) #else #define SKEIN_UNROLL_256 (0) #endif @@ -60,17 +55,329 @@ void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr, #if (RCNT % SKEIN_UNROLL_256) #error "Invalid SKEIN_UNROLL_256" /* sanity check on unroll count */ #endif - size_t r; - u64 kw[WCNT+4+RCNT*2]; /* key schedule: chaining vars + tweak + "rot"*/ +#endif +#define ROUND256(p0, p1, p2, p3, ROT, r_num) \ +do { \ + X##p0 += X##p1; \ + X##p1 = rotl_64(X##p1, ROT##_0); \ + X##p1 ^= X##p0; \ + X##p2 += X##p3; \ + X##p3 = rotl_64(X##p3, ROT##_1); \ + X##p3 ^= X##p2; \ +} while (0) + +#if SKEIN_UNROLL_256 == 0 +#define R256(p0, p1, p2, p3, ROT, r_num) /* fully unrolled */ \ +do { \ + ROUND256(p0, p1, p2, p3, ROT, r_num); \ +} while (0) + +#define I256(R) \ +do { \ + /* inject the key schedule value */ \ + X0 += ks[((R) + 1) % 5]; \ + X1 += ks[((R) + 2) % 5] + ts[((R) + 1) % 3]; \ + X2 += ks[((R) + 3) % 5] + ts[((R) + 2) % 3]; \ + X3 += ks[((R) + 4) % 5] + (R) + 1; \ +} while (0) #else - u64 kw[WCNT+4]; /* key schedule words : chaining vars + tweak */ +/* looping version */ +#define R256(p0, p1, p2, p3, ROT, r_num) \ +do { \ + ROUND256(p0, p1, p2, p3, ROT, r_num); \ +} while (0) + +#define I256(R) \ +do { \ + /* inject the key schedule value */ \ + X0 += ks[r + (R) + 0]; \ + X1 += ks[r + (R) + 1] + ts[r + (R) + 0]; \ + X2 += ks[r + (R) + 2] + ts[r + (R) + 1]; \ + X3 += ks[r + (R) + 3] + r + (R); \ + /* rotate key schedule */ \ + ks[r + (R) + 4] = ks[r + (R) - 1]; \ + ts[r + (R) + 2] = ts[r + (R) - 1]; \ +} while (0) +#endif +#define R256_8_ROUNDS(R) \ +do { \ + R256(0, 1, 2, 3, R_256_0, 8 * (R) + 1); \ + R256(0, 3, 2, 1, R_256_1, 8 * (R) + 2); \ + R256(0, 1, 2, 3, R_256_2, 8 * (R) + 3); \ + R256(0, 3, 2, 1, R_256_3, 8 * (R) + 4); \ + I256(2 * (R)); \ + R256(0, 1, 2, 3, R_256_4, 8 * (R) + 5); \ + R256(0, 3, 2, 1, R_256_5, 8 * (R) + 6); \ + R256(0, 1, 2, 3, R_256_6, 8 * (R) + 7); \ + R256(0, 3, 2, 1, R_256_7, 8 * (R) + 8); \ + I256(2 * (R) + 1); \ +} while (0) + +#define R256_UNROLL_R(NN) \ + ((SKEIN_UNROLL_256 == 0 && \ + SKEIN_256_ROUNDS_TOTAL / 8 > (NN)) || \ + (SKEIN_UNROLL_256 > (NN))) + +#if (SKEIN_UNROLL_256 > 14) +#error "need more unrolling in skein_256_process_block" +#endif +#endif + +#if !(SKEIN_USE_ASM & 512) +#undef RCNT +#define RCNT (SKEIN_512_ROUNDS_TOTAL/8) + +#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ +#define SKEIN_UNROLL_512 (((SKEIN_LOOP)/10)%10) +#else +#define SKEIN_UNROLL_512 (0) +#endif + +#if SKEIN_UNROLL_512 +#if (RCNT % SKEIN_UNROLL_512) +#error "Invalid SKEIN_UNROLL_512" /* sanity check on unroll count */ +#endif +#endif +#define ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ +do { \ + X##p0 += X##p1; \ + X##p1 = rotl_64(X##p1, ROT##_0); \ + X##p1 ^= X##p0; \ + X##p2 += X##p3; \ + X##p3 = rotl_64(X##p3, ROT##_1); \ + X##p3 ^= X##p2; \ + X##p4 += X##p5; \ + X##p5 = rotl_64(X##p5, ROT##_2); \ + X##p5 ^= X##p4; \ + X##p6 += X##p7; X##p7 = rotl_64(X##p7, ROT##_3); \ + X##p7 ^= X##p6; \ +} while (0) + +#if SKEIN_UNROLL_512 == 0 +#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) /* unrolled */ \ +do { \ + ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num); \ +} while (0) + +#define I512(R) \ +do { \ + /* inject the key schedule value */ \ + X0 += ks[((R) + 1) % 9]; \ + X1 += ks[((R) + 2) % 9]; \ + X2 += ks[((R) + 3) % 9]; \ + X3 += ks[((R) + 4) % 9]; \ + X4 += ks[((R) + 5) % 9]; \ + X5 += ks[((R) + 6) % 9] + ts[((R) + 1) % 3]; \ + X6 += ks[((R) + 7) % 9] + ts[((R) + 2) % 3]; \ + X7 += ks[((R) + 8) % 9] + (R) + 1; \ +} while (0) + +#else /* looping version */ +#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ +do { \ + ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num); \ +} while (0) + +#define I512(R) \ +do { \ + /* inject the key schedule value */ \ + X0 += ks[r + (R) + 0]; \ + X1 += ks[r + (R) + 1]; \ + X2 += ks[r + (R) + 2]; \ + X3 += ks[r + (R) + 3]; \ + X4 += ks[r + (R) + 4]; \ + X5 += ks[r + (R) + 5] + ts[r + (R) + 0]; \ + X6 += ks[r + (R) + 6] + ts[r + (R) + 1]; \ + X7 += ks[r + (R) + 7] + r + (R); \ + /* rotate key schedule */ \ + ks[r + (R) + 8] = ks[r + (R) - 1]; \ + ts[r + (R) + 2] = ts[r + (R) - 1]; \ +} while (0) +#endif /* end of looped code definitions */ +#define R512_8_ROUNDS(R) /* do 8 full rounds */ \ +do { \ + R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_0, 8 * (R) + 1); \ + R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_1, 8 * (R) + 2); \ + R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_2, 8 * (R) + 3); \ + R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_3, 8 * (R) + 4); \ + I512(2 * (R)); \ + R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_4, 8 * (R) + 5); \ + R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_5, 8 * (R) + 6); \ + R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_6, 8 * (R) + 7); \ + R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_7, 8 * (R) + 8); \ + I512(2 * (R) + 1); /* and key injection */ \ +} while (0) +#define R512_UNROLL_R(NN) \ + ((SKEIN_UNROLL_512 == 0 && \ + SKEIN_512_ROUNDS_TOTAL/8 > (NN)) || \ + (SKEIN_UNROLL_512 > (NN))) + +#if (SKEIN_UNROLL_512 > 14) +#error "need more unrolling in skein_512_process_block" +#endif +#endif + +#if !(SKEIN_USE_ASM & 1024) +#undef RCNT +#define RCNT (SKEIN_1024_ROUNDS_TOTAL/8) +#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ +#define SKEIN_UNROLL_1024 ((SKEIN_LOOP)%10) +#else +#define SKEIN_UNROLL_1024 (0) +#endif + +#if (SKEIN_UNROLL_1024 != 0) +#if (RCNT % SKEIN_UNROLL_1024) +#error "Invalid SKEIN_UNROLL_1024" /* sanity check on unroll count */ +#endif +#endif +#define ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ + pF, ROT, r_num) \ +do { \ + X##p0 += X##p1; \ + X##p1 = rotl_64(X##p1, ROT##_0); \ + X##p1 ^= X##p0; \ + X##p2 += X##p3; \ + X##p3 = rotl_64(X##p3, ROT##_1); \ + X##p3 ^= X##p2; \ + X##p4 += X##p5; \ + X##p5 = rotl_64(X##p5, ROT##_2); \ + X##p5 ^= X##p4; \ + X##p6 += X##p7; \ + X##p7 = rotl_64(X##p7, ROT##_3); \ + X##p7 ^= X##p6; \ + X##p8 += X##p9; \ + X##p9 = rotl_64(X##p9, ROT##_4); \ + X##p9 ^= X##p8; \ + X##pA += X##pB; \ + X##pB = rotl_64(X##pB, ROT##_5); \ + X##pB ^= X##pA; \ + X##pC += X##pD; \ + X##pD = rotl_64(X##pD, ROT##_6); \ + X##pD ^= X##pC; \ + X##pE += X##pF; \ + X##pF = rotl_64(X##pF, ROT##_7); \ + X##pF ^= X##pE; \ +} while (0) + +#if SKEIN_UNROLL_1024 == 0 +#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \ + ROT, rn) \ +do { \ + ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ + pF, ROT, rn); \ +} while (0) + +#define I1024(R) \ +do { \ + /* inject the key schedule value */ \ + X00 += ks[((R) + 1) % 17]; \ + X01 += ks[((R) + 2) % 17]; \ + X02 += ks[((R) + 3) % 17]; \ + X03 += ks[((R) + 4) % 17]; \ + X04 += ks[((R) + 5) % 17]; \ + X05 += ks[((R) + 6) % 17]; \ + X06 += ks[((R) + 7) % 17]; \ + X07 += ks[((R) + 8) % 17]; \ + X08 += ks[((R) + 9) % 17]; \ + X09 += ks[((R) + 10) % 17]; \ + X10 += ks[((R) + 11) % 17]; \ + X11 += ks[((R) + 12) % 17]; \ + X12 += ks[((R) + 13) % 17]; \ + X13 += ks[((R) + 14) % 17] + ts[((R) + 1) % 3]; \ + X14 += ks[((R) + 15) % 17] + ts[((R) + 2) % 3]; \ + X15 += ks[((R) + 16) % 17] + (R) + 1; \ +} while (0) +#else /* looping version */ +#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \ + ROT, rn) \ +do { \ + ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ + pF, ROT, rn); \ +} while (0) + +#define I1024(R) \ +do { \ + /* inject the key schedule value */ \ + X00 += ks[r + (R) + 0]; \ + X01 += ks[r + (R) + 1]; \ + X02 += ks[r + (R) + 2]; \ + X03 += ks[r + (R) + 3]; \ + X04 += ks[r + (R) + 4]; \ + X05 += ks[r + (R) + 5]; \ + X06 += ks[r + (R) + 6]; \ + X07 += ks[r + (R) + 7]; \ + X08 += ks[r + (R) + 8]; \ + X09 += ks[r + (R) + 9]; \ + X10 += ks[r + (R) + 10]; \ + X11 += ks[r + (R) + 11]; \ + X12 += ks[r + (R) + 12]; \ + X13 += ks[r + (R) + 13] + ts[r + (R) + 0]; \ + X14 += ks[r + (R) + 14] + ts[r + (R) + 1]; \ + X15 += ks[r + (R) + 15] + r + (R); \ + /* rotate key schedule */ \ + ks[r + (R) + 16] = ks[r + (R) - 1]; \ + ts[r + (R) + 2] = ts[r + (R) - 1]; \ +} while (0) + +#endif +#define R1024_8_ROUNDS(R) \ +do { \ + R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, \ + R1024_0, 8*(R) + 1); \ + R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, 05, 08, 01, \ + R1024_1, 8*(R) + 2); \ + R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, 11, 10, 09, \ + R1024_2, 8*(R) + 3); \ + R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, 03, 12, 07, \ + R1024_3, 8*(R) + 4); \ + I1024(2*(R)); \ + R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, \ + R1024_4, 8*(R) + 5); \ + R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, 05, 08, 01, \ + R1024_5, 8*(R) + 6); \ + R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, 11, 10, 09, \ + R1024_6, 8*(R) + 7); \ + R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, 03, 12, 07, \ + R1024_7, 8*(R) + 8); \ + I1024(2*(R)+1); \ +} while (0) + +#define R1024_UNROLL_R(NN) \ + ((SKEIN_UNROLL_1024 == 0 && \ + SKEIN_1024_ROUNDS_TOTAL/8 > (NN)) || \ + (SKEIN_UNROLL_1024 > (NN))) + +#if (SKEIN_UNROLL_1024 > 14) +#error "need more unrolling in Skein_1024_Process_Block" +#endif +#endif + +/***************************** SKEIN_256 ******************************/ +#if !(SKEIN_USE_ASM & 256) +void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr, + size_t blk_cnt, size_t byte_cnt_add) +{ /* do it in C */ + enum { + WCNT = SKEIN_256_STATE_WORDS + }; + size_t r; +#if SKEIN_UNROLL_256 + /* key schedule: chaining vars + tweak + "rot"*/ + u64 kw[WCNT+4+RCNT*2]; +#else + /* key schedule words : chaining vars + tweak */ + u64 kw[WCNT+4]; #endif u64 X0, X1, X2, X3; /* local copy of context vars, for speed */ u64 w[WCNT]; /* local copy of input block */ #ifdef SKEIN_DEBUG const u64 *X_ptr[4]; /* use for debugging (help cc put Xn in regs) */ - X_ptr[0] = &X0; X_ptr[1] = &X1; X_ptr[2] = &X2; X_ptr[3] = &X3; + X_ptr[0] = &X0; + X_ptr[1] = &X1; + X_ptr[2] = &X2; + X_ptr[3] = &X3; #endif skein_assert(blk_cnt != 0); /* never call with blk_cnt == 0! */ ts[0] = ctx->h.tweak[0]; @@ -94,132 +401,62 @@ void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr, /* get input block in little-endian format */ skein_get64_lsb_first(w, blk_ptr, WCNT); debug_save_tweak(ctx); - skein_show_block(BLK_BITS, &ctx->h, ctx->x, blk_ptr, w, ks, ts); - X0 = w[0] + ks[0]; /* do the first full key injection */ + /* do the first full key injection */ + X0 = w[0] + ks[0]; X1 = w[1] + ks[1] + ts[0]; X2 = w[2] + ks[2] + ts[1]; X3 = w[3] + ks[3]; - /* show starting state values */ - skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INITIAL, - x_ptr); - blk_ptr += SKEIN_256_BLOCK_BYTES; /* run the rounds */ - -#define ROUND256(p0, p1, p2, p3, ROT, r_num) \ -do { \ - X##p0 += X##p1; X##p1 = rotl_64(X##p1, ROT##_0); X##p1 ^= X##p0; \ - X##p2 += X##p3; X##p3 = rotl_64(X##p3, ROT##_1); X##p3 ^= X##p2; \ -} while (0) - -#if SKEIN_UNROLL_256 == 0 -#define R256(p0, p1, p2, p3, ROT, r_num) /* fully unrolled */ \ -do { \ - ROUND256(p0, p1, p2, p3, ROT, r_num); \ - skein_show_r_ptr(BLK_BITS, &ctx->h, r_num, X_ptr); \ -} while (0) - -#define I256(R) \ -do { \ - /* inject the key schedule value */ \ - X0 += ks[((R)+1) % 5]; \ - X1 += ks[((R)+2) % 5] + ts[((R)+1) % 3]; \ - X2 += ks[((R)+3) % 5] + ts[((R)+2) % 3]; \ - X3 += ks[((R)+4) % 5] + (R)+1; \ - skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ -} while (0) -#else /* looping version */ -#define R256(p0, p1, p2, p3, ROT, r_num) \ -do { \ - ROUND256(p0, p1, p2, p3, ROT, r_num); \ - skein_show_r_ptr(BLK_BITS, &ctx->h, 4 * (r - 1) + r_num, X_ptr); \ -} while (0) - -#define I256(R) \ -do { \ - /* inject the key schedule value */ \ - X0 += ks[r+(R)+0]; \ - X1 += ks[r+(R)+1] + ts[r+(R)+0]; \ - X2 += ks[r+(R)+2] + ts[r+(R)+1]; \ - X3 += ks[r+(R)+3] + r+(R); \ - /* rotate key schedule */ \ - ks[r + (R) + 4] = ks[r + (R) - 1]; \ - ts[r + (R) + 2] = ts[r + (R) - 1]; \ - skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ -} while (0) - - for (r = 1; r < 2 * RCNT; r += 2 * SKEIN_UNROLL_256) + for (r = 1; + r < (SKEIN_UNROLL_256 ? 2 * RCNT : 2); + r += (SKEIN_UNROLL_256 ? 2 * SKEIN_UNROLL_256 : 1)) { + R256_8_ROUNDS(0); +#if R256_UNROLL_R(1) + R256_8_ROUNDS(1); +#endif +#if R256_UNROLL_R(2) + R256_8_ROUNDS(2); +#endif +#if R256_UNROLL_R(3) + R256_8_ROUNDS(3); +#endif +#if R256_UNROLL_R(4) + R256_8_ROUNDS(4); +#endif +#if R256_UNROLL_R(5) + R256_8_ROUNDS(5); +#endif +#if R256_UNROLL_R(6) + R256_8_ROUNDS(6); +#endif +#if R256_UNROLL_R(7) + R256_8_ROUNDS(7); +#endif +#if R256_UNROLL_R(8) + R256_8_ROUNDS(8); +#endif +#if R256_UNROLL_R(9) + R256_8_ROUNDS(9); +#endif +#if R256_UNROLL_R(10) + R256_8_ROUNDS(10); +#endif +#if R256_UNROLL_R(11) + R256_8_ROUNDS(11); +#endif +#if R256_UNROLL_R(12) + R256_8_ROUNDS(12); +#endif +#if R256_UNROLL_R(13) + R256_8_ROUNDS(13); +#endif +#if R256_UNROLL_R(14) + R256_8_ROUNDS(14); #endif - { -#define R256_8_ROUNDS(R) \ -do { \ - R256(0, 1, 2, 3, R_256_0, 8 * (R) + 1); \ - R256(0, 3, 2, 1, R_256_1, 8 * (R) + 2); \ - R256(0, 1, 2, 3, R_256_2, 8 * (R) + 3); \ - R256(0, 3, 2, 1, R_256_3, 8 * (R) + 4); \ - I256(2 * (R)); \ - R256(0, 1, 2, 3, R_256_4, 8 * (R) + 5); \ - R256(0, 3, 2, 1, R_256_5, 8 * (R) + 6); \ - R256(0, 1, 2, 3, R_256_6, 8 * (R) + 7); \ - R256(0, 3, 2, 1, R_256_7, 8 * (R) + 8); \ - I256(2 * (R) + 1); \ -} while (0) - - R256_8_ROUNDS(0); - -#define R256_UNROLL_R(NN) \ - ((SKEIN_UNROLL_256 == 0 && \ - SKEIN_256_ROUNDS_TOTAL/8 > (NN)) || \ - (SKEIN_UNROLL_256 > (NN))) - - #if R256_UNROLL_R(1) - R256_8_ROUNDS(1); - #endif - #if R256_UNROLL_R(2) - R256_8_ROUNDS(2); - #endif - #if R256_UNROLL_R(3) - R256_8_ROUNDS(3); - #endif - #if R256_UNROLL_R(4) - R256_8_ROUNDS(4); - #endif - #if R256_UNROLL_R(5) - R256_8_ROUNDS(5); - #endif - #if R256_UNROLL_R(6) - R256_8_ROUNDS(6); - #endif - #if R256_UNROLL_R(7) - R256_8_ROUNDS(7); - #endif - #if R256_UNROLL_R(8) - R256_8_ROUNDS(8); - #endif - #if R256_UNROLL_R(9) - R256_8_ROUNDS(9); - #endif - #if R256_UNROLL_R(10) - R256_8_ROUNDS(10); - #endif - #if R256_UNROLL_R(11) - R256_8_ROUNDS(11); - #endif - #if R256_UNROLL_R(12) - R256_8_ROUNDS(12); - #endif - #if R256_UNROLL_R(13) - R256_8_ROUNDS(13); - #endif - #if R256_UNROLL_R(14) - R256_8_ROUNDS(14); - #endif - #if (SKEIN_UNROLL_256 > 14) -#error "need more unrolling in skein_256_process_block" - #endif } /* do the final "feedforward" xor, update context chaining */ ctx->x[0] = X0 ^ w[0]; @@ -227,8 +464,6 @@ do { \ ctx->x[2] = X2 ^ w[2]; ctx->x[3] = X3 ^ w[3]; - skein_show_round(BLK_BITS, &ctx->h, SKEIN_RND_FEED_FWD, ctx->x); - ts[1] &= ~SKEIN_T1_FLAG_FIRST; } while (--blk_cnt); ctx->h.tweak[0] = ts[0]; @@ -256,20 +491,8 @@ void skein_512_process_block(struct skein_512_ctx *ctx, const u8 *blk_ptr, enum { WCNT = SKEIN_512_STATE_WORDS }; -#undef RCNT -#define RCNT (SKEIN_512_ROUNDS_TOTAL/8) - -#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ -#define SKEIN_UNROLL_512 (((SKEIN_LOOP)/10)%10) -#else -#define SKEIN_UNROLL_512 (0) -#endif - -#if SKEIN_UNROLL_512 -#if (RCNT % SKEIN_UNROLL_512) -#error "Invalid SKEIN_UNROLL_512" /* sanity check on unroll count */ -#endif size_t r; +#if SKEIN_UNROLL_512 u64 kw[WCNT+4+RCNT*2]; /* key sched: chaining vars + tweak + "rot"*/ #else u64 kw[WCNT+4]; /* key schedule words : chaining vars + tweak */ @@ -279,8 +502,14 @@ void skein_512_process_block(struct skein_512_ctx *ctx, const u8 *blk_ptr, #ifdef SKEIN_DEBUG const u64 *X_ptr[8]; /* use for debugging (help cc put Xn in regs) */ - X_ptr[0] = &X0; X_ptr[1] = &X1; X_ptr[2] = &X2; X_ptr[3] = &X3; - X_ptr[4] = &X4; X_ptr[5] = &X5; X_ptr[6] = &X6; X_ptr[7] = &X7; + X_ptr[0] = &X0; + X_ptr[1] = &X1; + X_ptr[2] = &X2; + X_ptr[3] = &X3; + X_ptr[4] = &X4; + X_ptr[5] = &X5; + X_ptr[6] = &X6; + X_ptr[7] = &X7; #endif skein_assert(blk_cnt != 0); /* never call with blk_cnt == 0! */ @@ -310,143 +539,68 @@ void skein_512_process_block(struct skein_512_ctx *ctx, const u8 *blk_ptr, /* get input block in little-endian format */ skein_get64_lsb_first(w, blk_ptr, WCNT); debug_save_tweak(ctx); - skein_show_block(BLK_BITS, &ctx->h, ctx->x, blk_ptr, w, ks, ts); - X0 = w[0] + ks[0]; /* do the first full key injection */ - X1 = w[1] + ks[1]; - X2 = w[2] + ks[2]; - X3 = w[3] + ks[3]; - X4 = w[4] + ks[4]; - X5 = w[5] + ks[5] + ts[0]; - X6 = w[6] + ks[6] + ts[1]; - X7 = w[7] + ks[7]; + /* do the first full key injection */ + X0 = w[0] + ks[0]; + X1 = w[1] + ks[1]; + X2 = w[2] + ks[2]; + X3 = w[3] + ks[3]; + X4 = w[4] + ks[4]; + X5 = w[5] + ks[5] + ts[0]; + X6 = w[6] + ks[6] + ts[1]; + X7 = w[7] + ks[7]; blk_ptr += SKEIN_512_BLOCK_BYTES; - skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INITIAL, - X_ptr); /* run the rounds */ -#define ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ -do { \ - X##p0 += X##p1; X##p1 = rotl_64(X##p1, ROT##_0); X##p1 ^= X##p0; \ - X##p2 += X##p3; X##p3 = rotl_64(X##p3, ROT##_1); X##p3 ^= X##p2; \ - X##p4 += X##p5; X##p5 = rotl_64(X##p5, ROT##_2); X##p5 ^= X##p4; \ - X##p6 += X##p7; X##p7 = rotl_64(X##p7, ROT##_3); X##p7 ^= X##p6; \ -} while (0) - -#if SKEIN_UNROLL_512 == 0 -#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) /* unrolled */ \ -do { \ - ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ - skein_show_r_ptr(BLK_BITS, &ctx->h, r_num, X_ptr); \ -} while (0) - -#define I512(R) \ -do { \ - /* inject the key schedule value */ \ - X0 += ks[((R) + 1) % 9]; \ - X1 += ks[((R) + 2) % 9]; \ - X2 += ks[((R) + 3) % 9]; \ - X3 += ks[((R) + 4) % 9]; \ - X4 += ks[((R) + 5) % 9]; \ - X5 += ks[((R) + 6) % 9] + ts[((R) + 1) % 3]; \ - X6 += ks[((R) + 7) % 9] + ts[((R) + 2) % 3]; \ - X7 += ks[((R) + 8) % 9] + (R) + 1; \ - skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ -} while (0) -#else /* looping version */ -#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ -do { \ - ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num); \ - skein_show_r_ptr(BLK_BITS, &ctx->h, 4 * (r - 1) + r_num, X_ptr); \ -} while (0) - -#define I512(R) \ -do { \ - /* inject the key schedule value */ \ - X0 += ks[r + (R) + 0]; \ - X1 += ks[r + (R) + 1]; \ - X2 += ks[r + (R) + 2]; \ - X3 += ks[r + (R) + 3]; \ - X4 += ks[r + (R) + 4]; \ - X5 += ks[r + (R) + 5] + ts[r + (R) + 0]; \ - X6 += ks[r + (R) + 6] + ts[r + (R) + 1]; \ - X7 += ks[r + (R) + 7] + r + (R); \ - /* rotate key schedule */ \ - ks[r + (R) + 8] = ks[r + (R) - 1]; \ - ts[r + (R) + 2] = ts[r + (R) - 1]; \ - skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ -} while (0) - - for (r = 1; r < 2 * RCNT; r += 2 * SKEIN_UNROLL_512) -#endif /* end of looped code definitions */ - { -#define R512_8_ROUNDS(R) /* do 8 full rounds */ \ -do { \ - R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_0, 8 * (R) + 1); \ - R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_1, 8 * (R) + 2); \ - R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_2, 8 * (R) + 3); \ - R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_3, 8 * (R) + 4); \ - I512(2 * (R)); \ - R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_4, 8 * (R) + 5); \ - R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_5, 8 * (R) + 6); \ - R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_6, 8 * (R) + 7); \ - R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_7, 8 * (R) + 8); \ - I512(2 * (R) + 1); /* and key injection */ \ -} while (0) + for (r = 1; + r < (SKEIN_UNROLL_512 ? 2 * RCNT : 2); + r += (SKEIN_UNROLL_512 ? 2 * SKEIN_UNROLL_512 : 1)) { R512_8_ROUNDS(0); -#define R512_UNROLL_R(NN) \ - ((SKEIN_UNROLL_512 == 0 && \ - SKEIN_512_ROUNDS_TOTAL/8 > (NN)) || \ - (SKEIN_UNROLL_512 > (NN))) - - #if R512_UNROLL_R(1) +#if R512_UNROLL_R(1) R512_8_ROUNDS(1); - #endif - #if R512_UNROLL_R(2) +#endif +#if R512_UNROLL_R(2) R512_8_ROUNDS(2); - #endif - #if R512_UNROLL_R(3) +#endif +#if R512_UNROLL_R(3) R512_8_ROUNDS(3); - #endif - #if R512_UNROLL_R(4) +#endif +#if R512_UNROLL_R(4) R512_8_ROUNDS(4); - #endif - #if R512_UNROLL_R(5) +#endif +#if R512_UNROLL_R(5) R512_8_ROUNDS(5); - #endif - #if R512_UNROLL_R(6) +#endif +#if R512_UNROLL_R(6) R512_8_ROUNDS(6); - #endif - #if R512_UNROLL_R(7) +#endif +#if R512_UNROLL_R(7) R512_8_ROUNDS(7); - #endif - #if R512_UNROLL_R(8) +#endif +#if R512_UNROLL_R(8) R512_8_ROUNDS(8); - #endif - #if R512_UNROLL_R(9) +#endif +#if R512_UNROLL_R(9) R512_8_ROUNDS(9); - #endif - #if R512_UNROLL_R(10) +#endif +#if R512_UNROLL_R(10) R512_8_ROUNDS(10); - #endif - #if R512_UNROLL_R(11) +#endif +#if R512_UNROLL_R(11) R512_8_ROUNDS(11); - #endif - #if R512_UNROLL_R(12) +#endif +#if R512_UNROLL_R(12) R512_8_ROUNDS(12); - #endif - #if R512_UNROLL_R(13) +#endif +#if R512_UNROLL_R(13) R512_8_ROUNDS(13); - #endif - #if R512_UNROLL_R(14) +#endif +#if R512_UNROLL_R(14) R512_8_ROUNDS(14); - #endif - #if (SKEIN_UNROLL_512 > 14) -#error "need more unrolling in skein_512_process_block" - #endif +#endif } /* do the final "feedforward" xor, update context chaining */ @@ -458,7 +612,6 @@ do { \ ctx->x[5] = X5 ^ w[5]; ctx->x[6] = X6 ^ w[6]; ctx->x[7] = X7 ^ w[7]; - skein_show_round(BLK_BITS, &ctx->h, SKEIN_RND_FEED_FWD, ctx->x); ts[1] &= ~SKEIN_T1_FLAG_FIRST; } while (--blk_cnt); @@ -487,20 +640,8 @@ void skein_1024_process_block(struct skein_1024_ctx *ctx, const u8 *blk_ptr, enum { WCNT = SKEIN_1024_STATE_WORDS }; -#undef RCNT -#define RCNT (SKEIN_1024_ROUNDS_TOTAL/8) - -#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ -#define SKEIN_UNROLL_1024 ((SKEIN_LOOP)%10) -#else -#define SKEIN_UNROLL_1024 (0) -#endif - -#if (SKEIN_UNROLL_1024 != 0) -#if (RCNT % SKEIN_UNROLL_1024) -#error "Invalid SKEIN_UNROLL_1024" /* sanity check on unroll count */ -#endif size_t r; +#if (SKEIN_UNROLL_1024 != 0) u64 kw[WCNT+4+RCNT*2]; /* key sched: chaining vars + tweak + "rot" */ #else u64 kw[WCNT+4]; /* key schedule words : chaining vars + tweak */ @@ -510,16 +651,6 @@ void skein_1024_process_block(struct skein_1024_ctx *ctx, const u8 *blk_ptr, u64 X00, X01, X02, X03, X04, X05, X06, X07, X08, X09, X10, X11, X12, X13, X14, X15; u64 w[WCNT]; /* local copy of input block */ -#ifdef SKEIN_DEBUG - const u64 *X_ptr[16]; /* use for debugging (help cc put Xn in regs) */ - - X_ptr[0] = &X00; X_ptr[1] = &X01; X_ptr[2] = &X02; - X_ptr[3] = &X03; X_ptr[4] = &X04; X_ptr[5] = &X05; - X_ptr[6] = &X06; X_ptr[7] = &X07; X_ptr[8] = &X08; - X_ptr[9] = &X09; X_ptr[10] = &X10; X_ptr[11] = &X11; - X_ptr[12] = &X12; X_ptr[13] = &X13; X_ptr[14] = &X14; - X_ptr[15] = &X15; -#endif skein_assert(blk_cnt != 0); /* never call with blk_cnt == 0! */ ts[0] = ctx->h.tweak[0]; @@ -548,192 +679,81 @@ void skein_1024_process_block(struct skein_1024_ctx *ctx, const u8 *blk_ptr, ks[13] = ctx->x[13]; ks[14] = ctx->x[14]; ks[15] = ctx->x[15]; - ks[16] = ks[0] ^ ks[1] ^ ks[2] ^ ks[3] ^ - ks[4] ^ ks[5] ^ ks[6] ^ ks[7] ^ - ks[8] ^ ks[9] ^ ks[10] ^ ks[11] ^ + ks[16] = ks[0] ^ ks[1] ^ ks[2] ^ ks[3] ^ + ks[4] ^ ks[5] ^ ks[6] ^ ks[7] ^ + ks[8] ^ ks[9] ^ ks[10] ^ ks[11] ^ ks[12] ^ ks[13] ^ ks[14] ^ ks[15] ^ SKEIN_KS_PARITY; - ts[2] = ts[0] ^ ts[1]; + ts[2] = ts[0] ^ ts[1]; /* get input block in little-endian format */ skein_get64_lsb_first(w, blk_ptr, WCNT); debug_save_tweak(ctx); - skein_show_block(BLK_BITS, &ctx->h, ctx->x, blk_ptr, w, ks, ts); - - X00 = w[0] + ks[0]; /* do the first full key injection */ - X01 = w[1] + ks[1]; - X02 = w[2] + ks[2]; - X03 = w[3] + ks[3]; - X04 = w[4] + ks[4]; - X05 = w[5] + ks[5]; - X06 = w[6] + ks[6]; - X07 = w[7] + ks[7]; - X08 = w[8] + ks[8]; - X09 = w[9] + ks[9]; - X10 = w[10] + ks[10]; - X11 = w[11] + ks[11]; - X12 = w[12] + ks[12]; - X13 = w[13] + ks[13] + ts[0]; - X14 = w[14] + ks[14] + ts[1]; - X15 = w[15] + ks[15]; - - skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INITIAL, - X_ptr); - -#define ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ - pF, ROT, r_num) \ -do { \ - X##p0 += X##p1; X##p1 = rotl_64(X##p1, ROT##_0); X##p1 ^= X##p0; \ - X##p2 += X##p3; X##p3 = rotl_64(X##p3, ROT##_1); X##p3 ^= X##p2; \ - X##p4 += X##p5; X##p5 = rotl_64(X##p5, ROT##_2); X##p5 ^= X##p4; \ - X##p6 += X##p7; X##p7 = rotl_64(X##p7, ROT##_3); X##p7 ^= X##p6; \ - X##p8 += X##p9; X##p9 = rotl_64(X##p9, ROT##_4); X##p9 ^= X##p8; \ - X##pA += X##pB; X##pB = rotl_64(X##pB, ROT##_5); X##pB ^= X##pA; \ - X##pC += X##pD; X##pD = rotl_64(X##pD, ROT##_6); X##pD ^= X##pC; \ - X##pE += X##pF; X##pF = rotl_64(X##pF, ROT##_7); X##pF ^= X##pE; \ -} while (0) - -#if SKEIN_UNROLL_1024 == 0 -#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \ - ROT, rn) \ -do { \ - ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ - pF, ROT, rn); \ - skein_show_r_ptr(BLK_BITS, &ctx->h, rn, X_ptr); \ -} while (0) - -#define I1024(R) \ -do { \ - /* inject the key schedule value */ \ - X00 += ks[((R) + 1) % 17]; \ - X01 += ks[((R) + 2) % 17]; \ - X02 += ks[((R) + 3) % 17]; \ - X03 += ks[((R) + 4) % 17]; \ - X04 += ks[((R) + 5) % 17]; \ - X05 += ks[((R) + 6) % 17]; \ - X06 += ks[((R) + 7) % 17]; \ - X07 += ks[((R) + 8) % 17]; \ - X08 += ks[((R) + 9) % 17]; \ - X09 += ks[((R) + 10) % 17]; \ - X10 += ks[((R) + 11) % 17]; \ - X11 += ks[((R) + 12) % 17]; \ - X12 += ks[((R) + 13) % 17]; \ - X13 += ks[((R) + 14) % 17] + ts[((R) + 1) % 3]; \ - X14 += ks[((R) + 15) % 17] + ts[((R) + 2) % 3]; \ - X15 += ks[((R) + 16) % 17] + (R) + 1; \ - skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ -} while (0) -#else /* looping version */ -#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \ - ROT, rn) \ -do { \ - ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ - pF, ROT, rn); \ - skein_show_r_ptr(BLK_BITS, &ctx->h, 4 * (r - 1) + rn, X_ptr); \ -} while (0) - -#define I1024(R) \ -do { \ - /* inject the key schedule value */ \ - X00 += ks[r + (R) + 0]; \ - X01 += ks[r + (R) + 1]; \ - X02 += ks[r + (R) + 2]; \ - X03 += ks[r + (R) + 3]; \ - X04 += ks[r + (R) + 4]; \ - X05 += ks[r + (R) + 5]; \ - X06 += ks[r + (R) + 6]; \ - X07 += ks[r + (R) + 7]; \ - X08 += ks[r + (R) + 8]; \ - X09 += ks[r + (R) + 9]; \ - X10 += ks[r + (R) + 10]; \ - X11 += ks[r + (R) + 11]; \ - X12 += ks[r + (R) + 12]; \ - X13 += ks[r + (R) + 13] + ts[r + (R) + 0]; \ - X14 += ks[r + (R) + 14] + ts[r + (R) + 1]; \ - X15 += ks[r + (R) + 15] + r + (R); \ - /* rotate key schedule */ \ - ks[r + (R) + 16] = ks[r + (R) - 1]; \ - ts[r + (R) + 2] = ts[r + (R) - 1]; \ - skein_show_r_ptr(BLK_BITSi, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ -} while (0) - - for (r = 1; r <= 2 * RCNT; r += 2 * SKEIN_UNROLL_1024) -#endif - { -#define R1024_8_ROUNDS(R) \ -do { \ - R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, \ - R1024_0, 8*(R) + 1); \ - R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, 05, 08, 01, \ - R1024_1, 8*(R) + 2); \ - R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, 11, 10, 09, \ - R1024_2, 8*(R) + 3); \ - R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, 03, 12, 07, \ - R1024_3, 8*(R) + 4); \ - I1024(2*(R)); \ - R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, \ - R1024_4, 8*(R) + 5); \ - R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, 05, 08, 01, \ - R1024_5, 8*(R) + 6); \ - R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, 11, 10, 09, \ - R1024_6, 8*(R) + 7); \ - R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, 03, 12, 07, \ - R1024_7, 8*(R) + 8); \ - I1024(2*(R)+1); \ -} while (0) + /* do the first full key injection */ + X00 = w[0] + ks[0]; + X01 = w[1] + ks[1]; + X02 = w[2] + ks[2]; + X03 = w[3] + ks[3]; + X04 = w[4] + ks[4]; + X05 = w[5] + ks[5]; + X06 = w[6] + ks[6]; + X07 = w[7] + ks[7]; + X08 = w[8] + ks[8]; + X09 = w[9] + ks[9]; + X10 = w[10] + ks[10]; + X11 = w[11] + ks[11]; + X12 = w[12] + ks[12]; + X13 = w[13] + ks[13] + ts[0]; + X14 = w[14] + ks[14] + ts[1]; + X15 = w[15] + ks[15]; + + for (r = 1; + r < (SKEIN_UNROLL_1024 ? 2 * RCNT : 2); + r += (SKEIN_UNROLL_1024 ? 2 * SKEIN_UNROLL_1024 : 1)) { R1024_8_ROUNDS(0); - -#define R1024_UNROLL_R(NN) \ - ((SKEIN_UNROLL_1024 == 0 && \ - SKEIN_1024_ROUNDS_TOTAL/8 > (NN)) || \ - (SKEIN_UNROLL_1024 > (NN))) - - #if R1024_UNROLL_R(1) +#if R1024_UNROLL_R(1) R1024_8_ROUNDS(1); - #endif - #if R1024_UNROLL_R(2) +#endif +#if R1024_UNROLL_R(2) R1024_8_ROUNDS(2); - #endif - #if R1024_UNROLL_R(3) +#endif +#if R1024_UNROLL_R(3) R1024_8_ROUNDS(3); - #endif - #if R1024_UNROLL_R(4) +#endif +#if R1024_UNROLL_R(4) R1024_8_ROUNDS(4); - #endif - #if R1024_UNROLL_R(5) +#endif +#if R1024_UNROLL_R(5) R1024_8_ROUNDS(5); - #endif - #if R1024_UNROLL_R(6) +#endif +#if R1024_UNROLL_R(6) R1024_8_ROUNDS(6); - #endif - #if R1024_UNROLL_R(7) +#endif +#if R1024_UNROLL_R(7) R1024_8_ROUNDS(7); - #endif - #if R1024_UNROLL_R(8) +#endif +#if R1024_UNROLL_R(8) R1024_8_ROUNDS(8); - #endif - #if R1024_UNROLL_R(9) +#endif +#if R1024_UNROLL_R(9) R1024_8_ROUNDS(9); - #endif - #if R1024_UNROLL_R(10) +#endif +#if R1024_UNROLL_R(10) R1024_8_ROUNDS(10); - #endif - #if R1024_UNROLL_R(11) +#endif +#if R1024_UNROLL_R(11) R1024_8_ROUNDS(11); - #endif - #if R1024_UNROLL_R(12) +#endif +#if R1024_UNROLL_R(12) R1024_8_ROUNDS(12); - #endif - #if R1024_UNROLL_R(13) +#endif +#if R1024_UNROLL_R(13) R1024_8_ROUNDS(13); - #endif - #if R1024_UNROLL_R(14) +#endif +#if R1024_UNROLL_R(14) R1024_8_ROUNDS(14); - #endif -#if (SKEIN_UNROLL_1024 > 14) -#error "need more unrolling in Skein_1024_Process_Block" - #endif +#endif } /* do the final "feedforward" xor, update context chaining */ @@ -754,8 +774,6 @@ do { \ ctx->x[14] = X14 ^ w[14]; ctx->x[15] = X15 ^ w[15]; - skein_show_round(BLK_BITS, &ctx->h, SKEIN_RND_FEED_FWD, ctx->x); - ts[1] &= ~SKEIN_T1_FLAG_FIRST; blk_ptr += SKEIN_1024_BLOCK_BYTES; } while (--blk_cnt); diff --git a/drivers/staging/skein/skein_block.h b/drivers/staging/skein/skein_block.h index bd7bdc35df29..9d40f4a5267b 100644 --- a/drivers/staging/skein/skein_block.h +++ b/drivers/staging/skein/skein_block.h @@ -10,7 +10,7 @@ #ifndef _SKEIN_BLOCK_H_ #define _SKEIN_BLOCK_H_ -#include "skein.h" /* get the Skein API definitions */ +#include "skein_base.h" /* get the Skein API definitions */ void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr, size_t blk_cnt, size_t byte_cnt_add); diff --git a/drivers/staging/skein/skein_generic.c b/drivers/staging/skein/skein_generic.c new file mode 100644 index 000000000000..85bd7d0168b0 --- /dev/null +++ b/drivers/staging/skein/skein_generic.c @@ -0,0 +1,216 @@ +/* + * Cryptographic API. + * + * Skein256 Hash Algorithm. + * + * Derived from cryptoapi implementation, adapted for in-place + * scatterlist interface. + * + * Copyright (c) Eric Rost <eric.rost@mybabylon.net> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ +#include <linux/types.h> +#include <linux/init.h> +#include <linux/module.h> +#include <crypto/internal/hash.h> +#include "skein_base.h" + + +static int skein256_init(struct shash_desc *desc) +{ + return skein_256_init((struct skein_256_ctx *) shash_desc_ctx(desc), + SKEIN256_DIGEST_BIT_SIZE); +} + +static int skein256_update(struct shash_desc *desc, const u8 *data, + unsigned int len) +{ + return skein_256_update((struct skein_256_ctx *)shash_desc_ctx(desc), + data, len); +} + +static int skein256_final(struct shash_desc *desc, u8 *out) +{ + return skein_256_final((struct skein_256_ctx *)shash_desc_ctx(desc), + out); +} + +static int skein256_export(struct shash_desc *desc, void *out) +{ + struct skein_256_ctx *sctx = shash_desc_ctx(desc); + + memcpy(out, sctx, sizeof(*sctx)); + return 0; +} + +static int skein256_import(struct shash_desc *desc, const void *in) +{ + struct skein_256_ctx *sctx = shash_desc_ctx(desc); + + memcpy(sctx, in, sizeof(*sctx)); + return 0; +} + +static int skein512_init(struct shash_desc *desc) +{ + return skein_512_init((struct skein_512_ctx *)shash_desc_ctx(desc), + SKEIN512_DIGEST_BIT_SIZE); +} + +static int skein512_update(struct shash_desc *desc, const u8 *data, + unsigned int len) +{ + return skein_512_update((struct skein_512_ctx *)shash_desc_ctx(desc), + data, len); +} + +static int skein512_final(struct shash_desc *desc, u8 *out) +{ + return skein_512_final((struct skein_512_ctx *)shash_desc_ctx(desc), + out); +} + +static int skein512_export(struct shash_desc *desc, void *out) +{ + struct skein_512_ctx *sctx = shash_desc_ctx(desc); + + memcpy(out, sctx, sizeof(*sctx)); + return 0; +} + +static int skein512_import(struct shash_desc *desc, const void *in) +{ + struct skein_512_ctx *sctx = shash_desc_ctx(desc); + + memcpy(sctx, in, sizeof(*sctx)); + return 0; +} + +static int skein1024_init(struct shash_desc *desc) +{ + return skein_1024_init((struct skein_1024_ctx *)shash_desc_ctx(desc), + SKEIN1024_DIGEST_BIT_SIZE); +} + +static int skein1024_update(struct shash_desc *desc, const u8 *data, + unsigned int len) +{ + return skein_1024_update((struct skein_1024_ctx *)shash_desc_ctx(desc), + data, len); +} + +static int skein1024_final(struct shash_desc *desc, u8 *out) +{ + return skein_1024_final((struct skein_1024_ctx *)shash_desc_ctx(desc), + out); +} + +static int skein1024_export(struct shash_desc *desc, void *out) +{ + struct skein_1024_ctx *sctx = shash_desc_ctx(desc); + + memcpy(out, sctx, sizeof(*sctx)); + return 0; +} + +static int skein1024_import(struct shash_desc *desc, const void *in) +{ + struct skein_1024_ctx *sctx = shash_desc_ctx(desc); + + memcpy(sctx, in, sizeof(*sctx)); + return 0; +} + +static struct shash_alg alg256 = { + .digestsize = (SKEIN256_DIGEST_BIT_SIZE / 8), + .init = skein256_init, + .update = skein256_update, + .final = skein256_final, + .export = skein256_export, + .import = skein256_import, + .descsize = sizeof(struct skein_256_ctx), + .statesize = sizeof(struct skein_256_ctx), + .base = { + .cra_name = "skein256", + .cra_driver_name = "skein", + .cra_flags = CRYPTO_ALG_TYPE_SHASH, + .cra_blocksize = SKEIN_256_BLOCK_BYTES, + .cra_module = THIS_MODULE, + } +}; + +static struct shash_alg alg512 = { + .digestsize = (SKEIN512_DIGEST_BIT_SIZE / 8), + .init = skein512_init, + .update = skein512_update, + .final = skein512_final, + .export = skein512_export, + .import = skein512_import, + .descsize = sizeof(struct skein_512_ctx), + .statesize = sizeof(struct skein_512_ctx), + .base = { + .cra_name = "skein512", + .cra_driver_name = "skein", + .cra_flags = CRYPTO_ALG_TYPE_SHASH, + .cra_blocksize = SKEIN_512_BLOCK_BYTES, + .cra_module = THIS_MODULE, + } +}; + +static struct shash_alg alg1024 = { + .digestsize = (SKEIN1024_DIGEST_BIT_SIZE / 8), + .init = skein1024_init, + .update = skein1024_update, + .final = skein1024_final, + .export = skein1024_export, + .import = skein1024_import, + .descsize = sizeof(struct skein_1024_ctx), + .statesize = sizeof(struct skein_1024_ctx), + .base = { + .cra_name = "skein1024", + .cra_driver_name = "skein", + .cra_flags = CRYPTO_ALG_TYPE_SHASH, + .cra_blocksize = SKEIN_1024_BLOCK_BYTES, + .cra_module = THIS_MODULE, + } +}; + +static int __init skein_generic_init(void) +{ + if (crypto_register_shash(&alg256)) + goto out; + if (crypto_register_shash(&alg512)) + goto unreg256; + if (crypto_register_shash(&alg1024)) + goto unreg512; + + return 0; + + +unreg512: + crypto_unregister_shash(&alg512); +unreg256: + crypto_unregister_shash(&alg256); +out: + return -1; +} + +static void __exit skein_generic_fini(void) +{ + crypto_unregister_shash(&alg256); + crypto_unregister_shash(&alg512); + crypto_unregister_shash(&alg1024); +} + +module_init(skein_generic_init); +module_exit(skein_generic_fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Skein Hash Algorithm"); + +MODULE_ALIAS("skein"); diff --git a/drivers/staging/skein/skein_iv.h b/drivers/staging/skein/skein_iv.h index d9dc1d5ed551..8a06314d0ed4 100644 --- a/drivers/staging/skein/skein_iv.h +++ b/drivers/staging/skein/skein_iv.h @@ -1,7 +1,7 @@ #ifndef _SKEIN_IV_H_ #define _SKEIN_IV_H_ -#include "skein.h" /* get Skein macros and types */ +#include "skein_base.h" /* get Skein macros and types */ /* ***************** Pre-computed Skein IVs ******************* diff --git a/drivers/staging/skein/threefish_api.h b/drivers/staging/skein/threefish_api.h index 8d5ddf8b3a9b..8e0a0b77ecce 100644 --- a/drivers/staging/skein/threefish_api.h +++ b/drivers/staging/skein/threefish_api.h @@ -29,7 +29,7 @@ */ #include <linux/types.h> -#include "skein.h" +#include "skein_base.h" #define KEY_SCHEDULE_CONST 0x1BD11BDAA9FC1A22L diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 56ca3b6c1444..42d62ef56cb8 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -498,12 +498,14 @@ static int slic_card_download(struct adapter *adapter) slic_reg32_write(&slic_regs->slic_wcs, baseaddress + codeaddr, FLUSH); /* Write out instruction to low addr */ - slic_reg32_write(&slic_regs->slic_wcs, instruction, FLUSH); + slic_reg32_write(&slic_regs->slic_wcs, + instruction, FLUSH); instruction = *(u32 *)(fw->data + index); index += 4; /* Write out instruction to high addr */ - slic_reg32_write(&slic_regs->slic_wcs, instruction, FLUSH); + slic_reg32_write(&slic_regs->slic_wcs, + instruction, FLUSH); instruction = *(u32 *)(fw->data + index); index += 4; } @@ -596,8 +598,7 @@ static void slic_mac_address_config(struct adapter *adapter) u32 value2; __iomem struct slic_regs *slic_regs = adapter->slic_regs; - value = *(u32 *) &adapter->currmacaddr[2]; - value = ntohl(value); + value = ntohl(*(__be32 *) &adapter->currmacaddr[2]); slic_reg32_write(&slic_regs->slic_wraddral, value, FLUSH); slic_reg32_write(&slic_regs->slic_wraddrbl, value, FLUSH); @@ -1533,14 +1534,18 @@ retry_rcvqfill: dev_err(dev, "%s: LOW 32bits PHYSICAL ADDRESS == 0\n", __func__); dev_err(dev, "skb[%p] PROBLEM\n", skb); - dev_err(dev, " skbdata[%p]\n", skb->data); + dev_err(dev, " skbdata[%p]\n", + skb->data); dev_err(dev, " skblen[%x]\n", skb->len); dev_err(dev, " paddr[%p]\n", paddr); dev_err(dev, " paddrl[%x]\n", paddrl); dev_err(dev, " paddrh[%x]\n", paddrh); - dev_err(dev, " rcvq->head[%p]\n", rcvq->head); - dev_err(dev, " rcvq->tail[%p]\n", rcvq->tail); - dev_err(dev, " rcvq->count[%x]\n", rcvq->count); + dev_err(dev, " rcvq->head[%p]\n", + rcvq->head); + dev_err(dev, " rcvq->tail[%p]\n", + rcvq->tail); + dev_err(dev, " rcvq->count[%x]\n", + rcvq->count); dev_err(dev, "SKIP THIS SKB!!!!!!!!\n"); goto retry_rcvqfill; } @@ -1549,14 +1554,18 @@ retry_rcvqfill: dev_err(dev, "%s: LOW 32bits PHYSICAL ADDRESS == 0\n", __func__); dev_err(dev, "skb[%p] PROBLEM\n", skb); - dev_err(dev, " skbdata[%p]\n", skb->data); + dev_err(dev, " skbdata[%p]\n", + skb->data); dev_err(dev, " skblen[%x]\n", skb->len); dev_err(dev, " paddr[%p]\n", paddr); dev_err(dev, " paddrl[%x]\n", paddrl); dev_err(dev, " paddrh[%x]\n", paddrh); - dev_err(dev, " rcvq->head[%p]\n", rcvq->head); - dev_err(dev, " rcvq->tail[%p]\n", rcvq->tail); - dev_err(dev, " rcvq->count[%x]\n", rcvq->count); + dev_err(dev, " rcvq->head[%p]\n", + rcvq->head); + dev_err(dev, " rcvq->tail[%p]\n", + rcvq->tail); + dev_err(dev, " rcvq->count[%x]\n", + rcvq->count); dev_err(dev, "GIVE TO CARD ANYWAY\n"); } #endif @@ -1612,7 +1621,7 @@ static int slic_rcvqueue_init(struct adapter *adapter) rcvq->size = SLIC_RCVQ_ENTRIES; rcvq->errors = 0; rcvq->count = 0; - i = (SLIC_RCVQ_ENTRIES / SLIC_RCVQ_FILLENTRIES); + i = SLIC_RCVQ_ENTRIES / SLIC_RCVQ_FILLENTRIES; count = 0; while (i) { count += slic_rcvqueue_fill(adapter); @@ -1788,7 +1797,7 @@ static int slic_mcast_add_list(struct adapter *adapter, char *address) if (mcaddr == NULL) return 1; - memcpy(mcaddr->address, address, ETH_ALEN); + ether_addr_copy(mcaddr->address, address); mcaddr->next = adapter->mcastaddrs; adapter->mcastaddrs = mcaddr; @@ -1885,7 +1894,8 @@ static void slic_xmit_fail(struct adapter *adapter, break; case XMIT_FAIL_HOSTCMD_FAIL: dev_err(&adapter->netdev->dev, - "xmit_start skb[%p] type[%x] No host commands available\n", skb, skb->pkt_type); + "xmit_start skb[%p] type[%x] No host commands available\n", + skb, skb->pkt_type); break; } } @@ -2097,7 +2107,8 @@ static void slic_interrupt_card_up(u32 isr, struct adapter *adapter, } } else if (isr & ISR_XDROP) { dev_err(&dev->dev, - "isr & ISR_ERR [%x] ISR_XDROP\n", isr); + "isr & ISR_ERR [%x] ISR_XDROP\n", + isr); } else { dev_err(&dev->dev, "isr & ISR_ERR [%x]\n", @@ -2341,7 +2352,8 @@ static int slic_if_init(struct adapter *adapter) SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH); #else slic_reg32_write(&slic_regs->slic_addr_upper, 0, DONT_FLUSH); - slic_reg32_write(&slic_regs->slic_isp, (u32)&pshmem->isr, FLUSH); + slic_reg32_write(&slic_regs->slic_isp, (u32)&pshmem->isr, + FLUSH); #endif spin_unlock_irqrestore(&adapter->bit64reglock.lock, adapter->bit64reglock.flags); diff --git a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c index bcc7f62654f4..b12c76de60b0 100644 --- a/drivers/staging/speakup/kobjects.c +++ b/drivers/staging/speakup/kobjects.c @@ -81,7 +81,7 @@ static ssize_t chars_chartab_show(struct kobject *kobj, static void report_char_chartab_status(int reset, int received, int used, int rejected, int do_characters) { - char *object_type[] = { + static char const *object_type[] = { "character class entries", "character descriptions", }; @@ -809,10 +809,10 @@ static ssize_t message_store_helper(const char *buf, size_t count, if (msg_stored == -ENOMEM) reset = 1; break; - } else { - used++; } + used++; + cp = linefeed + 1; } diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index 3f30a1b6e72c..e9f0c150d246 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c @@ -695,7 +695,7 @@ static void say_next_word(struct vc_data *vc) static void spell_word(struct vc_data *vc) { - static char *delay_str[] = { "", ",", ".", ". .", ". . ." }; + static char const *delay_str[] = { "", ",", ".", ". .", ". . ." }; char *cp = buf, *str_cap = spk_str_caps_stop; char *cp1, *last_cap = spk_str_caps_stop; u_char ch; diff --git a/drivers/staging/speakup/speakup_dtlk.c b/drivers/staging/speakup/speakup_dtlk.c index d7d515273896..4e059ea78d4c 100644 --- a/drivers/staging/speakup/speakup_dtlk.c +++ b/drivers/staging/speakup/speakup_dtlk.c @@ -231,7 +231,7 @@ static void do_catch_up(struct spk_synth *synth) if (ch == '\n') ch = PROCSPEECH; spk_out(ch); - if ((jiffies >= jiff_max) && (ch == SPACE)) { + if (time_after_eq(jiffies, jiff_max) && (ch == SPACE)) { spk_out(PROCSPEECH); spin_lock_irqsave(&speakup_info.spinlock, flags); delay_time_val = delay_time->u.n.value; diff --git a/drivers/staging/speakup/speakup_keypc.c b/drivers/staging/speakup/speakup_keypc.c index 4ed38898a17a..cef20fdda646 100644 --- a/drivers/staging/speakup/speakup_keypc.c +++ b/drivers/staging/speakup/speakup_keypc.c @@ -229,7 +229,7 @@ spin_lock_irqsave(&speakup_info.spinlock, flags); ch = PROCSPEECH; outb_p(ch, synth_port); SWAIT; - if ((jiffies >= jiff_max) && (ch == SPACE)) { + if (time_after_eq(jiffies, jiff_max) && (ch == SPACE)) { timeout = 1000; while (synth_writable()) if (--timeout <= 0) diff --git a/drivers/staging/unisys/channels/channel.c b/drivers/staging/unisys/channels/channel.c index b4bdee4b575b..74cc4d6b515f 100644 --- a/drivers/staging/unisys/channels/channel.c +++ b/drivers/staging/unisys/channels/channel.c @@ -43,45 +43,45 @@ * Return value: * 1 if the insertion succeeds, 0 if the queue was full. */ -unsigned char -visor_signal_insert(CHANNEL_HEADER __iomem *pChannel, u32 Queue, void *pSignal) +unsigned char spar_signal_insert(struct channel_header __iomem *ch, u32 queue, + void *sig) { void __iomem *psignal; unsigned int head, tail, nof; - SIGNAL_QUEUE_HEADER __iomem *pqhdr = - (SIGNAL_QUEUE_HEADER __iomem *) - ((char __iomem *) pChannel + readq(&pChannel->oChannelSpace)) - + Queue; + struct signal_queue_header __iomem *pqhdr = + (struct signal_queue_header __iomem *) + ((char __iomem *)ch + readq(&ch->ch_space_offset)) + + queue; /* capture current head and tail */ - head = readl(&pqhdr->Head); - tail = readl(&pqhdr->Tail); + head = readl(&pqhdr->head); + tail = readl(&pqhdr->tail); /* queue is full if (head + 1) % n equals tail */ - if (((head + 1) % readl(&pqhdr->MaxSignalSlots)) == tail) { - nof = readq(&pqhdr->NumOverflows) + 1; - writeq(nof, &pqhdr->NumOverflows); + if (((head + 1) % readl(&pqhdr->max_slots)) == tail) { + nof = readq(&pqhdr->num_overflows) + 1; + writeq(nof, &pqhdr->num_overflows); return 0; } /* increment the head index */ - head = (head + 1) % readl(&pqhdr->MaxSignalSlots); + head = (head + 1) % readl(&pqhdr->max_slots); /* copy signal to the head location from the area pointed to * by pSignal */ - psignal = (char __iomem *)pqhdr + readq(&pqhdr->oSignalBase) + - (head * readl(&pqhdr->SignalSize)); - memcpy_toio(psignal, pSignal, readl(&pqhdr->SignalSize)); + psignal = (char __iomem *)pqhdr + readq(&pqhdr->sig_base_offset) + + (head * readl(&pqhdr->signal_size)); + memcpy_toio(psignal, sig, readl(&pqhdr->signal_size)); mb(); /* channel synch */ - writel(head, &pqhdr->Head); + writel(head, &pqhdr->head); - writeq(readq(&pqhdr->NumSignalsSent) + 1, &pqhdr->NumSignalsSent); + writeq(readq(&pqhdr->num_sent) + 1, &pqhdr->num_sent); return 1; } -EXPORT_SYMBOL_GPL(visor_signal_insert); +EXPORT_SYMBOL_GPL(spar_signal_insert); /* * Routine Description: @@ -102,40 +102,40 @@ EXPORT_SYMBOL_GPL(visor_signal_insert); * 1 if the removal succeeds, 0 if the queue was empty. */ unsigned char -visor_signal_remove(CHANNEL_HEADER __iomem *pChannel, u32 Queue, void *pSignal) +spar_signal_remove(struct channel_header __iomem *ch, u32 queue, void *sig) { void __iomem *psource; unsigned int head, tail; - SIGNAL_QUEUE_HEADER __iomem *pqhdr = - (SIGNAL_QUEUE_HEADER __iomem *) ((char __iomem *) pChannel + - readq(&pChannel->oChannelSpace)) + Queue; + struct signal_queue_header __iomem *pqhdr = + (struct signal_queue_header __iomem *)((char __iomem *)ch + + readq(&ch->ch_space_offset)) + queue; /* capture current head and tail */ - head = readl(&pqhdr->Head); - tail = readl(&pqhdr->Tail); + head = readl(&pqhdr->head); + tail = readl(&pqhdr->tail); /* queue is empty if the head index equals the tail index */ if (head == tail) { - writeq(readq(&pqhdr->NumEmptyCnt) + 1, &pqhdr->NumEmptyCnt); + writeq(readq(&pqhdr->num_empty) + 1, &pqhdr->num_empty); return 0; } /* advance past the 'empty' front slot */ - tail = (tail + 1) % readl(&pqhdr->MaxSignalSlots); + tail = (tail + 1) % readl(&pqhdr->max_slots); /* copy signal from tail location to the area pointed to by pSignal */ - psource = (char __iomem *) pqhdr + readq(&pqhdr->oSignalBase) + - (tail * readl(&pqhdr->SignalSize)); - memcpy_fromio(pSignal, psource, readl(&pqhdr->SignalSize)); + psource = (char __iomem *)pqhdr + readq(&pqhdr->sig_base_offset) + + (tail * readl(&pqhdr->signal_size)); + memcpy_fromio(sig, psource, readl(&pqhdr->signal_size)); mb(); /* channel synch */ - writel(tail, &pqhdr->Tail); + writel(tail, &pqhdr->tail); - writeq(readq(&pqhdr->NumSignalsReceived) + 1, - &pqhdr->NumSignalsReceived); + writeq(readq(&pqhdr->num_received) + 1, + &pqhdr->num_received); return 1; } -EXPORT_SYMBOL_GPL(visor_signal_remove); +EXPORT_SYMBOL_GPL(spar_signal_remove); /* * Routine Description: @@ -156,18 +156,18 @@ EXPORT_SYMBOL_GPL(visor_signal_remove); * Return value: * # of signals copied. */ -unsigned int -SignalRemoveAll(pCHANNEL_HEADER pChannel, u32 Queue, void *pSignal) +unsigned int spar_signal_remove_all(struct channel_header *ch, u32 queue, + void *sig) { void *psource; - unsigned int head, tail, signalCount = 0; - pSIGNAL_QUEUE_HEADER pqhdr = - (pSIGNAL_QUEUE_HEADER) ((char *) pChannel + - pChannel->oChannelSpace) + Queue; + unsigned int head, tail, count = 0; + struct signal_queue_header *pqhdr = + (struct signal_queue_header *)((char *)ch + + ch->ch_space_offset) + queue; /* capture current head and tail */ - head = pqhdr->Head; - tail = pqhdr->Tail; + head = pqhdr->head; + tail = pqhdr->tail; /* queue is empty if the head index equals the tail index */ if (head == tail) @@ -175,25 +175,25 @@ SignalRemoveAll(pCHANNEL_HEADER pChannel, u32 Queue, void *pSignal) while (head != tail) { /* advance past the 'empty' front slot */ - tail = (tail + 1) % pqhdr->MaxSignalSlots; + tail = (tail + 1) % pqhdr->max_slots; /* copy signal from tail location to the area pointed * to by pSignal */ psource = - (char *) pqhdr + pqhdr->oSignalBase + - (tail * pqhdr->SignalSize); - memcpy((char *) pSignal + (pqhdr->SignalSize * signalCount), - psource, pqhdr->SignalSize); + (char *)pqhdr + pqhdr->sig_base_offset + + (tail * pqhdr->signal_size); + memcpy((char *)sig + (pqhdr->signal_size * count), + psource, pqhdr->signal_size); mb(); /* channel synch */ - pqhdr->Tail = tail; + pqhdr->tail = tail; - signalCount++; - pqhdr->NumSignalsReceived++; + count++; + pqhdr->num_received++; } - return signalCount; + return count; } /* @@ -207,13 +207,13 @@ SignalRemoveAll(pCHANNEL_HEADER pChannel, u32 Queue, void *pSignal) * Return value: * 1 if the signal queue is empty, 0 otherwise. */ -unsigned char -visor_signalqueue_empty(CHANNEL_HEADER __iomem *pChannel, u32 Queue) +unsigned char spar_signalqueue_empty(struct channel_header __iomem *ch, + u32 queue) { - SIGNAL_QUEUE_HEADER __iomem *pqhdr = - (SIGNAL_QUEUE_HEADER __iomem *) ((char __iomem *) pChannel + - readq(&pChannel->oChannelSpace)) + Queue; - return readl(&pqhdr->Head) == readl(&pqhdr->Tail); + struct signal_queue_header __iomem *pqhdr = + (struct signal_queue_header __iomem *)((char __iomem *)ch + + readq(&ch->ch_space_offset)) + queue; + return readl(&pqhdr->head) == readl(&pqhdr->tail); } -EXPORT_SYMBOL_GPL(visor_signalqueue_empty); +EXPORT_SYMBOL_GPL(spar_signalqueue_empty); diff --git a/drivers/staging/unisys/channels/chanstub.c b/drivers/staging/unisys/channels/chanstub.c index d54c5d635a94..b6fd126f16f1 100644 --- a/drivers/staging/unisys/channels/chanstub.c +++ b/drivers/staging/unisys/channels/chanstub.c @@ -42,26 +42,26 @@ channel_mod_exit(void) } unsigned char -SignalInsert_withLock(CHANNEL_HEADER __iomem *pChannel, u32 Queue, +SignalInsert_withLock(struct channel_header __iomem *pChannel, u32 Queue, void *pSignal, spinlock_t *lock) { unsigned char result; unsigned long flags; spin_lock_irqsave(lock, flags); - result = visor_signal_insert(pChannel, Queue, pSignal); + result = spar_signal_insert(pChannel, Queue, pSignal); spin_unlock_irqrestore(lock, flags); return result; } unsigned char -SignalRemove_withLock(CHANNEL_HEADER __iomem *pChannel, u32 Queue, +SignalRemove_withLock(struct channel_header __iomem *pChannel, u32 Queue, void *pSignal, spinlock_t *lock) { unsigned char result; spin_lock(lock); - result = visor_signal_remove(pChannel, Queue, pSignal); + result = spar_signal_remove(pChannel, Queue, pSignal); spin_unlock(lock); return result; } diff --git a/drivers/staging/unisys/channels/chanstub.h b/drivers/staging/unisys/channels/chanstub.h index d08e2c69d2ad..1531759a1b31 100644 --- a/drivers/staging/unisys/channels/chanstub.h +++ b/drivers/staging/unisys/channels/chanstub.h @@ -15,9 +15,9 @@ #ifndef __CHANSTUB_H__ #define __CHANSTUB_H__ -unsigned char SignalInsert_withLock(CHANNEL_HEADER __iomem *pChannel, u32 Queue, - void *pSignal, spinlock_t *lock); -unsigned char SignalRemove_withLock(CHANNEL_HEADER __iomem *pChannel, u32 Queue, - void *pSignal, spinlock_t *lock); +unsigned char SignalInsert_withLock(struct channel_header __iomem *pChannel, + u32 Queue, void *pSignal, spinlock_t *lock); +unsigned char SignalRemove_withLock(struct channel_header __iomem *pChannel, + u32 Queue, void *pSignal, spinlock_t *lock); #endif diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index c25dfbf7f6bc..6fb6e5b3ddaf 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -50,43 +50,12 @@ #define ULTRA_CHANNEL_PROTOCOL_SIGNATURE SIGNATURE_32('E', 'C', 'N', 'L') -#define CHANNEL_GUID_MISMATCH(chType, chName, field, expected, actual, fil, \ - lin, logCtx) \ - do { \ - pr_err("Channel mismatch on channel=%s(%pUL) field=%s expected=%pUL actual=%pUL @%s:%d\n", \ - chName, &chType, field, \ - &expected, &actual, \ - fil, lin); \ - } while (0) -#define CHANNEL_U32_MISMATCH(chType, chName, field, expected, actual, fil, \ - lin, logCtx) \ - do { \ - pr_err("Channel mismatch on channel=%s(%pUL) field=%s expected=0x%-8.8lx actual=0x%-8.8lx @%s:%d\n", \ - chName, &chType, field, \ - (unsigned long)expected, (unsigned long)actual, \ - fil, lin); \ - } while (0) - -#define CHANNEL_U64_MISMATCH(chType, chName, field, expected, actual, fil, \ - lin, logCtx) \ - do { \ - pr_err("Channel mismatch on channel=%s(%pUL) field=%s expected=0x%-8.8Lx actual=0x%-8.8Lx @%s:%d\n", \ - chName, &chType, field, \ - (unsigned long long)expected, \ - (unsigned long long)actual, \ - fil, lin); \ - } while (0) - -#define UltraLogEvent(logCtx, EventId, Severity, SubsystemMask, pFunctionName, \ - LineNumber, Str, args...) \ - pr_info(Str, ## args) - -typedef enum { +enum channel_serverstate { CHANNELSRV_UNINITIALIZED = 0, /* channel is in an undefined state */ CHANNELSRV_READY = 1 /* channel has been initialized by server */ -} CHANNEL_SERVERSTATE; +}; -typedef enum { +enum channel_clientstate { CHANNELCLI_DETACHED = 0, CHANNELCLI_DISABLED = 1, /* client can see channel but is NOT * allowed to use it unless given TBD @@ -100,32 +69,32 @@ typedef enum { * using channel */ CHANNELCLI_OWNED = 5 /* "no worries" state - client can * access channel anytime */ -} CHANNEL_CLIENTSTATE; +}; + static inline const u8 * ULTRA_CHANNELCLI_STRING(u32 v) { switch (v) { case CHANNELCLI_DETACHED: - return (const u8 *) ("DETACHED"); + return (const u8 *)("DETACHED"); case CHANNELCLI_DISABLED: - return (const u8 *) ("DISABLED"); + return (const u8 *)("DISABLED"); case CHANNELCLI_ATTACHING: - return (const u8 *) ("ATTACHING"); + return (const u8 *)("ATTACHING"); case CHANNELCLI_ATTACHED: - return (const u8 *) ("ATTACHED"); + return (const u8 *)("ATTACHED"); case CHANNELCLI_BUSY: - return (const u8 *) ("BUSY"); + return (const u8 *)("BUSY"); case CHANNELCLI_OWNED: - return (const u8 *) ("OWNED"); + return (const u8 *)("OWNED"); default: break; } - return (const u8 *) ("?"); + return (const u8 *)("?"); } -#define ULTRA_CHANNELSRV_IS_READY(x) ((x) == CHANNELSRV_READY) -#define ULTRA_CHANNEL_SERVER_READY(pChannel) \ - (ULTRA_CHANNELSRV_IS_READY(readl(&(pChannel)->SrvState))) +#define SPAR_CHANNEL_SERVER_READY(ch) \ + (readl(&(ch)->srv_state) == CHANNELSRV_READY) #define ULTRA_VALID_CHANNELCLI_TRANSITION(o, n) \ (((((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_DISABLED)) || \ @@ -145,60 +114,41 @@ ULTRA_CHANNELCLI_STRING(u32 v) (((o) == CHANNELCLI_BUSY) && ((n) == CHANNELCLI_OWNED)) || (0)) \ ? (1) : (0)) -#define ULTRA_CHANNEL_CLIENT_CHK_TRANSITION(old, new, chanId, logCtx, \ +#define SPAR_CHANNEL_CLIENT_CHK_TRANSITION(old, new, id, log, \ file, line) \ do { \ if (!ULTRA_VALID_CHANNELCLI_TRANSITION(old, new)) \ - UltraLogEvent(logCtx, \ - CHANNELSTATE_DIAG_EVENTID_TRANSITERR, \ - CHANNELSTATE_DIAG_SEVERITY, \ - CHANNELSTATE_DIAG_SUBSYS, \ - __func__, __LINE__, \ - "%s Channel StateTransition INVALID! (%s) %s(%d)-->%s(%d) @%s:%d\n", \ - chanId, "CliState<x>", \ - ULTRA_CHANNELCLI_STRING(old), \ - old, \ - ULTRA_CHANNELCLI_STRING(new), \ - new, \ - PathName_Last_N_Nodes((u8 *)file, 4), \ - line); \ + pr_info("%s Channel StateTransition INVALID! (%s) %s(%d)-->%s(%d) @%s:%d\n", \ + id, "CliState<x>", \ + ULTRA_CHANNELCLI_STRING(old), \ + old, \ + ULTRA_CHANNELCLI_STRING(new), \ + new, \ + pathname_last_n_nodes((u8 *)file, 4), \ + line); \ } while (0) -#define ULTRA_CHANNEL_CLIENT_TRANSITION(pChan, chanId, \ - newstate, logCtx) \ +#define SPAR_CHANNEL_CLIENT_TRANSITION(ch, id, newstate, log) \ do { \ - ULTRA_CHANNEL_CLIENT_CHK_TRANSITION( \ - readl(&(((CHANNEL_HEADER __iomem *) \ - (pChan))->CliStateOS)), \ - newstate, \ - chanId, logCtx, __FILE__, __LINE__); \ - UltraLogEvent(logCtx, CHANNELSTATE_DIAG_EVENTID_TRANSITOK, \ - CHANNELSTATE_DIAG_SEVERITY, \ - CHANNELSTATE_DIAG_SUBSYS, \ - __func__, __LINE__, \ - "%s Channel StateTransition (%s) %s(%d)-->%s(%d) @%s:%d\n", \ - chanId, "CliStateOS", \ - ULTRA_CHANNELCLI_STRING( \ - readl(&((CHANNEL_HEADER __iomem *) \ - (pChan))->CliStateOS)), \ - readl(&((CHANNEL_HEADER __iomem *) \ - (pChan))->CliStateOS), \ - ULTRA_CHANNELCLI_STRING(newstate), \ - newstate, \ - PathName_Last_N_Nodes(__FILE__, 4), __LINE__); \ - writel(newstate, &((CHANNEL_HEADER __iomem *) \ - (pChan))->CliStateOS); \ + SPAR_CHANNEL_CLIENT_CHK_TRANSITION( \ + readl(&(((struct channel_header __iomem *)\ + (ch))->cli_state_os)), \ + newstate, id, log, __FILE__, __LINE__); \ + pr_info("%s Channel StateTransition (%s) %s(%d)-->%s(%d) @%s:%d\n", \ + id, "CliStateOS", \ + ULTRA_CHANNELCLI_STRING( \ + readl(&((struct channel_header __iomem *)\ + (ch))->cli_state_os)), \ + readl(&((struct channel_header __iomem *)\ + (ch))->cli_state_os), \ + ULTRA_CHANNELCLI_STRING(newstate), \ + newstate, \ + pathname_last_n_nodes(__FILE__, 4), __LINE__); \ + writel(newstate, &((struct channel_header __iomem *)\ + (ch))->cli_state_os); \ mb(); /* required for channel synch */ \ } while (0) -#define ULTRA_CHANNEL_CLIENT_ACQUIRE_OS(pChan, chanId, logCtx) \ - ULTRA_channel_client_acquire_os(pChan, chanId, logCtx, \ - (char *)__FILE__, __LINE__, \ - (char *)__func__) -#define ULTRA_CHANNEL_CLIENT_RELEASE_OS(pChan, chanId, logCtx) \ - ULTRA_channel_client_release_os(pChan, chanId, logCtx, \ - (char *)__FILE__, __LINE__, (char *)__func__) - /* Values for ULTRA_CHANNEL_PROTOCOL.CliErrorBoot: */ /* throttling invalid boot channel statetransition error due to client * disabled */ @@ -239,98 +189,98 @@ ULTRA_CHANNELCLI_STRING(u32 v) #pragma pack(push, 1) /* both GCC and VC now allow this pragma */ /* Common Channel Header */ -typedef struct _CHANNEL_HEADER { - u64 Signature; /* Signature */ - u32 LegacyState; /* DEPRECATED - being replaced by */ +struct channel_header { + u64 signature; /* Signature */ + u32 legacy_state; /* DEPRECATED - being replaced by */ /* / SrvState, CliStateBoot, and CliStateOS below */ - u32 HeaderSize; /* sizeof(CHANNEL_HEADER) */ - u64 Size; /* Total size of this channel in bytes */ - u64 Features; /* Flags to modify behavior */ - uuid_le Type; /* Channel type: data, bus, control, etc. */ - u64 PartitionHandle; /* ID of guest partition */ - u64 Handle; /* Device number of this channel in client */ - u64 oChannelSpace; /* Offset in bytes to channel specific area */ - u32 VersionId; /* CHANNEL_HEADER Version ID */ - u32 PartitionIndex; /* Index of guest partition */ - uuid_le ZoneGuid; /* Guid of Channel's zone */ - u32 oClientString; /* offset from channel header to + u32 header_size; /* sizeof(struct channel_header) */ + u64 size; /* Total size of this channel in bytes */ + u64 features; /* Flags to modify behavior */ + uuid_le chtype; /* Channel type: data, bus, control, etc. */ + u64 partition_handle; /* ID of guest partition */ + u64 handle; /* Device number of this channel in client */ + u64 ch_space_offset; /* Offset in bytes to channel specific area */ + u32 version_id; /* struct channel_header Version ID */ + u32 partition_index; /* Index of guest partition */ + uuid_le zone_uuid; /* Guid of Channel's zone */ + u32 cli_str_offset; /* offset from channel header to * nul-terminated ClientString (0 if * ClientString not present) */ - u32 CliStateBoot; /* CHANNEL_CLIENTSTATE of pre-boot + u32 cli_state_boot; /* CHANNEL_CLIENTSTATE of pre-boot * EFI client of this channel */ - u32 CmdStateCli; /* CHANNEL_COMMANDSTATE (overloaded in + u32 cmd_state_cli; /* CHANNEL_COMMANDSTATE (overloaded in * Windows drivers, see ServerStateUp, * ServerStateDown, etc) */ - u32 CliStateOS; /* CHANNEL_CLIENTSTATE of Guest OS + u32 cli_state_os; /* CHANNEL_CLIENTSTATE of Guest OS * client of this channel */ - u32 ChannelCharacteristics; /* CHANNEL_CHARACTERISTIC_<xxx> */ - u32 CmdStateSrv; /* CHANNEL_COMMANDSTATE (overloaded in + u32 ch_characteristic; /* CHANNEL_CHARACTERISTIC_<xxx> */ + u32 cmd_state_srv; /* CHANNEL_COMMANDSTATE (overloaded in * Windows drivers, see ServerStateUp, * ServerStateDown, etc) */ - u32 SrvState; /* CHANNEL_SERVERSTATE */ - u8 CliErrorBoot; /* bits to indicate err states for + u32 srv_state; /* CHANNEL_SERVERSTATE */ + u8 cli_error_boot; /* bits to indicate err states for * boot clients, so err messages can * be throttled */ - u8 CliErrorOS; /* bits to indicate err states for OS + u8 cli_error_os; /* bits to indicate err states for OS * clients, so err messages can be * throttled */ - u8 Filler[1]; /* Pad out to 128 byte cacheline */ + u8 filler[1]; /* Pad out to 128 byte cacheline */ /* Please add all new single-byte values below here */ - u8 RecoverChannel; -} CHANNEL_HEADER, *pCHANNEL_HEADER, ULTRA_CHANNEL_PROTOCOL; + u8 recover_channel; +}; #define ULTRA_CHANNEL_ENABLE_INTS (0x1ULL << 0) /* Subheader for the Signal Type variation of the Common Channel */ -typedef struct _SIGNAL_QUEUE_HEADER { +struct signal_queue_header { /* 1st cache line */ - u32 VersionId; /* SIGNAL_QUEUE_HEADER Version ID */ - u32 Type; /* Queue type: storage, network */ - u64 Size; /* Total size of this queue in bytes */ - u64 oSignalBase; /* Offset to signal queue area */ - u64 FeatureFlags; /* Flags to modify behavior */ - u64 NumSignalsSent; /* Total # of signals placed in this queue */ - u64 NumOverflows; /* Total # of inserts failed due to + u32 version; /* SIGNAL_QUEUE_HEADER Version ID */ + u32 chtype; /* Queue type: storage, network */ + u64 size; /* Total size of this queue in bytes */ + u64 sig_base_offset; /* Offset to signal queue area */ + u64 features; /* Flags to modify behavior */ + u64 num_sent; /* Total # of signals placed in this queue */ + u64 num_overflows; /* Total # of inserts failed due to * full queue */ - u32 SignalSize; /* Total size of a signal for this queue */ - u32 MaxSignalSlots; /* Max # of slots in queue, 1 slot is + u32 signal_size; /* Total size of a signal for this queue */ + u32 max_slots; /* Max # of slots in queue, 1 slot is * always empty */ - u32 MaxSignals; /* Max # of signals in queue + u32 max_signals; /* Max # of signals in queue * (MaxSignalSlots-1) */ - u32 Head; /* Queue head signal # */ + u32 head; /* Queue head signal # */ /* 2nd cache line */ - u64 NumSignalsReceived; /* Total # of signals removed from this queue */ - u32 Tail; /* Queue tail signal # (on separate + u64 num_received; /* Total # of signals removed from this queue */ + u32 tail; /* Queue tail signal # (on separate * cache line) */ - u32 Reserved1; /* Reserved field */ - u64 Reserved2; /* Resrved field */ - u64 ClientQueue; - u64 NumInterruptsReceived; /* Total # of Interrupts received. This + u32 reserved1; /* Reserved field */ + u64 reserved2; /* Reserved field */ + u64 client_queue; + u64 num_irq_received; /* Total # of Interrupts received. This * is incremented by the ISR in the * guest windows driver */ - u64 NumEmptyCnt; /* Number of times that visor_signal_remove + u64 num_empty; /* Number of times that visor_signal_remove * is called and returned Empty * Status. */ - u32 ErrorFlags; /* Error bits set during SignalReinit + u32 errorflags; /* Error bits set during SignalReinit * to denote trouble with client's * fields */ - u8 Filler[12]; /* Pad out to 64 byte cacheline */ -} SIGNAL_QUEUE_HEADER, *pSIGNAL_QUEUE_HEADER; + u8 filler[12]; /* Pad out to 64 byte cacheline */ +}; #pragma pack(pop) -#define SignalInit(chan, QHDRFLD, QDATAFLD, QDATATYPE, ver, typ) \ +#define spar_signal_init(chan, QHDRFLD, QDATAFLD, QDATATYPE, ver, typ) \ do { \ memset(&chan->QHDRFLD, 0, sizeof(chan->QHDRFLD)); \ - chan->QHDRFLD.VersionId = ver; \ - chan->QHDRFLD.Type = typ; \ - chan->QHDRFLD.Size = sizeof(chan->QDATAFLD); \ - chan->QHDRFLD.SignalSize = sizeof(QDATATYPE); \ - chan->QHDRFLD.oSignalBase = (u64)(chan->QDATAFLD)- \ + chan->QHDRFLD.version = ver; \ + chan->QHDRFLD.chtype = typ; \ + chan->QHDRFLD.size = sizeof(chan->QDATAFLD); \ + chan->QHDRFLD.signal_size = sizeof(QDATATYPE); \ + chan->QHDRFLD.sig_base_offset = (u64)(chan->QDATAFLD)- \ (u64)(&chan->QHDRFLD); \ - chan->QHDRFLD.MaxSignalSlots = \ + chan->QHDRFLD.max_slots = \ sizeof(chan->QDATAFLD)/sizeof(QDATATYPE); \ - chan->QHDRFLD.MaxSignals = chan->QHDRFLD.MaxSignalSlots-1; \ + chan->QHDRFLD.max_signals = chan->QHDRFLD.max_slots-1; \ } while (0) /* Generic function useful for validating any type of channel when it is @@ -339,64 +289,62 @@ typedef struct _SIGNAL_QUEUE_HEADER { * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages. */ static inline int -ULTRA_check_channel_client(void __iomem *pChannel, - uuid_le expectedTypeGuid, - char *channelName, - u64 expectedMinBytes, - u32 expectedVersionId, - u64 expectedSignature, - char *fileName, int lineNumber, void *logCtx) +spar_check_channel_client(void __iomem *ch, + uuid_le expected_uuid, + char *chname, + u64 expected_min_bytes, + u32 expected_version, + u64 expected_signature) { - if (uuid_le_cmp(expectedTypeGuid, NULL_UUID_LE) != 0) { + if (uuid_le_cmp(expected_uuid, NULL_UUID_LE) != 0) { uuid_le guid; memcpy_fromio(&guid, - &((CHANNEL_HEADER __iomem *)(pChannel))->Type, + &((struct channel_header __iomem *)(ch))->chtype, sizeof(guid)); /* caller wants us to verify type GUID */ - if (uuid_le_cmp(guid, expectedTypeGuid) != 0) { - CHANNEL_GUID_MISMATCH(expectedTypeGuid, channelName, - "type", expectedTypeGuid, - guid, fileName, - lineNumber, logCtx); + if (uuid_le_cmp(guid, expected_uuid) != 0) { + pr_err("Channel mismatch on channel=%s(%pUL) field=type expected=%pUL actual=%pUL\n", + chname, &expected_uuid, + &expected_uuid, &guid); return 0; } } - if (expectedMinBytes > 0) /* caller wants us to verify + if (expected_min_bytes > 0) { /* caller wants us to verify * channel size */ - if (readq(&((CHANNEL_HEADER __iomem *) - (pChannel))->Size) < expectedMinBytes) { - CHANNEL_U64_MISMATCH(expectedTypeGuid, channelName, - "size", expectedMinBytes, - readq(&((CHANNEL_HEADER __iomem *) - (pChannel))->Size), - fileName, - lineNumber, logCtx); + unsigned long long bytes = + readq(&((struct channel_header __iomem *) + (ch))->size); + if (bytes < expected_min_bytes) { + pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8Lx actual=0x%-8.8Lx\n", + chname, &expected_uuid, + (unsigned long long)expected_min_bytes, bytes); return 0; } - if (expectedVersionId > 0) /* caller wants us to verify + } + if (expected_version > 0) { /* caller wants us to verify * channel version */ - if (readl(&((CHANNEL_HEADER __iomem *) (pChannel))->VersionId) - != expectedVersionId) { - CHANNEL_U32_MISMATCH(expectedTypeGuid, channelName, - "version", expectedVersionId, - readl(&((CHANNEL_HEADER __iomem *) - (pChannel))->VersionId), - fileName, lineNumber, logCtx); + unsigned long ver = readl(&((struct channel_header __iomem *) + (ch))->version_id); + if (ver != expected_version) { + pr_err("Channel mismatch on channel=%s(%pUL) field=version expected=0x%-8.8lx actual=0x%-8.8lx\n", + chname, &expected_uuid, + (unsigned long)expected_version, ver); return 0; } - if (expectedSignature > 0) /* caller wants us to verify + } + if (expected_signature > 0) { /* caller wants us to verify * channel signature */ - if (readq(&((CHANNEL_HEADER __iomem *) (pChannel))->Signature) - != expectedSignature) { - CHANNEL_U64_MISMATCH(expectedTypeGuid, channelName, - "signature", expectedSignature, - readq(&((CHANNEL_HEADER __iomem *) - (pChannel))->Signature), - fileName, - lineNumber, logCtx); + unsigned long long sig = + readq(&((struct channel_header __iomem *) + (ch))->signature); + if (sig != expected_signature) { + pr_err("Channel mismatch on channel=%s(%pUL) field=signature expected=0x%-8.8llx actual=0x%-8.8llx\n", + chname, &expected_uuid, + expected_signature, sig); return 0; } + } return 1; } @@ -405,19 +353,16 @@ ULTRA_check_channel_client(void __iomem *pChannel, * Note that <logCtx> is only needed for callers in the EFI environment, and * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages. */ -static inline int -ULTRA_check_channel_server(uuid_le typeGuid, - char *channelName, - u64 expectedMinBytes, - u64 actualBytes, - char *fileName, int lineNumber, void *logCtx) +static inline int spar_check_channel_server(uuid_le typeuuid, char *name, + u64 expected_min_bytes, + u64 actual_bytes) { - if (expectedMinBytes > 0) /* caller wants us to verify + if (expected_min_bytes > 0) /* caller wants us to verify * channel size */ - if (actualBytes < expectedMinBytes) { - CHANNEL_U64_MISMATCH(typeGuid, channelName, "size", - expectedMinBytes, actualBytes, - fileName, lineNumber, logCtx); + if (actual_bytes < expected_min_bytes) { + pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8llx actual=0x%-8.8llx\n", + name, &typeuuid, expected_min_bytes, + actual_bytes); return 0; } return 1; @@ -430,7 +375,7 @@ ULTRA_check_channel_server(uuid_le typeGuid, * in it, the return pointer will be to the beginning of the string. */ static inline u8 * -PathName_Last_N_Nodes(u8 *s, unsigned int n) +pathname_last_n_nodes(u8 *s, unsigned int n) { u8 *p = s; unsigned int node_count = 0; @@ -455,59 +400,43 @@ PathName_Last_N_Nodes(u8 *s, unsigned int n) } static inline int -ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, - void *logCtx, char *file, int line, char *func) +spar_channel_client_acquire_os(void __iomem *ch, u8 *id) { - CHANNEL_HEADER __iomem *pChan = pChannel; + struct channel_header __iomem *hdr = ch; - if (readl(&pChan->CliStateOS) == CHANNELCLI_DISABLED) { - if ((readb(&pChan->CliErrorOS) + if (readl(&hdr->cli_state_os) == CHANNELCLI_DISABLED) { + if ((readb(&hdr->cli_error_os) & ULTRA_CLIERROROS_THROTTLEMSG_DISABLED) == 0) { /* we are NOT throttling this message */ - writeb(readb(&pChan->CliErrorOS) | + writeb(readb(&hdr->cli_error_os) | ULTRA_CLIERROROS_THROTTLEMSG_DISABLED, - &pChan->CliErrorOS); + &hdr->cli_error_os); /* throttle until acquire successful */ - UltraLogEvent(logCtx, - CHANNELSTATE_DIAG_EVENTID_TRANSITERR, - CHANNELSTATE_DIAG_SEVERITY, - CHANNELSTATE_DIAG_SUBSYS, func, line, - "%s Channel StateTransition INVALID! - acquire failed because OS client DISABLED @%s:%d\n", - chanId, PathName_Last_N_Nodes( - (u8 *) file, 4), line); + pr_info("%s Channel StateTransition INVALID! - acquire failed because OS client DISABLED\n", + id); } return 0; } - if ((readl(&pChan->CliStateOS) != CHANNELCLI_OWNED) - && (readl(&pChan->CliStateBoot) == CHANNELCLI_DISABLED)) { + if ((readl(&hdr->cli_state_os) != CHANNELCLI_OWNED) && + (readl(&hdr->cli_state_boot) == CHANNELCLI_DISABLED)) { /* Our competitor is DISABLED, so we can transition to OWNED */ - UltraLogEvent(logCtx, CHANNELSTATE_DIAG_EVENTID_TRANSITOK, - CHANNELSTATE_DIAG_SEVERITY, - CHANNELSTATE_DIAG_SUBSYS, func, line, - "%s Channel StateTransition (%s) %s(%d)-->%s(%d) @%s:%d\n", - chanId, "CliStateOS", - ULTRA_CHANNELCLI_STRING( - readl(&pChan->CliStateOS)), - readl(&pChan->CliStateOS), - ULTRA_CHANNELCLI_STRING(CHANNELCLI_OWNED), - CHANNELCLI_OWNED, - PathName_Last_N_Nodes((u8 *) file, 4), line); - writel(CHANNELCLI_OWNED, &pChan->CliStateOS); + pr_info("%s Channel StateTransition (%s) %s(%d)-->%s(%d)\n", + id, "cli_state_os", + ULTRA_CHANNELCLI_STRING(readl(&hdr->cli_state_os)), + readl(&hdr->cli_state_os), + ULTRA_CHANNELCLI_STRING(CHANNELCLI_OWNED), + CHANNELCLI_OWNED); + writel(CHANNELCLI_OWNED, &hdr->cli_state_os); mb(); /* required for channel synch */ } - if (readl(&pChan->CliStateOS) == CHANNELCLI_OWNED) { - if (readb(&pChan->CliErrorOS) != 0) { + if (readl(&hdr->cli_state_os) == CHANNELCLI_OWNED) { + if (readb(&hdr->cli_error_os) != 0) { /* we are in an error msg throttling state; * come out of it */ - UltraLogEvent(logCtx, - CHANNELSTATE_DIAG_EVENTID_TRANSITOK, - CHANNELSTATE_DIAG_SEVERITY, - CHANNELSTATE_DIAG_SUBSYS, func, line, - "%s Channel OS client acquire now successful @%s:%d\n", - chanId, PathName_Last_N_Nodes((u8 *) file, - 4), line); - writeb(0, &pChan->CliErrorOS); + pr_info("%s Channel OS client acquire now successful\n", + id); + writeb(0, &hdr->cli_error_os); } return 1; } @@ -515,95 +444,67 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, /* We have to do it the "hard way". We transition to BUSY, * and can use the channel iff our competitor has not also * transitioned to BUSY. */ - if (readl(&pChan->CliStateOS) != CHANNELCLI_ATTACHED) { - if ((readb(&pChan->CliErrorOS) + if (readl(&hdr->cli_state_os) != CHANNELCLI_ATTACHED) { + if ((readb(&hdr->cli_error_os) & ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED) == 0) { /* we are NOT throttling this message */ - writeb(readb(&pChan->CliErrorOS) | + writeb(readb(&hdr->cli_error_os) | ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED, - &pChan->CliErrorOS); + &hdr->cli_error_os); /* throttle until acquire successful */ - UltraLogEvent(logCtx, - CHANNELSTATE_DIAG_EVENTID_TRANSITERR, - CHANNELSTATE_DIAG_SEVERITY, - CHANNELSTATE_DIAG_SUBSYS, func, line, - "%s Channel StateTransition INVALID! - acquire failed because OS client NOT ATTACHED (state=%s(%d)) @%s:%d\n", - chanId, - ULTRA_CHANNELCLI_STRING( - readl(&pChan->CliStateOS)), - readl(&pChan->CliStateOS), - PathName_Last_N_Nodes((u8 *) file, 4), - line); + pr_info("%s Channel StateTransition INVALID! - acquire failed because OS client NOT ATTACHED (state=%s(%d))\n", + id, ULTRA_CHANNELCLI_STRING( + readl(&hdr->cli_state_os)), + readl(&hdr->cli_state_os)); } return 0; } - writel(CHANNELCLI_BUSY, &pChan->CliStateOS); + writel(CHANNELCLI_BUSY, &hdr->cli_state_os); mb(); /* required for channel synch */ - if (readl(&pChan->CliStateBoot) == CHANNELCLI_BUSY) { - if ((readb(&pChan->CliErrorOS) + if (readl(&hdr->cli_state_boot) == CHANNELCLI_BUSY) { + if ((readb(&hdr->cli_error_os) & ULTRA_CLIERROROS_THROTTLEMSG_BUSY) == 0) { /* we are NOT throttling this message */ - writeb(readb(&pChan->CliErrorOS) | + writeb(readb(&hdr->cli_error_os) | ULTRA_CLIERROROS_THROTTLEMSG_BUSY, - &pChan->CliErrorOS); + &hdr->cli_error_os); /* throttle until acquire successful */ - UltraLogEvent(logCtx, - CHANNELSTATE_DIAG_EVENTID_TRANSITBUSY, - CHANNELSTATE_DIAG_SEVERITY, - CHANNELSTATE_DIAG_SUBSYS, func, line, - "%s Channel StateTransition failed - host OS acquire failed because boot BUSY @%s:%d\n", - chanId, PathName_Last_N_Nodes((u8 *) file, - 4), line); + pr_info("%s Channel StateTransition failed - host OS acquire failed because boot BUSY\n", + id); } /* reset busy */ - writel(CHANNELCLI_ATTACHED, &pChan->CliStateOS); + writel(CHANNELCLI_ATTACHED, &hdr->cli_state_os); mb(); /* required for channel synch */ return 0; } - if (readb(&pChan->CliErrorOS) != 0) { + if (readb(&hdr->cli_error_os) != 0) { /* we are in an error msg throttling state; come out of it */ - UltraLogEvent(logCtx, CHANNELSTATE_DIAG_EVENTID_TRANSITOK, - CHANNELSTATE_DIAG_SEVERITY, - CHANNELSTATE_DIAG_SUBSYS, func, line, - "%s Channel OS client acquire now successful @%s:%d\n", - chanId, PathName_Last_N_Nodes((u8 *) file, 4), - line); - writeb(0, &pChan->CliErrorOS); + pr_info("%s Channel OS client acquire now successful\n", id); + writeb(0, &hdr->cli_error_os); } return 1; } static inline void -ULTRA_channel_client_release_os(void __iomem *pChannel, u8 *chanId, - void *logCtx, char *file, int line, char *func) +spar_channel_client_release_os(void __iomem *ch, u8 *id) { - CHANNEL_HEADER __iomem *pChan = pChannel; + struct channel_header __iomem *hdr = ch; - if (readb(&pChan->CliErrorOS) != 0) { + if (readb(&hdr->cli_error_os) != 0) { /* we are in an error msg throttling state; come out of it */ - UltraLogEvent(logCtx, CHANNELSTATE_DIAG_EVENTID_TRANSITOK, - CHANNELSTATE_DIAG_SEVERITY, - CHANNELSTATE_DIAG_SUBSYS, func, line, - "%s Channel OS client error state cleared @%s:%d\n", - chanId, PathName_Last_N_Nodes((u8 *) file, 4), - line); - writeb(0, &pChan->CliErrorOS); + pr_info("%s Channel OS client error state cleared\n", id); + writeb(0, &hdr->cli_error_os); } - if (readl(&pChan->CliStateOS) == CHANNELCLI_OWNED) + if (readl(&hdr->cli_state_os) == CHANNELCLI_OWNED) return; - if (readl(&pChan->CliStateOS) != CHANNELCLI_BUSY) { - UltraLogEvent(logCtx, CHANNELSTATE_DIAG_EVENTID_TRANSITERR, - CHANNELSTATE_DIAG_SEVERITY, - CHANNELSTATE_DIAG_SUBSYS, func, line, - "%s Channel StateTransition INVALID! - release failed because OS client NOT BUSY (state=%s(%d)) @%s:%d\n", - chanId, - ULTRA_CHANNELCLI_STRING( - readl(&pChan->CliStateOS)), - readl(&pChan->CliStateOS), - PathName_Last_N_Nodes((u8 *) file, 4), line); + if (readl(&hdr->cli_state_os) != CHANNELCLI_BUSY) { + pr_info("%s Channel StateTransition INVALID! - release failed because OS client NOT BUSY (state=%s(%d))\n", + id, ULTRA_CHANNELCLI_STRING( + readl(&hdr->cli_state_os)), + readl(&hdr->cli_state_os)); /* return; */ } - writel(CHANNELCLI_ATTACHED, &pChan->CliStateOS); /* release busy */ + writel(CHANNELCLI_ATTACHED, &hdr->cli_state_os); /* release busy */ } /* @@ -625,8 +526,8 @@ ULTRA_channel_client_release_os(void __iomem *pChannel, u8 *chanId, * full. */ -unsigned char visor_signal_insert(CHANNEL_HEADER __iomem *pChannel, u32 Queue, - void *pSignal); +unsigned char spar_signal_insert(struct channel_header __iomem *ch, u32 queue, + void *sig); /* * Routine Description: @@ -647,8 +548,8 @@ unsigned char visor_signal_insert(CHANNEL_HEADER __iomem *pChannel, u32 Queue, * empty. */ -unsigned char visor_signal_remove(CHANNEL_HEADER __iomem *pChannel, u32 Queue, - void *pSignal); +unsigned char spar_signal_remove(struct channel_header __iomem *ch, u32 queue, + void *sig); /* * Routine Description: @@ -669,8 +570,8 @@ unsigned char visor_signal_remove(CHANNEL_HEADER __iomem *pChannel, u32 Queue, * Return value: * # of signals copied. */ -unsigned int SignalRemoveAll(pCHANNEL_HEADER pChannel, u32 Queue, - void *pSignal); +unsigned int spar_signal_remove_all(struct channel_header *ch, u32 queue, + void *sig); /* * Routine Description: @@ -683,7 +584,7 @@ unsigned int SignalRemoveAll(pCHANNEL_HEADER pChannel, u32 Queue, * Return value: * 1 if the signal queue is empty, 0 otherwise. */ -unsigned char visor_signalqueue_empty(CHANNEL_HEADER __iomem *pChannel, - u32 Queue); +unsigned char spar_signalqueue_empty(struct channel_header __iomem *ch, + u32 queue); #endif diff --git a/drivers/staging/unisys/common-spar/include/channels/channel_guid.h b/drivers/staging/unisys/common-spar/include/channels/channel_guid.h index 63c67ca4c9ec..706363fc3e9a 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel_guid.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel_guid.h @@ -20,45 +20,42 @@ /* Used in IOChannel * {414815ed-c58c-11da-95a9-00e08161165f} */ -#define ULTRA_VHBA_CHANNEL_PROTOCOL_GUID \ +#define SPAR_VHBA_CHANNEL_PROTOCOL_UUID \ UUID_LE(0x414815ed, 0xc58c, 0x11da, \ 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) -static const uuid_le UltraVhbaChannelProtocolGuid = - ULTRA_VHBA_CHANNEL_PROTOCOL_GUID; +static const uuid_le spar_vhba_channel_protocol_uuid = + SPAR_VHBA_CHANNEL_PROTOCOL_UUID; /* Used in IOChannel * {8cd5994d-c58e-11da-95a9-00e08161165f} */ -#define ULTRA_VNIC_CHANNEL_PROTOCOL_GUID \ +#define SPAR_VNIC_CHANNEL_PROTOCOL_UUID \ UUID_LE(0x8cd5994d, 0xc58e, 0x11da, \ 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) -static const uuid_le UltraVnicChannelProtocolGuid = - ULTRA_VNIC_CHANNEL_PROTOCOL_GUID; +static const uuid_le spar_vnic_channel_protocol_uuid = + SPAR_VNIC_CHANNEL_PROTOCOL_UUID; /* Used in IOChannel * {72120008-4AAB-11DC-8530-444553544200} */ -#define ULTRA_SIOVM_GUID \ +#define SPAR_SIOVM_UUID \ UUID_LE(0x72120008, 0x4AAB, 0x11DC, \ 0x85, 0x30, 0x44, 0x45, 0x53, 0x54, 0x42, 0x00) -static const uuid_le UltraSIOVMGuid = ULTRA_SIOVM_GUID; - +static const uuid_le spar_siovm_uuid = SPAR_SIOVM_UUID; /* Used in visornoop/visornoop_main.c * {5b52c5ac-e5f5-4d42-8dff-429eaecd221f} */ -#define ULTRA_CONTROLDIRECTOR_CHANNEL_PROTOCOL_GUID \ +#define SPAR_CONTROLDIRECTOR_CHANNEL_PROTOCOL_UUID \ UUID_LE(0x5b52c5ac, 0xe5f5, 0x4d42, \ 0x8d, 0xff, 0x42, 0x9e, 0xae, 0xcd, 0x22, 0x1f) -static const uuid_le UltraControlDirectorChannelProtocolGuid = - ULTRA_CONTROLDIRECTOR_CHANNEL_PROTOCOL_GUID; +static const uuid_le spar_controldirector_channel_protocol_uuid = + SPAR_CONTROLDIRECTOR_CHANNEL_PROTOCOL_UUID; /* Used in visorchipset/visorchipset_main.c * {B4E79625-AEDE-4EAA-9E11-D3EDDCD4504C} */ -#define ULTRA_DIAG_POOL_CHANNEL_PROTOCOL_GUID \ +#define SPAR_DIAG_POOL_CHANNEL_PROTOCOL_UUID \ UUID_LE(0xb4e79625, 0xaede, 0x4eaa, \ 0x9e, 0x11, 0xd3, 0xed, 0xdc, 0xd4, 0x50, 0x4c) - - diff --git a/drivers/staging/unisys/common-spar/include/channels/controlframework.h b/drivers/staging/unisys/common-spar/include/channels/controlframework.h index fd4726e754ea..33d9caf337c8 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlframework.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlframework.h @@ -28,50 +28,35 @@ #include <linux/types.h> #include "channel.h" -#define ULTRA_MEMORY_COUNT_Ki 1024 - -/* Scale order 0 is one 32-bit (4-byte) word (in 64 or 128-bit - * architecture potentially 64 or 128-bit word) */ -#define ULTRA_MEMORY_PAGE_WORD 4 - -/* Define Ki scale page to be traditional 4KB page */ -#define ULTRA_MEMORY_PAGE_Ki (ULTRA_MEMORY_PAGE_WORD * ULTRA_MEMORY_COUNT_Ki) -typedef struct _ULTRA_SEGMENT_STATE { - u16 Enabled:1; /* Bit 0: May enter other states */ - u16 Active:1; /* Bit 1: Assigned to active partition */ - u16 Alive:1; /* Bit 2: Configure message sent to +struct spar_segment_state { + u16 enabled:1; /* Bit 0: May enter other states */ + u16 active:1; /* Bit 1: Assigned to active partition */ + u16 alive:1; /* Bit 2: Configure message sent to * service/server */ - u16 Revoked:1; /* Bit 3: similar to partition state + u16 revoked:1; /* Bit 3: similar to partition state * ShuttingDown */ - u16 Allocated:1; /* Bit 4: memory (device/port number) + u16 allocated:1; /* Bit 4: memory (device/port number) * has been selected by Command */ - u16 Known:1; /* Bit 5: has been introduced to the + u16 known:1; /* Bit 5: has been introduced to the * service/guest partition */ - u16 Ready:1; /* Bit 6: service/Guest partition has + u16 ready:1; /* Bit 6: service/Guest partition has * responded to introduction */ - u16 Operating:1; /* Bit 7: resource is configured and + u16 operating:1; /* Bit 7: resource is configured and * operating */ /* Note: don't use high bit unless we need to switch to ushort * which is non-compliant */ -} ULTRA_SEGMENT_STATE; -static const ULTRA_SEGMENT_STATE SegmentStateRunning = { +}; + +static const struct spar_segment_state segment_state_running = { 1, 1, 1, 0, 1, 1, 1, 1 }; -static const ULTRA_SEGMENT_STATE SegmentStatePaused = { + +static const struct spar_segment_state segment_state_paused = { 1, 1, 1, 0, 1, 1, 1, 0 }; -static const ULTRA_SEGMENT_STATE SegmentStateStandby = { + +static const struct spar_segment_state segment_state_standby = { 1, 1, 0, 0, 1, 1, 1, 0 }; -typedef union { - u64 Full; - struct { - u8 Major; /* will be 1 for the first release and - * increment thereafter */ - u8 Minor; - u16 Maintenance; - u32 Revision; /* Subversion revision */ - } Part; -} ULTRA_COMPONENT_VERSION; #endif /* _CONTROL_FRAMEWORK_H_ not defined */ diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index d08c198e0de3..a66db7968d6c 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -27,12 +27,12 @@ enum { INVALID_GUEST_FIRMWARE, SAMPLE_GUEST_FIRMWARE, }; /* {2B3C2D10-7EF5-4ad8-B966-3448B7386B3D} */ -#define ULTRA_CONTROLVM_CHANNEL_PROTOCOL_GUID \ +#define SPAR_CONTROLVM_CHANNEL_PROTOCOL_UUID \ UUID_LE(0x2b3c2d10, 0x7ef5, 0x4ad8, \ 0xb9, 0x66, 0x34, 0x48, 0xb7, 0x38, 0x6b, 0x3d) -static const uuid_le UltraControlvmChannelProtocolGuid = - ULTRA_CONTROLVM_CHANNEL_PROTOCOL_GUID; +static const uuid_le spar_controlvm_channel_protocol_uuid = + SPAR_CONTROLVM_CHANNEL_PROTOCOL_UUID; #define ULTRA_CONTROLVM_CHANNEL_PROTOCOL_SIGNATURE \ ULTRA_CHANNEL_PROTOCOL_SIGNATURE @@ -45,19 +45,13 @@ static const uuid_le UltraControlvmChannelProtocolGuid = * channel struct withOUT needing to increment this. */ #define ULTRA_CONTROLVM_CHANNEL_PROTOCOL_VERSIONID 1 -#define ULTRA_CONTROLVM_CHANNEL_OK_CLIENT(pChannel, logCtx) \ - (ULTRA_check_channel_client(pChannel, \ - UltraControlvmChannelProtocolGuid, \ +#define SPAR_CONTROLVM_CHANNEL_OK_CLIENT(ch) \ + spar_check_channel_client(ch, \ + spar_controlvm_channel_protocol_uuid, \ "controlvm", \ - sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL), \ + sizeof(struct spar_controlvm_channel_protocol), \ ULTRA_CONTROLVM_CHANNEL_PROTOCOL_VERSIONID, \ - ULTRA_CONTROLVM_CHANNEL_PROTOCOL_SIGNATURE, \ - __FILE__, __LINE__, logCtx)) -#define ULTRA_CONTROLVM_CHANNEL_OK_SERVER(actualBytes, logCtx) \ - (ULTRA_check_channel_server(UltraControlvmChannelProtocolGuid, \ - "controlvm", \ - sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL), \ - actualBytes, __FILE__, __LINE__, logCtx)) + ULTRA_CONTROLVM_CHANNEL_PROTOCOL_SIGNATURE) #define MY_DEVICE_INDEX 0 #define MAX_MACDATA_LEN 8 /* number of bytes for MAC address in config packet */ @@ -88,7 +82,7 @@ static const uuid_le UltraControlvmChannelProtocolGuid = * - issued on the EventQueue queue (q #2) in the ControlVm channel * - responded to on the EventAckQueue queue (q #3) in the ControlVm channel */ -typedef enum { +enum controlvm_id { CONTROLVM_INVALID = 0, /* SWITCH commands required Parameter: SwitchNumber */ /* BUS commands required Parameter: BusNumber */ @@ -117,9 +111,9 @@ typedef enum { CONTROLVM_CHIPSET_READY = 0x304, /* CP --> SP */ CONTROLVM_CHIPSET_SELFTEST = 0x305, /* CP --> SP */ -} CONTROLVM_ID; +}; -struct InterruptInfo { +struct irq_info { /**< specifies interrupt info. It is used to send interrupts * for this channel. The peer at the end of this channel * who has registered an interrupt (using recv fields @@ -128,495 +122,390 @@ struct InterruptInfo { * interrupt. Currently this is used by IOPart-SP to wake * up GP when Data Channel transitions from empty to * non-empty.*/ - u64 sendInterruptHandle; + u64 send_irq_handle; /**< specifies interrupt handle. It is used to retrieve the * corresponding interrupt pin from Monitor; and the * interrupt pin is used to connect to the corresponding - * intrrupt. Used by IOPart-GP only. */ - u64 recvInterruptHandle; + * interrupt. Used by IOPart-GP only. */ + u64 recv_irq_handle; /**< specifies interrupt vector. It, interrupt pin, and shared are * used to connect to the corresponding interrupt. Used by * IOPart-GP only. */ - u32 recvInterruptVector; + u32 recv_irq_vector; /**< specifies if the recvInterrupt is shared. It, interrupt pin * and vector are used to connect to 0 = not shared; 1 = shared. * the corresponding interrupt. Used by IOPart-GP only. */ - u8 recvInterruptShared; + u8 recv_irq_shared; u8 reserved[3]; /* Natural alignment purposes */ }; -struct PciId { - u16 Domain; - u8 Bus; - u8 Slot; - u8 Func; - u8 Reserved[3]; /* Natural alignment purposes */ -}; - -struct PciConfigHdr { - u16 VendorId; - u16 SubSysVendor; - u16 DeviceId; - u16 SubSysDevice; - u32 ClassCode; - u32 Reserved; /* Natural alignment purposes */ -}; - -struct ScsiId { - u32 Bus; - u32 Target; - u32 Lun; - u32 Host; /* Command should ignore this for * - * DiskArrival/RemovalEvents */ -}; - -struct WWID { - u32 wwid1; - u32 wwid2; -}; - -struct virtDiskInfo { - u32 switchNo; /* defined by SWITCH_CREATE */ - u32 externalPortNo; /* 0 for SAS RAID provided (external) - * virtual disks, 1 for virtual disk - * images, 2 for gold disk images */ - u16 VirtualDiskIndex; /* Index of disk descriptor in the - * VirtualDisk segment associated with - * externalPortNo */ - u16 Reserved1; - u32 Reserved2; +struct pci_id { + u16 domain; + u8 bus; + u8 slot; + u8 func; + u8 reserved[3]; /* Natural alignment purposes */ }; -typedef enum { - CONTROLVM_ACTION_NONE = 0, - CONTROLVM_ACTION_SET_RESTORE = 0x05E7, - CONTROLVM_ACTION_CLEAR_RESTORE = 0x0C18, - CONTROLVM_ACTION_RESTORING = 0x08E5, - CONTROLVM_ACTION_RESTORE_BUSY = 0x0999, - CONTROLVM_ACTION_CLEAR_NVRAM = 0xB01 -} CONTROLVM_ACTION; - -typedef enum _ULTRA_TOOL_ACTIONS { - /* enumeration that defines intended action */ - ULTRA_TOOL_ACTION_NONE = 0, /* normal boot of boot disk */ - ULTRA_TOOL_ACTION_INSTALL = 1, /* install source disk(s) to boot - * disk */ - ULTRA_TOOL_ACTION_CAPTURE = 2, /* capture boot disk to target disk(s) - * as 'gold image' */ - ULTRA_TOOL_ACTION_REPAIR = 3, /* use source disk(s) to repair - * installation on boot disk */ - ULTRA_TOOL_ACTION_CLEAN = 4, /* 'scrub' virtual disk before - * releasing back to storage pool */ - ULTRA_TOOL_ACTION_UPGRADE = 5, /* upgrade to use content of images - * referenced from newer blueprint */ - ULTRA_TOOL_ACTION_DIAG = 6, /* use tool to invoke diagnostic script - * provided by blueprint */ - ULTRA_TOOL_ACTION_FAILED = 7, /* used when tool fails installation - and cannot continue */ - ULTRA_TOOL_ACTION_COUNT = 8 -} ULTRA_TOOL_ACTIONS; - -typedef struct _ULTRA_EFI_SPAR_INDICATION { - u64 BootToFirmwareUI:1; /* Bit 0: Stop in uefi ui */ - u64 ClearNvram:1; /* Bit 1: Clear NVRAM */ - u64 ClearCmos:1; /* Bit 2: Clear CMOS */ - u64 BootToTool:1; /* Bit 3: Run install tool */ +struct efi_spar_indication { + u64 boot_to_fw_ui:1; /* Bit 0: Stop in uefi ui */ + u64 clear_nvram:1; /* Bit 1: Clear NVRAM */ + u64 clear_cmos:1; /* Bit 2: Clear CMOS */ + u64 boot_to_tool:1; /* Bit 3: Run install tool */ /* remaining bits are available */ -} ULTRA_EFI_SPAR_INDICATION; +}; -typedef enum { +enum ultra_chipset_feature { ULTRA_CHIPSET_FEATURE_REPLY = 0x00000001, ULTRA_CHIPSET_FEATURE_PARA_HOTPLUG = 0x00000002, ULTRA_CHIPSET_FEATURE_PCIVBUS = 0x00000004 -} ULTRA_CHIPSET_FEATURE; +}; /** This is the common structure that is at the beginning of every * ControlVm message (both commands and responses) in any ControlVm * queue. Commands are easily distinguished from responses by * looking at the flags.response field. */ -typedef struct _CONTROLVM_MESSAGE_HEADER { - u32 Id; /* See CONTROLVM_ID. */ +struct controlvm_message_header { + u32 id; /* See CONTROLVM_ID. */ /* For requests, indicates the message type. */ /* For responses, indicates the type of message we are responding to. */ - u32 MessageSize; /* Includes size of this struct + size + u32 message_size; /* Includes size of this struct + size * of message */ - u32 SegmentIndex; /* Index of segment containing Vm + u32 segment_index; /* Index of segment containing Vm * message/information */ - u32 CompletionStatus; /* Error status code or result of + u32 completion_status; /* Error status code or result of * message completion */ struct { u32 failed:1; /**< =1 in a response to * signify * failure */ - u32 responseExpected:1; /**< =1 in all messages that expect a + u32 response_expected:1; /**< =1 in all messages that expect a * response (Control ignores this * bit) */ u32 server:1; /**< =1 in all bus & device-related * messages where the message * receiver is to act as the bus or * device server */ - u32 testMessage:1; /**< =1 for testing use only + u32 test_message:1; /**< =1 for testing use only * (Control and Command ignore this * bit) */ - u32 partialCompletion:1; /**< =1 if there are forthcoming + u32 partial_completion:1; /**< =1 if there are forthcoming * responses/acks associated * with this message */ u32 preserve:1; /**< =1 this is to let us know to * preserve channel contents * (for running guests)*/ - u32 writerInDiag:1; /**< =1 the DiagWriter is active in the + u32 writer_in_diag:1; /**< =1 the DiagWriter is active in the * Diagnostic Partition*/ - - /* remaining bits in this 32-bit word are available */ - } Flags; - u32 Reserved; /* Natural alignment */ - u64 MessageHandle; /* Identifies the particular message instance, + } flags; + u32 reserved; /* Natural alignment */ + u64 message_handle; /* Identifies the particular message instance, * and is used to match particular */ /* request instances with the corresponding response instance. */ - u64 PayloadVmOffset; /* Offset of payload area from start of this + u64 payload_vm_offset; /* Offset of payload area from start of this * instance of ControlVm segment */ - u32 PayloadMaxBytes; /* Maximum bytes allocated in payload + u32 payload_max_bytes; /* Maximum bytes allocated in payload * area of ControlVm segment */ - u32 PayloadBytes; /* Actual number of bytes of payload + u32 payload_bytes; /* Actual number of bytes of payload * area to copy between IO/Command; */ /* if non-zero, there is a payload to copy. */ -} CONTROLVM_MESSAGE_HEADER; - -typedef struct _CONTROLVM_PACKET_DEVICE_CREATE { - u32 busNo; /**< bus # (0..n-1) from the msg receiver's - * perspective */ +}; - /* Control uses header SegmentIndex field to access bus number... */ - u32 devNo; /**< bus-relative (0..n-1) device number */ - u64 channelAddr; /**< Guest physical address of the channel, which - * can be dereferenced by the receiver - * of this ControlVm command */ - u64 channelBytes; /**< specifies size of the channel in bytes */ - uuid_le dataTypeGuid;/**< specifies format of data in channel */ - uuid_le devInstGuid; /**< instance guid for the device */ - struct InterruptInfo intr; /**< specifies interrupt information */ -} CONTROLVM_PACKET_DEVICE_CREATE; /* for CONTROLVM_DEVICE_CREATE */ - -typedef struct _CONTROLVM_PACKET_DEVICE_CONFIGURE { - u32 busNo; /**< bus # (0..n-1) from the msg +struct controlvm_packet_device_create { + u32 bus_no; /* bus # (0..n-1) from the msg receiver's end */ + u32 dev_no; /* bus-relative (0..n-1) device number */ + u64 channel_addr; /* Guest physical address of the channel, which + * can be dereferenced by the receiver of this + * ControlVm command */ + u64 channel_bytes; /* specifies size of the channel in bytes */ + uuid_le data_type_uuid; /* specifies format of data in channel */ + uuid_le dev_inst_uuid; /* instance guid for the device */ + struct irq_info intr; /* specifies interrupt information */ +}; /* for CONTROLVM_DEVICE_CREATE */ + +struct controlvm_packet_device_configure { + u32 bus_no; /**< bus # (0..n-1) from the msg * receiver's perspective */ /* Control uses header SegmentIndex field to access bus number... */ - u32 devNo; /**< bus-relative (0..n-1) device number */ -} CONTROLVM_PACKET_DEVICE_CONFIGURE; /* for CONTROLVM_DEVICE_CONFIGURE */ + u32 dev_no; /**< bus-relative (0..n-1) device number */ +} ; /* for CONTROLVM_DEVICE_CONFIGURE */ -typedef struct _CONTROLVM_MESSAGE_DEVICE_CREATE { - CONTROLVM_MESSAGE_HEADER Header; - CONTROLVM_PACKET_DEVICE_CREATE Packet; -} CONTROLVM_MESSAGE_DEVICE_CREATE; /* total 128 bytes */ +struct controlvm_message_device_create { + struct controlvm_message_header header; + struct controlvm_packet_device_create packet; +}; /* total 128 bytes */ -typedef struct _CONTROLVM_MESSAGE_DEVICE_CONFIGURE { - CONTROLVM_MESSAGE_HEADER Header; - CONTROLVM_PACKET_DEVICE_CONFIGURE Packet; -} CONTROLVM_MESSAGE_DEVICE_CONFIGURE; /* total 56 bytes */ +struct controlvm_message_device_configure { + struct controlvm_message_header header; + struct controlvm_packet_device_configure packet; +}; /* total 56 bytes */ /* This is the format for a message in any ControlVm queue. */ -typedef struct _CONTROLVM_MESSAGE_PACKET { +struct controlvm_message_packet { union { - - /* BEGIN Request messages */ struct { - u32 busNo; /*< bus # (0..n-1) from the msg - * receiver's perspective */ - - /* Control uses header SegmentIndex field to access bus number... */ - u32 deviceCount; /*< indicates the max number of - * devices on this bus */ - u64 channelAddr; /*< Guest physical address of the - * channel, which can be - * dereferenced by the receiver - * of this ControlVm command */ - u64 channelBytes; /*< size of the channel in bytes */ - uuid_le busDataTypeGuid;/*< indicates format of data in - bus channel */ - uuid_le busInstGuid; /*< instance guid for the bus */ - } createBus; /* for CONTROLVM_BUS_CREATE */ + u32 bus_no; /* bus # (0..n-1) from the msg + * receiver's perspective */ + u32 dev_count; /* indicates the max number of + * devices on this bus */ + u64 channel_addr; /* Guest physical address of + * the channel, which can be + * dereferenced by the receiver + * of this ControlVm command */ + u64 channel_bytes; /* size of the channel */ + uuid_le bus_data_type_uuid; /* indicates format of + * data in bus channel*/ + uuid_le bus_inst_uuid; /* instance uuid for the bus */ + } create_bus; /* for CONTROLVM_BUS_CREATE */ struct { - u32 busNo; /*< bus # (0..n-1) from the msg - * receiver's perspective */ - - /* Control uses header SegmentIndex field to access bus number... */ + u32 bus_no; /* bus # (0..n-1) from the msg + * receiver's perspective */ u32 reserved; /* Natural alignment purposes */ - } destroyBus; /* for CONTROLVM_BUS_DESTROY */ + } destroy_bus; /* for CONTROLVM_BUS_DESTROY */ struct { - u32 busNo; /*< bus # (0..n-1) from the - * msg receiver's - * perspective */ - - /* Control uses header SegmentIndex field to access bus number... */ - u32 reserved1; /* for alignment purposes */ - u64 guestHandle; /* This is used to convert - * guest physical address to real - * physical address for DMA, for ex. */ - u64 recvBusInterruptHandle;/*< specifies interrupt - * info. It is used by SP to register - * to receive interrupts from the CP. - * This interrupt is used for bus - * level notifications. The - * corresponding - * sendBusInterruptHandle is kept in - * CP. */ - } configureBus; /* for CONTROLVM_BUS_CONFIGURE */ - + u32 bus_no; /* bus # (0..n-1) from the receiver's + * perspective */ + u32 reserved1; /* for alignment purposes */ + u64 guest_handle; /* This is used to convert + * guest physical address to + * physical address */ + u64 recv_bus_irq_handle; + /* specifies interrupt info. It is used by SP + * to register to receive interrupts from the + * CP. This interrupt is used for bus level + * notifications. The corresponding + * sendBusInterruptHandle is kept in CP. */ + } configure_bus; /* for CONTROLVM_BUS_CONFIGURE */ /* for CONTROLVM_DEVICE_CREATE */ - CONTROLVM_PACKET_DEVICE_CREATE createDevice; + struct controlvm_packet_device_create create_device; struct { - u32 busNo; /*< bus # (0..n-1) from the msg - * receiver's perspective */ - - /* Control uses header SegmentIndex field to access bus number... */ - u32 devNo; /*< bus-relative (0..n-1) device - * number */ - } destroyDevice; /* for CONTROLVM_DEVICE_DESTROY */ - + u32 bus_no; /* bus # (0..n-1) from the msg + * receiver's perspective */ + u32 dev_no; /* bus-relative (0..n-1) device # */ + } destroy_device; /* for CONTROLVM_DEVICE_DESTROY */ /* for CONTROLVM_DEVICE_CONFIGURE */ - CONTROLVM_PACKET_DEVICE_CONFIGURE configureDevice; + struct controlvm_packet_device_configure configure_device; struct { - u32 busNo; /*< bus # (0..n-1) from the msg - * receiver's perspective */ - - /* Control uses header SegmentIndex field to access bus number... */ - u32 devNo; /*< bus-relative (0..n-1) device - * number */ - } reconfigureDevice; /* for CONTROLVM_DEVICE_RECONFIGURE */ + u32 bus_no; /* bus # (0..n-1) from the msg + * receiver's perspective */ + u32 dev_no; /* bus-relative (0..n-1) device # */ + } reconfigure_device; /* for CONTROLVM_DEVICE_RECONFIGURE */ struct { - u32 busNo; - ULTRA_SEGMENT_STATE state; + u32 bus_no; + struct spar_segment_state state; u8 reserved[2]; /* Natural alignment purposes */ - } busChangeState; /* for CONTROLVM_BUS_CHANGESTATE */ + } bus_change_state; /* for CONTROLVM_BUS_CHANGESTATE */ struct { - u32 busNo; - u32 devNo; - ULTRA_SEGMENT_STATE state; + u32 bus_no; + u32 dev_no; + struct spar_segment_state state; struct { - u32 physicalDevice:1; /* =1 if message is for + u32 phys_device:1; /* =1 if message is for * a physical device */ - /* remaining bits in this 32-bit word are available */ } flags; u8 reserved[2]; /* Natural alignment purposes */ - } deviceChangeState; /* for CONTROLVM_DEVICE_CHANGESTATE */ + } device_change_state; /* for CONTROLVM_DEVICE_CHANGESTATE */ struct { - u32 busNo; - u32 devNo; - ULTRA_SEGMENT_STATE state; + u32 bus_no; + u32 dev_no; + struct spar_segment_state state; u8 reserved[6]; /* Natural alignment purposes */ - } deviceChangeStateEvent; /* for CONTROLVM_DEVICE_CHANGESTATE_EVENT */ + } device_change_state_event; + /* for CONTROLVM_DEVICE_CHANGESTATE_EVENT */ struct { - u32 busCount; /*< indicates the max number of busses */ - u32 switchCount; /*< indicates the max number of - * switches (applicable for service - * partition only) */ - ULTRA_CHIPSET_FEATURE features; - u32 platformNumber; /* Platform Number */ - } initChipset; /* for CONTROLVM_CHIPSET_INIT */ + u32 bus_count; /* indicates the max number of busses */ + u32 switch_count; /* indicates the max number of + * switches if a service partition */ + enum ultra_chipset_feature features; + u32 platform_number; /* Platform Number */ + } init_chipset; /* for CONTROLVM_CHIPSET_INIT */ struct { - u32 Options; /*< reserved */ - u32 Test; /*< bit 0 set to run embedded selftest */ - } chipsetSelftest; /* for CONTROLVM_CHIPSET_SELFTEST */ - - /* END Request messages */ - - /* BEGIN Response messages */ - - /* END Response messages */ - - /* BEGIN Event messages */ + u32 options; /* reserved */ + u32 test; /* bit 0 set to run embedded selftest */ + } chipset_selftest; /* for CONTROLVM_CHIPSET_SELFTEST */ + u64 addr; /* a physical address of something, that can be + * dereferenced by the receiver of this + * ControlVm command (depends on command id) */ + u64 handle; /* a handle of something (depends on command + * id) */ + }; +}; - /* END Event messages */ +/* All messages in any ControlVm queue have this layout. */ +struct controlvm_message { + struct controlvm_message_header hdr; + struct controlvm_message_packet cmd; +}; - /* BEGIN Ack messages */ +struct device_map { + GUEST_PHYSICAL_ADDRESS device_channel_address; + u64 device_channel_size; + u32 ca_index; + u32 reserved; /* natural alignment */ + u64 reserved2; /* Align structure on 32-byte boundary */ +}; - /* END Ack messages */ - u64 addr; /*< a physical address of something, that - * can be dereferenced by the receiver of - * this ControlVm command (depends on - * command id) */ - u64 handle; /*< a handle of something (depends on - * command id) */ - }; -} CONTROLVM_MESSAGE_PACKET; +struct guest_devices { + struct device_map video_channel; + struct device_map keyboard_channel; + struct device_map network_channel; + struct device_map storage_channel; + struct device_map console_channel; + u32 partition_index; + u32 pad; +}; -/* All messages in any ControlVm queue have this layout. */ -typedef struct _CONTROLVM_MESSAGE { - CONTROLVM_MESSAGE_HEADER hdr; - CONTROLVM_MESSAGE_PACKET cmd; -} CONTROLVM_MESSAGE; - -typedef struct _DEVICE_MAP { - GUEST_PHYSICAL_ADDRESS DeviceChannelAddress; - u64 DeviceChannelSize; - u32 CA_Index; - u32 Reserved; /* natural alignment */ - u64 Reserved2; /* Align structure on 32-byte boundary */ -} DEVICE_MAP; - -typedef struct _GUEST_DEVICES { - DEVICE_MAP VideoChannel; - DEVICE_MAP KeyboardChannel; - DEVICE_MAP NetworkChannel; - DEVICE_MAP StorageChannel; - DEVICE_MAP ConsoleChannel; - u32 PartitionIndex; - u32 Pad; -} GUEST_DEVICES; - -typedef struct _ULTRA_CONTROLVM_CHANNEL_PROTOCOL { - CHANNEL_HEADER Header; - GUEST_PHYSICAL_ADDRESS gpControlVm; /* guest physical address of +struct spar_controlvm_channel_protocol { + struct channel_header header; + GUEST_PHYSICAL_ADDRESS gp_controlvm; /* guest physical address of * this channel */ - GUEST_PHYSICAL_ADDRESS gpPartitionTables; /* guest physical address of - * partition tables */ - GUEST_PHYSICAL_ADDRESS gpDiagGuest; /* guest physical address of + GUEST_PHYSICAL_ADDRESS gp_partition_tables;/* guest physical address of + * partition tables */ + GUEST_PHYSICAL_ADDRESS gp_diag_guest; /* guest physical address of * diagnostic channel */ - GUEST_PHYSICAL_ADDRESS gpBootRomDisk; /* guest phys addr of (read + GUEST_PHYSICAL_ADDRESS gp_boot_romdisk;/* guest phys addr of (read * only) Boot ROM disk */ - GUEST_PHYSICAL_ADDRESS gpBootRamDisk; /* guest phys addr of writable + GUEST_PHYSICAL_ADDRESS gp_boot_ramdisk;/* guest phys addr of writable * Boot RAM disk */ - GUEST_PHYSICAL_ADDRESS gpAcpiTable; /* guest phys addr of acpi + GUEST_PHYSICAL_ADDRESS gp_acpi_table; /* guest phys addr of acpi * table */ - GUEST_PHYSICAL_ADDRESS gpControlChannel; /* guest phys addr of control - * channel */ - GUEST_PHYSICAL_ADDRESS gpDiagRomDisk; /* guest phys addr of diagnostic + GUEST_PHYSICAL_ADDRESS gp_control_channel;/* guest phys addr of control + * channel */ + GUEST_PHYSICAL_ADDRESS gp_diag_romdisk;/* guest phys addr of diagnostic * ROM disk */ - GUEST_PHYSICAL_ADDRESS gpNvram; /* guest phys addr of NVRAM + GUEST_PHYSICAL_ADDRESS gp_nvram; /* guest phys addr of NVRAM * channel */ - u64 RequestPayloadOffset; /* Offset to request payload area */ - u64 EventPayloadOffset; /* Offset to event payload area */ - u32 RequestPayloadBytes; /* Bytes available in request payload + u64 request_payload_offset; /* Offset to request payload area */ + u64 event_payload_offset; /* Offset to event payload area */ + u32 request_payload_bytes; /* Bytes available in request payload * area */ - u32 EventPayloadBytes; /* Bytes available in event payload area */ - u32 ControlChannelBytes; - u32 NvramChannelBytes; /* Bytes in PartitionNvram segment */ - u32 MessageBytes; /* sizeof(CONTROLVM_MESSAGE) */ - u32 MessageCount; /* CONTROLVM_MESSAGE_MAX */ - GUEST_PHYSICAL_ADDRESS gpSmbiosTable; /* guest phys addr of SMBIOS + u32 event_payload_bytes;/* Bytes available in event payload area */ + u32 control_channel_bytes; + u32 nvram_channel_bytes; /* Bytes in PartitionNvram segment */ + u32 message_bytes; /* sizeof(CONTROLVM_MESSAGE) */ + u32 message_count; /* CONTROLVM_MESSAGE_MAX */ + GUEST_PHYSICAL_ADDRESS gp_smbios_table;/* guest phys addr of SMBIOS * tables */ - GUEST_PHYSICAL_ADDRESS gpPhysicalSmbiosTable; /* guest phys addr of - * SMBIOS table */ + GUEST_PHYSICAL_ADDRESS gp_physical_smbios_table;/* guest phys addr of + * SMBIOS table */ /* ULTRA_MAX_GUESTS_PER_SERVICE */ - GUEST_DEVICES gpObsoleteGuestDevices[16]; + struct guest_devices gp_obsolete_guest_devices[16]; /* guest physical address of EFI firmware image base */ - GUEST_PHYSICAL_ADDRESS VirtualGuestFirmwareImageBase; + GUEST_PHYSICAL_ADDRESS virtual_guest_firmware_image_base; /* guest physical address of EFI firmware entry point */ - GUEST_PHYSICAL_ADDRESS VirtualGuestFirmwareEntryPoint; + GUEST_PHYSICAL_ADDRESS virtual_guest_firmware_entry_point; /* guest EFI firmware image size */ - u64 VirtualGuestFirmwareImageSize; + u64 virtual_guest_firmware_image_size; /* GPA = 1MB where EFI firmware image is copied to */ - GUEST_PHYSICAL_ADDRESS VirtualGuestFirmwareBootBase; - GUEST_PHYSICAL_ADDRESS VirtualGuestImageBase; - GUEST_PHYSICAL_ADDRESS VirtualGuestImageSize; - u64 PrototypeControlChannelOffset; - GUEST_PHYSICAL_ADDRESS VirtualGuestPartitionHandle; + GUEST_PHYSICAL_ADDRESS virtual_guest_firmware_boot_base; + GUEST_PHYSICAL_ADDRESS virtual_guest_image_base; + GUEST_PHYSICAL_ADDRESS virtual_guest_image_size; + u64 prototype_control_channel_offset; + GUEST_PHYSICAL_ADDRESS virtual_guest_partition_handle; - u16 RestoreAction; /* Restore Action field to restore the guest + u16 restore_action; /* Restore Action field to restore the guest * partition */ - u16 DumpAction; /* For Windows guests it shows if the visordisk + u16 dump_action; /* For Windows guests it shows if the visordisk * is running in dump mode */ - u16 NvramFailCount; - u16 SavedCrashMsgCount; /* = CONTROLVM_CRASHMSG_MAX */ - u32 SavedCrashMsgOffset; /* Offset to request payload area needed + u16 nvram_fail_count; + u16 saved_crash_message_count; /* = CONTROLVM_CRASHMSG_MAX */ + u32 saved_crash_message_offset; /* Offset to request payload area needed * for crash dump */ - u32 InstallationError; /* Type of error encountered during + u32 installation_error; /* Type of error encountered during * installation */ - u32 InstallationTextId; /* Id of string to display */ - u16 InstallationRemainingSteps; /* Number of remaining installation - * steps (for progress bars) */ - u8 ToolAction; /* ULTRA_TOOL_ACTIONS Installation Action + u32 installation_text_id; /* Id of string to display */ + u16 installation_remaining_steps;/* Number of remaining installation + * steps (for progress bars) */ + u8 tool_action; /* ULTRA_TOOL_ACTIONS Installation Action * field */ - u8 Reserved; /* alignment */ - ULTRA_EFI_SPAR_INDICATION EfiSparIndication; - ULTRA_EFI_SPAR_INDICATION EfiSparIndicationSupported; - u32 SPReserved; - u8 Reserved2[28]; /* Force signals to begin on 128-byte cache + u8 reserved; /* alignment */ + struct efi_spar_indication efi_spar_ind; + struct efi_spar_indication efi_spar_ind_supported; + u32 sp_reserved; + u8 reserved2[28]; /* Force signals to begin on 128-byte cache * line */ - SIGNAL_QUEUE_HEADER RequestQueue; /* Service or guest partition - * uses this queue to send - * requests to Control */ - SIGNAL_QUEUE_HEADER ResponseQueue; /* Control uses this queue to - * respond to service or guest - * partition requests */ - SIGNAL_QUEUE_HEADER EventQueue; /* Control uses this queue to + struct signal_queue_header request_queue;/* Service or guest partition + * uses this queue to send + * requests to Control */ + struct signal_queue_header response_queue;/* Control uses this queue to + * respond to service or guest + * partition requests */ + struct signal_queue_header event_queue; /* Control uses this queue to * send events to service or * guest partition */ - SIGNAL_QUEUE_HEADER EventAckQueue; /* Service or guest partition - * uses this queue to ack - * Control events */ + struct signal_queue_header event_ack_queue;/* Service or guest partition + * uses this queue to ack + * Control events */ /* Request fixed-size message pool - does not include payload */ - CONTROLVM_MESSAGE RequestMsg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message request_msg[CONTROLVM_MESSAGE_MAX]; /* Response fixed-size message pool - does not include payload */ - CONTROLVM_MESSAGE ResponseMsg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message response_msg[CONTROLVM_MESSAGE_MAX]; /* Event fixed-size message pool - does not include payload */ - CONTROLVM_MESSAGE EventMsg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message event_msg[CONTROLVM_MESSAGE_MAX]; /* Ack fixed-size message pool - does not include payload */ - CONTROLVM_MESSAGE EventAckMsg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message event_ack_msg[CONTROLVM_MESSAGE_MAX]; /* Message stored during IOVM creation to be reused after crash */ - CONTROLVM_MESSAGE SavedCrashMsg[CONTROLVM_CRASHMSG_MAX]; -} ULTRA_CONTROLVM_CHANNEL_PROTOCOL; + struct controlvm_message saved_crash_msg[CONTROLVM_CRASHMSG_MAX]; +}; /* Offsets for VM channel attributes... */ #define VM_CH_REQ_QUEUE_OFFSET \ - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, RequestQueue) + offsetof(struct spar_controlvm_channel_protocol, request_queue) #define VM_CH_RESP_QUEUE_OFFSET \ - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, ResponseQueue) + offsetof(struct spar_controlvm_channel_protocol, response_queue) #define VM_CH_EVENT_QUEUE_OFFSET \ - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, EventQueue) + offsetof(struct spar_controlvm_channel_protocol, event_queue) #define VM_CH_ACK_QUEUE_OFFSET \ - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, EventAckQueue) + offsetof(struct spar_controlvm_channel_protocol, event_ack_queue) #define VM_CH_REQ_MSG_OFFSET \ - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, RequestMsg) + offsetof(struct spar_controlvm_channel_protocol, request_msg) #define VM_CH_RESP_MSG_OFFSET \ - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, ResponseMsg) + offsetof(struct spar_controlvm_channel_protocol, response_msg) #define VM_CH_EVENT_MSG_OFFSET \ - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, EventMsg) + offsetof(struct spar_controlvm_channel_protocol, event_msg) #define VM_CH_ACK_MSG_OFFSET \ - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, EventAckMsg) + offsetof(struct spar_controlvm_channel_protocol, event_ack_msg) #define VM_CH_CRASH_MSG_OFFSET \ - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, SavedCrashMsg) + offsetof(struct spar_controlvm_channel_protocol, saved_crash_msg) /* The following header will be located at the beginning of PayloadVmOffset for - * various ControlVm commands. The receiver of a ControlVm command with a - * PayloadVmOffset will dereference this address and then use ConnectionOffset, - * InitiatorOffset, and TargetOffset to get the location of UTF-8 formatted - * strings that can be parsed to obtain command-specific information. The value - * of TotalLength should equal PayloadBytes. The format of the strings at - * PayloadVmOffset will take different forms depending on the message. See the - * following Wiki page for more information: - * https://ustr-linux-1.na.uis.unisys.com/spar/index.php/ControlVm_Parameters_Area + * various ControlVm commands. The receiver of a ControlVm command with a + * PayloadVmOffset will dereference this address and then use connection_offset, + * initiator_offset, and target_offset to get the location of UTF-8 formatted + * strings that can be parsed to obtain command-specific information. The value + * of total_length should equal PayloadBytes. The format of the strings at + * PayloadVmOffset will take different forms depending on the message. */ -typedef struct _ULTRA_CONTROLVM_PARAMETERS_HEADER { - u32 TotalLength; - u32 HeaderLength; - u32 ConnectionOffset; - u32 ConnectionLength; - u32 InitiatorOffset; - u32 InitiatorLength; - u32 TargetOffset; - u32 TargetLength; - u32 ClientOffset; - u32 ClientLength; - u32 NameOffset; - u32 NameLength; - uuid_le Id; - u32 Revision; - u32 Reserved; /* Natural alignment */ -} ULTRA_CONTROLVM_PARAMETERS_HEADER; +struct spar_controlvm_parameters_header { + u32 total_length; + u32 header_length; + u32 connection_offset; + u32 connection_length; + u32 initiator_offset; + u32 initiator_length; + u32 target_offset; + u32 target_length; + u32 client_offset; + u32 client_length; + u32 name_offset; + u32 name_length; + uuid_le id; + u32 revision; + u32 reserved; /* Natural alignment */ +}; #endif /* __CONTROLVMCHANNEL_H__ */ diff --git a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h index 9912e51b89b5..e8fb8678a8e2 100644 --- a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h @@ -37,12 +37,12 @@ #include "channel.h" /* {EEA7A573-DB82-447c-8716-EFBEAAAE4858} */ -#define ULTRA_DIAG_CHANNEL_PROTOCOL_GUID \ +#define SPAR_DIAG_CHANNEL_PROTOCOL_UUID \ UUID_LE(0xeea7a573, 0xdb82, 0x447c, \ 0x87, 0x16, 0xef, 0xbe, 0xaa, 0xae, 0x48, 0x58) -static const uuid_le UltraDiagChannelProtocolGuid = - ULTRA_DIAG_CHANNEL_PROTOCOL_GUID; +static const uuid_le spar_diag_channel_protocol_uuid = + SPAR_DIAG_CHANNEL_PROTOCOL_UUID; /* {E850F968-3263-4484-8CA5-2A35D087A5A8} */ #define ULTRA_DIAG_ROOT_CHANNEL_PROTOCOL_GUID \ @@ -58,19 +58,20 @@ static const uuid_le UltraDiagChannelProtocolGuid = * increment this. */ #define ULTRA_DIAG_CHANNEL_PROTOCOL_VERSIONID 2 -#define ULTRA_DIAG_CHANNEL_OK_CLIENT(pChannel, logCtx) \ - (ULTRA_check_channel_client(pChannel, \ - UltraDiagChannelProtocolGuid, \ - "diag", \ - sizeof(ULTRA_DIAG_CHANNEL_PROTOCOL), \ - ULTRA_DIAG_CHANNEL_PROTOCOL_VERSIONID, \ - ULTRA_DIAG_CHANNEL_PROTOCOL_SIGNATURE, \ - __FILE__, __LINE__, logCtx)) -#define ULTRA_DIAG_CHANNEL_OK_SERVER(actualBytes, logCtx) \ - (ULTRA_check_channel_server(UltraDiagChannelProtocolGuid, \ - "diag", \ - sizeof(ULTRA_DIAG_CHANNEL_PROTOCOL), \ - actualBytes, __FILE__, __LINE__, logCtx)) +#define SPAR_DIAG_CHANNEL_OK_CLIENT(ch)\ + (spar_check_channel_client(ch,\ + spar_diag_channel_protocol_uuid,\ + "diag",\ + sizeof(struct spar_diag_channel_protocol),\ + ULTRA_DIAG_CHANNEL_PROTOCOL_VERSIONID,\ + ULTRA_DIAG_CHANNEL_PROTOCOL_SIGNATURE)) + +#define SPAR_DIAG_CHANNEL_OK_SERVER(bytes)\ + (spar_check_channel_server(spar_diag_channel_protocol_uuid,\ + "diag",\ + sizeof(struct spar_diag_channel_protocol),\ + bytes)) + #define MAX_MODULE_NAME_SIZE 128 /* Maximum length of module name... */ #define MAX_ADDITIONAL_INFO_SIZE 256 /* Maximum length of any additional info * accompanying event... */ @@ -105,21 +106,21 @@ static const uuid_le UltraDiagChannelProtocolGuid = /* Copied from EFI's EFI_TIME struct in efidef.h. EFI headers are not allowed * in some of the Supervisor areas, such as Monitor, so it has been "ported" here * for use in diagnostic event timestamps... */ -typedef struct _DIAG_EFI_TIME { - u16 Year; /* 1998 - 20XX */ - u8 Month; /* 1 - 12 */ - u8 Day; /* 1 - 31 */ - u8 Hour; /* 0 - 23 */ - u8 Minute; /* 0 - 59 */ - u8 Second; /* 0 - 59 */ - u8 Pad1; - u32 Nanosecond; /* 0 - 999, 999, 999 */ - s16 TimeZone; /* -1440 to 1440 or 2047 */ - u8 Daylight; - u8 Pad2; -} DIAG_EFI_TIME; - -typedef enum { +struct diag_efi_time { + u16 year; /* 1998 - 20XX */ + u8 month; /* 1 - 12 */ + u8 day; /* 1 - 31 */ + u8 hour; /* 0 - 23 */ + u8 minute; /* 0 - 59 */ + u8 second; /* 0 - 59 */ + u8 pad1; + u32 nanosecond; /* 0 - 999, 999, 999 */ + s16 timezone; /* -1440 to 1440 or 2047 */ + u8 daylight; + u8 pad2; +}; + +enum spar_component_types { ULTRA_COMPONENT_GUEST = 0, ULTRA_COMPONENT_MONITOR = 0x01, ULTRA_COMPONENT_CCM = 0x02, /* Common Control module */ @@ -144,9 +145,9 @@ typedef enum { ULTRA_COMPONENT_PSERVICES = 0x17, ULTRA_COMPONENT_PDIAG = 0x18 /* RESERVED 0x18 - 0x1F */ -} ULTRA_COMPONENT_TYPES; +}; -/* Structure: DIAG_CHANNEL_EVENT Purpose: Contains attributes that make up an +/* Structure: diag_channel_event Purpose: Contains attributes that make up an * event to be written to the DIAG_CHANNEL memory. Attributes: EventId: Id of * the diagnostic event to write to memory. Severity: Severity of the event * (Error, Info, etc). ModuleName: Module/file name where event originated. @@ -155,40 +156,40 @@ typedef enum { * Reserved: Padding to align structure on a 64-byte cache line boundary. * AdditionalInfo: Array of characters for additional event info (may be * empty). */ -typedef struct _DIAG_CHANNEL_EVENT { - u32 EventId; - u32 Severity; - u8 ModuleName[MAX_MODULE_NAME_SIZE]; - u32 LineNumber; - DIAG_EFI_TIME Timestamp; /* Size = 16 bytes */ - u32 PartitionNumber; /* Filled in by Diag Switch as pool blocks are +struct diag_channel_event { + u32 event_id; + u32 severity; + u8 module_name[MAX_MODULE_NAME_SIZE]; + u32 line_number; + struct diag_efi_time timestamp; /* Size = 16 bytes */ + u32 partition_number; /* Filled in by Diag Switch as pool blocks are * filled */ - u16 VirtualProcessorNumber; - u16 LogicalProcessorNumber; - u8 ComponentType; /* ULTRA_COMPONENT_TYPES */ - u8 Subsystem; - u16 Reserved0; /* pad to u64 alignment */ - u32 BlockNumber; /* filled in by DiagSwitch as pool blocks are + u16 vcpu_number; + u16 lcpu_number; + u8 component_type; /* ULTRA_COMPONENT_TYPES */ + u8 subsystem; + u16 reserved0; /* pad to u64 alignment */ + u32 block_no; /* filled in by DiagSwitch as pool blocks are * filled */ - u32 BlockNumberHigh; - u32 EventNumber; /* filled in by DiagSwitch as pool blocks are + u32 block_no_high; + u32 event_no; /* filled in by DiagSwitch as pool blocks are * filled */ - u32 EventNumberHigh; + u32 event_no_high; - /* The BlockNumber and EventNumber fields are set only by DiagSwitch + /* The block_no and event_no fields are set only by DiagSwitch * and referenced only by WinDiagDisplay formatting tool as * additional diagnostic information. Other tools including * WinDiagDisplay currently ignore these 'Reserved' bytes. */ - u8 Reserved[8]; - u8 AdditionalInfo[MAX_ADDITIONAL_INFO_SIZE]; + u8 reserved[8]; + u8 additional_info[MAX_ADDITIONAL_INFO_SIZE]; - /* NOTE: Changesto DIAG_CHANNEL_EVENT generally need to be reflected in + /* NOTE: Changes to diag_channel_event generally need to be reflected in * existing copies * * - for AppOS at * GuestLinux/visordiag_early/supervisor_diagchannel.h * * - for WinDiagDisplay at * EFI/Ultra/Tools/WinDiagDisplay/WinDiagDisplay/diagstruct.h */ -} DIAG_CHANNEL_EVENT; +}; /* Levels of severity for diagnostic events, in order from lowest severity to * highest (i.e. fatal errors are the most severe, and should always be logged, @@ -201,7 +202,8 @@ typedef struct _DIAG_CHANNEL_EVENT { * they are valid for controlling the amount of event data. This enum is also * defined in DotNet\sParFramework\ControlFramework\ControlFramework.cs. If a * change is made to this enum, they should also be reflected in that file. */ -typedef enum { DIAG_SEVERITY_ENUM_BEGIN = 0, +enum diag_severity { + DIAG_SEVERITY_ENUM_BEGIN = 0, DIAG_SEVERITY_OVERRIDE = DIAG_SEVERITY_ENUM_BEGIN, DIAG_SEVERITY_VERBOSE = DIAG_SEVERITY_OVERRIDE, /* 0 */ DIAG_SEVERITY_INFO = DIAG_SEVERITY_VERBOSE + 1, /* 1 */ @@ -212,7 +214,7 @@ typedef enum { DIAG_SEVERITY_ENUM_BEGIN = 0, DIAG_SEVERITY_ENUM_END = DIAG_SEVERITY_SHUTOFF, /* 5 */ DIAG_SEVERITY_NONFATAL_ERR = DIAG_SEVERITY_ERR, DIAG_SEVERITY_FATAL_ERR = DIAG_SEVERITY_PRINT -} DIAG_SEVERITY; +}; /* Event Cause enums * @@ -233,26 +235,24 @@ typedef enum { DIAG_SEVERITY_ENUM_BEGIN = 0, * If a change is made to this enum, they should also be reflected in that * file. */ - - /* A cause value "DIAG_CAUSE_FILE_XFER" together with a severity value of * "DIAG_SEVERITY_PRINT" (=4), is used for transferring text or binary file to * the Diag partition. This cause-severity combination will be used by Logger * DiagSwitch to segregate events into block types. The files are transferred in -* 256 byte chunks maximum, in the AdditionalInfo field of the DIAG_CHANNEL_EVENT +* 256 byte chunks maximum, in the AdditionalInfo field of the diag_channel_event * structure. In the file transfer mode, some event fields will have different * meaning: EventId specifies the file offset, severity specifies the block type, * ModuleName specifies the filename, LineNumber specifies the number of valid * data bytes in an event and AdditionalInfo contains up to 256 bytes of data. */ /* The Diag DiagWriter appends event blocks to events.raw as today, and for data - * blocks uses DIAG_CHANNEL_EVENT + * blocks uses diag_channel_event * PartitionNumber to extract and append 'AdditionalInfo' to filename (specified * by ModuleName). */ /* The Dell PDiag uses this new mechanism to stash DSET .zip onto the * 'diagnostic' virtual disk. */ -typedef enum { +enum diag_cause { DIAG_CAUSE_UNKNOWN = 0, DIAG_CAUSE_UNKNOWN_DEBUG = DIAG_CAUSE_UNKNOWN + 1, /* 1 */ DIAG_CAUSE_DEBUG = DIAG_CAUSE_UNKNOWN_DEBUG + 1, /* 2 */ @@ -264,7 +264,7 @@ typedef enum { DIAG_CAUSE_INTERNAL_ERROR = DIAG_CAUSE_INVALID_REQUEST + 1, /* 8 */ DIAG_CAUSE_FILE_XFER = DIAG_CAUSE_INTERNAL_ERROR + 1, /* 9 */ DIAG_CAUSE_ENUM_END = DIAG_CAUSE_FILE_XFER /* 9 */ -} DIAG_CAUSE; +}; /* Event Cause category defined into the byte 2 of Severity */ #define CAUSE_DEBUG (DIAG_CAUSE_DEBUG << CAUSE_SHIFT_AMT) @@ -344,7 +344,7 @@ typedef enum { #define CAUSE_FILE_XFER_SEVERITY_PRINT \ (CAUSE_FILE_XFER | DIAG_SEVERITY_PRINT) -/* Structure: DIAG_CHANNEL_PROTOCOL_HEADER +/* Structure: diag_channel_protocol_header * * Purpose: Contains attributes that make up the header specific to the * DIAG_CHANNEL area. @@ -362,12 +362,12 @@ typedef enum { * whether events are logged. Any event's severity for a * particular subsystem below this level will be discarded. */ -typedef struct _DIAG_CHANNEL_PROTOCOL_HEADER { - volatile u32 DiagLock; - u8 IsChannelInitialized; - u8 Reserved[3]; - u8 SubsystemSeverityFilter[64]; -} DIAG_CHANNEL_PROTOCOL_HEADER; +struct diag_channel_protocol_header { + u32 diag_lock; + u8 channel_initialized; + u8 reserved[3]; + u8 subsystem_severity_filter[64]; +}; /* The Diagram for the Diagnostic Channel: */ /* ----------------------- */ @@ -375,19 +375,20 @@ typedef struct _DIAG_CHANNEL_PROTOCOL_HEADER { /* ----------------------- */ /* | Signal Queue Header | Defined by SIGNAL_QUEUE_HEADER */ /* ----------------------- */ -/* | DiagChannel Header | Defined by DIAG_CHANNEL_PROTOCOL_HEADER */ +/* | DiagChannel Header | Defined by diag_channel_protocol_header */ /* ----------------------- */ -/* | Channel Event Info | Defined by (DIAG_CHANNEL_EVENT * MAX_EVENTS) */ +/* | Channel Event Info | Defined by diag_channel_event*MAX_EVENTS */ /* ----------------------- */ /* | Reserved | Reserved (pad out to 4MB) */ /* ----------------------- */ /* Offsets/sizes for diagnostic channel attributes... */ -#define DIAG_CH_QUEUE_HEADER_OFFSET (sizeof(ULTRA_CHANNEL_PROTOCOL)) -#define DIAG_CH_QUEUE_HEADER_SIZE (sizeof(SIGNAL_QUEUE_HEADER)) +#define DIAG_CH_QUEUE_HEADER_OFFSET (sizeof(struct channel_header)) +#define DIAG_CH_QUEUE_HEADER_SIZE (sizeof(struct signal_queue_header)) #define DIAG_CH_PROTOCOL_HEADER_OFFSET \ (DIAG_CH_QUEUE_HEADER_OFFSET + DIAG_CH_QUEUE_HEADER_SIZE) -#define DIAG_CH_PROTOCOL_HEADER_SIZE (sizeof(DIAG_CHANNEL_PROTOCOL_HEADER)) +#define DIAG_CH_PROTOCOL_HEADER_SIZE \ + (sizeof(struct diag_channel_protocol_header)) #define DIAG_CH_EVENT_OFFSET \ (DIAG_CH_PROTOCOL_HEADER_OFFSET + DIAG_CH_PROTOCOL_HEADER_SIZE) #define DIAG_CH_SIZE (4096 * 1024) @@ -397,7 +398,7 @@ typedef struct _DIAG_CHANNEL_PROTOCOL_HEADER { #define DIAG_CH_LRG_SIZE (2 * DIAG_CH_SIZE) /* 8 MB */ /* - * Structure: ULTRA_DIAG_CHANNEL_PROTOCOL + * Structure: spar_diag_channel_protocol * * Purpose: Contains attributes that make up the DIAG_CHANNEL memory. * @@ -409,19 +410,18 @@ typedef struct _DIAG_CHANNEL_PROTOCOL_HEADER { * store event. * * DiagChannelHeader: Diagnostic channel header info (see - * DIAG_CHANNEL_PROTOCOL_HEADER comments). + * diag_channel_protocol_header comments). * * Events: Area where diagnostic events (up to MAX_EVENTS) are written. * *Reserved: Reserved area to allow for correct channel size padding. */ -typedef struct _ULTRA_DIAG_CHANNEL_PROTOCOL { - ULTRA_CHANNEL_PROTOCOL CommonChannelHeader; - SIGNAL_QUEUE_HEADER QueueHeader; - DIAG_CHANNEL_PROTOCOL_HEADER DiagChannelHeader; - DIAG_CHANNEL_EVENT Events[(DIAG_CH_SIZE - DIAG_CH_EVENT_OFFSET) / - sizeof(DIAG_CHANNEL_EVENT)]; -} -ULTRA_DIAG_CHANNEL_PROTOCOL; +struct spar_diag_channel_protocol { + struct channel_header common_channel_header; + struct signal_queue_header queue_header; + struct diag_channel_protocol_header diag_channel_header; + struct diag_channel_event events[(DIAG_CH_SIZE - DIAG_CH_EVENT_OFFSET) / + sizeof(struct diag_channel_event)]; +}; #endif diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index b1dd73d1f42c..eb7efe484f6f 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -8,7 +8,6 @@ * this file. Note: Everything is OS-independent because this file is * used by Windows, Linux and possible EFI drivers. */ - /* * Communication flow between the IOPart and GuestPart uses the channel headers * channel state. The following states are currently being used: @@ -60,42 +59,22 @@ #define ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID 2 #define ULTRA_VSWITCH_CHANNEL_PROTOCOL_VERSIONID 1 -#define ULTRA_VHBA_CHANNEL_OK_CLIENT(pChannel, logCtx) \ - (ULTRA_check_channel_client(pChannel, UltraVhbaChannelProtocolGuid, \ - "vhba", MIN_IO_CHANNEL_SIZE, \ - ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID, \ - ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE, \ - __FILE__, __LINE__, logCtx)) -#define ULTRA_VHBA_CHANNEL_OK_SERVER(actualBytes, logCtx) \ - (ULTRA_check_channel_server(UltraVhbaChannelProtocolGuid, \ - "vhba", MIN_IO_CHANNEL_SIZE, actualBytes, \ - __FILE__, __LINE__, logCtx)) -#define ULTRA_VNIC_CHANNEL_OK_CLIENT(pChannel, logCtx) \ - (ULTRA_check_channel_client(pChannel, UltraVnicChannelProtocolGuid, \ - "vnic", MIN_IO_CHANNEL_SIZE, \ - ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID, \ - ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE, \ - __FILE__, __LINE__, logCtx)) -#define ULTRA_VNIC_CHANNEL_OK_SERVER(actualBytes, logCtx) \ - (ULTRA_check_channel_server(UltraVnicChannelProtocolGuid, \ - "vnic", MIN_IO_CHANNEL_SIZE, actualBytes, \ - __FILE__, __LINE__, logCtx)) -#define ULTRA_VSWITCH_CHANNEL_OK_CLIENT(pChannel, logCtx) \ - (ULTRA_check_channel_client(pChannel, UltraVswitchChannelProtocolGuid, \ - "vswitch", MIN_IO_CHANNEL_SIZE, \ - ULTRA_VSWITCH_CHANNEL_PROTOCOL_VERSIONID, \ - ULTRA_VSWITCH_CHANNEL_PROTOCOL_SIGNATURE, \ - __FILE__, __LINE__, logCtx)) -#define ULTRA_VSWITCH_CHANNEL_OK_SERVER(actualBytes, logCtx) \ - (ULTRA_check_channel_server(UltraVswitchChannelProtocolGuid, \ - "vswitch", MIN_IO_CHANNEL_SIZE, \ - actualBytes, \ - __FILE__, __LINE__, logCtx)) +#define SPAR_VHBA_CHANNEL_OK_CLIENT(ch) \ + (spar_check_channel_client(ch, spar_vhba_channel_protocol_uuid, \ + "vhba", MIN_IO_CHANNEL_SIZE, \ + ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID, \ + ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE)) + +#define SPAR_VNIC_CHANNEL_OK_CLIENT(ch) \ + (spar_check_channel_client(ch, spar_vnic_channel_protocol_uuid, \ + "vnic", MIN_IO_CHANNEL_SIZE, \ + ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID, \ + ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE)) + /* * Everything necessary to handle SCSI & NIC traffic between Guest Partition and * IO Partition is defined below. */ - /* * Defines and enums. */ @@ -172,8 +151,9 @@ * SCSI Host value */ /* various types of network packets that can be sent in cmdrsp */ -typedef enum { NET_RCV_POST = 0, /* submit buffer to hold receiving - * incoming packet */ +enum net_types { + NET_RCV_POST = 0, /* submit buffer to hold receiving + * incoming packet */ /* virtnic -> uisnic */ NET_RCV, /* incoming packet received */ /* uisnic -> virtpci */ @@ -195,7 +175,7 @@ typedef enum { NET_RCV_POST = 0, /* submit buffer to hold receiving * its MAC addr */ NET_MACADDR_ACK, /* MAC address */ -} NET_TYPES; +}; #define ETH_HEADER_SIZE 14 /* size of ethernet header */ @@ -211,19 +191,23 @@ typedef enum { NET_RCV_POST = 0, /* submit buffer to hold receiving #define MAX_MACADDR_LEN 6 /* number of bytes in MAC address */ #endif /* MAX_MACADDR_LEN */ -#define ETH_IS_LOCALLY_ADMINISTERED(Address) \ - (((u8 *) (Address))[0] & ((u8) 0x02)) +#define ETH_IS_LOCALLY_ADMINISTERED(address) \ + (((u8 *)(address))[0] & ((u8)0x02)) #define NIC_VENDOR_ID 0x0008000B /* various types of scsi task mgmt commands */ -typedef enum { TASK_MGMT_ABORT_TASK = - 1, TASK_MGMT_BUS_RESET, TASK_MGMT_LUN_RESET, - TASK_MGMT_TARGET_RESET, -} TASK_MGMT_TYPES; +enum task_mgmt_types { + TASK_MGMT_ABORT_TASK = 1, + TASK_MGMT_BUS_RESET, + TASK_MGMT_LUN_RESET, + TASK_MGMT_TARGET_RESET, +}; /* various types of vdisk mgmt commands */ -typedef enum { VDISK_MGMT_ACQUIRE = 1, VDISK_MGMT_RELEASE, -} VDISK_MGMT_TYPES; +enum vdisk_mgmt_types { + VDISK_MGMT_ACQUIRE = 1, + VDISK_MGMT_RELEASE, +}; /* this is used in the vdest field */ #define VDEST_ALL 0xFFFF @@ -242,7 +226,6 @@ typedef enum { VDISK_MGMT_ACQUIRE = 1, VDISK_MGMT_RELEASE, /* * structs with pragma pack */ - /* ///////////// BEGIN PRAGMA PACK PUSH 1 ///////////////////////// */ /* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */ @@ -377,16 +360,16 @@ struct uiscmdrsp_scsi { do { \ memset(buf, 0, \ MINNUM(len, \ - (unsigned int) NO_DISK_INQUIRY_RESULT_LEN)); \ - buf[2] = (u8) SCSI_SPC2_VER; \ + (unsigned int)NO_DISK_INQUIRY_RESULT_LEN)); \ + buf[2] = (u8)SCSI_SPC2_VER; \ if (lun == 0) { \ - buf[0] = (u8) lun0notpresent; \ - buf[3] = (u8) DEV_HISUPPORT; \ + buf[0] = (u8)lun0notpresent; \ + buf[3] = (u8)DEV_HISUPPORT; \ } else \ - buf[0] = (u8) notpresent; \ - buf[4] = (u8) ( \ + buf[0] = (u8)notpresent; \ + buf[4] = (u8)( \ MINNUM(len, \ - (unsigned int) NO_DISK_INQUIRY_RESULT_LEN) - 5); \ + (unsigned int)NO_DISK_INQUIRY_RESULT_LEN) - 5);\ if (len >= NO_DISK_INQUIRY_RESULT_LEN) { \ buf[8] = 'D'; \ buf[9] = 'E'; \ @@ -410,12 +393,10 @@ struct uiscmdrsp_scsi { } \ } while (0) - /* * Struct & Defines to support sense information. */ - /* The following struct is returned in sensebuf field in uiscmdrsp_scsi. It is * initialized in exactly the manner that is recommended in Windows (hence the * odd values). @@ -429,21 +410,21 @@ struct uiscmdrsp_scsi { * AdditionalSenseLength contains will be sizeof(sense_data)-8=10. */ struct sense_data { - u8 ErrorCode:7; - u8 Valid:1; - u8 SegmentNumber; - u8 SenseKey:4; - u8 Reserved:1; - u8 IncorrectLength:1; - u8 EndOfMedia:1; - u8 FileMark:1; - u8 Information[4]; - u8 AdditionalSenseLength; - u8 CommandSpecificInformation[4]; - u8 AdditionalSenseCode; - u8 AdditionalSenseCodeQualifier; - u8 FieldReplaceableUnitCode; - u8 SenseKeySpecific[3]; + u8 errorcode:7; + u8 valid:1; + u8 segment_number; + u8 sense_key:4; + u8 reserved:1; + u8 incorrect_length:1; + u8 end_of_media:1; + u8 file_mark:1; + u8 information[4]; + u8 additional_sense_length; + u8 command_specific_information[4]; + u8 additional_sense_code; + u8 additional_sense_code_qualifier; + u8 fru_code; + u8 sense_key_specific[3]; }; /* some SCSI ADSENSE codes */ @@ -484,7 +465,6 @@ struct net_pkt_xmt { * each fragment */ char ethhdr[ETH_HEADER_SIZE]; /* the ethernet header */ struct { - /* these are needed for csum at uisnic end */ u8 valid; /* 1 = rest of this struct is valid - else * ignore */ @@ -528,13 +508,12 @@ struct net_pkt_rcvpost { * to be describable */ struct phys_info frag; /* physical page information for the * single fragment 2K rcv buf */ - u64 UniqueNum; /* This is used to make sure that + u64 unique_num; /* This is used to make sure that * receive posts are returned to */ /* the Adapter which sent them origonally. */ }; struct net_pkt_rcv { - /* the number of receive buffers that can be chained */ /* is based on max mtu and size of each rcv buf */ u32 rcv_done_len; /* length of received data */ @@ -544,8 +523,8 @@ struct net_pkt_rcv { * that must be chained; */ /* each entry is a receive buffer provided by NET_RCV_POST. */ /* NOTE: first rcvbuf in the chain will also be provided in net.buf. */ - u64 UniqueNum; - u32 RcvsDroppedDelta; + u64 unique_num; + u32 rcvs_dropped_delta; }; struct net_pkt_enbdis { @@ -560,7 +539,7 @@ struct net_pkt_macaddr { /* cmd rsp packet used for VNIC network traffic */ struct uiscmdrsp_net { - NET_TYPES type; + enum net_types type; void *buf; union { struct net_pkt_xmt xmt; /* used for NET_XMIT */ @@ -576,7 +555,7 @@ struct uiscmdrsp_net { }; struct uiscmdrsp_scsitaskmgmt { - TASK_MGMT_TYPES tasktype; + enum task_mgmt_types tasktype; /* the type of task */ struct uisscsi_dest vdest; @@ -594,7 +573,7 @@ struct uiscmdrsp_scsitaskmgmt { * For windows guests, this is a pointer to a location that a waiting * thread is testing to see if the taskmgmt command has completed. * When the rsp is received by guest, the thread receiving the - * response uses this to notify the the thread waiting for taskmgmt + * response uses this to notify the thread waiting for taskmgmt * command completion. Its value is preserved by iopart & returned * as is in the task mgmt rsp. */ void *notifyresult; @@ -615,7 +594,7 @@ struct uiscmdrsp_scsitaskmgmt { /* Note that the vHba pointer is not used by the Client/Guest side. */ struct uiscmdrsp_disknotify { u8 add; /* 0-remove, 1-add */ - void *vHba; /* Pointer to vhba_info for channel info to + void *v_hba; /* Pointer to vhba_info for channel info to * route msg */ u32 channel, id, lun; /* SCSI Path of Disk to added or removed */ }; @@ -623,7 +602,7 @@ struct uiscmdrsp_disknotify { /* The following is used by virthba/vSCSI to send the Acquire/Release commands * to the IOVM. */ struct uiscmdrsp_vdiskmgmt { - VDISK_MGMT_TYPES vdisktype; + enum vdisk_mgmt_types vdisktype; /* the type of task */ struct uisscsi_dest vdest; @@ -641,7 +620,7 @@ struct uiscmdrsp_vdiskmgmt { * For windows guests, this is a pointer to a location that a waiting * thread is testing to see if the taskmgmt command has completed. * When the rsp is received by guest, the thread receiving the - * response uses this to notify the the thread waiting for taskmgmt + * response uses this to notify the thread waiting for taskmgmt * command completion. Its value is preserved by iopart & returned * as is in the task mgmt rsp. */ void *notifyresult; @@ -683,11 +662,11 @@ struct uiscmdrsp { /* This is just the header of the IO channel. It is assumed that directly after * this header there is a large region of memory which contains the command and -* response queues as specified in cmdQ and rspQ SIGNAL_QUEUE_HEADERS. */ -typedef struct _ULTRA_IO_CHANNEL_PROTOCOL { - CHANNEL_HEADER ChannelHeader; - SIGNAL_QUEUE_HEADER cmdQ; - SIGNAL_QUEUE_HEADER rspQ; +* response queues as specified in cmd_q and rsp_q SIGNAL_QUEUE_HEADERS. */ +struct spar_io_channel_protocol { + struct channel_header channel_header; + struct signal_queue_header cmd_q; + struct signal_queue_header rsp_q; union { struct { struct vhba_wwnn wwnn; /* 8 bytes */ @@ -697,14 +676,14 @@ typedef struct _ULTRA_IO_CHANNEL_PROTOCOL { u8 macaddr[MAX_MACADDR_LEN]; /* 6 bytes */ u32 num_rcv_bufs; /* 4 */ u32 mtu; /* 4 */ - uuid_le zoneGuid; /* 16 */ + uuid_le zone_uuid; /* 16 */ } vnic; /* total 30 */ }; #define MAX_CLIENTSTRING_LEN 1024 - u8 clientString[MAX_CLIENTSTRING_LEN]; /* NULL terminated - so holds + u8 client_string[MAX_CLIENTSTRING_LEN];/* NULL terminated - so holds * max - 1 bytes */ -} ULTRA_IO_CHANNEL_PROTOCOL; +}; #pragma pack(pop) /* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */ @@ -733,144 +712,17 @@ typedef struct _ULTRA_IO_CHANNEL_PROTOCOL { * INLINE functions for initializing and accessing I/O data channels */ - -#define NUMSIGNALS(x, q) (((ULTRA_IO_CHANNEL_PROTOCOL *)(x))->q.MaxSignalSlots) -#define SIZEOF_PROTOCOL (COVER(sizeof(ULTRA_IO_CHANNEL_PROTOCOL), 64)) +#define SIZEOF_PROTOCOL (COVER(sizeof(struct spar_io_channel_protocol), 64)) #define SIZEOF_CMDRSP (COVER(sizeof(struct uiscmdrsp), 64)) -#define IO_CHANNEL_SIZE(x) COVER(SIZEOF_PROTOCOL + \ - (NUMSIGNALS(x, cmdQ) + \ - NUMSIGNALS(x, rspQ)) * SIZEOF_CMDRSP, 4096) #define MIN_IO_CHANNEL_SIZE COVER(SIZEOF_PROTOCOL + \ 2 * MIN_NUMSIGNALS * SIZEOF_CMDRSP, 4096) -#ifdef __GNUC__ -/* These defines should only ever be used in service partitons */ -/* because they rely on the size of uiscmdrsp */ -#define QSLOTSFROMBYTES(bytes) (((bytes-SIZEOF_PROTOCOL)/2)/SIZEOF_CMDRSP) -#define QSIZEFROMBYTES(bytes) (QSLOTSFROMBYTES(bytes)*SIZEOF_CMDRSP) -#define SignalQInit(x) \ - do { \ - x->cmdQ.Size = QSIZEFROMBYTES(x->ChannelHeader.Size); \ - x->cmdQ.oSignalBase = SIZEOF_PROTOCOL - \ - offsetof(ULTRA_IO_CHANNEL_PROTOCOL, cmdQ); \ - x->cmdQ.SignalSize = SIZEOF_CMDRSP; \ - x->cmdQ.MaxSignalSlots = \ - QSLOTSFROMBYTES(x->ChannelHeader.Size); \ - x->cmdQ.MaxSignals = x->cmdQ.MaxSignalSlots - 1; \ - x->rspQ.Size = QSIZEFROMBYTES(x->ChannelHeader.Size); \ - x->rspQ.oSignalBase = \ - (SIZEOF_PROTOCOL + x->cmdQ.Size) - \ - offsetof(ULTRA_IO_CHANNEL_PROTOCOL, rspQ); \ - x->rspQ.SignalSize = SIZEOF_CMDRSP; \ - x->rspQ.MaxSignalSlots = \ - QSLOTSFROMBYTES(x->ChannelHeader.Size); \ - x->rspQ.MaxSignals = x->rspQ.MaxSignalSlots - 1; \ - x->ChannelHeader.oChannelSpace = \ - offsetof(ULTRA_IO_CHANNEL_PROTOCOL, cmdQ); \ - } while (0) - -#define INIT_CLIENTSTRING(chan, type, clientStr, clientStrLen) \ - do { \ - if (clientStr) { \ - chan->ChannelHeader.oClientString = \ - offsetof(type, clientString); \ - memcpy(chan->clientString, clientStr, \ - MINNUM(clientStrLen, \ - (u32) (MAX_CLIENTSTRING_LEN - 1))); \ - chan->clientString[MINNUM(clientStrLen, \ - (u32) (MAX_CLIENTSTRING_LEN \ - - 1))] \ - = '\0'; \ - } \ - else \ - if (clientStrLen > 0) \ - return 0; \ - } while (0) - - -#define ULTRA_IO_CHANNEL_SERVER_READY(x, chanId, logCtx) \ - ULTRA_CHANNEL_SERVER_TRANSITION(x, chanId, SrvState, CHANNELSRV_READY, \ - logCtx) - -#define ULTRA_IO_CHANNEL_SERVER_NOTREADY(x, chanId, logCtx) \ - ULTRA_CHANNEL_SERVER_TRANSITION(x, chanId, SrvState, \ - CHANNELSRV_UNINITIALIZED, logCtx) - -static inline int ULTRA_VHBA_init_channel(ULTRA_IO_CHANNEL_PROTOCOL *x, - struct vhba_wwnn *wwnn, - struct vhba_config_max *max, - unsigned char *clientStr, - u32 clientStrLen, u64 bytes) { - memset(x, 0, sizeof(ULTRA_IO_CHANNEL_PROTOCOL)); - x->ChannelHeader.VersionId = ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID; - x->ChannelHeader.Signature = ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE; - x->ChannelHeader.SrvState = CHANNELSRV_UNINITIALIZED; - x->ChannelHeader.HeaderSize = sizeof(x->ChannelHeader); - x->ChannelHeader.Size = COVER(bytes, 4096); - x->ChannelHeader.Type = UltraVhbaChannelProtocolGuid; - x->ChannelHeader.ZoneGuid = NULL_UUID_LE; - x->vhba.wwnn = *wwnn; - x->vhba.max = *max; - INIT_CLIENTSTRING(x, ULTRA_IO_CHANNEL_PROTOCOL, clientStr, - clientStrLen); - SignalQInit(x); - if ((x->cmdQ.MaxSignalSlots > MAX_NUMSIGNALS) || - (x->rspQ.MaxSignalSlots > MAX_NUMSIGNALS)) { - return 0; - } - if ((x->cmdQ.MaxSignalSlots < MIN_NUMSIGNALS) || - (x->rspQ.MaxSignalSlots < MIN_NUMSIGNALS)) { - return 0; - } - return 1; -} - -static inline void ULTRA_VHBA_set_max(ULTRA_IO_CHANNEL_PROTOCOL *x, - struct vhba_config_max *max) { - x->vhba.max = *max; -} - -static inline int ULTRA_VNIC_init_channel(ULTRA_IO_CHANNEL_PROTOCOL *x, - unsigned char *macaddr, - u32 num_rcv_bufs, u32 mtu, - uuid_le zoneGuid, - unsigned char *clientStr, - u32 clientStrLen, - u64 bytes) { - memset(x, 0, sizeof(ULTRA_IO_CHANNEL_PROTOCOL)); - x->ChannelHeader.VersionId = ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID; - x->ChannelHeader.Signature = ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE; - x->ChannelHeader.SrvState = CHANNELSRV_UNINITIALIZED; - x->ChannelHeader.HeaderSize = sizeof(x->ChannelHeader); - x->ChannelHeader.Size = COVER(bytes, 4096); - x->ChannelHeader.Type = UltraVnicChannelProtocolGuid; - x->ChannelHeader.ZoneGuid = NULL_UUID_LE; - memcpy(x->vnic.macaddr, macaddr, MAX_MACADDR_LEN); - x->vnic.num_rcv_bufs = num_rcv_bufs; - x->vnic.mtu = mtu; - x->vnic.zoneGuid = zoneGuid; - INIT_CLIENTSTRING(x, ULTRA_IO_CHANNEL_PROTOCOL, clientStr, - clientStrLen); - SignalQInit(x); - if ((x->cmdQ.MaxSignalSlots > MAX_NUMSIGNALS) || - (x->rspQ.MaxSignalSlots > MAX_NUMSIGNALS)) { - return 0; - } - if ((x->cmdQ.MaxSignalSlots < MIN_NUMSIGNALS) || - (x->rspQ.MaxSignalSlots < MIN_NUMSIGNALS)) { - return 0; - } - return 1; -} - -#endif /* __GNUC__ */ /* * INLINE function for expanding a guest's pfn-off-size into multiple 4K page * pfn-off-size entires. */ - /* we deal with 4K page sizes when we it comes to passing page information * between */ /* Guest and IOPartition. */ @@ -900,13 +752,12 @@ add_physinfo_entries(u32 inp_pfn, /* input - specifies the pfn to be used firstlen = PI_PAGE_SIZE - inp_off; if (inp_len <= firstlen) { - /* the input entry spans only one page - add as is */ if (index >= max_pi_arr_entries) return 0; pi_arr[index].pi_pfn = inp_pfn; - pi_arr[index].pi_off = (u16) inp_off; - pi_arr[index].pi_len = (u16) inp_len; + pi_arr[index].pi_off = (u16)inp_off; + pi_arr[index].pi_len = (u16)inp_len; return index + 1; } @@ -924,9 +775,8 @@ add_physinfo_entries(u32 inp_pfn, /* input - specifies the pfn to be used else { pi_arr[index + i].pi_off = 0; pi_arr[index + i].pi_len = - (u16) MINNUM(len, (u32) PI_PAGE_SIZE); + (u16)MINNUM(len, (u32)PI_PAGE_SIZE); } - } return index + i; } diff --git a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h index 1231c454176f..2c42ce16e0cf 100644 --- a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h @@ -28,65 +28,61 @@ #include "channel.h" /* {193b331b-c58f-11da-95a9-00e08161165f} */ -#define ULTRA_VBUS_CHANNEL_PROTOCOL_GUID \ +#define SPAR_VBUS_CHANNEL_PROTOCOL_UUID \ UUID_LE(0x193b331b, 0xc58f, 0x11da, \ 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) -static const uuid_le UltraVbusChannelProtocolGuid = - ULTRA_VBUS_CHANNEL_PROTOCOL_GUID; +static const uuid_le spar_vbus_channel_protocol_uuid = + SPAR_VBUS_CHANNEL_PROTOCOL_UUID; -#define ULTRA_VBUS_CHANNEL_PROTOCOL_SIGNATURE ULTRA_CHANNEL_PROTOCOL_SIGNATURE +#define SPAR_VBUS_CHANNEL_PROTOCOL_SIGNATURE ULTRA_CHANNEL_PROTOCOL_SIGNATURE /* Must increment this whenever you insert or delete fields within this channel * struct. Also increment whenever you change the meaning of fields within this * channel struct so as to break pre-existing software. Note that you can * usually add fields to the END of the channel struct withOUT needing to * increment this. */ -#define ULTRA_VBUS_CHANNEL_PROTOCOL_VERSIONID 1 +#define SPAR_VBUS_CHANNEL_PROTOCOL_VERSIONID 1 -#define ULTRA_VBUS_CHANNEL_OK_CLIENT(pChannel, logCtx) \ - (ULTRA_check_channel_client(pChannel, \ - UltraVbusChannelProtocolGuid, \ - "vbus", \ - sizeof(ULTRA_VBUS_CHANNEL_PROTOCOL), \ - ULTRA_VBUS_CHANNEL_PROTOCOL_VERSIONID, \ - ULTRA_VBUS_CHANNEL_PROTOCOL_SIGNATURE, \ - __FILE__, __LINE__, logCtx)) - -#define ULTRA_VBUS_CHANNEL_OK_SERVER(actualBytes, logCtx) \ - (ULTRA_check_channel_server(UltraVbusChannelProtocolGuid, \ - "vbus", \ - sizeof(ULTRA_VBUS_CHANNEL_PROTOCOL), \ - actualBytes, \ - __FILE__, __LINE__, logCtx)) +#define SPAR_VBUS_CHANNEL_OK_CLIENT(ch) \ + spar_check_channel_client(ch, \ + spar_vbus_channel_protocol_uuid, \ + "vbus", \ + sizeof(struct spar_vbus_channel_protocol),\ + SPAR_VBUS_CHANNEL_PROTOCOL_VERSIONID, \ + SPAR_VBUS_CHANNEL_PROTOCOL_SIGNATURE) +#define SPAR_VBUS_CHANNEL_OK_SERVER(actual_bytes) \ + (spar_check_channel_server(spar_vbus_channel_protocol_uuid, \ + "vbus", \ + sizeof(struct ultra_vbus_channel_protocol),\ + actual_bytes)) #pragma pack(push, 1) /* both GCC and VC now allow this pragma */ -typedef struct _ULTRA_VBUS_HEADERINFO { - u32 structBytes; /* size of this struct in bytes */ - u32 deviceInfoStructBytes; /* sizeof(ULTRA_VBUS_DEVICEINFO) */ - u32 devInfoCount; /* num of items in DevInfo member */ +struct spar_vbus_headerinfo { + u32 struct_bytes; /* size of this struct in bytes */ + u32 device_info_struct_bytes; /* sizeof(ULTRA_VBUS_DEVICEINFO) */ + u32 dev_info_count; /* num of items in DevInfo member */ /* (this is the allocated size) */ - u32 chpInfoByteOffset; /* byte offset from beginning of this struct */ - /* to the the ChpInfo struct (below) */ - u32 busInfoByteOffset; /* byte offset from beginning of this struct */ - /* to the the BusInfo struct (below) */ - u32 devInfoByteOffset; /* byte offset from beginning of this struct */ - /* to the the DevInfo array (below) */ + u32 chp_info_offset; /* byte offset from beginning of this struct */ + /* to the ChpInfo struct (below) */ + u32 bus_info_offset; /* byte offset from beginning of this struct */ + /* to the BusInfo struct (below) */ + u32 dev_info_offset; /* byte offset from beginning of this struct */ + /* to the DevInfo array (below) */ u8 reserved[104]; -} ULTRA_VBUS_HEADERINFO; +}; -typedef struct _ULTRA_VBUS_CHANNEL_PROTOCOL { - ULTRA_CHANNEL_PROTOCOL ChannelHeader; /* initialized by server */ - ULTRA_VBUS_HEADERINFO HdrInfo; /* initialized by server */ +struct spar_vbus_channel_protocol { + struct channel_header channel_header; /* initialized by server */ + struct spar_vbus_headerinfo hdr_info; /* initialized by server */ /* the remainder of this channel is filled in by the client */ - ULTRA_VBUS_DEVICEINFO ChpInfo; /* describes client chipset device and - * driver */ - ULTRA_VBUS_DEVICEINFO BusInfo; /* describes client bus device and - * driver */ - ULTRA_VBUS_DEVICEINFO DevInfo[0]; /* describes client device and - * driver for */ - /* each device on the bus */ -} ULTRA_VBUS_CHANNEL_PROTOCOL; + struct ultra_vbus_deviceinfo chp_info; + /* describes client chipset device and driver */ + struct ultra_vbus_deviceinfo bus_info; + /* describes client bus device and driver */ + struct ultra_vbus_deviceinfo dev_info[0]; + /* describes client device and driver for each device on the bus */ +}; #define VBUS_CH_SIZE_EXACT(MAXDEVICES) \ (sizeof(ULTRA_VBUS_CHANNEL_PROTOCOL) + ((MAXDEVICES) * \ diff --git a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h b/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h index 3bbdc2bb7ebf..9b6d3e69355c 100644 --- a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h +++ b/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h @@ -25,13 +25,13 @@ * It is filled in by the client side to provide info about the device * and driver from the client's perspective. */ -typedef struct _ULTRA_VBUS_DEVICEINFO { - u8 devType[16]; /* short string identifying the device type */ - u8 drvName[16]; /* driver .sys file name */ - u8 infoStrings[96]; /* sequence of tab-delimited id strings: */ +struct ultra_vbus_deviceinfo { + u8 devtype[16]; /* short string identifying the device type */ + u8 drvname[16]; /* driver .sys file name */ + u8 infostrs[96]; /* sequence of tab-delimited id strings: */ /* <DRIVER_REV> <DRIVER_VERTAG> <DRIVER_COMPILETIME> */ u8 reserved[128]; /* pad size to 256 bytes */ -} ULTRA_VBUS_DEVICEINFO; +}; #pragma pack(pop) @@ -63,8 +63,9 @@ vbuschannel_sanitize_buffer(char *p, int remain, char *src, int srcmax) p++; remain--; chars++; - } else if (p == NULL) + } else if (p == NULL) { chars++; + } nonprintable_streak = 0; } if (remain > 0) { @@ -72,10 +73,12 @@ vbuschannel_sanitize_buffer(char *p, int remain, char *src, int srcmax) p++; remain--; chars++; - } else if (p == NULL) + } else if (p == NULL) { chars++; - } else + } + } else { nonprintable_streak = 1; + } src++; srcmax--; } @@ -115,7 +118,7 @@ vbuschannel_itoa(char *p, int remain, int num) } /* form a backwards decimal ascii string in <s> */ while (num > 0) { - if (digits >= (int) sizeof(s)) + if (digits >= (int)sizeof(s)) return 0; s[digits++] = (num % 10) + '0'; num = num / 10; @@ -147,15 +150,15 @@ vbuschannel_itoa(char *p, int remain, int num) * Returns the number of bytes written to <p>. */ static inline int -vbuschannel_devinfo_to_string(ULTRA_VBUS_DEVICEINFO *devinfo, - char *p, int remain, int devix) +vbuschannel_devinfo_to_string(struct ultra_vbus_deviceinfo *devinfo, + char *p, int remain, int devix) { char *psrc; int nsrc, x, i, pad; int chars = 0; - psrc = &(devinfo->devType[0]); - nsrc = sizeof(devinfo->devType); + psrc = &devinfo->devtype[0]; + nsrc = sizeof(devinfo->devtype); if (vbuschannel_sanitize_buffer(NULL, 0, psrc, nsrc) <= 0) return 0; @@ -184,8 +187,8 @@ vbuschannel_devinfo_to_string(ULTRA_VBUS_DEVICEINFO *devinfo, VBUSCHANNEL_ADDACHAR(' ', p, remain, chars); /* emit driver name */ - psrc = &(devinfo->drvName[0]); - nsrc = sizeof(devinfo->drvName); + psrc = &devinfo->drvname[0]; + nsrc = sizeof(devinfo->drvname); x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc); p += x; remain -= x; @@ -196,8 +199,8 @@ vbuschannel_devinfo_to_string(ULTRA_VBUS_DEVICEINFO *devinfo, VBUSCHANNEL_ADDACHAR(' ', p, remain, chars); /* emit strings */ - psrc = &(devinfo->infoStrings[0]); - nsrc = sizeof(devinfo->infoStrings); + psrc = &devinfo->infostrs[0]; + nsrc = sizeof(devinfo->infostrs); x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc); p += x; remain -= x; diff --git a/drivers/staging/unisys/common-spar/include/vmcallinterface.h b/drivers/staging/unisys/common-spar/include/vmcallinterface.h index 0b5b5626af5a..78333719c496 100644 --- a/drivers/staging/unisys/common-spar/include/vmcallinterface.h +++ b/drivers/staging/unisys/common-spar/include/vmcallinterface.h @@ -33,7 +33,7 @@ /* define subsystem number for AppOS, used in uislib driver */ #define MDS_APPOS 0x4000000000000000L /* subsystem = 62 - AppOS */ -typedef enum { /* VMCALL identification tuples */ +enum vmcall_monitor_interface_method_tuple { /* VMCALL identification tuples */ /* Note: when a new VMCALL is added: * - the 1st 2 hex digits correspond to one of the * VMCALL_MONITOR_INTERFACE types and @@ -66,7 +66,7 @@ typedef enum { /* VMCALL identification tuples */ * ULTRA_SERVICE_CAPABILITY_TIME * capable guest to make * VMCALL */ -} VMCALL_MONITOR_INTERFACE_METHOD_TUPLE; +}; #define VMCALL_SUCCESS 0 #define VMCALL_SUCCESSFUL(result) (result == 0) @@ -76,12 +76,12 @@ typedef enum { /* VMCALL identification tuples */ __unisys_vmcall_gnuc(tuple, reg_ebx, reg_ecx) #define unisys_extended_vmcall(tuple, reg_ebx, reg_ecx, reg_edx) \ __unisys_extended_vmcall_gnuc(tuple, reg_ebx, reg_ecx, reg_edx) -#define ISSUE_IO_VMCALL(InterfaceMethod, param, result) \ - (result = unisys_vmcall(InterfaceMethod, (param) & 0xFFFFFFFF, \ +#define ISSUE_IO_VMCALL(method, param, result) \ + (result = unisys_vmcall(method, (param) & 0xFFFFFFFF, \ (param) >> 32)) -#define ISSUE_IO_EXTENDED_VMCALL(InterfaceMethod, param1, param2, \ +#define ISSUE_IO_EXTENDED_VMCALL(method, param1, param2, \ param3, result) \ - (result = unisys_extended_vmcall(InterfaceMethod, param1, \ + (result = unisys_extended_vmcall(method, param1, \ param2, param3)) /* The following uses VMCALL_POST_CODE_LOGEVENT interface but is currently @@ -107,21 +107,20 @@ struct phys_info { #pragma pack(pop) /* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */ -typedef struct phys_info IO_DATA_STRUCTURE; /* ///////////// BEGIN PRAGMA PACK PUSH 1 ///////////////////////// */ /* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */ #pragma pack(push, 1) /* Parameters to VMCALL_IO_CONTROLVM_ADDR interface */ -typedef struct _VMCALL_IO_CONTROLVM_ADDR_PARAMS { +struct vmcall_io_controlvm_addr_params { /* The Guest-relative physical address of the ControlVm channel. * This VMCall fills this in with the appropriate address. */ - u64 ChannelAddress; /* contents provided by this VMCALL (OUT) */ + u64 address; /* contents provided by this VMCALL (OUT) */ /* the size of the ControlVm channel in bytes This VMCall fills this * in with the appropriate address. */ - u32 ChannelBytes; /* contents provided by this VMCALL (OUT) */ - u8 Unused[4]; /* Unused Bytes in the 64-Bit Aligned Struct */ -} VMCALL_IO_CONTROLVM_ADDR_PARAMS; + u32 channel_bytes; /* contents provided by this VMCALL (OUT) */ + u8 unused[4]; /* Unused Bytes in the 64-Bit Aligned Struct */ +}; #pragma pack(pop) /* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */ @@ -130,11 +129,11 @@ typedef struct _VMCALL_IO_CONTROLVM_ADDR_PARAMS { /* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */ #pragma pack(push, 1) /* Parameters to VMCALL_IO_DIAG_ADDR interface */ -typedef struct _VMCALL_IO_DIAG_ADDR_PARAMS { +struct vmcall_io_diag_addr_params { /* The Guest-relative physical address of the diagnostic channel. * This VMCall fills this in with the appropriate address. */ - u64 ChannelAddress; /* contents provided by this VMCALL (OUT) */ -} VMCALL_IO_DIAG_ADDR_PARAMS; + u64 address; /* contents provided by this VMCALL (OUT) */ +}; #pragma pack(pop) /* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */ @@ -143,25 +142,25 @@ typedef struct _VMCALL_IO_DIAG_ADDR_PARAMS { /* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */ #pragma pack(push, 1) /* Parameters to VMCALL_IO_VISORSERIAL_ADDR interface */ -typedef struct _VMCALL_IO_VISORSERIAL_ADDR_PARAMS { +struct vmcall_io_visorserial_addr_params { /* The Guest-relative physical address of the serial console * channel. This VMCall fills this in with the appropriate * address. */ - u64 ChannelAddress; /* contents provided by this VMCALL (OUT) */ -} VMCALL_IO_VISORSERIAL_ADDR_PARAMS; + u64 address; /* contents provided by this VMCALL (OUT) */ +}; #pragma pack(pop) /* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */ /* Parameters to VMCALL_CHANNEL_MISMATCH interface */ -typedef struct _VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS { - u8 ChannelName[32]; /* Null terminated string giving name of channel +struct vmcall_channel_version_mismatch_params { + u8 chname[32]; /* Null terminated string giving name of channel * (IN) */ - u8 ItemName[32]; /* Null terminated string giving name of + u8 item_name[32]; /* Null terminated string giving name of * mismatched item (IN) */ - u32 SourceLineNumber; /* line# where invoked. (IN) */ - u8 SourceFileName[36]; /* source code where invoked - Null terminated + u32 line_no; /* line# where invoked. (IN) */ + u8 file_name[36]; /* source code where invoked - Null terminated * string (IN) */ -} VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS; +}; #endif /* __IOMONINTF_H__ */ diff --git a/drivers/staging/unisys/include/timskmod.h b/drivers/staging/unisys/include/timskmod.h index b14494ff6c1b..cff7983dab85 100644 --- a/drivers/staging/unisys/include/timskmod.h +++ b/drivers/staging/unisys/include/timskmod.h @@ -31,7 +31,6 @@ #include <linux/slab.h> #include <linux/errno.h> #include <linux/interrupt.h> -#include <linux/sched.h> #include <linux/wait.h> #include <linux/vmalloc.h> #include <linux/proc_fs.h> @@ -71,7 +70,6 @@ /** Try to evaulate the provided expression, and do a RETINT(x) iff * the expression evaluates to < 0. - * @param x the expression to try */ #define ASSERT(cond) \ do { if (!(cond)) \ @@ -89,11 +87,6 @@ (void *)(p2) = SWAPPOINTERS_TEMP; \ } while (0) -/** - * @addtogroup driverlogging - * @{ - */ - #define PRINTKDRV(fmt, args...) LOGINF(fmt, ## args) #define TBDDRV(fmt, args...) LOGERR(fmt, ## args) #define HUHDRV(fmt, args...) LOGERR(fmt, ## args) @@ -114,8 +107,6 @@ #define INFODEVX(devno, fmt, args...) LOGINFDEVX(devno, fmt, ## args) #define DEBUGDEV(devname, fmt, args...) DBGINFDEV(devname, fmt, ## args) -/* @} */ - /** Verifies the consistency of your PRIVATEDEVICEDATA structure using * conventional "signature" fields: * <p> @@ -139,7 +130,7 @@ ((fd)->sig2 == fd)) /** Sleep for an indicated number of seconds (for use in kernel mode). - * @param x the number of seconds to sleep. + * x - the number of seconds to sleep. */ #define SLEEP(x) \ do { current->state = TASK_INTERRUPTIBLE; \ @@ -147,17 +138,13 @@ } while (0) /** Sleep for an indicated number of jiffies (for use in kernel mode). - * @param x the number of jiffies to sleep. + * x - the number of jiffies to sleep. */ #define SLEEPJIFFIES(x) \ do { current->state = TASK_INTERRUPTIBLE; \ schedule_timeout(x); \ } while (0) -#ifndef max -#define max(a, b) (((a) > (b)) ? (a) : (b)) -#endif - static inline struct cdev *cdev_alloc_init(struct module *owner, const struct file_operations *fops) { diff --git a/drivers/staging/unisys/include/uisqueue.h b/drivers/staging/unisys/include/uisqueue.h index 5178270b98d1..25b6181d78af 100644 --- a/drivers/staging/unisys/include/uisqueue.h +++ b/drivers/staging/unisys/include/uisqueue.h @@ -34,8 +34,7 @@ #include "controlvmcompletionstatus.h" struct uisqueue_info { - - CHANNEL_HEADER __iomem *chan; + struct channel_header __iomem *chan; /* channel containing queues in which scsi commands & * responses are queued */ @@ -48,8 +47,8 @@ struct uisqueue_info { u64 non_empty_wakeup_cnt; struct { - SIGNAL_QUEUE_HEADER reserved1; /* */ - SIGNAL_QUEUE_HEADER reserved2; /* */ + struct signal_queue_header reserved1; /* */ + struct signal_queue_header reserved2; /* */ } safe_uis_queue; unsigned int (*send_int_if_needed)(struct uisqueue_info *info, unsigned int whichcqueue, @@ -119,7 +118,7 @@ struct extport_info { */ struct switch_info *swtch; - struct PciId pci_id; + struct pci_id pci_id; char name[MAX_NAME_SIZE_UISQUEUE]; union { struct vhba_wwnn wwnn; @@ -133,7 +132,7 @@ struct device_info { u64 channel_bytes; uuid_le channel_uuid; uuid_le instance_uuid; - struct InterruptInfo intr; + struct irq_info intr; struct switch_info *swtch; char devid[30]; /* "vbus<busno>:dev<devno>" */ u16 polling; @@ -149,30 +148,27 @@ struct device_info { unsigned long long last_on_list_cnt; }; -typedef enum { +enum switch_type { RECOVERY_LAN = 1, IB_LAN = 2 -} SWITCH_TYPE; +}; struct bus_info { - u32 busNo, deviceCount; + u32 bus_no, device_count; struct device_info **device; - u64 guestHandle, recvBusInterruptHandle; - uuid_le busInstGuid; - ULTRA_VBUS_CHANNEL_PROTOCOL __iomem *pBusChannel; - int busChannelBytes; + u64 guest_handle, recv_bus_irq_handle; + uuid_le bus_inst_uuid; + struct ultra_vbus_channel_protocol __iomem *bus_channel; + int bus_channel_bytes; struct proc_dir_entry *proc_dir; /* proc/uislib/vbus/<x> */ struct proc_dir_entry *proc_info; /* proc/uislib/vbus/<x>/info */ char name[25]; - char partitionName[99]; + char partition_name[99]; struct bus_info *next; - u8 localVnic; /* 1 if local vnic created internally + u8 local_vnic; /* 1 if local vnic created internally * by IOVM; 0 otherwise... */ }; -#define DEDICATED_SWITCH(s) ((s->extPortCount == 1) && \ - (s->intPortCount == 1)) - struct sn_list_entry { struct uisscsi_dest pdest; /* scsi bus, target, lun for * phys disk */ @@ -183,23 +179,12 @@ struct sn_list_entry { struct sn_list_entry *next; }; -struct network_policy { - u32 promiscuous:1; - u32 macassign:1; - u32 peerforwarding:1; - u32 nonotify:1; - u32 standby:1; - u32 callhome:2; - char ip_addr[30]; -}; - /* * IO messages sent to UisnicControlChanFunc & UissdControlChanFunc by * code that processes the ControlVm channel messages. */ - -typedef enum { +enum iopart_msg_type { IOPART_ADD_VNIC, IOPART_DEL_VNIC, IOPART_DEL_ALL_VNICS, @@ -219,7 +204,7 @@ typedef enum { IOPART_RESUME_VDISK, IOPART_ADD_DEVICE, /* add generic device */ IOPART_DEL_DEVICE, /* del generic device */ -} IOPART_MSG_TYPE; +}; struct add_virt_iopart { void *chanptr; /* pointer to data channel */ @@ -228,7 +213,7 @@ struct add_virt_iopart { * for DMA, for ex. */ u64 recv_bus_irq_handle; /* used to register to receive * bus level interrupts. */ - struct InterruptInfo intr; /* contains recv & send + struct irq_info intr; /* contains recv & send * interrupt info */ /* recvInterruptHandle is used to register to receive * interrupts on the data channel. Used by GuestLinux/Windows @@ -259,21 +244,15 @@ struct add_vdisk_iopart { struct uisscsi_dest pdest; /* scsi bus, target, lun for phys disk */ u8 sernum[MAX_SERIAL_NUM]; /* serial num of physical disk */ u32 serlen; /* length of serial num */ - u32 bus_no; - u32 dev_no; }; struct del_vdisk_iopart { void *chanptr; /* pointer to data channel */ struct uisscsi_dest vdest; /* scsi bus, target, lun for virt disk */ - u32 bus_no; - u32 dev_no; }; struct del_virt_iopart { void *chanptr; /* pointer to data channel */ - u32 bus_no; - u32 dev_no; }; struct det_virt_iopart { /* detach internal port */ @@ -297,8 +276,7 @@ struct del_switch_iopart { /* destroy switch */ }; struct io_msgs { - - IOPART_MSG_TYPE msgtype; + enum iopart_msg_type msgtype; /* additional params needed by some messages */ union { @@ -329,7 +307,7 @@ struct io_msgs { * the ControlVm channel messages. */ -typedef enum { +enum guestpart_msg_type { GUEST_ADD_VBUS, GUEST_ADD_VHBA, GUEST_ADD_VNIC, @@ -344,15 +322,15 @@ typedef enum { GUEST_PAUSE_VNIC, GUEST_RESUME_VHBA, GUEST_RESUME_VNIC -} GUESTPART_MSG_TYPE; +}; struct add_vbus_guestpart { void __iomem *chanptr; /* pointer to data channel for bus - * NOT YET USED */ - u32 busNo; /* bus number to be created/deleted */ - u32 deviceCount; /* max num of devices on bus */ - uuid_le busTypeGuid; /* indicates type of bus */ - uuid_le busInstGuid; /* instance guid for device */ + u32 bus_no; /* bus number to be created/deleted */ + u32 dev_count; /* max num of devices on bus */ + uuid_le bus_uuid; /* indicates type of bus */ + uuid_le instance_uuid; /* instance guid for device */ }; struct del_vbus_guestpart { @@ -367,7 +345,7 @@ struct add_virt_guestpart { u32 bus_no; /* bus number for the operation */ u32 device_no; /* number of device on the bus */ uuid_le instance_uuid; /* instance guid for device */ - struct InterruptInfo intr; /* recv/send interrupt info */ + struct irq_info intr; /* recv/send interrupt info */ /* recvInterruptHandle contains info needed in order to * register to receive interrupts on the data channel. * sendInterruptHandle contains handle which is provided to @@ -394,8 +372,7 @@ struct init_chipset_guestpart { }; struct guest_msgs { - - GUESTPART_MSG_TYPE msgtype; + enum guestpart_msg_type msgtype; /* additional params needed by messages */ union { diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 74e7cf65502c..7414220676d3 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -26,6 +26,7 @@ #include <linux/sched.h> #include <linux/gfp.h> #include <linux/uuid.h> +#include <linux/if_ether.h> #include "vmcallinterface.h" #include "channel.h" @@ -43,39 +44,38 @@ /* global function pointers that act as callback functions into * uisnicmod, uissdmod, and virtpcimod */ -extern int (*UisnicControlChanFunc)(struct io_msgs *); -extern int (*UissdControlChanFunc)(struct io_msgs *); -extern int (*VirtControlChanFunc)(struct guest_msgs *); +extern int (*uisnic_control_chan_func)(struct io_msgs *); +extern int (*uissd_control_chan_func)(struct io_msgs *); +extern int (*virt_control_chan_func)(struct guest_msgs *); /* Return values of above callback functions: */ #define CCF_ERROR 0 /* completed and failed */ #define CCF_OK 1 /* completed successfully */ #define CCF_PENDING 2 /* operation still pending */ -extern atomic_t UisUtils_Registered_Services; +extern atomic_t uisutils_registered_services; -typedef unsigned int MACARRAY[MAX_MACADDR_LEN]; -typedef struct ReqHandlerInfo_struct { - uuid_le switchTypeGuid; +struct req_handler_info { + uuid_le switch_uuid; int (*controlfunc)(struct io_msgs *); unsigned long min_channel_bytes; - int (*Server_Channel_Ok)(unsigned long channelBytes); - int (*Server_Channel_Init) - (void *x, unsigned char *clientStr, u32 clientStrLen, u64 bytes); + int (*server_channel_ok)(unsigned long channel_bytes); + int (*server_channel_init)(void *x, unsigned char *client_str, + u32 client_str_len, u64 bytes); char switch_type_name[99]; struct list_head list_link; /* links into ReqHandlerInfo_list */ -} ReqHandlerInfo_t; +}; -ReqHandlerInfo_t *ReqHandlerAdd(uuid_le switchTypeGuid, +struct req_handler_info *req_handler_add(uuid_le switch_uuid, const char *switch_type_name, int (*controlfunc)(struct io_msgs *), unsigned long min_channel_bytes, - int (*Server_Channel_Ok)(unsigned long - channelBytes), - int (*Server_Channel_Init) - (void *x, unsigned char *clientStr, - u32 clientStrLen, u64 bytes)); -ReqHandlerInfo_t *ReqHandlerFind(uuid_le switchTypeGuid); -int ReqHandlerDel(uuid_le switchTypeGuid); + int (*svr_channel_ok)(unsigned long + channel_bytes), + int (*svr_channel_init)(void *x, + unsigned char *client_str, + u32 client_str_len, u64 bytes)); +struct req_handler_info *req_handler_find(uuid_le switch_uuid); +int req_handler_del(uuid_le switch_uuid); #define uislib_ioremap_cache(addr, size) \ dbg_ioremap_cache(addr, size, __FILE__, __LINE__) @@ -114,52 +114,49 @@ int uisutil_add_proc_line_ex(int *total, char **buffer, int *buffer_remaining, char *format, ...); int uisctrl_register_req_handler(int type, void *fptr, - ULTRA_VBUS_DEVICEINFO *chipset_driver_info); -int uisctrl_register_req_handler_ex(uuid_le switchTypeGuid, - const char *switch_type_name, - int (*fptr)(struct io_msgs *), - unsigned long min_channel_bytes, - int (*Server_Channel_Ok)(unsigned long - channelBytes), - int (*Server_Channel_Init) - (void *x, unsigned char *clientStr, - u32 clientStrLen, u64 bytes), - ULTRA_VBUS_DEVICEINFO *chipset_DriverInfo); - -int uisctrl_unregister_req_handler_ex(uuid_le switchTypeGuid); + struct ultra_vbus_deviceinfo *chipset_driver_info); +int uisctrl_register_req_handler_ex(uuid_le switch_guid, + const char *switch_type_name, + int (*fptr)(struct io_msgs *), + unsigned long min_channel_bytes, + int (*svr_channel_ok)(unsigned long + channel_bytes), + int (*svr_channel_init)(void *x, + unsigned char *client_str, + u32 client_str_len, + u64 bytes), + struct ultra_vbus_deviceinfo *chipset_driver_info); + +int uisctrl_unregister_req_handler_ex(uuid_le switch_uuid); unsigned char *util_map_virt(struct phys_info *sg); void util_unmap_virt(struct phys_info *sg); unsigned char *util_map_virt_atomic(struct phys_info *sg); void util_unmap_virt_atomic(void *buf); -int uislib_server_inject_add_vnic(u32 switchNo, u32 BusNo, u32 numIntPorts, - u32 numExtPorts, MACARRAY pmac[], - pCHANNEL_HEADER **chan); -void uislib_server_inject_del_vnic(u32 switchNo, u32 busNo, u32 numIntPorts, - u32 numExtPorts); -int uislib_client_inject_add_bus(u32 busNo, uuid_le instGuid, - u64 channelAddr, ulong nChannelBytes); -int uislib_client_inject_del_bus(u32 busNo); - -int uislib_client_inject_add_vhba(u32 busNo, u32 devNo, +int uislib_client_inject_add_bus(u32 bus_no, uuid_le inst_uuid, + u64 channel_addr, ulong n_channel_bytes); +int uislib_client_inject_del_bus(u32 bus_no); + +int uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, u64 phys_chan_addr, u32 chan_bytes, - int is_test_addr, uuid_le instGuid, - struct InterruptInfo *intr); -int uislib_client_inject_pause_vhba(u32 busNo, u32 devNo); -int uislib_client_inject_resume_vhba(u32 busNo, u32 devNo); -int uislib_client_inject_del_vhba(u32 busNo, u32 devNo); -int uislib_client_inject_add_vnic(u32 busNo, u32 devNo, + int is_test_addr, uuid_le inst_uuid, + struct irq_info *intr); +int uislib_client_inject_pause_vhba(u32 bus_no, u32 dev_no); +int uislib_client_inject_resume_vhba(u32 bus_no, u32 dev_no); +int uislib_client_inject_del_vhba(u32 bus_no, u32 dev_no); +int uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, u64 phys_chan_addr, u32 chan_bytes, - int is_test_addr, uuid_le instGuid, - struct InterruptInfo *intr); -int uislib_client_inject_pause_vnic(u32 busNo, u32 devNo); -int uislib_client_inject_resume_vnic(u32 busNo, u32 devNo); -int uislib_client_inject_del_vnic(u32 busNo, u32 devNo); + int is_test_addr, uuid_le inst_uuid, + struct irq_info *intr); +int uislib_client_inject_pause_vnic(u32 bus_no, u32 dev_no); +int uislib_client_inject_resume_vnic(u32 bus_no, u32 dev_no); +int uislib_client_inject_del_vnic(u32 bus_no, u32 dev_no); #ifdef STORAGE_CHANNEL u64 uislib_storage_channel(int client_id); #endif int uislib_get_owned_pdest(struct uisscsi_dest *pdest); -int uislib_send_event(CONTROLVM_ID id, CONTROLVM_MESSAGE_PACKET *event); +int uislib_send_event(enum controlvm_id id, + struct controlvm_message_packet *event); /* structure used by vhba & vnic to keep track of queue & thread info */ struct chaninfo { @@ -182,11 +179,14 @@ struct chaninfo { set_current_state(TASK_INTERRUPTIBLE); \ schedule_timeout(msecs_to_jiffies(x)); \ } + #define UIS_THREAD_WAIT_USEC(x) { \ set_current_state(TASK_INTERRUPTIBLE); \ schedule_timeout(usecs_to_jiffies(x)); \ } + #define UIS_THREAD_WAIT UIS_THREAD_WAIT_MSEC(5) + #define UIS_THREAD_WAIT_SEC(x) { \ set_current_state(TASK_INTERRUPTIBLE); \ schedule_timeout((x)*HZ); \ @@ -224,42 +224,42 @@ unsigned int uisutil_copy_fragsinfo_from_skb(unsigned char *calling_ctx, static inline unsigned int issue_vmcall_io_controlvm_addr(u64 *control_addr, u32 *control_bytes) { - VMCALL_IO_CONTROLVM_ADDR_PARAMS params; + struct vmcall_io_controlvm_addr_params params; int result = VMCALL_SUCCESS; u64 physaddr; physaddr = virt_to_phys(¶ms); ISSUE_IO_VMCALL(VMCALL_IO_CONTROLVM_ADDR, physaddr, result); if (VMCALL_SUCCESSFUL(result)) { - *control_addr = params.ChannelAddress; - *control_bytes = params.ChannelBytes; + *control_addr = params.address; + *control_bytes = params.channel_bytes; } return result; } static inline unsigned int issue_vmcall_io_diag_addr(u64 *diag_channel_addr) { - VMCALL_IO_DIAG_ADDR_PARAMS params; + struct vmcall_io_diag_addr_params params; int result = VMCALL_SUCCESS; u64 physaddr; physaddr = virt_to_phys(¶ms); ISSUE_IO_VMCALL(VMCALL_IO_DIAG_ADDR, physaddr, result); if (VMCALL_SUCCESSFUL(result)) - *diag_channel_addr = params.ChannelAddress; + *diag_channel_addr = params.address; return result; } static inline unsigned int issue_vmcall_io_visorserial_addr(u64 *channel_addr) { - VMCALL_IO_VISORSERIAL_ADDR_PARAMS params; + struct vmcall_io_visorserial_addr_params params; int result = VMCALL_SUCCESS; u64 physaddr; physaddr = virt_to_phys(¶ms); ISSUE_IO_VMCALL(VMCALL_IO_VISORSERIAL_ADDR, physaddr, result); if (VMCALL_SUCCESSFUL(result)) - *channel_addr = params.ChannelAddress; + *channel_addr = params.address; return result; } @@ -273,17 +273,8 @@ static inline s64 issue_vmcall_query_guest_virtual_time_offset(void) return result; } -static inline s64 issue_vmcall_measurement_do_nothing(void) -{ - u64 result = VMCALL_SUCCESS; - u64 physaddr = 0; - - ISSUE_IO_VMCALL(VMCALL_MEASUREMENT_DO_NOTHING, physaddr, result); - return result; -} - struct log_info_t { - volatile unsigned long long last_cycles; + unsigned long long last_cycles; unsigned long long delta_sum[64]; unsigned long long delta_cnt[64]; unsigned long long max_delta[64]; @@ -302,44 +293,29 @@ static inline unsigned int issue_vmcall_channel_mismatch(const char *chname, const char *item_name, u32 line_no, const char *path_n_fn) { - VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS params; + struct vmcall_channel_version_mismatch_params params; int result = VMCALL_SUCCESS; u64 physaddr; char *last_slash = NULL; - strlcpy(params.ChannelName, chname, - lengthof(VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS, ChannelName)); - strlcpy(params.ItemName, item_name, - lengthof(VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS, ItemName)); - params.SourceLineNumber = line_no; + strlcpy(params.chname, chname, sizeof(params.chname)); + strlcpy(params.item_name, item_name, sizeof(params.item_name)); + params.line_no = line_no; last_slash = strrchr(path_n_fn, '/'); if (last_slash != NULL) { last_slash++; - strlcpy(params.SourceFileName, last_slash, - lengthof(VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS, - SourceFileName)); + strlcpy(params.file_name, last_slash, sizeof(params.file_name)); } else - strlcpy(params.SourceFileName, + strlcpy(params.file_name, "Cannot determine source filename", - lengthof(VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS, - SourceFileName)); + sizeof(params.file_name)); physaddr = virt_to_phys(¶ms); ISSUE_IO_VMCALL(VMCALL_CHANNEL_VERSION_MISMATCH, physaddr, result); return result; } -static inline unsigned int issue_vmcall_fatal(void) -{ - int result = VMCALL_SUCCESS; - u64 physaddr = 0; - - ISSUE_IO_VMCALL(VMCALL_GENERIC_SURRENDER_QUANTUM_FOREVER, physaddr, - result); - return result; -} - #define UIS_DAEMONIZE(nam) void *uislib_cache_alloc(struct kmem_cache *cur_pool, char *fn, int ln); #define UISCACHEALLOC(cur_pool) uislib_cache_alloc(cur_pool, __FILE__, __LINE__) diff --git a/drivers/staging/unisys/include/vbushelper.h b/drivers/staging/unisys/include/vbushelper.h index 1bde549ec0df..84abe5f99f54 100644 --- a/drivers/staging/unisys/include/vbushelper.h +++ b/drivers/staging/unisys/include/vbushelper.h @@ -26,19 +26,19 @@ #define TARGET_HOSTNAME "linuxguest" static inline void bus_device_info_init( - ULTRA_VBUS_DEVICEINFO * bus_device_info_ptr, + struct ultra_vbus_deviceinfo *bus_device_info_ptr, const char *dev_type, const char *drv_name, const char *ver, const char *ver_tag) { - memset(bus_device_info_ptr, 0, sizeof(ULTRA_VBUS_DEVICEINFO)); - snprintf(bus_device_info_ptr->devType, - sizeof(bus_device_info_ptr->devType), + memset(bus_device_info_ptr, 0, sizeof(struct ultra_vbus_deviceinfo)); + snprintf(bus_device_info_ptr->devtype, + sizeof(bus_device_info_ptr->devtype), "%s", (dev_type) ? dev_type : "unknownType"); - snprintf(bus_device_info_ptr->drvName, - sizeof(bus_device_info_ptr->drvName), + snprintf(bus_device_info_ptr->drvname, + sizeof(bus_device_info_ptr->drvname), "%s", (drv_name) ? drv_name : "unknownDriver"); - snprintf(bus_device_info_ptr->infoStrings, - sizeof(bus_device_info_ptr->infoStrings), "%s\t%s\t%s", + snprintf(bus_device_info_ptr->infostrs, + sizeof(bus_device_info_ptr->infostrs), "%s\t%s\t%s", (ver) ? ver : "unknownVer", (ver_tag) ? ver_tag : "unknownVerTag", TARGET_HOSTNAME); diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 706f1c0c2c6e..7c87452a9f14 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -57,7 +57,7 @@ #define __MYFILE__ "uislib.c" /* global function pointers that act as callback functions into virtpcimod */ -int (*VirtControlChanFunc)(struct guest_msgs *); +int (*virt_control_chan_func)(struct guest_msgs *); static int ProcReadBufferValid; static char *ProcReadBuffer; /* Note this MUST be global, @@ -121,12 +121,12 @@ static const struct file_operations debugfs_info_fops = { }; static void -init_msg_header(CONTROLVM_MESSAGE *msg, u32 id, uint rsp, uint svr) +init_msg_header(struct controlvm_message *msg, u32 id, uint rsp, uint svr) { - memset(msg, 0, sizeof(CONTROLVM_MESSAGE)); - msg->hdr.Id = id; - msg->hdr.Flags.responseExpected = rsp; - msg->hdr.Flags.server = svr; + memset(msg, 0, sizeof(struct controlvm_message)); + msg->hdr.id = id; + msg->hdr.flags.response_expected = rsp; + msg->hdr.flags.server = svr; } static __iomem void * @@ -142,7 +142,7 @@ init_vbus_channel(u64 channelAddr, u32 channelBytes) rc = NULL; goto Away; } - if (!ULTRA_VBUS_CHANNEL_OK_CLIENT(pChan, NULL)) { + if (!SPAR_VBUS_CHANNEL_OK_CLIENT(pChan)) { ERRDRV("%s channel cannot be used", __func__); uislib_iounmap(pChan); rc = NULL; @@ -154,7 +154,7 @@ Away: } static int -create_bus(CONTROLVM_MESSAGE *msg, char *buf) +create_bus(struct controlvm_message *msg, char *buf) { u32 busNo, deviceCount; struct bus_info *tmp, *bus; @@ -168,8 +168,8 @@ create_bus(CONTROLVM_MESSAGE *msg, char *buf) return CONTROLVM_RESP_ERROR_MAX_BUSES; } - busNo = msg->cmd.createBus.busNo; - deviceCount = msg->cmd.createBus.deviceCount; + busNo = msg->cmd.create_bus.bus_no; + deviceCount = msg->cmd.create_bus.dev_count; POSTCODE_LINUX_4(BUS_CREATE_ENTRY_PC, busNo, deviceCount, POSTCODE_SEVERITY_INFO); @@ -188,25 +188,25 @@ create_bus(CONTROLVM_MESSAGE *msg, char *buf) /* Currently by default, the bus Number is the GuestHandle. * Configure Bus message can override this. */ - if (msg->hdr.Flags.testMessage) { + if (msg->hdr.flags.test_message) { /* This implies we're the IOVM so set guest handle to 0... */ - bus->guestHandle = 0; - bus->busNo = busNo; - bus->localVnic = 1; + bus->guest_handle = 0; + bus->bus_no = busNo; + bus->local_vnic = 1; } else - bus->busNo = bus->guestHandle = busNo; - sprintf(bus->name, "%d", (int) bus->busNo); - bus->deviceCount = deviceCount; + bus->bus_no = bus->guest_handle = busNo; + sprintf(bus->name, "%d", (int) bus->bus_no); + bus->device_count = deviceCount; bus->device = (struct device_info **) ((char *) bus + sizeof(struct bus_info)); - bus->busInstGuid = msg->cmd.createBus.busInstGuid; - bus->busChannelBytes = 0; - bus->pBusChannel = NULL; + bus->bus_inst_uuid = msg->cmd.create_bus.bus_inst_uuid; + bus->bus_channel_bytes = 0; + bus->bus_channel = NULL; /* add bus to our bus list - but check for duplicates first */ read_lock(&BusListLock); for (tmp = BusListHead; tmp; tmp = tmp->next) { - if (tmp->busNo == bus->busNo) + if (tmp->bus_no == bus->bus_no) break; } read_unlock(&BusListLock); @@ -215,39 +215,39 @@ create_bus(CONTROLVM_MESSAGE *msg, char *buf) * reject add */ LOGERR("CONTROLVM_BUS_CREATE Failed: bus %d already exists.\n", - bus->busNo); - POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->busNo, + bus->bus_no); + POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->bus_no, POSTCODE_SEVERITY_ERR); kfree(bus); return CONTROLVM_RESP_ERROR_ALREADY_DONE; } - if ((msg->cmd.createBus.channelAddr != 0) - && (msg->cmd.createBus.channelBytes != 0)) { - bus->busChannelBytes = msg->cmd.createBus.channelBytes; - bus->pBusChannel = - init_vbus_channel(msg->cmd.createBus.channelAddr, - msg->cmd.createBus.channelBytes); + if ((msg->cmd.create_bus.channel_addr != 0) + && (msg->cmd.create_bus.channel_bytes != 0)) { + bus->bus_channel_bytes = msg->cmd.create_bus.channel_bytes; + bus->bus_channel = + init_vbus_channel(msg->cmd.create_bus.channel_addr, + msg->cmd.create_bus.channel_bytes); } /* the msg is bound for virtpci; send guest_msgs struct to callback */ - if (!msg->hdr.Flags.server) { + if (!msg->hdr.flags.server) { struct guest_msgs cmd; cmd.msgtype = GUEST_ADD_VBUS; - cmd.add_vbus.busNo = busNo; - cmd.add_vbus.chanptr = bus->pBusChannel; - cmd.add_vbus.deviceCount = deviceCount; - cmd.add_vbus.busTypeGuid = msg->cmd.createBus.busDataTypeGuid; - cmd.add_vbus.busInstGuid = msg->cmd.createBus.busInstGuid; - if (!VirtControlChanFunc) { + cmd.add_vbus.bus_no = busNo; + cmd.add_vbus.chanptr = bus->bus_channel; + cmd.add_vbus.dev_count = deviceCount; + cmd.add_vbus.bus_uuid = msg->cmd.create_bus.bus_data_type_uuid; + cmd.add_vbus.instance_uuid = msg->cmd.create_bus.bus_inst_uuid; + if (!virt_control_chan_func) { LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci callback not registered."); - POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->busNo, + POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->bus_no, POSTCODE_SEVERITY_ERR); kfree(bus); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE; } - if (!VirtControlChanFunc(&cmd)) { + if (!virt_control_chan_func(&cmd)) { LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci GUEST_ADD_VBUS returned error."); - POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->busNo, + POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->bus_no, POSTCODE_SEVERITY_ERR); kfree(bus); return @@ -266,26 +266,26 @@ create_bus(CONTROLVM_MESSAGE *msg, char *buf) BusListCount++; write_unlock(&BusListLock); - POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus->busNo, + POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus->bus_no, POSTCODE_SEVERITY_INFO); return CONTROLVM_RESP_SUCCESS; } static int -destroy_bus(CONTROLVM_MESSAGE *msg, char *buf) +destroy_bus(struct controlvm_message *msg, char *buf) { int i; struct bus_info *bus, *prev = NULL; struct guest_msgs cmd; u32 busNo; - busNo = msg->cmd.destroyBus.busNo; + busNo = msg->cmd.destroy_bus.bus_no; read_lock(&BusListLock); bus = BusListHead; while (bus) { - if (bus->busNo == busNo) + if (bus->bus_no == busNo) break; prev = bus; bus = bus->next; @@ -299,7 +299,7 @@ destroy_bus(CONTROLVM_MESSAGE *msg, char *buf) } /* verify that this bus has no devices. */ - for (i = 0; i < bus->deviceCount; i++) { + for (i = 0; i < bus->device_count; i++) { if (bus->device[i] != NULL) { LOGERR("CONTROLVM_BUS_DESTROY Failed: device %i attached to bus %d.", i, busNo); @@ -309,18 +309,18 @@ destroy_bus(CONTROLVM_MESSAGE *msg, char *buf) } read_unlock(&BusListLock); - if (msg->hdr.Flags.server) + if (msg->hdr.flags.server) goto remove; /* client messages require us to call the virtpci callback associated with this bus. */ cmd.msgtype = GUEST_DEL_VBUS; cmd.del_vbus.bus_no = busNo; - if (!VirtControlChanFunc) { + if (!virt_control_chan_func) { LOGERR("CONTROLVM_BUS_DESTROY Failed: virtpci callback not registered."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE; } - if (!VirtControlChanFunc(&cmd)) { + if (!virt_control_chan_func(&cmd)) { LOGERR("CONTROLVM_BUS_DESTROY Failed: virtpci GUEST_DEL_VBUS returned error."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR; } @@ -335,9 +335,9 @@ remove: BusListCount--; write_unlock(&BusListLock); - if (bus->pBusChannel) { - uislib_iounmap(bus->pBusChannel); - bus->pBusChannel = NULL; + if (bus->bus_channel) { + uislib_iounmap(bus->bus_channel); + bus->bus_channel = NULL; } kfree(bus); @@ -345,17 +345,17 @@ remove: } static int -create_device(CONTROLVM_MESSAGE *msg, char *buf) +create_device(struct controlvm_message *msg, char *buf) { struct device_info *dev; struct bus_info *bus; u32 busNo, devNo; int result = CONTROLVM_RESP_SUCCESS; u64 minSize = MIN_IO_CHANNEL_SIZE; - ReqHandlerInfo_t *pReqHandler; + struct req_handler_info *pReqHandler; - busNo = msg->cmd.createDevice.busNo; - devNo = msg->cmd.createDevice.devNo; + busNo = msg->cmd.create_device.bus_no; + devNo = msg->cmd.create_device.dev_no; POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, devNo, busNo, POSTCODE_SEVERITY_INFO); @@ -368,26 +368,26 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) return CONTROLVM_RESP_ERROR_KMALLOC_FAILED; } - dev->channel_uuid = msg->cmd.createDevice.dataTypeGuid; - dev->intr = msg->cmd.createDevice.intr; - dev->channel_addr = msg->cmd.createDevice.channelAddr; + dev->channel_uuid = msg->cmd.create_device.data_type_uuid; + dev->intr = msg->cmd.create_device.intr; + dev->channel_addr = msg->cmd.create_device.channel_addr; dev->bus_no = busNo; dev->dev_no = devNo; sema_init(&dev->interrupt_callback_lock, 1); /* unlocked */ sprintf(dev->devid, "vbus%u:dev%u", (unsigned) busNo, (unsigned) devNo); /* map the channel memory for the device. */ - if (msg->hdr.Flags.testMessage) + if (msg->hdr.flags.test_message) dev->chanptr = (void __iomem *)__va(dev->channel_addr); else { - pReqHandler = ReqHandlerFind(dev->channel_uuid); + pReqHandler = req_handler_find(dev->channel_uuid); if (pReqHandler) /* generic service handler registered for this * channel */ minSize = pReqHandler->min_channel_bytes; - if (minSize > msg->cmd.createDevice.channelBytes) { + if (minSize > msg->cmd.create_device.channel_bytes) { LOGERR("CONTROLVM_DEVICE_CREATE Failed: channel size is too small, channel size:0x%lx, required size:0x%lx", - (ulong) msg->cmd.createDevice.channelBytes, + (ulong) msg->cmd.create_device.channel_bytes, (ulong) minSize); POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo, POSTCODE_SEVERITY_ERR); @@ -396,27 +396,27 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) } dev->chanptr = uislib_ioremap_cache(dev->channel_addr, - msg->cmd.createDevice.channelBytes); + msg->cmd.create_device.channel_bytes); if (!dev->chanptr) { LOGERR("CONTROLVM_DEVICE_CREATE Failed: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed", dev->channel_addr, - msg->cmd.createDevice.channelBytes); + msg->cmd.create_device.channel_bytes); result = CONTROLVM_RESP_ERROR_IOREMAP_FAILED; POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo, POSTCODE_SEVERITY_ERR); goto Away; } } - dev->instance_uuid = msg->cmd.createDevice.devInstGuid; - dev->channel_bytes = msg->cmd.createDevice.channelBytes; + dev->instance_uuid = msg->cmd.create_device.dev_inst_uuid; + dev->channel_bytes = msg->cmd.create_device.channel_bytes; read_lock(&BusListLock); for (bus = BusListHead; bus; bus = bus->next) { - if (bus->busNo == busNo) { + if (bus->bus_no == busNo) { /* make sure the device number is valid */ - if (devNo >= bus->deviceCount) { + if (devNo >= bus->device_count) { LOGERR("CONTROLVM_DEVICE_CREATE Failed: device (%d) >= deviceCount (%d).", - devNo, bus->deviceCount); + devNo, bus->device_count); result = CONTROLVM_RESP_ERROR_MAX_DEVICES; POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo, @@ -439,17 +439,18 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) /* the msg is bound for virtpci; send * guest_msgs struct to callback */ - if (!msg->hdr.Flags.server) { + if (!msg->hdr.flags.server) { struct guest_msgs cmd; if (!uuid_le_cmp(dev->channel_uuid, - UltraVhbaChannelProtocolGuid)) { - wait_for_valid_guid(&((CHANNEL_HEADER - __iomem *) (dev-> + spar_vhba_channel_protocol_uuid)) { + wait_for_valid_guid(&(( + struct channel_header + __iomem *) (dev-> chanptr))-> - Type); - if (!ULTRA_VHBA_CHANNEL_OK_CLIENT - (dev->chanptr, NULL)) { + chtype); + if (!SPAR_VHBA_CHANNEL_OK_CLIENT + (dev->chanptr)) { LOGERR("CONTROLVM_DEVICE_CREATE Failed:[CLIENT]VHBA dev %d chan invalid.", devNo); POSTCODE_LINUX_4 @@ -468,13 +469,14 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) cmd.add_vhba.intr = dev->intr; } else if (!uuid_le_cmp(dev->channel_uuid, - UltraVnicChannelProtocolGuid)) { - wait_for_valid_guid(&((CHANNEL_HEADER - __iomem *) (dev-> + spar_vnic_channel_protocol_uuid)) { + wait_for_valid_guid(&(( + struct channel_header + __iomem *) (dev-> chanptr))-> - Type); - if (!ULTRA_VNIC_CHANNEL_OK_CLIENT - (dev->chanptr, NULL)) { + chtype); + if (!SPAR_VNIC_CHANNEL_OK_CLIENT + (dev->chanptr)) { LOGERR("CONTROLVM_DEVICE_CREATE Failed: VNIC[CLIENT] dev %d chan invalid.", devNo); POSTCODE_LINUX_4 @@ -500,7 +502,7 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) goto Away; } - if (!VirtControlChanFunc) { + if (!virt_control_chan_func) { LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci callback not registered."); POSTCODE_LINUX_4 (DEVICE_CREATE_FAILURE_PC, devNo, @@ -509,7 +511,7 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) goto Away; } - if (!VirtControlChanFunc(&cmd)) { + if (!virt_control_chan_func(&cmd)) { LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci GUEST_ADD_[VHBA||VNIC] returned error."); POSTCODE_LINUX_4 (DEVICE_CREATE_FAILURE_PC, devNo, @@ -532,7 +534,7 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) result = CONTROLVM_RESP_ERROR_BUS_INVALID; Away: - if (!msg->hdr.Flags.testMessage) { + if (!msg->hdr.flags.test_message) { uislib_iounmap(dev->chanptr); dev->chanptr = NULL; } @@ -542,7 +544,7 @@ Away: } static int -pause_device(CONTROLVM_MESSAGE *msg) +pause_device(struct controlvm_message *msg) { u32 busNo, devNo; struct bus_info *bus; @@ -550,16 +552,16 @@ pause_device(CONTROLVM_MESSAGE *msg) struct guest_msgs cmd; int retval = CONTROLVM_RESP_SUCCESS; - busNo = msg->cmd.deviceChangeState.busNo; - devNo = msg->cmd.deviceChangeState.devNo; + busNo = msg->cmd.device_change_state.bus_no; + devNo = msg->cmd.device_change_state.dev_no; read_lock(&BusListLock); for (bus = BusListHead; bus; bus = bus->next) { - if (bus->busNo == busNo) { + if (bus->bus_no == busNo) { /* make sure the device number is valid */ - if (devNo >= bus->deviceCount) { + if (devNo >= bus->device_count) { LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: device(%d) >= deviceCount(%d).", - devNo, bus->deviceCount); + devNo, bus->device_count); retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID; } else { /* make sure this device exists */ @@ -585,22 +587,22 @@ pause_device(CONTROLVM_MESSAGE *msg) * guest_msgs struct to callback */ if (!uuid_le_cmp(dev->channel_uuid, - UltraVhbaChannelProtocolGuid)) { + spar_vhba_channel_protocol_uuid)) { cmd.msgtype = GUEST_PAUSE_VHBA; cmd.pause_vhba.chanptr = dev->chanptr; } else if (!uuid_le_cmp(dev->channel_uuid, - UltraVnicChannelProtocolGuid)) { + spar_vnic_channel_protocol_uuid)) { cmd.msgtype = GUEST_PAUSE_VNIC; cmd.pause_vnic.chanptr = dev->chanptr; } else { LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: unknown channelTypeGuid.\n"); return CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN; } - if (!VirtControlChanFunc) { + if (!virt_control_chan_func) { LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: virtpci callback not registered."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE; } - if (!VirtControlChanFunc(&cmd)) { + if (!virt_control_chan_func(&cmd)) { LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: virtpci GUEST_PAUSE_[VHBA||VNIC] returned error."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR; @@ -610,7 +612,7 @@ pause_device(CONTROLVM_MESSAGE *msg) } static int -resume_device(CONTROLVM_MESSAGE *msg) +resume_device(struct controlvm_message *msg) { u32 busNo, devNo; struct bus_info *bus; @@ -618,16 +620,16 @@ resume_device(CONTROLVM_MESSAGE *msg) struct guest_msgs cmd; int retval = CONTROLVM_RESP_SUCCESS; - busNo = msg->cmd.deviceChangeState.busNo; - devNo = msg->cmd.deviceChangeState.devNo; + busNo = msg->cmd.device_change_state.bus_no; + devNo = msg->cmd.device_change_state.dev_no; read_lock(&BusListLock); for (bus = BusListHead; bus; bus = bus->next) { - if (bus->busNo == busNo) { + if (bus->bus_no == busNo) { /* make sure the device number is valid */ - if (devNo >= bus->deviceCount) { + if (devNo >= bus->device_count) { LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device(%d) >= deviceCount(%d).", - devNo, bus->deviceCount); + devNo, bus->device_count); retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID; } else { /* make sure this device exists */ @@ -654,22 +656,22 @@ resume_device(CONTROLVM_MESSAGE *msg) */ if (retval == CONTROLVM_RESP_SUCCESS) { if (!uuid_le_cmp(dev->channel_uuid, - UltraVhbaChannelProtocolGuid)) { + spar_vhba_channel_protocol_uuid)) { cmd.msgtype = GUEST_RESUME_VHBA; cmd.resume_vhba.chanptr = dev->chanptr; } else if (!uuid_le_cmp(dev->channel_uuid, - UltraVnicChannelProtocolGuid)) { + spar_vnic_channel_protocol_uuid)) { cmd.msgtype = GUEST_RESUME_VNIC; cmd.resume_vnic.chanptr = dev->chanptr; } else { LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: unknown channelTypeGuid.\n"); return CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN; } - if (!VirtControlChanFunc) { + if (!virt_control_chan_func) { LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: virtpci callback not registered."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE; } - if (!VirtControlChanFunc(&cmd)) { + if (!virt_control_chan_func(&cmd)) { LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: virtpci GUEST_RESUME_[VHBA||VNIC] returned error."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR; @@ -679,7 +681,7 @@ resume_device(CONTROLVM_MESSAGE *msg) } static int -destroy_device(CONTROLVM_MESSAGE *msg, char *buf) +destroy_device(struct controlvm_message *msg, char *buf) { u32 busNo, devNo; struct bus_info *bus; @@ -687,17 +689,17 @@ destroy_device(CONTROLVM_MESSAGE *msg, char *buf) struct guest_msgs cmd; int retval = CONTROLVM_RESP_SUCCESS; - busNo = msg->cmd.destroyDevice.busNo; - devNo = msg->cmd.destroyDevice.devNo; + busNo = msg->cmd.destroy_device.bus_no; + devNo = msg->cmd.destroy_device.bus_no; read_lock(&BusListLock); LOGINF("destroy_device called for busNo=%u, devNo=%u", busNo, devNo); for (bus = BusListHead; bus; bus = bus->next) { - if (bus->busNo == busNo) { + if (bus->bus_no == busNo) { /* make sure the device number is valid */ - if (devNo >= bus->deviceCount) { + if (devNo >= bus->device_count) { LOGERR("CONTROLVM_DEVICE_DESTORY Failed: device(%d) >= deviceCount(%d).", - devNo, bus->deviceCount); + devNo, bus->device_count); retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID; } else { /* make sure this device exists */ @@ -724,11 +726,11 @@ destroy_device(CONTROLVM_MESSAGE *msg, char *buf) * guest_msgs struct to callback */ if (!uuid_le_cmp(dev->channel_uuid, - UltraVhbaChannelProtocolGuid)) { + spar_vhba_channel_protocol_uuid)) { cmd.msgtype = GUEST_DEL_VHBA; cmd.del_vhba.chanptr = dev->chanptr; } else if (!uuid_le_cmp(dev->channel_uuid, - UltraVnicChannelProtocolGuid)) { + spar_vnic_channel_protocol_uuid)) { cmd.msgtype = GUEST_DEL_VNIC; cmd.del_vnic.chanptr = dev->chanptr; } else { @@ -736,12 +738,12 @@ destroy_device(CONTROLVM_MESSAGE *msg, char *buf) return CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN; } - if (!VirtControlChanFunc) { + if (!virt_control_chan_func) { LOGERR("CONTROLVM_DEVICE_DESTORY Failed: virtpci callback not registered."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE; } - if (!VirtControlChanFunc(&cmd)) { + if (!virt_control_chan_func(&cmd)) { LOGERR("CONTROLVM_DEVICE_DESTROY Failed: virtpci GUEST_DEL_[VHBA||VNIC] returned error."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR; @@ -756,7 +758,7 @@ destroy_device(CONTROLVM_MESSAGE *msg, char *buf) uislib_disable_channel_interrupts(busNo, devNo); } /* unmap the channel memory for the device. */ - if (!msg->hdr.Flags.testMessage) { + if (!msg->hdr.flags.test_message) { LOGINF("destroy_device, doing iounmap"); uislib_iounmap(dev->chanptr); } @@ -767,23 +769,23 @@ destroy_device(CONTROLVM_MESSAGE *msg, char *buf) } static int -init_chipset(CONTROLVM_MESSAGE *msg, char *buf) +init_chipset(struct controlvm_message *msg, char *buf) { POSTCODE_LINUX_2(CHIPSET_INIT_ENTRY_PC, POSTCODE_SEVERITY_INFO); - MaxBusCount = msg->cmd.initChipset.busCount; - PlatformNumber = msg->cmd.initChipset.platformNumber; + MaxBusCount = msg->cmd.init_chipset.bus_count; + PlatformNumber = msg->cmd.init_chipset.platform_number; PhysicalDataChan = 0; /* We need to make sure we have our functions registered * before processing messages. If we are a test vehicle the - * testMessage for init_chipset will be set. We can ignore the + * test_message for init_chipset will be set. We can ignore the * waits for the callbacks, since this will be manually entered - * from a user. If no testMessage is set, we will wait for the + * from a user. If no test_message is set, we will wait for the * functions. */ - if (!msg->hdr.Flags.testMessage) - WAIT_ON_CALLBACK(VirtControlChanFunc); + if (!msg->hdr.flags.test_message) + WAIT_ON_CALLBACK(virt_control_chan_func); chipset_inited = 1; POSTCODE_LINUX_2(CHIPSET_INIT_EXIT_PC, POSTCODE_SEVERITY_INFO); @@ -794,10 +796,10 @@ init_chipset(CONTROLVM_MESSAGE *msg, char *buf) static int delete_bus_glue(u32 busNo) { - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0); - msg.cmd.destroyBus.busNo = busNo; + msg.cmd.destroy_bus.bus_no = busNo; if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("destroy_bus failed. busNo=0x%x\n", busNo); return 0; @@ -808,11 +810,11 @@ delete_bus_glue(u32 busNo) static int delete_device_glue(u32 busNo, u32 devNo) { - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; init_msg_header(&msg, CONTROLVM_DEVICE_DESTROY, 0, 0); - msg.cmd.destroyDevice.busNo = busNo; - msg.cmd.destroyDevice.devNo = devNo; + msg.cmd.destroy_device.bus_no = busNo; + msg.cmd.destroy_device.dev_no = devNo; if (destroy_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("destroy_device failed. busNo=0x%x devNo=0x%x\n", busNo, devNo); @@ -822,14 +824,14 @@ delete_device_glue(u32 busNo, u32 devNo) } int -uislib_client_inject_add_bus(u32 busNo, uuid_le instGuid, - u64 channelAddr, ulong nChannelBytes) +uislib_client_inject_add_bus(u32 bus_no, uuid_le inst_uuid, + u64 channel_addr, ulong n_channel_bytes) { - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; - LOGINF("enter busNo=0x%x\n", busNo); + LOGINF("enter busNo=0x%x\n", bus_no); /* step 0: init the chipset */ - POSTCODE_LINUX_3(CHIPSET_INIT_ENTRY_PC, busNo, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX_3(CHIPSET_INIT_ENTRY_PC, bus_no, POSTCODE_SEVERITY_INFO); if (!chipset_inited) { /* step: initialize the chipset */ @@ -841,31 +843,32 @@ uislib_client_inject_add_bus(u32 busNo, uuid_le instGuid, * after number 4, then the add_vnic will fail, and the * ultraboot will fail. */ - msg.cmd.initChipset.busCount = 23; - msg.cmd.initChipset.switchCount = 0; + msg.cmd.init_chipset.bus_count = 23; + msg.cmd.init_chipset.switch_count = 0; if (init_chipset(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("init_chipset failed.\n"); return 0; } LOGINF("chipset initialized\n"); - POSTCODE_LINUX_3(CHIPSET_INIT_EXIT_PC, busNo, + POSTCODE_LINUX_3(CHIPSET_INIT_EXIT_PC, bus_no, POSTCODE_SEVERITY_INFO); } /* step 1: create a bus */ - POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, busNo, POSTCODE_SEVERITY_WARNING); + POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, bus_no, + POSTCODE_SEVERITY_WARNING); init_msg_header(&msg, CONTROLVM_BUS_CREATE, 0, 0); - msg.cmd.createBus.busNo = busNo; - msg.cmd.createBus.deviceCount = 23; /* devNo+1; */ - msg.cmd.createBus.channelAddr = channelAddr; - msg.cmd.createBus.channelBytes = nChannelBytes; + msg.cmd.create_bus.bus_no = bus_no; + msg.cmd.create_bus.dev_count = 23; /* devNo+1; */ + msg.cmd.create_bus.channel_addr = channel_addr; + msg.cmd.create_bus.channel_bytes = n_channel_bytes; if (create_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("create_bus failed.\n"); - POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, busNo, + POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus_no, POSTCODE_SEVERITY_ERR); return 0; } - POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, busNo, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus_no, POSTCODE_SEVERITY_INFO); return 1; } @@ -873,26 +876,26 @@ EXPORT_SYMBOL_GPL(uislib_client_inject_add_bus); int -uislib_client_inject_del_bus(u32 busNo) +uislib_client_inject_del_bus(u32 bus_no) { - return delete_bus_glue(busNo); + return delete_bus_glue(bus_no); } EXPORT_SYMBOL_GPL(uislib_client_inject_del_bus); int -uislib_client_inject_pause_vhba(u32 busNo, u32 devNo) +uislib_client_inject_pause_vhba(u32 bus_no, u32 dev_no) { - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; int rc; init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0); - msg.cmd.deviceChangeState.busNo = busNo; - msg.cmd.deviceChangeState.devNo = devNo; - msg.cmd.deviceChangeState.state = SegmentStateStandby; + msg.cmd.device_change_state.bus_no = bus_no; + msg.cmd.device_change_state.dev_no = dev_no; + msg.cmd.device_change_state.state = segment_state_standby; rc = pause_device(&msg); if (rc != CONTROLVM_RESP_SUCCESS) { LOGERR("VHBA pause_device failed. busNo=0x%x devNo=0x%x\n", - busNo, devNo); + bus_no, dev_no); return rc; } return 0; @@ -900,19 +903,19 @@ uislib_client_inject_pause_vhba(u32 busNo, u32 devNo) EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vhba); int -uislib_client_inject_resume_vhba(u32 busNo, u32 devNo) +uislib_client_inject_resume_vhba(u32 bus_no, u32 dev_no) { - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; int rc; init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0); - msg.cmd.deviceChangeState.busNo = busNo; - msg.cmd.deviceChangeState.devNo = devNo; - msg.cmd.deviceChangeState.state = SegmentStateRunning; + msg.cmd.device_change_state.bus_no = bus_no; + msg.cmd.device_change_state.dev_no = dev_no; + msg.cmd.device_change_state.state = segment_state_running; rc = resume_device(&msg); if (rc != CONTROLVM_RESP_SUCCESS) { LOGERR("VHBA resume_device failed. busNo=0x%x devNo=0x%x\n", - busNo, devNo); + bus_no, dev_no); return rc; } return 0; @@ -921,19 +924,19 @@ uislib_client_inject_resume_vhba(u32 busNo, u32 devNo) EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vhba); int -uislib_client_inject_add_vhba(u32 busNo, u32 devNo, +uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, u64 phys_chan_addr, u32 chan_bytes, - int is_test_addr, uuid_le instGuid, - struct InterruptInfo *intr) + int is_test_addr, uuid_le inst_uuid, + struct irq_info *intr) { - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; - LOGINF(" enter busNo=0x%x devNo=0x%x\n", busNo, devNo); + LOGINF(" enter busNo=0x%x devNo=0x%x\n", bus_no, dev_no); /* chipset init'ed with bus bus has been previously created - * Verify it still exists step 2: create the VHBA device on the * bus */ - POSTCODE_LINUX_4(VHBA_CREATE_ENTRY_PC, devNo, busNo, + POSTCODE_LINUX_4(VHBA_CREATE_ENTRY_PC, dev_no, bus_no, POSTCODE_SEVERITY_INFO); init_msg_header(&msg, CONTROLVM_DEVICE_CREATE, 0, 0); @@ -941,16 +944,16 @@ uislib_client_inject_add_vhba(u32 busNo, u32 devNo, /* signify that the physical channel address does NOT * need to be ioremap()ed */ - msg.hdr.Flags.testMessage = 1; - msg.cmd.createDevice.busNo = busNo; - msg.cmd.createDevice.devNo = devNo; - msg.cmd.createDevice.devInstGuid = instGuid; + msg.hdr.flags.test_message = 1; + msg.cmd.create_device.bus_no = bus_no; + msg.cmd.create_device.dev_no = dev_no; + msg.cmd.create_device.dev_inst_uuid = inst_uuid; if (intr) - msg.cmd.createDevice.intr = *intr; + msg.cmd.create_device.intr = *intr; else - memset(&msg.cmd.createDevice.intr, 0, - sizeof(struct InterruptInfo)); - msg.cmd.createDevice.channelAddr = phys_chan_addr; + memset(&msg.cmd.create_device.intr, 0, + sizeof(struct irq_info)); + msg.cmd.create_device.channel_addr = phys_chan_addr; if (chan_bytes < MIN_IO_CHANNEL_SIZE) { LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n", chan_bytes, (unsigned int) MIN_IO_CHANNEL_SIZE); @@ -958,41 +961,41 @@ uislib_client_inject_add_vhba(u32 busNo, u32 devNo, MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR); return 0; } - msg.cmd.createDevice.channelBytes = chan_bytes; - msg.cmd.createDevice.dataTypeGuid = UltraVhbaChannelProtocolGuid; + msg.cmd.create_device.channel_bytes = chan_bytes; + msg.cmd.create_device.data_type_uuid = spar_vhba_channel_protocol_uuid; if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("VHBA create_device failed.\n"); - POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC, devNo, busNo, + POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); return 0; } - POSTCODE_LINUX_4(VHBA_CREATE_SUCCESS_PC, devNo, busNo, + POSTCODE_LINUX_4(VHBA_CREATE_SUCCESS_PC, dev_no, bus_no, POSTCODE_SEVERITY_INFO); return 1; } EXPORT_SYMBOL_GPL(uislib_client_inject_add_vhba); int -uislib_client_inject_del_vhba(u32 busNo, u32 devNo) +uislib_client_inject_del_vhba(u32 bus_no, u32 dev_no) { - return delete_device_glue(busNo, devNo); + return delete_device_glue(bus_no, dev_no); } EXPORT_SYMBOL_GPL(uislib_client_inject_del_vhba); int -uislib_client_inject_add_vnic(u32 busNo, u32 devNo, +uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, u64 phys_chan_addr, u32 chan_bytes, - int is_test_addr, uuid_le instGuid, - struct InterruptInfo *intr) + int is_test_addr, uuid_le inst_uuid, + struct irq_info *intr) { - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; - LOGINF(" enter busNo=0x%x devNo=0x%x\n", busNo, devNo); + LOGINF(" enter busNo=0x%x devNo=0x%x\n", bus_no, dev_no); /* chipset init'ed with bus bus has been previously created - * Verify it still exists step 2: create the VNIC device on the * bus */ - POSTCODE_LINUX_4(VNIC_CREATE_ENTRY_PC, devNo, busNo, + POSTCODE_LINUX_4(VNIC_CREATE_ENTRY_PC, dev_no, bus_no, POSTCODE_SEVERITY_INFO); init_msg_header(&msg, CONTROLVM_DEVICE_CREATE, 0, 0); @@ -1000,16 +1003,16 @@ uislib_client_inject_add_vnic(u32 busNo, u32 devNo, /* signify that the physical channel address does NOT * need to be ioremap()ed */ - msg.hdr.Flags.testMessage = 1; - msg.cmd.createDevice.busNo = busNo; - msg.cmd.createDevice.devNo = devNo; - msg.cmd.createDevice.devInstGuid = instGuid; + msg.hdr.flags.test_message = 1; + msg.cmd.create_device.bus_no = bus_no; + msg.cmd.create_device.dev_no = dev_no; + msg.cmd.create_device.dev_inst_uuid = inst_uuid; if (intr) - msg.cmd.createDevice.intr = *intr; + msg.cmd.create_device.intr = *intr; else - memset(&msg.cmd.createDevice.intr, 0, - sizeof(struct InterruptInfo)); - msg.cmd.createDevice.channelAddr = phys_chan_addr; + memset(&msg.cmd.create_device.intr, 0, + sizeof(struct irq_info)); + msg.cmd.create_device.channel_addr = phys_chan_addr; if (chan_bytes < MIN_IO_CHANNEL_SIZE) { LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n", chan_bytes, (unsigned int) MIN_IO_CHANNEL_SIZE); @@ -1017,35 +1020,35 @@ uislib_client_inject_add_vnic(u32 busNo, u32 devNo, MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR); return 0; } - msg.cmd.createDevice.channelBytes = chan_bytes; - msg.cmd.createDevice.dataTypeGuid = UltraVnicChannelProtocolGuid; + msg.cmd.create_device.channel_bytes = chan_bytes; + msg.cmd.create_device.data_type_uuid = spar_vnic_channel_protocol_uuid; if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("VNIC create_device failed.\n"); - POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC, devNo, busNo, + POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); return 0; } - POSTCODE_LINUX_4(VNIC_CREATE_SUCCESS_PC, devNo, busNo, + POSTCODE_LINUX_4(VNIC_CREATE_SUCCESS_PC, dev_no, bus_no, POSTCODE_SEVERITY_INFO); return 1; } EXPORT_SYMBOL_GPL(uislib_client_inject_add_vnic); int -uislib_client_inject_pause_vnic(u32 busNo, u32 devNo) +uislib_client_inject_pause_vnic(u32 bus_no, u32 dev_no) { - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; int rc; init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0); - msg.cmd.deviceChangeState.busNo = busNo; - msg.cmd.deviceChangeState.devNo = devNo; - msg.cmd.deviceChangeState.state = SegmentStateStandby; + msg.cmd.device_change_state.bus_no = bus_no; + msg.cmd.device_change_state.dev_no = dev_no; + msg.cmd.device_change_state.state = segment_state_standby; rc = pause_device(&msg); if (rc != CONTROLVM_RESP_SUCCESS) { LOGERR("VNIC pause_device failed. busNo=0x%x devNo=0x%x\n", - busNo, devNo); + bus_no, dev_no); return -1; } return 0; @@ -1053,19 +1056,19 @@ uislib_client_inject_pause_vnic(u32 busNo, u32 devNo) EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vnic); int -uislib_client_inject_resume_vnic(u32 busNo, u32 devNo) +uislib_client_inject_resume_vnic(u32 bus_no, u32 dev_no) { - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; int rc; init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0); - msg.cmd.deviceChangeState.busNo = busNo; - msg.cmd.deviceChangeState.devNo = devNo; - msg.cmd.deviceChangeState.state = SegmentStateRunning; + msg.cmd.device_change_state.bus_no = bus_no; + msg.cmd.device_change_state.dev_no = dev_no; + msg.cmd.device_change_state.state = segment_state_running; rc = resume_device(&msg); if (rc != CONTROLVM_RESP_SUCCESS) { LOGERR("VNIC resume_device failed. busNo=0x%x devNo=0x%x\n", - busNo, devNo); + bus_no, dev_no); return -1; } return 0; @@ -1074,88 +1077,12 @@ uislib_client_inject_resume_vnic(u32 busNo, u32 devNo) EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vnic); int -uislib_client_inject_del_vnic(u32 busNo, u32 devNo) +uislib_client_inject_del_vnic(u32 bus_no, u32 dev_no) { - return delete_device_glue(busNo, devNo); + return delete_device_glue(bus_no, dev_no); } EXPORT_SYMBOL_GPL(uislib_client_inject_del_vnic); -static int -uislib_client_add_vnic(u32 busNo) -{ - BOOL busCreated = FALSE; - int devNo = 0; /* Default to 0, since only one device - * will be created for this bus... */ - CONTROLVM_MESSAGE msg; - - init_msg_header(&msg, CONTROLVM_BUS_CREATE, 0, 0); - msg.hdr.Flags.testMessage = 1; - msg.cmd.createBus.busNo = busNo; - msg.cmd.createBus.deviceCount = 4; - msg.cmd.createBus.channelAddr = 0; - msg.cmd.createBus.channelBytes = 0; - if (create_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { - LOGERR("client create_bus failed"); - return 0; - } - busCreated = TRUE; - - init_msg_header(&msg, CONTROLVM_DEVICE_CREATE, 0, 0); - msg.hdr.Flags.testMessage = 1; - msg.cmd.createDevice.busNo = busNo; - msg.cmd.createDevice.devNo = devNo; - msg.cmd.createDevice.devInstGuid = NULL_UUID_LE; - memset(&msg.cmd.createDevice.intr, 0, sizeof(struct InterruptInfo)); - msg.cmd.createDevice.channelAddr = PhysicalDataChan; - msg.cmd.createDevice.channelBytes = MIN_IO_CHANNEL_SIZE; - msg.cmd.createDevice.dataTypeGuid = UltraVnicChannelProtocolGuid; - if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { - LOGERR("client create_device failed"); - goto AwayCleanup; - } - - return 1; - -AwayCleanup: - if (busCreated) { - init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0); - msg.hdr.Flags.testMessage = 1; - msg.cmd.destroyBus.busNo = busNo; - if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) - LOGERR("client destroy_bus failed.\n"); - } - - return 0; -} /* end uislib_client_add_vnic */ -EXPORT_SYMBOL_GPL(uislib_client_add_vnic); - -static int -uislib_client_delete_vnic(u32 busNo) -{ - int devNo = 0; /* Default to 0, since only one device - * will be created for this bus... */ - CONTROLVM_MESSAGE msg; - - init_msg_header(&msg, CONTROLVM_DEVICE_DESTROY, 0, 0); - msg.hdr.Flags.testMessage = 1; - msg.cmd.destroyDevice.busNo = busNo; - msg.cmd.destroyDevice.devNo = devNo; - if (destroy_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { - /* Don't error exit - try to see if bus can be destroyed... */ - LOGERR("client destroy_device failed.\n"); - } - - init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0); - msg.hdr.Flags.testMessage = 1; - msg.cmd.destroyBus.busNo = busNo; - if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) - LOGERR("client destroy_bus failed.\n"); - - return 1; -} -EXPORT_SYMBOL_GPL(uislib_client_delete_vnic); -/* end client_delete_vnic */ - void * uislib_cache_alloc(struct kmem_cache *cur_pool, char *fn, int ln) { @@ -1206,17 +1133,17 @@ info_debugfs_read_helper(char **buff, int *buff_len) for (bus = BusListHead; bus; bus = bus->next) { if (PLINE(" bus=0x%p, busNo=%d, deviceCount=%d\n", - bus, bus->busNo, bus->deviceCount) < 0) + bus, bus->bus_no, bus->device_count) < 0) goto err_done_unlock; if (PLINE(" Devices:\n") < 0) goto err_done_unlock; - for (i = 0; i < bus->deviceCount; i++) { + for (i = 0; i < bus->device_count; i++) { if (bus->device[i]) { if (PLINE(" busNo %d, device[%i]: 0x%p, chanptr=0x%p, swtch=0x%p\n", - bus->busNo, i, bus->device[i], + bus->bus_no, i, bus->device[i], bus->device[i]->chanptr, bus->device[i]->swtch) < 0) goto err_done_unlock; @@ -1232,7 +1159,7 @@ info_debugfs_read_helper(char **buff, int *buff_len) read_unlock(&BusListLock); if (PLINE("UisUtils_Registered_Services: %d\n", - atomic_read(&UisUtils_Registered_Services)) < 0) + atomic_read(&uisutils_registered_services)) < 0) goto err_done; if (PLINE("cycles_before_wait %llu wait_cycles:%llu\n", cycles_before_wait, wait_cycles) < 0) @@ -1294,9 +1221,9 @@ find_dev(u32 busNo, u32 devNo) read_lock(&BusListLock); for (bus = BusListHead; bus; bus = bus->next) { - if (bus->busNo == busNo) { + if (bus->bus_no == busNo) { /* make sure the device number is valid */ - if (devNo >= bus->deviceCount) { + if (devNo >= bus->device_count) { LOGERR("%s bad busNo, devNo=%d,%d", __func__, (int) (busNo), (int) (devNo)); @@ -1560,13 +1487,13 @@ uislib_mod_init(void) LOGINF("sizeof(uiscmdrsp_net):%lu\n", (ulong) sizeof(struct uiscmdrsp_net)); LOGINF("sizeof(CONTROLVM_MESSAGE):%lu bytes\n", - (ulong) sizeof(CONTROLVM_MESSAGE)); - LOGINF("sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL):%lu bytes\n", - (ulong) sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL)); + (ulong) sizeof(struct controlvm_message)); + LOGINF("sizeof(struct spar_controlvm_channel_protocol):%lu bytes\n", + (ulong) sizeof(struct spar_controlvm_channel_protocol)); LOGINF("sizeof(CHANNEL_HEADER):%lu bytes\n", - (ulong) sizeof(CHANNEL_HEADER)); - LOGINF("sizeof(ULTRA_IO_CHANNEL_PROTOCOL):%lu bytes\n", - (ulong) sizeof(ULTRA_IO_CHANNEL_PROTOCOL)); + (ulong) sizeof(struct channel_header)); + LOGINF("sizeof(struct spar_io_channel_protocol):%lu bytes\n", + (ulong) sizeof(struct spar_io_channel_protocol)); LOGINF("SIZEOF_CMDRSP:%lu bytes\n", SIZEOF_CMDRSP); LOGINF("SIZEOF_PROTOCOL:%lu bytes\n", SIZEOF_PROTOCOL); @@ -1574,7 +1501,7 @@ uislib_mod_init(void) BusListHead = NULL; BusListCount = MaxBusCount = 0; rwlock_init(&BusListLock); - VirtControlChanFunc = NULL; + virt_control_chan_func = NULL; /* Issue VMCALL_GET_CONTROLVM_ADDR to get CtrlChanPhysAddr and * then map this physical address to a virtual address. */ diff --git a/drivers/staging/unisys/uislib/uisqueue.c b/drivers/staging/unisys/uislib/uisqueue.c index 44208841bd5a..f9f8442d58c5 100644 --- a/drivers/staging/unisys/uislib/uisqueue.c +++ b/drivers/staging/unisys/uislib/uisqueue.c @@ -81,13 +81,13 @@ do_locked_client_insert(struct uisqueue_info *queueinfo, u8 rc = 0; spin_lock_irqsave(lock, flags); - if (!ULTRA_CHANNEL_CLIENT_ACQUIRE_OS(queueinfo->chan, channelId, NULL)) + if (!spar_channel_client_acquire_os(queueinfo->chan, channelId)) goto unlock; - if (visor_signal_insert(queueinfo->chan, whichqueue, pSignal)) { + if (spar_signal_insert(queueinfo->chan, whichqueue, pSignal)) { queueinfo->packets_sent++; rc = 1; } - ULTRA_CHANNEL_CLIENT_RELEASE_OS(queueinfo->chan, channelId, NULL); + spar_channel_client_release_os(queueinfo->chan, channelId); unlock: spin_unlock_irqrestore((spinlock_t *)lock, flags); return rc; @@ -125,7 +125,7 @@ int uisqueue_get_cmdrsp(struct uisqueue_info *queueinfo, void *cmdrsp, unsigned int whichqueue) { - if (!visor_signal_remove(queueinfo->chan, whichqueue, cmdrsp)) + if (!spar_signal_remove(queueinfo->chan, whichqueue, cmdrsp)) return 0; queueinfo->packets_received++; diff --git a/drivers/staging/unisys/uislib/uisutils.c b/drivers/staging/unisys/uislib/uisutils.c index 8ff6d26ff00b..4a5b86773927 100644 --- a/drivers/staging/unisys/uislib/uisutils.c +++ b/drivers/staging/unisys/uislib/uisutils.c @@ -25,9 +25,7 @@ #include "uisutils.h" #include "version.h" #include "vbushelper.h" -#include <linux/uuid.h> #include <linux/skbuff.h> -#include <linux/uuid.h> #ifdef CONFIG_HIGHMEM #include <linux/highmem.h> #endif @@ -39,7 +37,7 @@ #define __MYFILE__ "uisutils.c" /* exports */ -atomic_t UisUtils_Registered_Services = ATOMIC_INIT(0); +atomic_t uisutils_registered_services = ATOMIC_INIT(0); /* num registrations via * uisctrl_register_req_handler() or * uisctrl_register_req_handler_ex() */ @@ -75,20 +73,20 @@ EXPORT_SYMBOL_GPL(uisutil_add_proc_line_ex); int uisctrl_register_req_handler(int type, void *fptr, - ULTRA_VBUS_DEVICEINFO *chipset_driver_info) + struct ultra_vbus_deviceinfo *chipset_driver_info) { LOGINF("type = %d, fptr = 0x%p.\n", type, fptr); switch (type) { case 2: if (fptr) { - if (!VirtControlChanFunc) - atomic_inc(&UisUtils_Registered_Services); - VirtControlChanFunc = fptr; + if (!virt_control_chan_func) + atomic_inc(&uisutils_registered_services); + virt_control_chan_func = fptr; } else { - if (VirtControlChanFunc) - atomic_dec(&UisUtils_Registered_Services); - VirtControlChanFunc = NULL; + if (virt_control_chan_func) + atomic_dec(&uisutils_registered_services); + virt_control_chan_func = NULL; } break; @@ -105,76 +103,75 @@ uisctrl_register_req_handler(int type, void *fptr, EXPORT_SYMBOL_GPL(uisctrl_register_req_handler); int -uisctrl_register_req_handler_ex(uuid_le switchTypeGuid, - const char *switch_type_name, - int (*controlfunc)(struct io_msgs *), - unsigned long min_channel_bytes, - int (*Server_Channel_Ok)(unsigned long - channelBytes), - int (*Server_Channel_Init) - (void *x, unsigned char *clientStr, - u32 clientStrLen, u64 bytes), - ULTRA_VBUS_DEVICEINFO *chipset_DriverInfo) +uisctrl_register_req_handler_ex(uuid_le switch_uuid, + const char *switch_type_name, + int (*controlfunc)(struct io_msgs *), + unsigned long min_channel_bytes, + int (*server_channel_ok)(unsigned long channel_bytes), + int (*server_channel_init)(void *x, + unsigned char *client_str, + u32 client_str_len, u64 bytes), + struct ultra_vbus_deviceinfo *chipset_driver_info) { - ReqHandlerInfo_t *pReqHandlerInfo; + struct req_handler_info *pReqHandlerInfo; int rc = 0; /* assume failure */ LOGINF("type=%pUL, controlfunc=0x%p.\n", - &switchTypeGuid, controlfunc); + &switch_uuid, controlfunc); if (!controlfunc) { - LOGERR("%pUL: controlfunc must be supplied\n", &switchTypeGuid); + LOGERR("%pUL: controlfunc must be supplied\n", &switch_uuid); goto Away; } - if (!Server_Channel_Ok) { + if (!server_channel_ok) { LOGERR("%pUL: Server_Channel_Ok must be supplied\n", - &switchTypeGuid); + &switch_uuid); goto Away; } - if (!Server_Channel_Init) { + if (!server_channel_init) { LOGERR("%pUL: Server_Channel_Init must be supplied\n", - &switchTypeGuid); + &switch_uuid); goto Away; } - pReqHandlerInfo = ReqHandlerAdd(switchTypeGuid, + pReqHandlerInfo = req_handler_add(switch_uuid, switch_type_name, controlfunc, min_channel_bytes, - Server_Channel_Ok, Server_Channel_Init); + server_channel_ok, server_channel_init); if (!pReqHandlerInfo) { - LOGERR("failed to add %pUL to server list\n", &switchTypeGuid); + LOGERR("failed to add %pUL to server list\n", &switch_uuid); goto Away; } - atomic_inc(&UisUtils_Registered_Services); + atomic_inc(&uisutils_registered_services); rc = 1; /* success */ Away: if (rc) { - if (chipset_DriverInfo) - bus_device_info_init(chipset_DriverInfo, "chipset", + if (chipset_driver_info) + bus_device_info_init(chipset_driver_info, "chipset", "uislib", VERSION, NULL); } else - LOGERR("failed to register type %pUL.\n", &switchTypeGuid); + LOGERR("failed to register type %pUL.\n", &switch_uuid); return rc; } EXPORT_SYMBOL_GPL(uisctrl_register_req_handler_ex); int -uisctrl_unregister_req_handler_ex(uuid_le switchTypeGuid) +uisctrl_unregister_req_handler_ex(uuid_le switch_uuid) { int rc = 0; /* assume failure */ - LOGINF("type=%pUL.\n", &switchTypeGuid); - if (ReqHandlerDel(switchTypeGuid) < 0) { + LOGINF("type=%pUL.\n", &switch_uuid); + if (req_handler_del(switch_uuid) < 0) { LOGERR("failed to remove %pUL from server list\n", - &switchTypeGuid); + &switch_uuid); goto Away; } - atomic_dec(&UisUtils_Registered_Services); + atomic_dec(&uisutils_registered_services); rc = 1; /* success */ Away: if (!rc) - LOGERR("failed to unregister type %pUL.\n", &switchTypeGuid); + LOGERR("failed to unregister type %pUL.\n", &switch_uuid); return rc; } EXPORT_SYMBOL_GPL(uisctrl_unregister_req_handler_ex); @@ -275,11 +272,11 @@ dolist: if (skb_shinfo(skb)->frag_list) { } EXPORT_SYMBOL_GPL(uisutil_copy_fragsinfo_from_skb); -static LIST_HEAD(ReqHandlerInfo_list); /* list of ReqHandlerInfo_t */ +static LIST_HEAD(ReqHandlerInfo_list); /* list of struct req_handler_info */ static DEFINE_SPINLOCK(ReqHandlerInfo_list_lock); -ReqHandlerInfo_t * -ReqHandlerAdd(uuid_le switchTypeGuid, +struct req_handler_info * +req_handler_add(uuid_le switch_uuid, const char *switch_type_name, int (*controlfunc)(struct io_msgs *), unsigned long min_channel_bytes, @@ -287,16 +284,16 @@ ReqHandlerAdd(uuid_le switchTypeGuid, int (*Server_Channel_Init) (void *x, unsigned char *clientStr, u32 clientStrLen, u64 bytes)) { - ReqHandlerInfo_t *rc = NULL; + struct req_handler_info *rc = NULL; rc = kzalloc(sizeof(*rc), GFP_ATOMIC); if (!rc) return NULL; - rc->switchTypeGuid = switchTypeGuid; + rc->switch_uuid = switch_uuid; rc->controlfunc = controlfunc; rc->min_channel_bytes = min_channel_bytes; - rc->Server_Channel_Ok = Server_Channel_Ok; - rc->Server_Channel_Init = Server_Channel_Init; + rc->server_channel_ok = Server_Channel_Ok; + rc->server_channel_init = Server_Channel_Init; if (switch_type_name) strncpy(rc->switch_type_name, switch_type_name, sizeof(rc->switch_type_name) - 1); @@ -307,16 +304,16 @@ ReqHandlerAdd(uuid_le switchTypeGuid, return rc; } -ReqHandlerInfo_t * -ReqHandlerFind(uuid_le switchTypeGuid) +struct req_handler_info * +req_handler_find(uuid_le switch_uuid) { struct list_head *lelt, *tmp; - ReqHandlerInfo_t *entry = NULL; + struct req_handler_info *entry = NULL; spin_lock(&ReqHandlerInfo_list_lock); list_for_each_safe(lelt, tmp, &ReqHandlerInfo_list) { - entry = list_entry(lelt, ReqHandlerInfo_t, list_link); - if (uuid_le_cmp(entry->switchTypeGuid, switchTypeGuid) == 0) { + entry = list_entry(lelt, struct req_handler_info, list_link); + if (uuid_le_cmp(entry->switch_uuid, switch_uuid) == 0) { spin_unlock(&ReqHandlerInfo_list_lock); return entry; } @@ -326,16 +323,16 @@ ReqHandlerFind(uuid_le switchTypeGuid) } int -ReqHandlerDel(uuid_le switchTypeGuid) +req_handler_del(uuid_le switch_uuid) { struct list_head *lelt, *tmp; - ReqHandlerInfo_t *entry = NULL; + struct req_handler_info *entry = NULL; int rc = -1; spin_lock(&ReqHandlerInfo_list_lock); list_for_each_safe(lelt, tmp, &ReqHandlerInfo_list) { - entry = list_entry(lelt, ReqHandlerInfo_t, list_link); - if (uuid_le_cmp(entry->switchTypeGuid, switchTypeGuid) == 0) { + entry = list_entry(lelt, struct req_handler_info, list_link); + if (uuid_le_cmp(entry->switch_uuid, switch_uuid) == 0) { list_del(lelt); kfree(entry); rc++; diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index 938e2c82c1ab..d7a629b5f111 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -101,7 +101,6 @@ static DEF_SCSI_QCMD(virthba_queue_command) #define virthba_queue_command virthba_queue_command_lck #endif - static int virthba_slave_alloc(struct scsi_device *scsidev); static int virthba_slave_configure(struct scsi_device *scsidev); static void virthba_slave_destroy(struct scsi_device *scsidev); @@ -172,7 +171,7 @@ struct virthba_info { struct virtpci_dev *virtpcidev; struct list_head dev_info_list; struct chaninfo chinfo; - struct InterruptInfo intr; /* use recvInterrupt info to receive + struct irq_info intr; /* use recvInterrupt info to receive interrupts when IOs complete */ int interrupt_vector; struct scsipending pending[MAX_PENDING_REQUESTS]; /* Tracks the requests @@ -420,8 +419,8 @@ static irqreturn_t virthba_ISR(int irq, void *dev_id) { struct virthba_info *virthbainfo = (struct virthba_info *) dev_id; - CHANNEL_HEADER __iomem *pChannelHeader; - SIGNAL_QUEUE_HEADER __iomem *pqhdr; + struct channel_header __iomem *pChannelHeader; + struct signal_queue_header __iomem *pqhdr; u64 mask; unsigned long long rc1; @@ -429,24 +428,24 @@ virthba_ISR(int irq, void *dev_id) return IRQ_NONE; virthbainfo->interrupts_rcvd++; pChannelHeader = virthbainfo->chinfo.queueinfo->chan; - if (((readq(&pChannelHeader->Features) + if (((readq(&pChannelHeader->features) & ULTRA_IO_IOVM_IS_OK_WITH_DRIVER_DISABLING_INTS) != 0) - && ((readq(&pChannelHeader->Features) & + && ((readq(&pChannelHeader->features) & ULTRA_IO_DRIVER_DISABLES_INTS) != 0)) { virthbainfo->interrupts_disabled++; mask = ~ULTRA_CHANNEL_ENABLE_INTS; rc1 = uisqueue_interlocked_and(virthbainfo->flags_addr, mask); } - if (visor_signalqueue_empty(pChannelHeader, IOCHAN_FROM_IOPART)) { + if (spar_signalqueue_empty(pChannelHeader, IOCHAN_FROM_IOPART)) { virthbainfo->interrupts_notme++; return IRQ_NONE; } - pqhdr = (SIGNAL_QUEUE_HEADER __iomem *) + pqhdr = (struct signal_queue_header __iomem *) ((char __iomem *) pChannelHeader + - readq(&pChannelHeader->oChannelSpace)) + IOCHAN_FROM_IOPART; - writeq(readq(&pqhdr->NumInterruptsReceived) + 1, - &pqhdr->NumInterruptsReceived); + readq(&pChannelHeader->ch_space_offset)) + IOCHAN_FROM_IOPART; + writeq(readq(&pqhdr->num_irq_received) + 1, + &pqhdr->num_irq_received); atomic_set(&virthbainfo->interrupt_rcvd, 1); wake_up_interruptible(&virthbainfo->rsp_queue); return IRQ_HANDLED; @@ -461,17 +460,17 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) int rsp; int i; irq_handler_t handler = virthba_ISR; - CHANNEL_HEADER __iomem *pChannelHeader; - SIGNAL_QUEUE_HEADER __iomem *pqhdr; + struct channel_header __iomem *pChannelHeader; + struct signal_queue_header __iomem *pqhdr; u64 mask; LOGVER("entering virthba_probe...\n"); - LOGVER("virtpcidev busNo<<%d>>devNo<<%d>>", virtpcidev->busNo, - virtpcidev->deviceNo); + LOGVER("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no, + virtpcidev->device_no); LOGINF("entering virthba_probe...\n"); - LOGINF("virtpcidev busNo<<%d>>devNo<<%d>>", virtpcidev->busNo, - virtpcidev->deviceNo); + LOGINF("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no, + virtpcidev->device_no); POSTCODE_LINUX_2(VHBA_PROBE_ENTRY_PC, POSTCODE_SEVERITY_INFO); /* call scsi_host_alloc to register a scsi host adapter * instance - this virthba that has just been created is an @@ -578,18 +577,18 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) INIT_WORK(&virthbainfo->serverdown_completion, virthba_serverdown_complete); - writeq(readq(&virthbainfo->chinfo.queueinfo->chan->Features) | + writeq(readq(&virthbainfo->chinfo.queueinfo->chan->features) | ULTRA_IO_CHANNEL_IS_POLLING, - &virthbainfo->chinfo.queueinfo->chan->Features); + &virthbainfo->chinfo.queueinfo->chan->features); /* start thread that will receive scsicmnd responses */ DBGINF("starting rsp thread -- queueinfo: 0x%p, threadinfo: 0x%p.\n", virthbainfo->chinfo.queueinfo, &virthbainfo->chinfo.threadinfo); pChannelHeader = virthbainfo->chinfo.queueinfo->chan; - pqhdr = (SIGNAL_QUEUE_HEADER __iomem *) + pqhdr = (struct signal_queue_header __iomem *) ((char __iomem *)pChannelHeader + - readq(&pChannelHeader->oChannelSpace)) + IOCHAN_FROM_IOPART; - virthbainfo->flags_addr = &pqhdr->FeatureFlags; + readq(&pChannelHeader->ch_space_offset)) + IOCHAN_FROM_IOPART; + virthbainfo->flags_addr = &pqhdr->features; if (!uisthread_start(&virthbainfo->chinfo.threadinfo, process_incoming_rsps, @@ -603,16 +602,16 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) return -ENODEV; } LOGINF("sendInterruptHandle=0x%16llX", - virthbainfo->intr.sendInterruptHandle); + virthbainfo->intr.send_irq_handle); LOGINF("recvInterruptHandle=0x%16llX", - virthbainfo->intr.recvInterruptHandle); + virthbainfo->intr.recv_irq_handle); LOGINF("recvInterruptVector=0x%8X", - virthbainfo->intr.recvInterruptVector); + virthbainfo->intr.recv_irq_vector); LOGINF("recvInterruptShared=0x%2X", - virthbainfo->intr.recvInterruptShared); + virthbainfo->intr.recv_irq_shared); LOGINF("scsihost.hostt->name=%s", scsihost->hostt->name); virthbainfo->interrupt_vector = - virthbainfo->intr.recvInterruptHandle & INTERRUPT_VECTOR_MASK; + virthbainfo->intr.recv_irq_handle & INTERRUPT_VECTOR_MASK; rsp = request_irq(virthbainfo->interrupt_vector, handler, IRQF_SHARED, scsihost->hostt->name, virthbainfo); if (rsp != 0) { @@ -622,7 +621,7 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) POSTCODE_LINUX_2(VHBA_PROBE_FAILURE_PC, POSTCODE_SEVERITY_ERR); } else { u64 __iomem *Features_addr = - &virthbainfo->chinfo.queueinfo->chan->Features; + &virthbainfo->chinfo.queueinfo->chan->features; LOGERR("request_irq(%d) uislib_virthba_ISR request succeeded\n", virthbainfo->interrupt_vector); mask = ~(ULTRA_IO_CHANNEL_IS_POLLING | @@ -649,8 +648,8 @@ virthba_remove(struct virtpci_dev *virtpcidev) struct Scsi_Host *scsihost = (struct Scsi_Host *) virtpcidev->scsi.scsihost; - LOGINF("virtpcidev busNo<<%d>>devNo<<%d>>", virtpcidev->busNo, - virtpcidev->deviceNo); + LOGINF("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no, + virtpcidev->device_no); virthbainfo = (struct virthba_info *) scsihost->hostdata; if (virthbainfo->interrupt_vector != -1) free_irq(virthbainfo->interrupt_vector, virthbainfo); @@ -674,7 +673,7 @@ virthba_remove(struct virtpci_dev *virtpcidev) } static int -forward_vdiskmgmt_command(VDISK_MGMT_TYPES vdiskcmdtype, +forward_vdiskmgmt_command(enum vdisk_mgmt_types vdiskcmdtype, struct Scsi_Host *scsihost, struct uisscsi_dest *vdest) { @@ -738,7 +737,8 @@ forward_vdiskmgmt_command(VDISK_MGMT_TYPES vdiskcmdtype, /*****************************************************/ static int -forward_taskmgmt_command(TASK_MGMT_TYPES tasktype, struct scsi_device *scsidev) +forward_taskmgmt_command(enum task_mgmt_types tasktype, + struct scsi_device *scsidev) { struct uiscmdrsp *cmdrsp; struct virthba_info *virthbainfo = @@ -1142,9 +1142,9 @@ do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) scsicmd, cmdrsp->scsi.cmnd[0], scsidev->host->host_no, scsidev->id, scsidev->channel, scsidev->lun, - cmdrsp->scsi.linuxstat, sd->Valid, sd->SenseKey, - sd->AdditionalSenseCode, - sd->AdditionalSenseCodeQualifier); + cmdrsp->scsi.linuxstat, sd->valid, sd->sense_key, + sd->additional_sense_code, + sd->additional_sense_code_qualifier); if (atomic_read(&vdisk->error_count) == VIRTHBA_ERROR_COUNT) { LOGERR("Throtling SCSICMD errors disk <%d:%d:%d:%llu>\n", @@ -1276,8 +1276,8 @@ drain_queue(struct virthba_info *virthbainfo, struct chaninfo *dc, while (1) { spin_lock_irqsave(&virthbainfo->chinfo.insertlock, flags); - if (!ULTRA_CHANNEL_CLIENT_ACQUIRE_OS(dc->queueinfo->chan, - "vhba", NULL)) { + if (!spar_channel_client_acquire_os(dc->queueinfo->chan, + "vhba")) { spin_unlock_irqrestore(&virthbainfo->chinfo.insertlock, flags); virthbainfo->acquire_failed_cnt++; @@ -1285,8 +1285,7 @@ drain_queue(struct virthba_info *virthbainfo, struct chaninfo *dc, } qrslt = uisqueue_get_cmdrsp(dc->queueinfo, cmdrsp, IOCHAN_FROM_IOPART); - ULTRA_CHANNEL_CLIENT_RELEASE_OS(dc->queueinfo->chan, - "vhba", NULL); + spar_channel_client_release_os(dc->queueinfo->chan, "vhba"); spin_unlock_irqrestore(&virthbainfo->chinfo.insertlock, flags); if (qrslt == 0) break; @@ -1310,7 +1309,7 @@ drain_queue(struct virthba_info *virthbainfo, struct chaninfo *dc, * a Client/Guest Partition. Let's be * safe and set it to NULL now. Do * not use it here! */ - cmdrsp->disknotify.vHba = NULL; + cmdrsp->disknotify.v_hba = NULL; process_disk_notify(shost, cmdrsp); } else if (cmdrsp->cmdtype == CMD_VDISKMGMT_TYPE) { if (!del_scsipending_entry(virthbainfo, @@ -1323,7 +1322,6 @@ drain_queue(struct virthba_info *virthbainfo, struct chaninfo *dc, } } - /* main function for the thread that waits for scsi commands to arrive * in a specified queue */ @@ -1453,7 +1451,7 @@ static ssize_t enable_ints_write(struct file *file, if (VirtHbasOpen[i].virthbainfo != NULL) { virthbainfo = VirtHbasOpen[i].virthbainfo; Features_addr = - &virthbainfo->chinfo.queueinfo->chan->Features; + &virthbainfo->chinfo.queueinfo->chan->features; if (new_value == 1) { mask = ~(ULTRA_IO_CHANNEL_IS_POLLING | ULTRA_IO_DRIVER_DISABLES_INTS); @@ -1482,8 +1480,8 @@ virthba_serverup(struct virtpci_dev *virtpcidev) (struct virthba_info *) ((struct Scsi_Host *) virtpcidev->scsi. scsihost)->hostdata; - DBGINF("virtpcidev busNo<<%d>>devNo<<%d>>", virtpcidev->busNo, - virtpcidev->deviceNo); + DBGINF("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no, + virtpcidev->device_no); if (!virthbainfo->serverdown) { DBGINF("Server up message received while server is already up.\n"); @@ -1498,9 +1496,9 @@ virthba_serverup(struct virtpci_dev *virtpcidev) /* Must transition channel to ATTACHED state BEFORE we * can start using the device again */ - ULTRA_CHANNEL_CLIENT_TRANSITION(virthbainfo->chinfo.queueinfo->chan, - dev_name(&virtpcidev->generic_dev), - CHANNELCLI_ATTACHED, NULL); + SPAR_CHANNEL_CLIENT_TRANSITION(virthbainfo->chinfo.queueinfo->chan, + dev_name(&virtpcidev->generic_dev), + CHANNELCLI_ATTACHED, NULL); /* Start Processing the IOVM Response Queue Again */ if (!uisthread_start(&virthbainfo->chinfo.threadinfo, @@ -1573,13 +1571,13 @@ virthba_serverdown_complete(struct work_struct *work) virtpcidev = virthbainfo->virtpcidev; - DBGINF("virtpcidev busNo<<%d>>devNo<<%d>>", virtpcidev->busNo, - virtpcidev->deviceNo); + DBGINF("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no, + virtpcidev->device_no); virthbainfo->serverdown = true; virthbainfo->serverchangingstate = false; /* Return the ServerDown response to Command */ - visorchipset_device_pause_response(virtpcidev->busNo, - virtpcidev->deviceNo, 0); + visorchipset_device_pause_response(virtpcidev->bus_no, + virtpcidev->device_no, 0); } /* As per VirtpciFunc returns 1 for success and 0 for failure */ @@ -1591,8 +1589,8 @@ virthba_serverdown(struct virtpci_dev *virtpcidev, u32 state) scsihost)->hostdata; DBGINF("virthba_serverdown"); - DBGINF("virtpcidev busNo<<%d>>devNo<<%d>>", virtpcidev->busNo, - virtpcidev->deviceNo); + DBGINF("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no, + virtpcidev->device_no); if (!virthbainfo->serverdown && !virthbainfo->serverchangingstate) { virthbainfo->serverchangingstate = true; diff --git a/drivers/staging/unisys/virthba/virthba.h b/drivers/staging/unisys/virthba/virthba.h index d4b809b0c7bc..59901668d4f4 100644 --- a/drivers/staging/unisys/virthba/virthba.h +++ b/drivers/staging/unisys/virthba/virthba.h @@ -19,13 +19,9 @@ * Unisys Virtual HBA driver header */ - - #ifndef __VIRTHBA_H__ #define __VIRTHBA_H__ - #define VIRTHBA_VERSION "01.00" - #endif /* __VIRTHBA_H__ */ diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index ee9f8260cd15..39b828dce503 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -50,6 +50,7 @@ struct driver_private { struct module_kobject *mkobj; struct device_driver *driver; }; + #define to_driver(obj) container_of(obj, struct driver_private, kobj) /* bus_id went away in 2.6.30 - the size was 20 bytes, so we'll define @@ -109,7 +110,7 @@ static int virtpci_device_probe(struct device *dev); static int virtpci_device_remove(struct device *dev); static ssize_t info_debugfs_read(struct file *file, char __user *buf, - size_t len, loff_t *offset); + size_t len, loff_t *offset); static const struct file_operations debugfs_info_fops = { .read = info_debugfs_read, @@ -137,7 +138,7 @@ static struct device virtpci_rootbus_device = { }; /* filled in with info about parent chipset driver when we register with it */ -static ULTRA_VBUS_DEVICEINFO Chipset_DriverInfo; +static struct ultra_vbus_deviceinfo chipset_driver_info; static const struct sysfs_ops virtpci_driver_sysfs_ops = { .show = virtpci_driver_attr_show, @@ -148,11 +149,11 @@ static struct kobj_type virtpci_driver_kobj_type = { .sysfs_ops = &virtpci_driver_sysfs_ops, }; -static struct virtpci_dev *VpcidevListHead; -static DEFINE_RWLOCK(VpcidevListLock); +static struct virtpci_dev *vpcidev_list_head; +static DEFINE_RWLOCK(vpcidev_list_lock); /* filled in with info about this driver, wrt it servicing client busses */ -static ULTRA_VBUS_DEVICEINFO Bus_DriverInfo; +static struct ultra_vbus_deviceinfo bus_driver_info; /*****************************************************/ /* debugfs entries */ @@ -171,13 +172,12 @@ struct virtpci_busdev { /*****************************************************/ static inline -int WAIT_FOR_IO_CHANNEL(ULTRA_IO_CHANNEL_PROTOCOL __iomem *chanptr) +int WAIT_FOR_IO_CHANNEL(struct spar_io_channel_protocol __iomem *chanptr) { int count = 120; while (count > 0) { - - if (ULTRA_CHANNEL_SERVER_READY(&chanptr->ChannelHeader)) + if (SPAR_CHANNEL_SERVER_READY(&chanptr->channel_header)) return 1; UIS_THREAD_WAIT_SEC(1); count--; @@ -186,8 +186,8 @@ int WAIT_FOR_IO_CHANNEL(ULTRA_IO_CHANNEL_PROTOCOL __iomem *chanptr) } /* Write the contents of <info> to the ULTRA_VBUS_CHANNEL_PROTOCOL.ChpInfo. */ -static int write_vbus_chpInfo(ULTRA_VBUS_CHANNEL_PROTOCOL *chan, - ULTRA_VBUS_DEVICEINFO *info) +static int write_vbus_chp_info(struct spar_vbus_channel_protocol *chan, + struct ultra_vbus_deviceinfo *info) { int off; @@ -195,18 +195,18 @@ static int write_vbus_chpInfo(ULTRA_VBUS_CHANNEL_PROTOCOL *chan, LOGERR("vbus channel not present"); return -1; } - off = sizeof(ULTRA_CHANNEL_PROTOCOL) + chan->HdrInfo.chpInfoByteOffset; - if (chan->HdrInfo.chpInfoByteOffset == 0) { - LOGERR("vbus channel not used, because chpInfoByteOffset == 0"); + off = sizeof(struct channel_header) + chan->hdr_info.chp_info_offset; + if (chan->hdr_info.chp_info_offset == 0) { + LOGERR("vbus channel not used, because chp_info_offset == 0"); return -1; } - memcpy(((u8 *) (chan)) + off, info, sizeof(*info)); + memcpy(((u8 *)(chan)) + off, info, sizeof(*info)); return 0; } /* Write the contents of <info> to the ULTRA_VBUS_CHANNEL_PROTOCOL.BusInfo. */ -static int write_vbus_busInfo(ULTRA_VBUS_CHANNEL_PROTOCOL *chan, - ULTRA_VBUS_DEVICEINFO *info) +static int write_vbus_bus_info(struct spar_vbus_channel_protocol *chan, + struct ultra_vbus_deviceinfo *info) { int off; @@ -214,12 +214,12 @@ static int write_vbus_busInfo(ULTRA_VBUS_CHANNEL_PROTOCOL *chan, LOGERR("vbus channel not present"); return -1; } - off = sizeof(ULTRA_CHANNEL_PROTOCOL) + chan->HdrInfo.busInfoByteOffset; - if (chan->HdrInfo.busInfoByteOffset == 0) { - LOGERR("vbus channel not used, because busInfoByteOffset == 0"); + off = sizeof(struct channel_header) + chan->hdr_info.bus_info_offset; + if (chan->hdr_info.bus_info_offset == 0) { + LOGERR("vbus channel not used, because bus_info_offset == 0"); return -1; } - memcpy(((u8 *) (chan)) + off, info, sizeof(*info)); + memcpy(((u8 *)(chan)) + off, info, sizeof(*info)); return 0; } @@ -227,8 +227,8 @@ static int write_vbus_busInfo(ULTRA_VBUS_CHANNEL_PROTOCOL *chan, * ULTRA_VBUS_CHANNEL_PROTOCOL.DevInfo[<devix>]. */ static int -write_vbus_devInfo(ULTRA_VBUS_CHANNEL_PROTOCOL *chan, - ULTRA_VBUS_DEVICEINFO *info, int devix) +write_vbus_dev_info(struct spar_vbus_channel_protocol *chan, + struct ultra_vbus_deviceinfo *info, int devix) { int off; @@ -237,14 +237,14 @@ write_vbus_devInfo(ULTRA_VBUS_CHANNEL_PROTOCOL *chan, return -1; } off = - (sizeof(ULTRA_CHANNEL_PROTOCOL) + - chan->HdrInfo.devInfoByteOffset) + - (chan->HdrInfo.deviceInfoStructBytes * devix); - if (chan->HdrInfo.devInfoByteOffset == 0) { - LOGERR("vbus channel not used, because devInfoByteOffset == 0"); + (sizeof(struct channel_header) + + chan->hdr_info.dev_info_offset) + + (chan->hdr_info.device_info_struct_bytes * devix); + if (chan->hdr_info.dev_info_offset == 0) { + LOGERR("vbus channel not used, because dev_info_offset == 0"); return -1; } - memcpy(((u8 *) (chan)) + off, info, sizeof(*info)); + memcpy(((u8 *)(chan)) + off, info, sizeof(*info)); return 0; } @@ -256,13 +256,13 @@ static int add_vbus(struct add_vbus_guestpart *addparams) int ret; struct device *vbus; - vbus = kzalloc(sizeof(struct device), GFP_ATOMIC); + vbus = kzalloc(sizeof(*vbus), GFP_ATOMIC); POSTCODE_LINUX_2(VPCI_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO); if (!vbus) return 0; - dev_set_name(vbus, "vbus%d", addparams->busNo); + dev_set_name(vbus, "vbus%d", addparams->bus_no); vbus->release = virtpci_bus_release; vbus->parent = &virtpci_rootbus_device; /* root bus is parent */ vbus->bus = &virtpci_bus_type; /* bus type */ @@ -279,11 +279,12 @@ static int add_vbus(struct add_vbus_guestpart *addparams) POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR); return 0; } - write_vbus_chpInfo(vbus->platform_data /* chanptr */ , - &Chipset_DriverInfo); - write_vbus_busInfo(vbus->platform_data /* chanptr */ , &Bus_DriverInfo); + write_vbus_chp_info(vbus->platform_data /* chanptr */ , + &chipset_driver_info); + write_vbus_bus_info(vbus->platform_data /* chanptr */ , + &bus_driver_info); LOGINF("Added vbus %d; device %s created successfully\n", - addparams->busNo, BUS_ID(vbus)); + addparams->bus_no, BUS_ID(vbus)); POSTCODE_LINUX_2(VPCI_CREATE_EXIT_PC, POSTCODE_SEVERITY_INFO); return 1; } @@ -293,26 +294,15 @@ static int add_vbus(struct add_vbus_guestpart *addparams) */ #define GET_SCSIADAPINFO_FROM_CHANPTR(chanptr) { \ memcpy_fromio(&scsi.wwnn, \ - &((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) \ + &((struct spar_io_channel_protocol __iomem *) \ chanptr)->vhba.wwnn, \ sizeof(struct vhba_wwnn)); \ memcpy_fromio(&scsi.max, \ - &((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) \ + &((struct spar_io_channel_protocol __iomem *) \ chanptr)->vhba.max, \ sizeof(struct vhba_config_max)); \ } -/* find bus device with the busid that matches - match_busid matches bus_id */ -#define GET_BUS_DEV(busno) { \ - sprintf(busid, "vbus%d", busno); \ - vbus = bus_find_device(&virtpci_bus_type, NULL, \ - (void *)busid, match_busid); \ - if (!vbus) { \ - LOGERR("**** FAILED to find vbus %s\n", busid); \ - return 0; \ - } \ -} - /* adds a vhba * returns 0 failure, 1 success, */ @@ -325,7 +315,7 @@ static int add_vhba(struct add_virt_guestpart *addparams) POSTCODE_LINUX_2(VPCI_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO); if (!WAIT_FOR_IO_CHANNEL - ((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) addparams->chanptr)) { + ((struct spar_io_channel_protocol __iomem *)addparams->chanptr)) { LOGERR("Timed out. Channel not ready\n"); POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR); return 0; @@ -333,7 +323,14 @@ static int add_vhba(struct add_virt_guestpart *addparams) GET_SCSIADAPINFO_FROM_CHANPTR(addparams->chanptr); - GET_BUS_DEV(addparams->bus_no); + /* find bus device with the busid that matches match_busid */ + sprintf(busid, "vbus%d", addparams->bus_no); + vbus = bus_find_device(&virtpci_bus_type, NULL, + (void *)busid, match_busid); + if (!vbus) { + LOGERR("**** FAILED to find vbus %s\n", busid); + return 0; + } LOGINF("Adding vhba wwnn:%x:%x config:%d-%d-%d-%d chanptr:%p\n", scsi.wwnn.wwnn1, scsi.wwnn.wwnn2, @@ -347,7 +344,6 @@ static int add_vhba(struct add_virt_guestpart *addparams) POSTCODE_SEVERITY_INFO); } return i; - } /* for CHANSOCK macaddr is AUTO-GENERATED; for normal channels, @@ -355,17 +351,17 @@ static int add_vhba(struct add_virt_guestpart *addparams) */ #define GET_NETADAPINFO_FROM_CHANPTR(chanptr) { \ memcpy_fromio(net.mac_addr, \ - ((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) \ - chanptr)->vnic.macaddr, \ + ((struct spar_io_channel_protocol __iomem *) \ + chanptr)->vnic.macaddr, \ MAX_MACADDR_LEN); \ net.num_rcv_bufs = \ - readl(&((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) \ - chanptr)->vnic.num_rcv_bufs); \ - net.mtu = readl(&((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) \ - chanptr)->vnic.mtu); \ - memcpy_fromio(&net.zoneGuid, \ - &((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) \ - chanptr)->vnic.zoneGuid, \ + readl(&((struct spar_io_channel_protocol __iomem *)\ + chanptr)->vnic.num_rcv_bufs); \ + net.mtu = readl(&((struct spar_io_channel_protocol __iomem *) \ + chanptr)->vnic.mtu); \ + memcpy_fromio(&net.zone_uuid, \ + &((struct spar_io_channel_protocol __iomem *)\ + chanptr)->vnic.zone_uuid, \ sizeof(uuid_le)); \ } @@ -382,7 +378,7 @@ add_vnic(struct add_virt_guestpart *addparams) POSTCODE_LINUX_2(VPCI_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO); if (!WAIT_FOR_IO_CHANNEL - ((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) addparams->chanptr)) { + ((struct spar_io_channel_protocol __iomem *)addparams->chanptr)) { LOGERR("Timed out, channel not ready\n"); POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR); return 0; @@ -390,12 +386,19 @@ add_vnic(struct add_virt_guestpart *addparams) GET_NETADAPINFO_FROM_CHANPTR(addparams->chanptr); - GET_BUS_DEV(addparams->bus_no); + /* find bus device with the busid that matches match_busid */ + sprintf(busid, "vbus%d", addparams->bus_no); + vbus = bus_find_device(&virtpci_bus_type, NULL, + (void *)busid, match_busid); + if (!vbus) { + LOGERR("**** FAILED to find vbus %s\n", busid); + return 0; + } LOGINF("Adding vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x rcvbufs:%d mtu:%d chanptr:%p%pUL\n", - net.mac_addr[0], net.mac_addr[1], net.mac_addr[2], net.mac_addr[3], - net.mac_addr[4], net.mac_addr[5], net.num_rcv_bufs, net.mtu, - addparams->chanptr, &net.zoneGuid); + net.mac_addr[0], net.mac_addr[1], net.mac_addr[2], + net.mac_addr[3], net.mac_addr[4], net.mac_addr[5], + net.num_rcv_bufs, net.mtu, addparams->chanptr, &net.zone_uuid); i = virtpci_device_add(vbus, VIRTNIC_TYPE, addparams, NULL, &net); if (i) { LOGINF("Added vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n", @@ -417,7 +420,15 @@ delete_vbus(struct del_vbus_guestpart *delparams) struct device *vbus; unsigned char busid[BUS_ID_SIZE]; - GET_BUS_DEV(delparams->bus_no); + /* find bus device with the busid that matches match_busid */ + sprintf(busid, "vbus%d", delparams->bus_no); + vbus = bus_find_device(&virtpci_bus_type, NULL, + (void *)busid, match_busid); + if (!vbus) { + LOGERR("**** FAILED to find vbus %s\n", busid); + return 0; + } + /* ensure that bus has no devices? -- TBD */ LOGINF("Deleting %s\n", BUS_ID(vbus)); if (delete_vbus_device(vbus, NULL)) @@ -430,9 +441,9 @@ static int delete_vbus_device(struct device *vbus, void *data) { int checkforroot = (data != NULL); - struct device *pDev = &virtpci_rootbus_device; + struct device *dev = &virtpci_rootbus_device; - if ((checkforroot) && match_busid(vbus, (void *) BUS_ID(pDev))) { + if ((checkforroot) && match_busid(vbus, (void *)BUS_ID(dev))) { /* skip it - don't delete root bus */ LOGINF("skipping root bus\n"); return 0; /* pretend no error */ @@ -590,10 +601,10 @@ static void delete_all(void) struct virtpci_dev *tmpvpcidev, *nextvpcidev; /* delete the entire vhba/vnic list in one shot */ - write_lock_irqsave(&VpcidevListLock, flags); - tmpvpcidev = VpcidevListHead; - VpcidevListHead = NULL; - write_unlock_irqrestore(&VpcidevListLock, flags); + write_lock_irqsave(&vpcidev_list_lock, flags); + tmpvpcidev = vpcidev_list_head; + vpcidev_list_head = NULL; + write_unlock_irqrestore(&vpcidev_list_lock, flags); /* delete one vhba/vnic at a time */ while (tmpvpcidev) { @@ -607,24 +618,32 @@ static void delete_all(void) /* now delete each vbus */ if (bus_for_each_dev - (&virtpci_bus_type, NULL, (void *) 1, delete_vbus_device)) + (&virtpci_bus_type, NULL, (void *)1, delete_vbus_device)) LOGERR("delete of all vbus failed\n"); } /* deletes all vnics or vhbas * returns 0 failure, 1 success, */ -static int delete_all_virt(VIRTPCI_DEV_TYPE devtype, struct del_vbus_guestpart *delparams) +static int delete_all_virt(enum virtpci_dev_type devtype, + struct del_vbus_guestpart *delparams) { int i; unsigned char busid[BUS_ID_SIZE]; struct device *vbus; - GET_BUS_DEV(delparams->bus_no); + /* find bus device with the busid that matches match_busid */ + sprintf(busid, "vbus%d", delparams->bus_no); + vbus = bus_find_device(&virtpci_bus_type, NULL, + (void *)busid, match_busid); + if (!vbus) { + LOGERR("**** FAILED to find vbus %s\n", busid); + return 0; + } if ((devtype != VIRTHBA_TYPE) && (devtype != VIRTNIC_TYPE)) { LOGERR("**** FAILED to delete all devices; devtype:%d not vhba:%d or vnic:%d\n", - devtype, VIRTHBA_TYPE, VIRTNIC_TYPE); + devtype, VIRTHBA_TYPE, VIRTNIC_TYPE); return 0; } @@ -694,10 +713,10 @@ virtpci_match_device(const struct pci_device_id *ids, { while (ids->vendor || ids->subvendor || ids->class_mask) { DBGINF("ids->vendor:%x dev->vendor:%x ids->device:%x dev->device:%x\n", - ids->vendor, dev->vendor, ids->device, dev->device); + ids->vendor, dev->vendor, ids->device, dev->device); - if ((ids->vendor == dev->vendor) - && (ids->device == dev->device)) + if ((ids->vendor == dev->vendor) && + (ids->device == dev->device)) return ids; ids++; @@ -752,15 +771,15 @@ static int virtpci_device_resume(struct device *dev) /* For a child device just created on a client bus, fill in * information about the driver that is controlling this device into - * the the appropriate slot within the vbus channel of the bus + * the appropriate slot within the vbus channel of the bus * instance. */ -static void fix_vbus_devInfo(struct device *dev, int devNo, int devType, - struct virtpci_driver *virtpcidrv) +static void fix_vbus_dev_info(struct device *dev, int dev_no, int dev_type, + struct virtpci_driver *virtpcidrv) { struct device *vbus; - void *pChan; - ULTRA_VBUS_DEVICEINFO devInfo; + void *chan; + struct ultra_vbus_deviceinfo dev_info; const char *stype; if (!dev) { @@ -776,12 +795,12 @@ static void fix_vbus_devInfo(struct device *dev, int devNo, int devType, LOGERR("%s dev has no parent bus", __func__); return; } - pChan = vbus->platform_data; - if (!pChan) { + chan = vbus->platform_data; + if (!chan) { LOGERR("%s dev bus has no channel", __func__); return; } - switch (devType) { + switch (dev_type) { case PCI_DEVICE_ID_VIRTHBA: stype = "vHBA"; break; @@ -792,17 +811,17 @@ static void fix_vbus_devInfo(struct device *dev, int devNo, int devType, stype = "unknown"; break; } - bus_device_info_init(&devInfo, stype, - virtpcidrv->name, - virtpcidrv->version, - virtpcidrv->vertag); - write_vbus_devInfo(pChan, &devInfo, devNo); + bus_device_info_init(&dev_info, stype, + virtpcidrv->name, + virtpcidrv->version, + virtpcidrv->vertag); + write_vbus_dev_info(chan, &dev_info, dev_no); /* Re-write bus+chipset info, because it is possible that this * was previously written by our good counterpart, visorbus. */ - write_vbus_chpInfo(pChan, &Chipset_DriverInfo); - write_vbus_busInfo(pChan, &Bus_DriverInfo); + write_vbus_chp_info(chan, &chipset_driver_info); + write_vbus_bus_info(chan, &bus_driver_info); } /* This function is called to query the existence of a specific device @@ -842,13 +861,14 @@ static int virtpci_device_probe(struct device *dev) */ error = virtpcidrv->probe(virtpcidev, id); if (!error) { - fix_vbus_devInfo(dev, virtpcidev->deviceNo, - virtpcidev->device, virtpcidrv); + fix_vbus_dev_info(dev, virtpcidev->device_no, + virtpcidev->device, virtpcidrv); virtpcidev->mydriver = virtpcidrv; POSTCODE_LINUX_2(VPCI_PROBE_EXIT_PC, POSTCODE_SEVERITY_INFO); - } else + } else { put_device(dev); + } } POSTCODE_LINUX_2(VPCI_PROBE_FAILURE_PC, POSTCODE_SEVERITY_ERR); return error; /* -ENODEV for probe failure */ @@ -896,17 +916,20 @@ static void virtpci_bus_release(struct device *dev) /* Adapter functions */ /*****************************************************/ +/* scsi is expected to be NULL for VNIC add + * net is expected to be NULL for VHBA add + */ static int virtpci_device_add(struct device *parentbus, int devtype, struct add_virt_guestpart *addparams, - struct scsi_adap_info *scsi, /* NULL for VNIC add */ - struct net_adap_info *net /* NULL for VHBA add */) + struct scsi_adap_info *scsi, + struct net_adap_info *net) { struct virtpci_dev *virtpcidev = NULL; struct virtpci_dev *tmpvpcidev = NULL, *prev; unsigned long flags; int ret; - ULTRA_IO_CHANNEL_PROTOCOL __iomem *pIoChan = NULL; - struct device *pDev; + struct spar_io_channel_protocol __iomem *io_chan = NULL; + struct device *dev; LOGINF("virtpci_device_add parentbus:%p chanptr:%p\n", parentbus, addparams->chanptr); @@ -915,14 +938,14 @@ static int virtpci_device_add(struct device *parentbus, int devtype, if ((devtype != VIRTHBA_TYPE) && (devtype != VIRTNIC_TYPE)) { LOGERR("**** FAILED to add device; devtype:%d not vhba:%d or vnic:%d\n", - devtype, VIRTHBA_TYPE, VIRTNIC_TYPE); + devtype, VIRTHBA_TYPE, VIRTNIC_TYPE); POSTCODE_LINUX_3(VPCI_CREATE_FAILURE_PC, devtype, POSTCODE_SEVERITY_ERR); return 0; } /* add a Virtual Device */ - virtpcidev = kzalloc(sizeof(struct virtpci_dev), GFP_ATOMIC); + virtpcidev = kzalloc(sizeof(*virtpcidev), GFP_ATOMIC); if (virtpcidev == NULL) { LOGERR("can't add device - malloc FALLED\n"); POSTCODE_LINUX_2(MALLOC_FAILURE_PC, POSTCODE_SEVERITY_ERR); @@ -939,14 +962,14 @@ static int virtpci_device_add(struct device *parentbus, int devtype, virtpcidev->net = *net; } virtpcidev->vendor = PCI_VENDOR_ID_UNISYS; - virtpcidev->busNo = addparams->bus_no; - virtpcidev->deviceNo = addparams->device_no; + virtpcidev->bus_no = addparams->bus_no; + virtpcidev->device_no = addparams->device_no; virtpcidev->queueinfo.chan = addparams->chanptr; virtpcidev->queueinfo.send_int_if_needed = NULL; /* Set up safe queue... */ - pIoChan = (ULTRA_IO_CHANNEL_PROTOCOL __iomem *) + io_chan = (struct spar_io_channel_protocol __iomem *) virtpcidev->queueinfo.chan; virtpcidev->intr = addparams->intr; @@ -962,8 +985,8 @@ static int virtpci_device_add(struct device *parentbus, int devtype, /* add the vhba/vnic to virtpci device list - but check for * duplicate wwnn/macaddr first */ - write_lock_irqsave(&VpcidevListLock, flags); - for (tmpvpcidev = VpcidevListHead; tmpvpcidev; + write_lock_irqsave(&vpcidev_list_lock, flags); + for (tmpvpcidev = vpcidev_list_head; tmpvpcidev; tmpvpcidev = tmpvpcidev->next) { if (devtype == VIRTHBA_TYPE) { if ((tmpvpcidev->scsi.wwnn.wwnn1 == scsi->wwnn.wwnn1) && @@ -984,7 +1007,7 @@ static int virtpci_device_add(struct device *parentbus, int devtype, /* found a vhba/vnic already in the list with same * wwnn or macaddr - reject add */ - write_unlock_irqrestore(&VpcidevListLock, flags); + write_unlock_irqrestore(&vpcidev_list_lock, flags); kfree(virtpcidev); LOGERR("**** FAILED vhba/vnic already exists in the list\n"); POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR); @@ -992,26 +1015,26 @@ static int virtpci_device_add(struct device *parentbus, int devtype, } /* add it at the head */ - if (!VpcidevListHead) - VpcidevListHead = virtpcidev; - else { + if (!vpcidev_list_head) { + vpcidev_list_head = virtpcidev; + } else { /* insert virtpcidev at the head of our linked list of * vpcidevs */ - virtpcidev->next = VpcidevListHead; - VpcidevListHead = virtpcidev; + virtpcidev->next = vpcidev_list_head; + vpcidev_list_head = virtpcidev; } - write_unlock_irqrestore(&VpcidevListLock, flags); + write_unlock_irqrestore(&vpcidev_list_lock, flags); /* Must transition channel to ATTACHED state BEFORE * registering the device, because polling of the channel * queues can begin at any time after device_register(). */ - pDev = &virtpcidev->generic_dev; - ULTRA_CHANNEL_CLIENT_TRANSITION(addparams->chanptr, - BUS_ID(pDev), - CHANNELCLI_ATTACHED, NULL); + dev = &virtpcidev->generic_dev; + SPAR_CHANNEL_CLIENT_TRANSITION(addparams->chanptr, + BUS_ID(dev), + CHANNELCLI_ATTACHED, NULL); /* don't register until device has been added to * list. Otherwise, a device_unregister from this function can @@ -1031,24 +1054,24 @@ static int virtpci_device_add(struct device *parentbus, int devtype, */ if (ret) { LOGERR("device_register returned %d\n", ret); - pDev = &virtpcidev->generic_dev; - ULTRA_CHANNEL_CLIENT_TRANSITION(addparams->chanptr, - BUS_ID(pDev), - CHANNELCLI_DETACHED, NULL); + dev = &virtpcidev->generic_dev; + SPAR_CHANNEL_CLIENT_TRANSITION(addparams->chanptr, + BUS_ID(dev), + CHANNELCLI_DETACHED, NULL); /* remove virtpcidev, the one we just added, from the list */ - write_lock_irqsave(&VpcidevListLock, flags); - for (tmpvpcidev = VpcidevListHead, prev = NULL; + write_lock_irqsave(&vpcidev_list_lock, flags); + for (tmpvpcidev = vpcidev_list_head, prev = NULL; tmpvpcidev; prev = tmpvpcidev, tmpvpcidev = tmpvpcidev->next) { if (tmpvpcidev == virtpcidev) { if (prev) prev->next = tmpvpcidev->next; else - VpcidevListHead = tmpvpcidev->next; + vpcidev_list_head = tmpvpcidev->next; break; } } - write_unlock_irqrestore(&VpcidevListLock, flags); + write_unlock_irqrestore(&vpcidev_list_lock, flags); kfree(virtpcidev); return 0; } @@ -1080,9 +1103,9 @@ static int virtpci_device_serverdown(struct device *parentbus, } /* find the vhba or vnic in virtpci device list */ - write_lock_irqsave(&VpcidevListLock, flags); + write_lock_irqsave(&vpcidev_list_lock, flags); - for (tmpvpcidev = VpcidevListHead, prevvpcidev = NULL; + for (tmpvpcidev = vpcidev_list_head, prevvpcidev = NULL; (tmpvpcidev && !found); prevvpcidev = tmpvpcidev, tmpvpcidev = tmpvpcidev->next) { if (tmpvpcidev->devtype != devtype) @@ -1110,7 +1133,7 @@ static int virtpci_device_serverdown(struct device *parentbus, vpcidriver = tmpvpcidev->mydriver; rc = vpcidriver->suspend(tmpvpcidev, 0); } - write_unlock_irqrestore(&VpcidevListLock, flags); + write_unlock_irqrestore(&vpcidev_list_lock, flags); if (!found) { LOGERR("**** FAILED to find vhba/vnic in the list\n"); @@ -1139,9 +1162,9 @@ static int virtpci_device_serverup(struct device *parentbus, } /* find the vhba or vnic in virtpci device list */ - write_lock_irqsave(&VpcidevListLock, flags); + write_lock_irqsave(&vpcidev_list_lock, flags); - for (tmpvpcidev = VpcidevListHead, prevvpcidev = NULL; + for (tmpvpcidev = vpcidev_list_head, prevvpcidev = NULL; (tmpvpcidev && !found); prevvpcidev = tmpvpcidev, tmpvpcidev = tmpvpcidev->next) { if (tmpvpcidev->devtype != devtype) @@ -1172,12 +1195,13 @@ static int virtpci_device_serverup(struct device *parentbus, * ever have a bus that contains NO devices, since we * would never even get here in that case. */ - fix_vbus_devInfo(&tmpvpcidev->generic_dev, tmpvpcidev->deviceNo, - tmpvpcidev->device, vpcidriver); + fix_vbus_dev_info(&tmpvpcidev->generic_dev, + tmpvpcidev->device_no, + tmpvpcidev->device, vpcidriver); rc = vpcidriver->resume(tmpvpcidev); } - write_unlock_irqrestore(&VpcidevListLock, flags); + write_unlock_irqrestore(&vpcidev_list_lock, flags); if (!found) { LOGERR("**** FAILED to find vhba/vnic in the list\n"); @@ -1218,8 +1242,8 @@ static int virtpci_device_del(struct device *parentbus, * device_unregister after we release the lock; otherwise we * encounter "schedule while atomic" */ - write_lock_irqsave(&VpcidevListLock, flags); - for (tmpvpcidev = VpcidevListHead, prevvpcidev = NULL; tmpvpcidev;) { + write_lock_irqsave(&vpcidev_list_lock, flags); + for (tmpvpcidev = vpcidev_list_head, prevvpcidev = NULL; tmpvpcidev;) { if (tmpvpcidev->devtype != devtype) DEL_CONTINUE; @@ -1253,7 +1277,7 @@ static int virtpci_device_del(struct device *parentbus, /* not at head */ prevvpcidev->next = tmpvpcidev->next; else - VpcidevListHead = tmpvpcidev->next; + vpcidev_list_head = tmpvpcidev->next; /* add it to our deletelist */ tmpvpcidev->next = dellist; @@ -1268,9 +1292,9 @@ static int virtpci_device_del(struct device *parentbus, if (prevvpcidev) tmpvpcidev = prevvpcidev->next; else - tmpvpcidev = VpcidevListHead; + tmpvpcidev = vpcidev_list_head; } - write_unlock_irqrestore(&VpcidevListLock, flags); + write_unlock_irqrestore(&vpcidev_list_lock, flags); if (!all && (count == 0)) { LOGERR("**** FAILED to find vhba/vnic in the list\n"); @@ -1425,7 +1449,7 @@ static int print_vbus(struct device *vbus, void *data) } static ssize_t info_debugfs_read(struct file *file, char __user *buf, - size_t len, loff_t *offset) + size_t len, loff_t *offset) { ssize_t bytes_read = 0; int str_pos = 0; @@ -1446,18 +1470,19 @@ static ssize_t info_debugfs_read(struct file *file, char __user *buf, printparam.buf = vbuf; printparam.len = &len; if (bus_for_each_dev(&virtpci_bus_type, NULL, - (void *) &printparam, print_vbus)) + (void *)&printparam, print_vbus)) LOGERR("Failed to find bus\n"); str_pos += scnprintf(vbuf + str_pos, len - str_pos, "\n Virtual PCI devices\n"); - read_lock_irqsave(&VpcidevListLock, flags); - tmpvpcidev = VpcidevListHead; + read_lock_irqsave(&vpcidev_list_lock, flags); + tmpvpcidev = vpcidev_list_head; while (tmpvpcidev) { if (tmpvpcidev->devtype == VIRTHBA_TYPE) { str_pos += scnprintf(vbuf + str_pos, len - str_pos, "[%d:%d] VHba:%08x:%08x max-config:%d-%d-%d-%d", - tmpvpcidev->busNo, tmpvpcidev->deviceNo, + tmpvpcidev->bus_no, + tmpvpcidev->device_no, tmpvpcidev->scsi.wwnn.wwnn1, tmpvpcidev->scsi.wwnn.wwnn2, tmpvpcidev->scsi.max.max_channel, @@ -1467,7 +1492,8 @@ static ssize_t info_debugfs_read(struct file *file, char __user *buf, } else { str_pos += scnprintf(vbuf + str_pos, len - str_pos, "[%d:%d] VNic:%02x:%02x:%02x:%02x:%02x:%02x num_rcv_bufs:%d mtu:%d", - tmpvpcidev->busNo, tmpvpcidev->deviceNo, + tmpvpcidev->bus_no, + tmpvpcidev->device_no, tmpvpcidev->net.mac_addr[0], tmpvpcidev->net.mac_addr[1], tmpvpcidev->net.mac_addr[2], @@ -1482,7 +1508,7 @@ static ssize_t info_debugfs_read(struct file *file, char __user *buf, tmpvpcidev->queueinfo.chan); tmpvpcidev = tmpvpcidev->next; } - read_unlock_irqrestore(&VpcidevListLock, flags); + read_unlock_irqrestore(&vpcidev_list_lock, flags); str_pos += scnprintf(vbuf + str_pos, len - str_pos, "\n"); bytes_read = simple_read_from_buffer(buf, len, offset, vbuf, str_pos); @@ -1498,7 +1524,6 @@ static int __init virtpci_mod_init(void) { int ret; - if (!unisys_spar_platform) return -ENODEV; @@ -1515,8 +1540,8 @@ static int __init virtpci_mod_init(void) return ret; } DBGINF("bus_register successful\n"); - bus_device_info_init(&Bus_DriverInfo, "clientbus", "virtpci", - VERSION, NULL); + bus_device_info_init(&bus_driver_info, "clientbus", "virtpci", + VERSION, NULL); /* create a root bus used to parent all the virtpci buses. */ ret = device_register(&virtpci_rootbus_device); @@ -1529,8 +1554,8 @@ static int __init virtpci_mod_init(void) } DBGINF("device_register successful ret:%x\n", ret); - if (!uisctrl_register_req_handler(2, (void *) &virtpci_ctrlchan_func, - &Chipset_DriverInfo)) { + if (!uisctrl_register_req_handler(2, (void *)&virtpci_ctrlchan_func, + &chipset_driver_info)) { LOGERR("uisctrl_register_req_handler ****FAILED.\n"); POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR); device_unregister(&virtpci_rootbus_device); @@ -1539,11 +1564,11 @@ static int __init virtpci_mod_init(void) } LOGINF("successfully registered virtpci_ctrlchan_func (0x%p) as callback.\n", - (void *) &virtpci_ctrlchan_func); + (void *)&virtpci_ctrlchan_func); /* create debugfs directory and info file inside. */ virtpci_debugfs_dir = debugfs_create_dir("virtpci", NULL); debugfs_create_file("info", S_IRUSR, virtpci_debugfs_dir, - NULL, &debugfs_info_fops); + NULL, &debugfs_info_fops); LOGINF("Leaving\n"); POSTCODE_LINUX_2(VPCI_CREATE_EXIT_PC, POSTCODE_SEVERITY_INFO); return 0; @@ -1561,7 +1586,6 @@ static void __exit virtpci_mod_exit(void) bus_unregister(&virtpci_bus_type); debugfs_remove_recursive(virtpci_debugfs_dir); LOGINF("Leaving\n"); - } module_init(virtpci_mod_init); diff --git a/drivers/staging/unisys/virtpci/virtpci.h b/drivers/staging/unisys/virtpci/virtpci.h index 6e26956c79f4..9d85f55e8169 100644 --- a/drivers/staging/unisys/virtpci/virtpci.h +++ b/drivers/staging/unisys/virtpci/virtpci.h @@ -42,25 +42,25 @@ struct net_adap_info { u8 mac_addr[MAX_MACADDR_LEN]; int num_rcv_bufs; unsigned mtu; - uuid_le zoneGuid; + uuid_le zone_uuid; }; -typedef enum { +enum virtpci_dev_type { VIRTHBA_TYPE = 0, VIRTNIC_TYPE = 1, VIRTBUS_TYPE = 6, -} VIRTPCI_DEV_TYPE; +}; struct virtpci_dev { - VIRTPCI_DEV_TYPE devtype; /* indicates type of the + enum virtpci_dev_type devtype; /* indicates type of the * virtual pci device */ struct virtpci_driver *mydriver; /* which driver has allocated * this device */ unsigned short vendor; /* vendor id for device */ unsigned short device; /* device id for device */ - u32 busNo; /* number of bus on which device exists */ - u32 deviceNo; /* device's number on the bus */ - struct InterruptInfo intr; /* interrupt info */ + u32 bus_no; /* number of bus on which device exists */ + u32 device_no; /* device's number on the bus */ + struct irq_info intr; /* interrupt info */ struct device generic_dev; /* generic device */ union { struct scsi_adap_info scsi; @@ -80,15 +80,15 @@ struct virtpci_driver { const struct pci_device_id *id_table; /* must be non-NULL for probe * to be called */ int (*probe)(struct virtpci_dev *dev, - const struct pci_device_id *id); /* device inserted */ + const struct pci_device_id *id); /* device inserted */ void (*remove)(struct virtpci_dev *dev); /* Device removed (NULL if * not a hot-plug capable * driver) */ int (*suspend)(struct virtpci_dev *dev, - u32 state); /* Device suspended */ + u32 state); /* Device suspended */ int (*resume)(struct virtpci_dev *dev); /* Device woken up */ int (*enable_wake)(struct virtpci_dev *dev, - u32 state, int enable); /* Enable wake event */ + u32 state, int enable); /* Enable wake event */ struct device_driver core_driver; /* VIRTPCI core fills this in */ }; diff --git a/drivers/staging/unisys/visorchannel/globals.h b/drivers/staging/unisys/visorchannel/globals.h index 07653b8dea7b..581ed83fe6d0 100644 --- a/drivers/staging/unisys/visorchannel/globals.h +++ b/drivers/staging/unisys/visorchannel/globals.h @@ -25,5 +25,4 @@ #define MYDRVNAME "visorchannel" - #endif diff --git a/drivers/staging/unisys/visorchannel/visorchannel.h b/drivers/staging/unisys/visorchannel/visorchannel.h index 9a4d7b6755d1..5061edff959a 100644 --- a/drivers/staging/unisys/visorchannel/visorchannel.h +++ b/drivers/staging/unisys/visorchannel/visorchannel.h @@ -66,7 +66,7 @@ char *visorchannel_id(VISORCHANNEL *channel, char *s); char *visorchannel_zoneid(VISORCHANNEL *channel, char *s); u64 visorchannel_get_clientpartition(VISORCHANNEL *channel); uuid_le visorchannel_get_uuid(VISORCHANNEL *channel); -MEMREGION *visorchannel_get_memregion(VISORCHANNEL *channel); +struct memregion *visorchannel_get_memregion(VISORCHANNEL *channel); char *visorchannel_uuid_id(uuid_le *guid, char *s); void visorchannel_debug(VISORCHANNEL *channel, int nQueues, struct seq_file *seq, u32 off); diff --git a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c index 01a44c553500..36559d5fa673 100644 --- a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c +++ b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c @@ -29,8 +29,8 @@ #define MYDRVNAME "visorchannel" struct VISORCHANNEL_Tag { - MEMREGION *memregion; /* from visor_memregion_create() */ - CHANNEL_HEADER chan_hdr; + struct memregion *memregion; /* from visor_memregion_create() */ + struct channel_header chan_hdr; uuid_le guid; ulong size; BOOL needs_lock; @@ -38,10 +38,10 @@ struct VISORCHANNEL_Tag { spinlock_t remove_lock; struct { - SIGNAL_QUEUE_HEADER req_queue; - SIGNAL_QUEUE_HEADER rsp_queue; - SIGNAL_QUEUE_HEADER event_queue; - SIGNAL_QUEUE_HEADER ack_queue; + struct signal_queue_header req_queue; + struct signal_queue_header rsp_queue; + struct signal_queue_header event_queue; + struct signal_queue_header ack_queue; } safe_uis_queue; }; @@ -60,7 +60,7 @@ visorchannel_create_guts(HOSTADDRESS physaddr, ulong channelBytes, if (p == NULL) { ERRDRV("allocation failed: (status=0)\n"); rc = NULL; - goto Away; + goto cleanup; } p->memregion = NULL; p->needs_lock = needs_lock; @@ -70,39 +70,39 @@ visorchannel_create_guts(HOSTADDRESS physaddr, ulong channelBytes, /* prepare chan_hdr (abstraction to read/write channel memory) */ if (parent == NULL) p->memregion = - visor_memregion_create(physaddr, sizeof(CHANNEL_HEADER)); + visor_memregion_create(physaddr, + sizeof(struct channel_header)); else p->memregion = visor_memregion_create_overlapped(parent->memregion, - off, - sizeof(CHANNEL_HEADER)); + off, sizeof(struct channel_header)); if (p->memregion == NULL) { ERRDRV("visor_memregion_create failed failed: (status=0)\n"); rc = NULL; - goto Away; + goto cleanup; } if (visor_memregion_read(p->memregion, 0, &p->chan_hdr, - sizeof(CHANNEL_HEADER)) < 0) { + sizeof(struct channel_header)) < 0) { ERRDRV("visor_memregion_read failed: (status=0)\n"); rc = NULL; - goto Away; + goto cleanup; } if (channelBytes == 0) /* we had better be a CLIENT of this channel */ - channelBytes = (ulong) p->chan_hdr.Size; + channelBytes = (ulong)p->chan_hdr.size; if (uuid_le_cmp(guid, NULL_UUID_LE) == 0) /* we had better be a CLIENT of this channel */ - guid = p->chan_hdr.Type; + guid = p->chan_hdr.chtype; if (visor_memregion_resize(p->memregion, channelBytes) < 0) { ERRDRV("visor_memregion_resize failed: (status=0)\n"); rc = NULL; - goto Away; + goto cleanup; } p->size = channelBytes; p->guid = guid; rc = p; -Away: +cleanup: if (rc == NULL) { if (p != NULL) { @@ -194,14 +194,14 @@ EXPORT_SYMBOL_GPL(visorchannel_id); char * visorchannel_zoneid(VISORCHANNEL *channel, char *s) { - return visorchannel_uuid_id(&channel->chan_hdr.ZoneGuid, s); + return visorchannel_uuid_id(&channel->chan_hdr.zone_uuid, s); } EXPORT_SYMBOL_GPL(visorchannel_zoneid); HOSTADDRESS visorchannel_get_clientpartition(VISORCHANNEL *channel) { - return channel->chan_hdr.PartitionHandle; + return channel->chan_hdr.partition_handle; } EXPORT_SYMBOL_GPL(visorchannel_get_clientpartition); @@ -212,7 +212,7 @@ visorchannel_get_uuid(VISORCHANNEL *channel) } EXPORT_SYMBOL_GPL(visorchannel_get_uuid); -MEMREGION * +struct memregion * visorchannel_get_memregion(VISORCHANNEL *channel) { return channel->memregion; @@ -225,8 +225,11 @@ visorchannel_read(VISORCHANNEL *channel, ulong offset, { int rc = visor_memregion_read(channel->memregion, offset, local, nbytes); - if ((rc >= 0) && (offset == 0) && (nbytes >= sizeof(CHANNEL_HEADER))) - memcpy(&channel->chan_hdr, local, sizeof(CHANNEL_HEADER)); + if ((rc >= 0) && (offset == 0) && + (nbytes >= sizeof(struct channel_header))) { + memcpy(&channel->chan_hdr, local, + sizeof(struct channel_header)); + } return rc; } EXPORT_SYMBOL_GPL(visorchannel_read); @@ -235,8 +238,9 @@ int visorchannel_write(VISORCHANNEL *channel, ulong offset, void *local, ulong nbytes) { - if (offset == 0 && nbytes >= sizeof(CHANNEL_HEADER)) - memcpy(&channel->chan_hdr, local, sizeof(CHANNEL_HEADER)); + if (offset == 0 && nbytes >= sizeof(struct channel_header)) + memcpy(&channel->chan_hdr, local, + sizeof(struct channel_header)); return visor_memregion_write(channel->memregion, offset, local, nbytes); } EXPORT_SYMBOL_GPL(visorchannel_write); @@ -251,7 +255,7 @@ visorchannel_clear(VISORCHANNEL *channel, ulong offset, u8 ch, ulong nbytes) if (buf == NULL) { ERRDRV("%s failed memory allocation", __func__); - goto Away; + goto cleanup; } memset(buf, ch, bufsize); while (nbytes > 0) { @@ -264,14 +268,14 @@ visorchannel_clear(VISORCHANNEL *channel, ulong offset, u8 ch, ulong nbytes) buf, thisbytes); if (x < 0) { rc = x; - goto Away; + goto cleanup; } written += thisbytes; nbytes -= thisbytes; } rc = 0; -Away: +cleanup: if (buf != NULL) { vfree(buf); buf = NULL; @@ -283,7 +287,7 @@ EXPORT_SYMBOL_GPL(visorchannel_clear); void __iomem * visorchannel_get_header(VISORCHANNEL *channel) { - return (void __iomem *) &(channel->chan_hdr); + return (void __iomem *)&channel->chan_hdr; } EXPORT_SYMBOL_GPL(visorchannel_get_header); @@ -291,14 +295,15 @@ EXPORT_SYMBOL_GPL(visorchannel_get_header); * channel header */ #define SIG_QUEUE_OFFSET(chan_hdr, q) \ - ((chan_hdr)->oChannelSpace + ((q) * sizeof(SIGNAL_QUEUE_HEADER))) + ((chan_hdr)->ch_space_offset + \ + ((q) * sizeof(struct signal_queue_header))) /** Return offset of a specific queue entry (data) from the beginning of a * channel header */ #define SIG_DATA_OFFSET(chan_hdr, q, sig_hdr, slot) \ - (SIG_QUEUE_OFFSET(chan_hdr, q) + (sig_hdr)->oSignalBase + \ - ((slot) * (sig_hdr)->SignalSize)) + (SIG_QUEUE_OFFSET(chan_hdr, q) + (sig_hdr)->sig_base_offset + \ + ((slot) * (sig_hdr)->signal_size)) /** Write the contents of a specific field within a SIGNAL_QUEUE_HEADER back * into host memory @@ -306,39 +311,42 @@ EXPORT_SYMBOL_GPL(visorchannel_get_header); #define SIG_WRITE_FIELD(channel, queue, sig_hdr, FIELD) \ (visor_memregion_write(channel->memregion, \ SIG_QUEUE_OFFSET(&channel->chan_hdr, queue)+ \ - offsetof(SIGNAL_QUEUE_HEADER, FIELD), \ + offsetof(struct signal_queue_header, FIELD),\ &((sig_hdr)->FIELD), \ sizeof((sig_hdr)->FIELD)) >= 0) static BOOL sig_read_header(VISORCHANNEL *channel, u32 queue, - SIGNAL_QUEUE_HEADER *sig_hdr) + struct signal_queue_header *sig_hdr) { BOOL rc = FALSE; - if (channel->chan_hdr.oChannelSpace < sizeof(CHANNEL_HEADER)) { + if (channel->chan_hdr.ch_space_offset < sizeof(struct channel_header)) { ERRDRV("oChannelSpace too small: (status=%d)\n", rc); - goto Away; + goto cleanup; } /* Read the appropriate SIGNAL_QUEUE_HEADER into local memory. */ if (visor_memregion_read(channel->memregion, SIG_QUEUE_OFFSET(&channel->chan_hdr, queue), - sig_hdr, sizeof(SIGNAL_QUEUE_HEADER)) < 0) { + sig_hdr, + sizeof(struct signal_queue_header)) < 0) { ERRDRV("queue=%d SIG_QUEUE_OFFSET=%d", queue, (int)SIG_QUEUE_OFFSET(&channel->chan_hdr, queue)); - ERRDRV("visor_memregion_read of signal queue failed: (status=%d)\n", rc); - goto Away; + ERRDRV("visor_memregion_read of signal queue failed: (status=%d)\n", + rc); + goto cleanup; } rc = TRUE; -Away: +cleanup: return rc; } static BOOL sig_do_data(VISORCHANNEL *channel, u32 queue, - SIGNAL_QUEUE_HEADER *sig_hdr, u32 slot, void *data, BOOL is_write) + struct signal_queue_header *sig_hdr, u32 slot, void *data, + BOOL is_write) { BOOL rc = FALSE; int signal_data_offset = SIG_DATA_OFFSET(&channel->chan_hdr, queue, @@ -346,53 +354,55 @@ sig_do_data(VISORCHANNEL *channel, u32 queue, if (is_write) { if (visor_memregion_write(channel->memregion, signal_data_offset, - data, sig_hdr->SignalSize) < 0) { - ERRDRV("visor_memregion_write of signal data failed: (status=%d)\n", rc); - goto Away; + data, sig_hdr->signal_size) < 0) { + ERRDRV("visor_memregion_write of signal data failed: (status=%d)\n", + rc); + goto cleanup; } } else { if (visor_memregion_read(channel->memregion, signal_data_offset, - data, sig_hdr->SignalSize) < 0) { - ERRDRV("visor_memregion_read of signal data failed: (status=%d)\n", rc); - goto Away; + data, sig_hdr->signal_size) < 0) { + ERRDRV("visor_memregion_read of signal data failed: (status=%d)\n", + rc); + goto cleanup; } } rc = TRUE; -Away: +cleanup: return rc; } static inline BOOL sig_read_data(VISORCHANNEL *channel, u32 queue, - SIGNAL_QUEUE_HEADER *sig_hdr, u32 slot, void *data) + struct signal_queue_header *sig_hdr, u32 slot, void *data) { return sig_do_data(channel, queue, sig_hdr, slot, data, FALSE); } static inline BOOL sig_write_data(VISORCHANNEL *channel, u32 queue, - SIGNAL_QUEUE_HEADER *sig_hdr, u32 slot, void *data) + struct signal_queue_header *sig_hdr, u32 slot, void *data) { return sig_do_data(channel, queue, sig_hdr, slot, data, TRUE); } static inline unsigned char -safe_sig_queue_validate(pSIGNAL_QUEUE_HEADER psafe_sqh, - pSIGNAL_QUEUE_HEADER punsafe_sqh, +safe_sig_queue_validate(struct signal_queue_header *psafe_sqh, + struct signal_queue_header *punsafe_sqh, u32 *phead, u32 *ptail) { - if ((*phead >= psafe_sqh->MaxSignalSlots) - || (*ptail >= psafe_sqh->MaxSignalSlots)) { + if ((*phead >= psafe_sqh->max_slots) || + (*ptail >= psafe_sqh->max_slots)) { /* Choose 0 or max, maybe based on current tail value */ *phead = 0; *ptail = 0; /* Sync with client as necessary */ - punsafe_sqh->Head = *phead; - punsafe_sqh->Tail = *ptail; + punsafe_sqh->head = *phead; + punsafe_sqh->tail = *ptail; ERRDRV("safe_sig_queue_validate: head = 0x%x, tail = 0x%x, MaxSlots = 0x%x", - *phead, *ptail, psafe_sqh->MaxSignalSlots); + *phead, *ptail, psafe_sqh->max_slots); return 0; } return 1; @@ -402,41 +412,42 @@ BOOL visorchannel_signalremove(VISORCHANNEL *channel, u32 queue, void *msg) { BOOL rc = FALSE; - SIGNAL_QUEUE_HEADER sig_hdr; + struct signal_queue_header sig_hdr; if (channel->needs_lock) spin_lock(&channel->remove_lock); if (!sig_read_header(channel, queue, &sig_hdr)) { rc = FALSE; - goto Away; + goto cleanup; } - if (sig_hdr.Head == sig_hdr.Tail) { + if (sig_hdr.head == sig_hdr.tail) { rc = FALSE; /* no signals to remove */ - goto Away; + goto cleanup; } - sig_hdr.Tail = (sig_hdr.Tail + 1) % sig_hdr.MaxSignalSlots; - if (!sig_read_data(channel, queue, &sig_hdr, sig_hdr.Tail, msg)) { + sig_hdr.tail = (sig_hdr.tail + 1) % sig_hdr.max_slots; + if (!sig_read_data(channel, queue, &sig_hdr, sig_hdr.tail, msg)) { ERRDRV("sig_read_data failed: (status=%d)\n", rc); - goto Away; + goto cleanup; } - sig_hdr.NumSignalsReceived++; + sig_hdr.num_received++; /* For each data field in SIGNAL_QUEUE_HEADER that was modified, * update host memory. */ mb(); /* required for channel synch */ - if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, Tail)) { + if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail)) { ERRDRV("visor_memregion_write of Tail failed: (status=%d)\n", rc); - goto Away; + goto cleanup; } - if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, NumSignalsReceived)) { - ERRDRV("visor_memregion_write of NumSignalsReceived failed: (status=%d)\n", rc); - goto Away; + if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received)) { + ERRDRV("visor_memregion_write of NumSignalsReceived failed: (status=%d)\n", + rc); + goto cleanup; } rc = TRUE; -Away: +cleanup: if (channel->needs_lock) spin_unlock(&channel->remove_lock); @@ -448,48 +459,50 @@ BOOL visorchannel_signalinsert(VISORCHANNEL *channel, u32 queue, void *msg) { BOOL rc = FALSE; - SIGNAL_QUEUE_HEADER sig_hdr; + struct signal_queue_header sig_hdr; if (channel->needs_lock) spin_lock(&channel->insert_lock); if (!sig_read_header(channel, queue, &sig_hdr)) { rc = FALSE; - goto Away; + goto cleanup; } - sig_hdr.Head = ((sig_hdr.Head + 1) % sig_hdr.MaxSignalSlots); - if (sig_hdr.Head == sig_hdr.Tail) { - sig_hdr.NumOverflows++; - if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, NumOverflows)) { - ERRDRV("visor_memregion_write of NumOverflows failed: (status=%d)\n", rc); - goto Away; + sig_hdr.head = ((sig_hdr.head + 1) % sig_hdr.max_slots); + if (sig_hdr.head == sig_hdr.tail) { + sig_hdr.num_overflows++; + if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_overflows)) { + ERRDRV("visor_memregion_write of NumOverflows failed: (status=%d)\n", + rc); + goto cleanup; } rc = FALSE; - goto Away; + goto cleanup; } - if (!sig_write_data(channel, queue, &sig_hdr, sig_hdr.Head, msg)) { + if (!sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg)) { ERRDRV("sig_write_data failed: (status=%d)\n", rc); - goto Away; + goto cleanup; } - sig_hdr.NumSignalsSent++; + sig_hdr.num_sent++; /* For each data field in SIGNAL_QUEUE_HEADER that was modified, * update host memory. */ mb(); /* required for channel synch */ - if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, Head)) { + if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, head)) { ERRDRV("visor_memregion_write of Head failed: (status=%d)\n", rc); - goto Away; + goto cleanup; } - if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, NumSignalsSent)) { - ERRDRV("visor_memregion_write of NumSignalsSent failed: (status=%d)\n", rc); - goto Away; + if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent)) { + ERRDRV("visor_memregion_write of NumSignalsSent failed: (status=%d)\n", + rc); + goto cleanup; } rc = TRUE; -Away: +cleanup: if (channel->needs_lock) spin_unlock(&channel->insert_lock); @@ -497,59 +510,58 @@ Away: } EXPORT_SYMBOL_GPL(visorchannel_signalinsert); - int visorchannel_signalqueue_slots_avail(VISORCHANNEL *channel, u32 queue) { - SIGNAL_QUEUE_HEADER sig_hdr; + struct signal_queue_header sig_hdr; u32 slots_avail, slots_used; u32 head, tail; if (!sig_read_header(channel, queue, &sig_hdr)) return 0; - head = sig_hdr.Head; - tail = sig_hdr.Tail; + head = sig_hdr.head; + tail = sig_hdr.tail; if (head < tail) - head = head + sig_hdr.MaxSignalSlots; + head = head + sig_hdr.max_slots; slots_used = (head - tail); - slots_avail = sig_hdr.MaxSignals - slots_used; - return (int) slots_avail; + slots_avail = sig_hdr.max_signals - slots_used; + return (int)slots_avail; } EXPORT_SYMBOL_GPL(visorchannel_signalqueue_slots_avail); int visorchannel_signalqueue_max_slots(VISORCHANNEL *channel, u32 queue) { - SIGNAL_QUEUE_HEADER sig_hdr; + struct signal_queue_header sig_hdr; if (!sig_read_header(channel, queue, &sig_hdr)) return 0; - return (int) sig_hdr.MaxSignals; + return (int)sig_hdr.max_signals; } EXPORT_SYMBOL_GPL(visorchannel_signalqueue_max_slots); static void -sigqueue_debug(SIGNAL_QUEUE_HEADER *q, int which, struct seq_file *seq) +sigqueue_debug(struct signal_queue_header *q, int which, struct seq_file *seq) { seq_printf(seq, "Signal Queue #%d\n", which); - seq_printf(seq, " VersionId = %lu\n", (ulong) q->VersionId); - seq_printf(seq, " Type = %lu\n", (ulong) q->Type); + seq_printf(seq, " VersionId = %lu\n", (ulong)q->version); + seq_printf(seq, " Type = %lu\n", (ulong)q->chtype); seq_printf(seq, " oSignalBase = %llu\n", - (long long) q->oSignalBase); - seq_printf(seq, " SignalSize = %lu\n", (ulong) q->SignalSize); + (long long)q->sig_base_offset); + seq_printf(seq, " SignalSize = %lu\n", (ulong)q->signal_size); seq_printf(seq, " MaxSignalSlots = %lu\n", - (ulong) q->MaxSignalSlots); - seq_printf(seq, " MaxSignals = %lu\n", (ulong) q->MaxSignals); + (ulong)q->max_slots); + seq_printf(seq, " MaxSignals = %lu\n", (ulong)q->max_signals); seq_printf(seq, " FeatureFlags = %-16.16Lx\n", - (long long) q->FeatureFlags); + (long long)q->features); seq_printf(seq, " NumSignalsSent = %llu\n", - (long long) q->NumSignalsSent); + (long long)q->num_sent); seq_printf(seq, " NumSignalsReceived = %llu\n", - (long long) q->NumSignalsReceived); + (long long)q->num_received); seq_printf(seq, " NumOverflows = %llu\n", - (long long) q->NumOverflows); - seq_printf(seq, " Head = %lu\n", (ulong) q->Head); - seq_printf(seq, " Tail = %lu\n", (ulong) q->Tail); + (long long)q->num_overflows); + seq_printf(seq, " Head = %lu\n", (ulong)q->head); + seq_printf(seq, " Tail = %lu\n", (ulong)q->tail); } void @@ -558,9 +570,9 @@ visorchannel_debug(VISORCHANNEL *channel, int nQueues, { HOSTADDRESS addr = 0; ulong nbytes = 0, nbytes_region = 0; - MEMREGION *memregion = NULL; - CHANNEL_HEADER hdr; - CHANNEL_HEADER *phdr = &hdr; + struct memregion *memregion = NULL; + struct channel_header hdr; + struct channel_header *phdr = &hdr; int i = 0; int errcode = 0; @@ -576,7 +588,7 @@ visorchannel_debug(VISORCHANNEL *channel, int nQueues, addr = visor_memregion_get_physaddr(memregion); nbytes_region = visor_memregion_get_nbytes(memregion); errcode = visorchannel_read(channel, off, - phdr, sizeof(CHANNEL_HEADER)); + phdr, sizeof(struct channel_header)); if (errcode < 0) { seq_printf(seq, "Read of channel header failed with errcode=%d)\n", @@ -584,39 +596,41 @@ visorchannel_debug(VISORCHANNEL *channel, int nQueues, if (off == 0) { phdr = &channel->chan_hdr; seq_puts(seq, "(following data may be stale)\n"); - } else + } else { return; + } } - nbytes = (ulong) (phdr->Size); + nbytes = (ulong)(phdr->size); seq_printf(seq, "--- Begin channel @0x%-16.16Lx for 0x%lx bytes (region=0x%lx bytes) ---\n", addr + off, nbytes, nbytes_region); - seq_printf(seq, "Type = %pUL\n", &phdr->Type); - seq_printf(seq, "ZoneGuid = %pUL\n", &phdr->ZoneGuid); + seq_printf(seq, "Type = %pUL\n", &phdr->chtype); + seq_printf(seq, "ZoneGuid = %pUL\n", &phdr->zone_uuid); seq_printf(seq, "Signature = 0x%-16.16Lx\n", - (long long) phdr->Signature); - seq_printf(seq, "LegacyState = %lu\n", (ulong) phdr->LegacyState); - seq_printf(seq, "SrvState = %lu\n", (ulong) phdr->SrvState); - seq_printf(seq, "CliStateBoot = %lu\n", (ulong) phdr->CliStateBoot); - seq_printf(seq, "CliStateOS = %lu\n", (ulong) phdr->CliStateOS); - seq_printf(seq, "HeaderSize = %lu\n", (ulong) phdr->HeaderSize); - seq_printf(seq, "Size = %llu\n", (long long) phdr->Size); + (long long)phdr->signature); + seq_printf(seq, "LegacyState = %lu\n", (ulong)phdr->legacy_state); + seq_printf(seq, "SrvState = %lu\n", (ulong)phdr->srv_state); + seq_printf(seq, "CliStateBoot = %lu\n", (ulong)phdr->cli_state_boot); + seq_printf(seq, "CliStateOS = %lu\n", (ulong)phdr->cli_state_os); + seq_printf(seq, "HeaderSize = %lu\n", (ulong)phdr->header_size); + seq_printf(seq, "Size = %llu\n", (long long)phdr->size); seq_printf(seq, "Features = 0x%-16.16llx\n", - (long long) phdr->Features); + (long long)phdr->features); seq_printf(seq, "PartitionHandle = 0x%-16.16llx\n", - (long long) phdr->PartitionHandle); + (long long)phdr->partition_handle); seq_printf(seq, "Handle = 0x%-16.16llx\n", - (long long) phdr->Handle); - seq_printf(seq, "VersionId = %lu\n", (ulong) phdr->VersionId); + (long long)phdr->handle); + seq_printf(seq, "VersionId = %lu\n", (ulong)phdr->version_id); seq_printf(seq, "oChannelSpace = %llu\n", - (long long) phdr->oChannelSpace); - if ((phdr->oChannelSpace == 0) || (errcode < 0)) + (long long)phdr->ch_space_offset); + if ((phdr->ch_space_offset == 0) || (errcode < 0)) ; else for (i = 0; i < nQueues; i++) { - SIGNAL_QUEUE_HEADER q; + struct signal_queue_header q; errcode = visorchannel_read(channel, - off + phdr->oChannelSpace + + off + + phdr->ch_space_offset + (i * sizeof(q)), &q, sizeof(q)); if (errcode < 0) { @@ -643,15 +657,17 @@ visorchannel_dump_section(VISORCHANNEL *chan, char *s, fmtbufsize = 100 * COVQ(len, 16); buf = kmalloc(len, GFP_KERNEL|__GFP_NORETRY); + if (!buf) + return; fmtbuf = kmalloc(fmtbufsize, GFP_KERNEL|__GFP_NORETRY); - if (buf == NULL || fmtbuf == NULL) - goto Away; + if (!fmtbuf) + goto fmt_failed; errcode = visorchannel_read(chan, off, buf, len); if (errcode < 0) { ERRDRV("%s failed to read %s from channel errcode=%d", s, __func__, errcode); - goto Away; + goto read_failed; } seq_printf(seq, "channel %s:\n", s); tbuf = buf; @@ -663,14 +679,9 @@ visorchannel_dump_section(VISORCHANNEL *chan, char *s, len -= 16; } -Away: - if (buf != NULL) { - kfree(buf); - buf = NULL; - } - if (fmtbuf != NULL) { - kfree(fmtbuf); - fmtbuf = NULL; - } +read_failed: + kfree(fmtbuf); +fmt_failed: + kfree(buf); } EXPORT_SYMBOL_GPL(visorchannel_dump_section); diff --git a/drivers/staging/unisys/visorchipset/file.c b/drivers/staging/unisys/visorchipset/file.c index 3321764069de..373fa36b7119 100644 --- a/drivers/staging/unisys/visorchipset/file.c +++ b/drivers/staging/unisys/visorchipset/file.c @@ -155,9 +155,9 @@ visorchipset_mmap(struct file *file, struct vm_area_struct *vma) return -ENXIO; } visorchannel_read(*PControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - gpControlChannel), &addr, - sizeof(addr)); + offsetof(struct spar_controlvm_channel_protocol, + gp_control_channel), + &addr, sizeof(addr)); if (addr == 0) { ERRDRV("%s control channel address is 0", __func__); return -ENXIO; diff --git a/drivers/staging/unisys/visorchipset/parser.c b/drivers/staging/unisys/visorchipset/parser.c index 661aaae9b154..9edbd3bbd186 100644 --- a/drivers/staging/unisys/visorchipset/parser.c +++ b/drivers/staging/unisys/visorchipset/parser.c @@ -47,8 +47,8 @@ parser_init_guts(u64 addr, u32 bytes, BOOL isLocal, int allocbytes = sizeof(PARSER_CONTEXT) + bytes; PARSER_CONTEXT *rc = NULL; PARSER_CONTEXT *ctx = NULL; - MEMREGION *rgn = NULL; - ULTRA_CONTROLVM_PARAMETERS_HEADER *phdr = NULL; + struct memregion *rgn = NULL; + struct spar_controlvm_parameters_header *phdr = NULL; if (tryAgain) *tryAgain = FALSE; @@ -110,27 +110,29 @@ parser_init_guts(u64 addr, u32 bytes, BOOL isLocal, rc = ctx; goto Away; } - phdr = (ULTRA_CONTROLVM_PARAMETERS_HEADER *) (ctx->data); - if (phdr->TotalLength != bytes) { + phdr = (struct spar_controlvm_parameters_header *)(ctx->data); + if (phdr->total_length != bytes) { ERRDRV("%s - bad total length %lu (should be %lu)", __func__, - (ulong) (phdr->TotalLength), (ulong) (bytes)); + (ulong) (phdr->total_length), (ulong) (bytes)); rc = NULL; goto Away; } - if (phdr->TotalLength < phdr->HeaderLength) { + if (phdr->total_length < phdr->header_length) { ERRDRV("%s - total length < header length (%lu < %lu)", __func__, - (ulong) (phdr->TotalLength), - (ulong) (phdr->HeaderLength)); + (ulong) (phdr->total_length), + (ulong) (phdr->header_length)); rc = NULL; goto Away; } - if (phdr->HeaderLength < sizeof(ULTRA_CONTROLVM_PARAMETERS_HEADER)) { + if (phdr->header_length < + sizeof(struct spar_controlvm_parameters_header)) { ERRDRV("%s - header is too small (%lu < %lu)", __func__, - (ulong) (phdr->HeaderLength), - (ulong) (sizeof(ULTRA_CONTROLVM_PARAMETERS_HEADER))); + (ulong) (phdr->header_length), + (ulong)(sizeof( + struct spar_controlvm_parameters_header))); rc = NULL; goto Away; } @@ -159,7 +161,7 @@ parser_init(u64 addr, u32 bytes, BOOL isLocal, BOOL *tryAgain) } /* Call this instead of parser_init() if the payload area consists of just - * a sequence of bytes, rather than a ULTRA_CONTROLVM_PARAMETERS_HEADER + * a sequence of bytes, rather than a struct spar_controlvm_parameters_header * structures. Afterwards, you can call parser_simpleString_get() or * parser_byteStream_get() to obtain the data. */ @@ -196,44 +198,44 @@ parser_byteStream_get(PARSER_CONTEXT *ctx, ulong *nbytes) uuid_le parser_id_get(PARSER_CONTEXT *ctx) { - ULTRA_CONTROLVM_PARAMETERS_HEADER *phdr = NULL; + struct spar_controlvm_parameters_header *phdr = NULL; if (ctx == NULL) { ERRDRV("%s (%s:%d) - no context", __func__, __FILE__, __LINE__); return NULL_UUID_LE; } - phdr = (ULTRA_CONTROLVM_PARAMETERS_HEADER *) (ctx->data); - return phdr->Id; + phdr = (struct spar_controlvm_parameters_header *)(ctx->data); + return phdr->id; } void parser_param_start(PARSER_CONTEXT *ctx, PARSER_WHICH_STRING which_string) { - ULTRA_CONTROLVM_PARAMETERS_HEADER *phdr = NULL; + struct spar_controlvm_parameters_header *phdr = NULL; if (ctx == NULL) { ERRDRV("%s (%s:%d) - no context", __func__, __FILE__, __LINE__); goto Away; } - phdr = (ULTRA_CONTROLVM_PARAMETERS_HEADER *) (ctx->data); + phdr = (struct spar_controlvm_parameters_header *)(ctx->data); switch (which_string) { case PARSERSTRING_INITIATOR: - ctx->curr = ctx->data + phdr->InitiatorOffset; - ctx->bytes_remaining = phdr->InitiatorLength; + ctx->curr = ctx->data + phdr->initiator_offset; + ctx->bytes_remaining = phdr->initiator_length; break; case PARSERSTRING_TARGET: - ctx->curr = ctx->data + phdr->TargetOffset; - ctx->bytes_remaining = phdr->TargetLength; + ctx->curr = ctx->data + phdr->target_offset; + ctx->bytes_remaining = phdr->target_length; break; case PARSERSTRING_CONNECTION: - ctx->curr = ctx->data + phdr->ConnectionOffset; - ctx->bytes_remaining = phdr->ConnectionLength; + ctx->curr = ctx->data + phdr->connection_offset; + ctx->bytes_remaining = phdr->connection_length; break; case PARSERSTRING_NAME: - ctx->curr = ctx->data + phdr->NameOffset; - ctx->bytes_remaining = phdr->NameLength; + ctx->curr = ctx->data + phdr->name_offset; + ctx->bytes_remaining = phdr->name_length; break; default: ERRDRV("%s - bad which_string %d", __func__, which_string); diff --git a/drivers/staging/unisys/visorchipset/testing.h b/drivers/staging/unisys/visorchipset/testing.h index 015d502cbb16..573aa8b5ba6a 100644 --- a/drivers/staging/unisys/visorchipset/testing.h +++ b/drivers/staging/unisys/visorchipset/testing.h @@ -23,8 +23,9 @@ #include "globals.h" #include "controlvmchannel.h" -void test_produce_test_message(CONTROLVM_MESSAGE *msg, int isLocalTestAddr); -BOOL test_consume_test_message(CONTROLVM_MESSAGE *msg); +void test_produce_test_message(struct controlvm_message *msg, + int isLocalTestAddr); +BOOL test_consume_test_message(struct controlvm_message *msg); void test_manufacture_vnic_client_add(void *p); void test_manufacture_vnic_client_add_phys(HOSTADDRESS addr); void test_manufacture_preamble_messages(void); diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index 2bf2e2f368ef..46dad63fa2c8 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -31,85 +31,85 @@ /** Describes the state from the perspective of which controlvm messages have * been received for a bus or device. */ -typedef struct { +struct visorchipset_state { u32 created:1; u32 attached:1; u32 configured:1; u32 running:1; /* Add new fields above. */ /* Remaining bits in this 32-bit word are unused. */ -} VISORCHIPSET_STATE; +}; -typedef enum { +enum visorchipset_addresstype { /** address is guest physical, but outside of the physical memory * region that is controlled by the running OS (this is the normal * address type for Supervisor channels) */ - ADDRTYPE_localPhysical, + ADDRTYPE_LOCALPHYSICAL, /** address is guest physical, and withIN the confines of the * physical memory controlled by the running OS. */ - ADDRTYPE_localTest, -} VISORCHIPSET_ADDRESSTYPE; + ADDRTYPE_LOCALTEST, +}; -typedef enum { - CRASH_dev, - CRASH_bus, -} CRASH_OBJ_TYPE; +enum crash_obj_type { + CRASH_DEV, + CRASH_BUS, +}; /** Attributes for a particular Supervisor channel. */ -typedef struct { - VISORCHIPSET_ADDRESSTYPE addrType; - HOSTADDRESS channelAddr; - struct InterruptInfo intr; - u64 nChannelBytes; - uuid_le channelTypeGuid; - uuid_le channelInstGuid; +struct visorchipset_channel_info { + enum visorchipset_addresstype addr_type; + HOSTADDRESS channel_addr; + struct irq_info intr; + u64 n_channel_bytes; + uuid_le channel_type_uuid; + uuid_le channel_inst_uuid; -} VISORCHIPSET_CHANNEL_INFO; +}; /** Attributes for a particular Supervisor device. * Any visorchipset client can query these attributes using * visorchipset_get_client_device_info() or * visorchipset_get_server_device_info(). */ -typedef struct { +struct visorchipset_device_info { struct list_head entry; - u32 busNo; - u32 devNo; - uuid_le devInstGuid; - VISORCHIPSET_STATE state; - VISORCHIPSET_CHANNEL_INFO chanInfo; - u32 Reserved1; /* CONTROLVM_ID */ - u64 Reserved2; - u32 switchNo; /* when devState.attached==1 */ - u32 internalPortNo; /* when devState.attached==1 */ - CONTROLVM_MESSAGE_HEADER pendingMsgHdr; /* CONTROLVM_MESSAGE */ + u32 bus_no; + u32 dev_no; + uuid_le dev_inst_uuid; + struct visorchipset_state state; + struct visorchipset_channel_info chan_info; + u32 reserved1; /* control_vm_id */ + u64 reserved2; + u32 switch_no; /* when devState.attached==1 */ + u32 internal_port_no; /* when devState.attached==1 */ + struct controlvm_message_header pending_msg_hdr;/* CONTROLVM_MESSAGE */ /** For private use by the bus driver */ void *bus_driver_context; -} VISORCHIPSET_DEVICE_INFO; +}; -static inline VISORCHIPSET_DEVICE_INFO * -finddevice(struct list_head *list, u32 busNo, u32 devNo) +static inline struct visorchipset_device_info *finddevice( + struct list_head *list, u32 bus_no, u32 dev_no) { - VISORCHIPSET_DEVICE_INFO *p; + struct visorchipset_device_info *p; list_for_each_entry(p, list, entry) { - if (p->busNo == busNo && p->devNo == devNo) + if (p->bus_no == bus_no && p->dev_no == dev_no) return p; } return NULL; } -static inline void delbusdevices(struct list_head *list, u32 busNo) +static inline void delbusdevices(struct list_head *list, u32 bus_no) { - VISORCHIPSET_DEVICE_INFO *p, *tmp; + struct visorchipset_device_info *p, *tmp; list_for_each_entry_safe(p, tmp, list, entry) { - if (p->busNo == busNo) { + if (p->bus_no == bus_no) { list_del(&p->entry); kfree(p); } @@ -122,37 +122,37 @@ static inline void delbusdevices(struct list_head *list, u32 busNo) * Any visorchipset client can query these attributes using * visorchipset_get_client_bus_info() or visorchipset_get_bus_info(). */ -typedef struct { +struct visorchipset_bus_info { struct list_head entry; - u32 busNo; - VISORCHIPSET_STATE state; - VISORCHIPSET_CHANNEL_INFO chanInfo; - uuid_le partitionGuid; - u64 partitionHandle; + u32 bus_no; + struct visorchipset_state state; + struct visorchipset_channel_info chan_info; + uuid_le partition_uuid; + u64 partition_handle; u8 *name; /* UTF8 */ u8 *description; /* UTF8 */ - u64 Reserved1; - u32 Reserved2; - MYPROCOBJECT *procObject; + u64 reserved1; + u32 reserved2; + MYPROCOBJECT *proc_object; struct { u32 server:1; /* Add new fields above. */ /* Remaining bits in this 32-bit word are unused. */ } flags; - CONTROLVM_MESSAGE_HEADER pendingMsgHdr; /* CONTROLVM MsgHdr */ + struct controlvm_message_header pending_msg_hdr;/* CONTROLVM MsgHdr */ /** For private use by the bus driver */ void *bus_driver_context; - u64 devNo; + u64 dev_no; -} VISORCHIPSET_BUS_INFO; +}; -static inline VISORCHIPSET_BUS_INFO * -findbus(struct list_head *list, u32 busNo) +static inline struct visorchipset_bus_info * +findbus(struct list_head *list, u32 bus_no) { - VISORCHIPSET_BUS_INFO *p; + struct visorchipset_bus_info *p; list_for_each_entry(p, list, entry) { - if (p->busNo == busNo) + if (p->bus_no == bus_no) return p; } return NULL; @@ -160,75 +160,73 @@ findbus(struct list_head *list, u32 busNo) /** Attributes for a particular Supervisor switch. */ -typedef struct { - u32 switchNo; - VISORCHIPSET_STATE state; - uuid_le switchTypeGuid; - u8 *authService1; - u8 *authService2; - u8 *authService3; - u8 *securityContext; - u64 Reserved; - u32 Reserved2; /* CONTROLVM_ID */ +struct visorchipset_switch_info { + u32 switch_no; + struct visorchipset_state state; + uuid_le switch_type_uuid; + u8 *authservice1; + u8 *authservice2; + u8 *authservice3; + u8 *security_context; + u64 reserved; + u32 reserved2; /* control_vm_id */ struct device dev; BOOL dev_exists; - CONTROLVM_MESSAGE_HEADER pendingMsgHdr; - -} VISORCHIPSET_SWITCH_INFO; + struct controlvm_message_header pending_msg_hdr; +}; /** Attributes for a particular Supervisor external port, which is connected * to a specific switch. */ -typedef struct { - u32 switchNo; - u32 externalPortNo; - VISORCHIPSET_STATE state; - uuid_le networkZoneGuid; - int pdPort; +struct visorchipset_externalport_info { + u32 switch_no; + u32 external_port_no; + struct visorchipset_state state; + uuid_le network_zone_uuid; + int pd_port; u8 *ip; - u8 *ipNetmask; - u8 *ipBroadcast; - u8 *ipNetwork; - u8 *ipGateway; - u8 *ipDNS; - u64 Reserved1; - u32 Reserved2; /* CONTROLVM_ID */ + u8 *ip_netmask; + u8 *ip_broadcast; + u8 *ip_network; + u8 *ip_gateway; + u8 *ip_dns; + u64 reserved1; + u32 reserved2; /* control_vm_id */ struct device dev; BOOL dev_exists; - CONTROLVM_MESSAGE_HEADER pendingMsgHdr; - -} VISORCHIPSET_EXTERNALPORT_INFO; + struct controlvm_message_header pending_msg_hdr; +}; /** Attributes for a particular Supervisor internal port, which is how a * device connects to a particular switch. */ -typedef struct { - u32 switchNo; - u32 internalPortNo; - VISORCHIPSET_STATE state; - u32 busNo; /* valid only when state.attached == 1 */ - u32 devNo; /* valid only when state.attached == 1 */ - u64 Reserved1; - u32 Reserved2; /* CONTROLVM_ID */ - CONTROLVM_MESSAGE_HEADER pendingMsgHdr; - MYPROCOBJECT *procObject; - -} VISORCHIPSET_INTERNALPORT_INFO; +struct visorchipset_internalport_info { + u32 switch_no; + u32 internal_port_no; + struct visorchipset_state state; + u32 bus_no; /* valid only when state.attached == 1 */ + u32 dev_no; /* valid only when state.attached == 1 */ + u64 reserved1; + u32 reserved2; /* CONTROLVM_ID */ + struct controlvm_message_header pending_msg_hdr; + MYPROCOBJECT *proc_object; + +}; /* These functions will be called from within visorchipset when certain * events happen. (The implementation of these functions is outside of * visorchipset.) */ -typedef struct { - void (*bus_create)(ulong busNo); - void (*bus_destroy)(ulong busNo); - void (*device_create)(ulong busNo, ulong devNo); - void (*device_destroy)(ulong busNo, ulong devNo); - void (*device_pause)(ulong busNo, ulong devNo); - void (*device_resume)(ulong busNo, ulong devNo); - int (*get_channel_info)(uuid_le typeGuid, ulong *minSize, - ulong *maxSize); -} VISORCHIPSET_BUSDEV_NOTIFIERS; +struct visorchipset_busdev_notifiers { + void (*bus_create)(ulong bus_no); + void (*bus_destroy)(ulong bus_no); + void (*device_create)(ulong bus_no, ulong dev_no); + void (*device_destroy)(ulong bus_no, ulong dev_no); + void (*device_pause)(ulong bus_no, ulong dev_no); + void (*device_resume)(ulong bus_no, ulong dev_no); + int (*get_channel_info)(uuid_le type_uuid, ulong *min_size, + ulong *max_size); +}; /* These functions live inside visorchipset, and will be called to indicate * responses to specific events (by code outside of visorchipset). @@ -236,14 +234,14 @@ typedef struct { * 0 = it worked * -1 = it failed */ -typedef struct { - void (*bus_create)(ulong busNo, int response); - void (*bus_destroy)(ulong busNo, int response); - void (*device_create)(ulong busNo, ulong devNo, int response); - void (*device_destroy)(ulong busNo, ulong devNo, int response); - void (*device_pause)(ulong busNo, ulong devNo, int response); - void (*device_resume)(ulong busNo, ulong devNo, int response); -} VISORCHIPSET_BUSDEV_RESPONDERS; +struct visorchipset_busdev_responders { + void (*bus_create)(ulong bus_no, int response); + void (*bus_destroy)(ulong bus_no, int response); + void (*device_create)(ulong bus_no, ulong dev_no, int response); + void (*device_destroy)(ulong bus_no, ulong dev_no, int response); + void (*device_pause)(ulong bus_no, ulong dev_no, int response); + void (*device_resume)(ulong bus_no, ulong dev_no, int response); +}; /** Register functions (in the bus driver) to get called by visorchipset * whenever a bus or device appears for which this service partition is @@ -252,9 +250,10 @@ typedef struct { * responses. */ void -visorchipset_register_busdev_client(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, - VISORCHIPSET_BUSDEV_RESPONDERS *responders, - ULTRA_VBUS_DEVICEINFO *driverInfo); +visorchipset_register_busdev_client( + struct visorchipset_busdev_notifiers *notifiers, + struct visorchipset_busdev_responders *responders, + struct ultra_vbus_deviceinfo *driver_info); /** Register functions (in the bus driver) to get called by visorchipset * whenever a bus or device appears for which this service partition is @@ -263,47 +262,31 @@ visorchipset_register_busdev_client(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, * responses. */ void -visorchipset_register_busdev_server(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, - VISORCHIPSET_BUSDEV_RESPONDERS *responders, - ULTRA_VBUS_DEVICEINFO *driverInfo); +visorchipset_register_busdev_server( + struct visorchipset_busdev_notifiers *notifiers, + struct visorchipset_busdev_responders *responders, + struct ultra_vbus_deviceinfo *driver_info); -typedef void (*SPARREPORTEVENT_COMPLETE_FUNC) (CONTROLVM_MESSAGE *msg, +typedef void (*SPARREPORTEVENT_COMPLETE_FUNC) (struct controlvm_message *msg, int status); -void visorchipset_device_pause_response(ulong busNo, ulong devNo, int response); +void visorchipset_device_pause_response(ulong bus_no, ulong dev_no, + int response); -BOOL visorchipset_get_bus_info(ulong busNo, VISORCHIPSET_BUS_INFO *busInfo); -BOOL visorchipset_get_device_info(ulong busNo, ulong devNo, - VISORCHIPSET_DEVICE_INFO *devInfo); -BOOL visorchipset_get_switch_info(ulong switchNo, - VISORCHIPSET_SWITCH_INFO *switchInfo); -BOOL visorchipset_get_externalport_info(ulong switchNo, ulong externalPortNo, - VISORCHIPSET_EXTERNALPORT_INFO - *externalPortInfo); -BOOL visorchipset_set_bus_context(ulong busNo, void *context); -BOOL visorchipset_set_device_context(ulong busNo, ulong devNo, void *context); +BOOL visorchipset_get_bus_info(ulong bus_no, + struct visorchipset_bus_info *bus_info); +BOOL visorchipset_get_device_info(ulong bus_no, ulong dev_no, + struct visorchipset_device_info *dev_info); +BOOL visorchipset_set_bus_context(ulong bus_no, void *context); +BOOL visorchipset_set_device_context(ulong bus_no, ulong dev_no, void *context); int visorchipset_chipset_ready(void); int visorchipset_chipset_selftest(void); int visorchipset_chipset_notready(void); -void visorchipset_controlvm_respond_reportEvent(CONTROLVM_MESSAGE *msg, - void *payload); -void visorchipset_save_message(CONTROLVM_MESSAGE *msg, CRASH_OBJ_TYPE type); +void visorchipset_save_message(struct controlvm_message *msg, + enum crash_obj_type type); void *visorchipset_cache_alloc(struct kmem_cache *pool, BOOL ok_to_block, char *fn, int ln); void visorchipset_cache_free(struct kmem_cache *pool, void *p, char *fn, int ln); -#if defined(TRANSMITFILE_DEBUG) || defined(DEBUG) -#define DBG_GETFILE_PAYLOAD(msg, controlvm_header) \ - LOGINF(msg, \ - (ulong)controlvm_header.PayloadVmOffset, \ - (ulong)controlvm_header.PayloadMaxBytes) -#define DBG_GETFILE(fmt, ...) LOGINF(fmt, ##__VA_ARGS__) -#define DBG_PUTFILE(fmt, ...) LOGINF(fmt, ##__VA_ARGS__) -#else -#define DBG_GETFILE_PAYLOAD(msg, controlvm_header) -#define DBG_GETFILE(fmt, ...) -#define DBG_PUTFILE(fmt, ...) -#endif - #endif diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index e5df39554a1a..7e6be32cf7bb 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -72,26 +72,28 @@ static struct workqueue_struct *Periodic_controlvm_workqueue; static DEFINE_SEMAPHORE(NotifierLock); typedef struct { - CONTROLVM_MESSAGE message; + struct controlvm_message message; unsigned int crc; } MESSAGE_ENVELOPE; -static CONTROLVM_MESSAGE_HEADER g_DiagMsgHdr; -static CONTROLVM_MESSAGE_HEADER g_ChipSetMsgHdr; -static CONTROLVM_MESSAGE_HEADER g_DelDumpMsgHdr; +static struct controlvm_message_header g_DiagMsgHdr; +static struct controlvm_message_header g_ChipSetMsgHdr; +static struct controlvm_message_header g_DelDumpMsgHdr; static const uuid_le UltraDiagPoolChannelProtocolGuid = - ULTRA_DIAG_POOL_CHANNEL_PROTOCOL_GUID; + SPAR_DIAG_POOL_CHANNEL_PROTOCOL_UUID; /* 0xffffff is an invalid Bus/Device number */ static ulong g_diagpoolBusNo = 0xffffff; static ulong g_diagpoolDevNo = 0xffffff; -static CONTROLVM_MESSAGE_PACKET g_DeviceChangeStatePacket; +static struct controlvm_message_packet g_DeviceChangeStatePacket; /* Only VNIC and VHBA channels are sent to visorclientbus (aka * "visorhackbus") */ #define FOR_VISORHACKBUS(channel_type_guid) \ - (((uuid_le_cmp(channel_type_guid, UltraVnicChannelProtocolGuid) == 0)\ - || (uuid_le_cmp(channel_type_guid, UltraVhbaChannelProtocolGuid) == 0))) + (((uuid_le_cmp(channel_type_guid,\ + spar_vnic_channel_protocol_uuid) == 0)\ + || (uuid_le_cmp(channel_type_guid,\ + spar_vhba_channel_protocol_uuid) == 0))) #define FOR_VISORBUS(channel_type_guid) (!(FOR_VISORHACKBUS(channel_type_guid))) #define is_diagpool_channel(channel_type_guid) \ @@ -112,12 +114,12 @@ typedef struct { /* Manages the request payload in the controlvm channel */ static CONTROLVM_PAYLOAD_INFO ControlVm_payload_info; -static pCHANNEL_HEADER Test_Vnic_channel; +static struct channel_header *Test_Vnic_channel; typedef struct { - CONTROLVM_MESSAGE_HEADER Dumpcapture_header; - CONTROLVM_MESSAGE_HEADER Gettextdump_header; - CONTROLVM_MESSAGE_HEADER Dumpcomplete_header; + struct controlvm_message_header Dumpcapture_header; + struct controlvm_message_header Gettextdump_header; + struct controlvm_message_header Dumpcomplete_header; BOOL Gettextdump_outstanding; u32 crc32; ulong length; @@ -134,7 +136,7 @@ static LIVEDUMP_INFO LiveDump_info; * this scenario, we simply stash the controlvm message, then attempt to * process it again the next time controlvm_periodic_work() runs. */ -static CONTROLVM_MESSAGE ControlVm_Pending_Msg; +static struct controlvm_message ControlVm_Pending_Msg; static BOOL ControlVm_Pending_Msg_Valid = FALSE; /* Pool of struct putfile_buffer_entry, for keeping track of pending (incoming) @@ -180,7 +182,7 @@ struct putfile_request { u64 sig; /* PUTFILE_REQUEST_SIG */ /* header from original TransmitFile request */ - CONTROLVM_MESSAGE_HEADER controlvm_header; + struct controlvm_message_header controlvm_header; u64 file_request_number; /* from original TransmitFile request */ /* link to next struct putfile_request */ @@ -218,7 +220,7 @@ struct parahotplug_request { struct list_head list; int id; unsigned long expiration; - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; }; static LIST_HEAD(Parahotplug_request_list); @@ -228,8 +230,8 @@ static void parahotplug_process_list(void); /* Manages the info for a CONTROLVM_DUMP_CAPTURESTATE / * CONTROLVM_REPORTEVENT. */ -static VISORCHIPSET_BUSDEV_NOTIFIERS BusDev_Server_Notifiers; -static VISORCHIPSET_BUSDEV_NOTIFIERS BusDev_Client_Notifiers; +static struct visorchipset_busdev_notifiers BusDev_Server_Notifiers; +static struct visorchipset_busdev_notifiers BusDev_Client_Notifiers; static void bus_create_response(ulong busNo, int response); static void bus_destroy_response(ulong busNo, int response); @@ -237,7 +239,7 @@ static void device_create_response(ulong busNo, ulong devNo, int response); static void device_destroy_response(ulong busNo, ulong devNo, int response); static void device_resume_response(ulong busNo, ulong devNo, int response); -static VISORCHIPSET_BUSDEV_RESPONDERS BusDev_Responders = { +static struct visorchipset_busdev_responders BusDev_Responders = { .bus_create = bus_create_response, .bus_destroy = bus_destroy_response, .device_create = device_create_response, @@ -342,13 +344,14 @@ static struct platform_device Visorchipset_platform_device = { }; /* Function prototypes */ -static void controlvm_respond(CONTROLVM_MESSAGE_HEADER *msgHdr, int response); -static void controlvm_respond_chipset_init(CONTROLVM_MESSAGE_HEADER *msgHdr, - int response, - ULTRA_CHIPSET_FEATURE features); -static void controlvm_respond_physdev_changestate(CONTROLVM_MESSAGE_HEADER * - msgHdr, int response, - ULTRA_SEGMENT_STATE state); +static void controlvm_respond(struct controlvm_message_header *msgHdr, + int response); +static void controlvm_respond_chipset_init( + struct controlvm_message_header *msgHdr, int response, + enum ultra_chipset_feature features); +static void controlvm_respond_physdev_changestate( + struct controlvm_message_header *msgHdr, int response, + struct spar_segment_state state); static ssize_t toolaction_show(struct device *dev, struct device_attribute *attr, @@ -357,8 +360,8 @@ static ssize_t toolaction_show(struct device *dev, u8 toolAction; visorchannel_read(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - ToolAction), &toolAction, sizeof(u8)); + offsetof(struct spar_controlvm_channel_protocol, + tool_action), &toolAction, sizeof(u8)); return scnprintf(buf, PAGE_SIZE, "%u\n", toolAction); } @@ -373,7 +376,7 @@ static ssize_t toolaction_store(struct device *dev, return -EINVAL; ret = visorchannel_write(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, ToolAction), + offsetof(struct spar_controlvm_channel_protocol, tool_action), &toolAction, sizeof(u8)); if (ret) @@ -385,14 +388,14 @@ static ssize_t boottotool_show(struct device *dev, struct device_attribute *attr, char *buf) { - ULTRA_EFI_SPAR_INDICATION efiSparIndication; + struct efi_spar_indication efiSparIndication; visorchannel_read(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - EfiSparIndication), &efiSparIndication, - sizeof(ULTRA_EFI_SPAR_INDICATION)); + offsetof(struct spar_controlvm_channel_protocol, + efi_spar_ind), &efiSparIndication, + sizeof(struct efi_spar_indication)); return scnprintf(buf, PAGE_SIZE, "%u\n", - efiSparIndication.BootToTool); + efiSparIndication.boot_to_tool); } static ssize_t boottotool_store(struct device *dev, @@ -400,17 +403,17 @@ static ssize_t boottotool_store(struct device *dev, const char *buf, size_t count) { int val, ret; - ULTRA_EFI_SPAR_INDICATION efiSparIndication; + struct efi_spar_indication efiSparIndication; if (kstrtoint(buf, 10, &val) != 0) return -EINVAL; - efiSparIndication.BootToTool = val; + efiSparIndication.boot_to_tool = val; ret = visorchannel_write(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - EfiSparIndication), + offsetof(struct spar_controlvm_channel_protocol, + efi_spar_ind), &(efiSparIndication), - sizeof(ULTRA_EFI_SPAR_INDICATION)); + sizeof(struct efi_spar_indication)); if (ret) return ret; @@ -423,7 +426,7 @@ static ssize_t error_show(struct device *dev, struct device_attribute *attr, u32 error; visorchannel_read(ControlVm_channel, offsetof( - ULTRA_CONTROLVM_CHANNEL_PROTOCOL, InstallationError), + struct spar_controlvm_channel_protocol, installation_error), &error, sizeof(u32)); return scnprintf(buf, PAGE_SIZE, "%i\n", error); } @@ -438,8 +441,8 @@ static ssize_t error_store(struct device *dev, struct device_attribute *attr, return -EINVAL; ret = visorchannel_write(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - InstallationError), + offsetof(struct spar_controlvm_channel_protocol, + installation_error), &error, sizeof(u32)); if (ret) return ret; @@ -452,7 +455,7 @@ static ssize_t textid_show(struct device *dev, struct device_attribute *attr, u32 textId; visorchannel_read(ControlVm_channel, offsetof( - ULTRA_CONTROLVM_CHANNEL_PROTOCOL, InstallationTextId), + struct spar_controlvm_channel_protocol, installation_text_id), &textId, sizeof(u32)); return scnprintf(buf, PAGE_SIZE, "%i\n", textId); } @@ -467,8 +470,8 @@ static ssize_t textid_store(struct device *dev, struct device_attribute *attr, return -EINVAL; ret = visorchannel_write(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - InstallationTextId), + offsetof(struct spar_controlvm_channel_protocol, + installation_text_id), &textId, sizeof(u32)); if (ret) return ret; @@ -482,8 +485,8 @@ static ssize_t remaining_steps_show(struct device *dev, u16 remainingSteps; visorchannel_read(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - InstallationRemainingSteps), + offsetof(struct spar_controlvm_channel_protocol, + installation_remaining_steps), &remainingSteps, sizeof(u16)); return scnprintf(buf, PAGE_SIZE, "%hu\n", remainingSteps); @@ -499,8 +502,8 @@ static ssize_t remaining_steps_store(struct device *dev, return -EINVAL; ret = visorchannel_write(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - InstallationRemainingSteps), + offsetof(struct spar_controlvm_channel_protocol, + installation_remaining_steps), &remainingSteps, sizeof(u16)); if (ret) return ret; @@ -539,11 +542,11 @@ testUnicode(void) static void busInfo_clear(void *v) { - VISORCHIPSET_BUS_INFO *p = (VISORCHIPSET_BUS_INFO *) (v); + struct visorchipset_bus_info *p = (struct visorchipset_bus_info *) (v); - if (p->procObject) { - visor_proc_DestroyObject(p->procObject); - p->procObject = NULL; + if (p->proc_object) { + visor_proc_DestroyObject(p->proc_object); + p->proc_object = NULL; } kfree(p->name); p->name = NULL; @@ -552,16 +555,17 @@ busInfo_clear(void *v) p->description = NULL; p->state.created = 0; - memset(p, 0, sizeof(VISORCHIPSET_BUS_INFO)); + memset(p, 0, sizeof(struct visorchipset_bus_info)); } static void devInfo_clear(void *v) { - VISORCHIPSET_DEVICE_INFO *p = (VISORCHIPSET_DEVICE_INFO *) (v); + struct visorchipset_device_info *p = + (struct visorchipset_device_info *)(v); p->state.created = 0; - memset(p, 0, sizeof(VISORCHIPSET_DEVICE_INFO)); + memset(p, 0, sizeof(struct visorchipset_device_info)); } static u8 @@ -585,9 +589,10 @@ clear_chipset_events(void) } void -visorchipset_register_busdev_server(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, - VISORCHIPSET_BUSDEV_RESPONDERS *responders, - ULTRA_VBUS_DEVICEINFO *driverInfo) +visorchipset_register_busdev_server( + struct visorchipset_busdev_notifiers *notifiers, + struct visorchipset_busdev_responders *responders, + struct ultra_vbus_deviceinfo *driver_info) { down(&NotifierLock); if (notifiers == NULL) { @@ -600,8 +605,8 @@ visorchipset_register_busdev_server(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, } if (responders) *responders = BusDev_Responders; - if (driverInfo) - bus_device_info_init(driverInfo, "chipset", "visorchipset", + if (driver_info) + bus_device_info_init(driver_info, "chipset", "visorchipset", VERSION, NULL); up(&NotifierLock); @@ -609,9 +614,10 @@ visorchipset_register_busdev_server(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, EXPORT_SYMBOL_GPL(visorchipset_register_busdev_server); void -visorchipset_register_busdev_client(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, - VISORCHIPSET_BUSDEV_RESPONDERS *responders, - ULTRA_VBUS_DEVICEINFO *driverInfo) +visorchipset_register_busdev_client( + struct visorchipset_busdev_notifiers *notifiers, + struct visorchipset_busdev_responders *responders, + struct ultra_vbus_deviceinfo *driver_info) { down(&NotifierLock); if (notifiers == NULL) { @@ -624,9 +630,9 @@ visorchipset_register_busdev_client(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, } if (responders) *responders = BusDev_Responders; - if (driverInfo) - bus_device_info_init(driverInfo, "chipset(bolts)", "visorchipset", - VERSION, NULL); + if (driver_info) + bus_device_info_init(driver_info, "chipset(bolts)", + "visorchipset", VERSION, NULL); up(&NotifierLock); } EXPORT_SYMBOL_GPL(visorchipset_register_busdev_client); @@ -634,8 +640,8 @@ EXPORT_SYMBOL_GPL(visorchipset_register_busdev_client); static void cleanup_controlvm_structures(void) { - VISORCHIPSET_BUS_INFO *bi, *tmp_bi; - VISORCHIPSET_DEVICE_INFO *di, *tmp_di; + struct visorchipset_bus_info *bi, *tmp_bi; + struct visorchipset_device_info *di, *tmp_di; list_for_each_entry_safe(bi, tmp_bi, &BusInfoList, entry) { busInfo_clear(bi); @@ -651,10 +657,10 @@ cleanup_controlvm_structures(void) } static void -chipset_init(CONTROLVM_MESSAGE *inmsg) +chipset_init(struct controlvm_message *inmsg) { static int chipset_inited; - ULTRA_CHIPSET_FEATURE features = 0; + enum ultra_chipset_feature features = 0; int rc = CONTROLVM_RESP_SUCCESS; POSTCODE_LINUX_2(CHIPSET_INIT_ENTRY_PC, POSTCODE_SEVERITY_INFO); @@ -669,7 +675,7 @@ chipset_init(CONTROLVM_MESSAGE *inmsg) /* Set features to indicate we support parahotplug (if Command * also supports it). */ features = - inmsg->cmd.initChipset. + inmsg->cmd.init_chipset. features & ULTRA_CHIPSET_FEATURE_PARA_HOTPLUG; /* Set the "reply" bit so Command knows this is a @@ -679,42 +685,42 @@ chipset_init(CONTROLVM_MESSAGE *inmsg) Away: if (rc < 0) cleanup_controlvm_structures(); - if (inmsg->hdr.Flags.responseExpected) + if (inmsg->hdr.flags.response_expected) controlvm_respond_chipset_init(&inmsg->hdr, rc, features); } static void -controlvm_init_response(CONTROLVM_MESSAGE *msg, - CONTROLVM_MESSAGE_HEADER *msgHdr, int response) -{ - memset(msg, 0, sizeof(CONTROLVM_MESSAGE)); - memcpy(&msg->hdr, msgHdr, sizeof(CONTROLVM_MESSAGE_HEADER)); - msg->hdr.PayloadBytes = 0; - msg->hdr.PayloadVmOffset = 0; - msg->hdr.PayloadMaxBytes = 0; +controlvm_init_response(struct controlvm_message *msg, + struct controlvm_message_header *msgHdr, int response) +{ + memset(msg, 0, sizeof(struct controlvm_message)); + memcpy(&msg->hdr, msgHdr, sizeof(struct controlvm_message_header)); + msg->hdr.payload_bytes = 0; + msg->hdr.payload_vm_offset = 0; + msg->hdr.payload_max_bytes = 0; if (response < 0) { - msg->hdr.Flags.failed = 1; - msg->hdr.CompletionStatus = (u32) (-response); + msg->hdr.flags.failed = 1; + msg->hdr.completion_status = (u32) (-response); } } static void -controlvm_respond(CONTROLVM_MESSAGE_HEADER *msgHdr, int response) +controlvm_respond(struct controlvm_message_header *msgHdr, int response) { - CONTROLVM_MESSAGE outmsg; + struct controlvm_message outmsg; controlvm_init_response(&outmsg, msgHdr, response); /* For DiagPool channel DEVICE_CHANGESTATE, we need to send * back the deviceChangeState structure in the packet. */ - if (msgHdr->Id == CONTROLVM_DEVICE_CHANGESTATE - && g_DeviceChangeStatePacket.deviceChangeState.busNo == + if (msgHdr->id == CONTROLVM_DEVICE_CHANGESTATE + && g_DeviceChangeStatePacket.device_change_state.bus_no == g_diagpoolBusNo - && g_DeviceChangeStatePacket.deviceChangeState.devNo == + && g_DeviceChangeStatePacket.device_change_state.dev_no == g_diagpoolDevNo) outmsg.cmd = g_DeviceChangeStatePacket; - if (outmsg.hdr.Flags.testMessage == 1) { + if (outmsg.hdr.flags.test_message == 1) { LOGINF("%s controlvm_msg=0x%x response=%d for test message", - __func__, outmsg.hdr.Id, response); + __func__, outmsg.hdr.id, response); return; } if (!visorchannel_signalinsert(ControlVm_channel, @@ -725,13 +731,14 @@ controlvm_respond(CONTROLVM_MESSAGE_HEADER *msgHdr, int response) } static void -controlvm_respond_chipset_init(CONTROLVM_MESSAGE_HEADER *msgHdr, int response, - ULTRA_CHIPSET_FEATURE features) +controlvm_respond_chipset_init(struct controlvm_message_header *msgHdr, + int response, + enum ultra_chipset_feature features) { - CONTROLVM_MESSAGE outmsg; + struct controlvm_message outmsg; controlvm_init_response(&outmsg, msgHdr, response); - outmsg.cmd.initChipset.features = features; + outmsg.cmd.init_chipset.features = features; if (!visorchannel_signalinsert(ControlVm_channel, CONTROLVM_QUEUE_REQUEST, &outmsg)) { LOGERR("signalinsert failed!"); @@ -739,15 +746,15 @@ controlvm_respond_chipset_init(CONTROLVM_MESSAGE_HEADER *msgHdr, int response, } } -static void -controlvm_respond_physdev_changestate(CONTROLVM_MESSAGE_HEADER *msgHdr, - int response, ULTRA_SEGMENT_STATE state) +static void controlvm_respond_physdev_changestate( + struct controlvm_message_header *msgHdr, int response, + struct spar_segment_state state) { - CONTROLVM_MESSAGE outmsg; + struct controlvm_message outmsg; controlvm_init_response(&outmsg, msgHdr, response); - outmsg.cmd.deviceChangeState.state = state; - outmsg.cmd.deviceChangeState.flags.physicalDevice = 1; + outmsg.cmd.device_change_state.state = state; + outmsg.cmd.device_change_state.flags.phys_device = 1; if (!visorchannel_signalinsert(ControlVm_channel, CONTROLVM_QUEUE_REQUEST, &outmsg)) { LOGERR("signalinsert failed!"); @@ -756,15 +763,16 @@ controlvm_respond_physdev_changestate(CONTROLVM_MESSAGE_HEADER *msgHdr, } void -visorchipset_save_message(CONTROLVM_MESSAGE *msg, CRASH_OBJ_TYPE type) +visorchipset_save_message(struct controlvm_message *msg, + enum crash_obj_type type) { u32 localSavedCrashMsgOffset; u16 localSavedCrashMsgCount; /* get saved message count */ if (visorchannel_read(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - SavedCrashMsgCount), + offsetof(struct spar_controlvm_channel_protocol, + saved_crash_message_count), &localSavedCrashMsgCount, sizeof(u16)) < 0) { LOGERR("failed to get Saved Message Count"); POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, @@ -783,8 +791,8 @@ visorchipset_save_message(CONTROLVM_MESSAGE *msg, CRASH_OBJ_TYPE type) /* get saved crash message offset */ if (visorchannel_read(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - SavedCrashMsgOffset), + offsetof(struct spar_controlvm_channel_protocol, + saved_crash_message_offset), &localSavedCrashMsgOffset, sizeof(u32)) < 0) { LOGERR("failed to get Saved Message Offset"); POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, @@ -792,10 +800,11 @@ visorchipset_save_message(CONTROLVM_MESSAGE *msg, CRASH_OBJ_TYPE type) return; } - if (type == CRASH_bus) { + if (type == CRASH_BUS) { if (visorchannel_write(ControlVm_channel, localSavedCrashMsgOffset, - msg, sizeof(CONTROLVM_MESSAGE)) < 0) { + msg, + sizeof(struct controlvm_message)) < 0) { LOGERR("SAVE_MSG_BUS_FAILURE: Failed to write CrashCreateBusMsg!"); POSTCODE_LINUX_2(SAVE_MSG_BUS_FAILURE_PC, POSTCODE_SEVERITY_ERR); @@ -804,8 +813,8 @@ visorchipset_save_message(CONTROLVM_MESSAGE *msg, CRASH_OBJ_TYPE type) } else { if (visorchannel_write(ControlVm_channel, localSavedCrashMsgOffset + - sizeof(CONTROLVM_MESSAGE), msg, - sizeof(CONTROLVM_MESSAGE)) < 0) { + sizeof(struct controlvm_message), msg, + sizeof(struct controlvm_message)) < 0) { LOGERR("SAVE_MSG_DEV_FAILURE: Failed to write CrashCreateDevMsg!"); POSTCODE_LINUX_2(SAVE_MSG_DEV_FAILURE_PC, POSTCODE_SEVERITY_ERR); @@ -816,9 +825,9 @@ visorchipset_save_message(CONTROLVM_MESSAGE *msg, CRASH_OBJ_TYPE type) EXPORT_SYMBOL_GPL(visorchipset_save_message); static void -bus_responder(CONTROLVM_ID cmdId, ulong busNo, int response) +bus_responder(enum controlvm_id cmdId, ulong busNo, int response) { - VISORCHIPSET_BUS_INFO *p = NULL; + struct visorchipset_bus_info *p = NULL; BOOL need_clear = FALSE; p = findbus(&BusInfoList, busNo); @@ -838,16 +847,16 @@ bus_responder(CONTROLVM_ID cmdId, ulong busNo, int response) need_clear = TRUE; } - if (p->pendingMsgHdr.Id == CONTROLVM_INVALID) { + if (p->pending_msg_hdr.id == CONTROLVM_INVALID) { LOGERR("bus_responder no pending msg"); return; /* no controlvm response needed */ } - if (p->pendingMsgHdr.Id != (u32) cmdId) { - LOGERR("expected=%d, found=%d", cmdId, p->pendingMsgHdr.Id); + if (p->pending_msg_hdr.id != (u32) cmdId) { + LOGERR("expected=%d, found=%d", cmdId, p->pending_msg_hdr.id); return; } - controlvm_respond(&p->pendingMsgHdr, response); - p->pendingMsgHdr.Id = CONTROLVM_INVALID; + controlvm_respond(&p->pending_msg_hdr, response); + p->pending_msg_hdr.id = CONTROLVM_INVALID; if (need_clear) { busInfo_clear(p); delbusdevices(&DevInfoList, busNo); @@ -855,32 +864,32 @@ bus_responder(CONTROLVM_ID cmdId, ulong busNo, int response) } static void -device_changestate_responder(CONTROLVM_ID cmdId, +device_changestate_responder(enum controlvm_id cmdId, ulong busNo, ulong devNo, int response, - ULTRA_SEGMENT_STATE responseState) + struct spar_segment_state responseState) { - VISORCHIPSET_DEVICE_INFO *p = NULL; - CONTROLVM_MESSAGE outmsg; + struct visorchipset_device_info *p = NULL; + struct controlvm_message outmsg; p = finddevice(&DevInfoList, busNo, devNo); if (!p) { LOGERR("internal error; busNo=%lu, devNo=%lu", busNo, devNo); return; } - if (p->pendingMsgHdr.Id == CONTROLVM_INVALID) { + if (p->pending_msg_hdr.id == CONTROLVM_INVALID) { LOGERR("device_responder no pending msg"); return; /* no controlvm response needed */ } - if (p->pendingMsgHdr.Id != cmdId) { - LOGERR("expected=%d, found=%d", cmdId, p->pendingMsgHdr.Id); + if (p->pending_msg_hdr.id != cmdId) { + LOGERR("expected=%d, found=%d", cmdId, p->pending_msg_hdr.id); return; } - controlvm_init_response(&outmsg, &p->pendingMsgHdr, response); + controlvm_init_response(&outmsg, &p->pending_msg_hdr, response); - outmsg.cmd.deviceChangeState.busNo = busNo; - outmsg.cmd.deviceChangeState.devNo = devNo; - outmsg.cmd.deviceChangeState.state = responseState; + outmsg.cmd.device_change_state.bus_no = busNo; + outmsg.cmd.device_change_state.dev_no = devNo; + outmsg.cmd.device_change_state.state = responseState; if (!visorchannel_signalinsert(ControlVm_channel, CONTROLVM_QUEUE_REQUEST, &outmsg)) { @@ -888,13 +897,14 @@ device_changestate_responder(CONTROLVM_ID cmdId, return; } - p->pendingMsgHdr.Id = CONTROLVM_INVALID; + p->pending_msg_hdr.id = CONTROLVM_INVALID; } static void -device_responder(CONTROLVM_ID cmdId, ulong busNo, ulong devNo, int response) +device_responder(enum controlvm_id cmdId, ulong busNo, ulong devNo, + int response) { - VISORCHIPSET_DEVICE_INFO *p = NULL; + struct visorchipset_device_info *p = NULL; BOOL need_clear = FALSE; p = finddevice(&DevInfoList, busNo, devNo); @@ -909,38 +919,38 @@ device_responder(CONTROLVM_ID cmdId, ulong busNo, ulong devNo, int response) need_clear = TRUE; } - if (p->pendingMsgHdr.Id == CONTROLVM_INVALID) { + if (p->pending_msg_hdr.id == CONTROLVM_INVALID) { LOGERR("device_responder no pending msg"); return; /* no controlvm response needed */ } - if (p->pendingMsgHdr.Id != (u32) cmdId) { - LOGERR("expected=%d, found=%d", cmdId, p->pendingMsgHdr.Id); + if (p->pending_msg_hdr.id != (u32) cmdId) { + LOGERR("expected=%d, found=%d", cmdId, p->pending_msg_hdr.id); return; } - controlvm_respond(&p->pendingMsgHdr, response); - p->pendingMsgHdr.Id = CONTROLVM_INVALID; + controlvm_respond(&p->pending_msg_hdr, response); + p->pending_msg_hdr.id = CONTROLVM_INVALID; if (need_clear) devInfo_clear(p); } static void bus_epilog(u32 busNo, - u32 cmd, CONTROLVM_MESSAGE_HEADER *msgHdr, + u32 cmd, struct controlvm_message_header *msgHdr, int response, BOOL needResponse) { BOOL notified = FALSE; - VISORCHIPSET_BUS_INFO *pBusInfo = findbus(&BusInfoList, busNo); + struct visorchipset_bus_info *pBusInfo = findbus(&BusInfoList, busNo); if (!pBusInfo) { LOGERR("HUH? bad busNo=%d", busNo); return; } if (needResponse) { - memcpy(&pBusInfo->pendingMsgHdr, msgHdr, - sizeof(CONTROLVM_MESSAGE_HEADER)); + memcpy(&pBusInfo->pending_msg_hdr, msgHdr, + sizeof(struct controlvm_message_header)); } else - pBusInfo->pendingMsgHdr.Id = CONTROLVM_INVALID; + pBusInfo->pending_msg_hdr.id = CONTROLVM_INVALID; down(&NotifierLock); if (response == CONTROLVM_RESP_SUCCESS) { @@ -981,7 +991,7 @@ bus_epilog(u32 busNo, } if (notified) /* The callback function just called above is responsible - * for calling the appropriate VISORCHIPSET_BUSDEV_RESPONDERS + * for calling the appropriate visorchipset_busdev_responders * function, which will call bus_responder() */ ; @@ -991,14 +1001,14 @@ bus_epilog(u32 busNo, } static void -device_epilog(u32 busNo, u32 devNo, ULTRA_SEGMENT_STATE state, u32 cmd, - CONTROLVM_MESSAGE_HEADER *msgHdr, int response, +device_epilog(u32 busNo, u32 devNo, struct spar_segment_state state, u32 cmd, + struct controlvm_message_header *msgHdr, int response, BOOL needResponse, BOOL for_visorbus) { - VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers = NULL; + struct visorchipset_busdev_notifiers *notifiers = NULL; BOOL notified = FALSE; - VISORCHIPSET_DEVICE_INFO *pDevInfo = + struct visorchipset_device_info *pDevInfo = finddevice(&DevInfoList, busNo, devNo); char *envp[] = { "SPARSP_DIAGPOOL_PAUSED_STATE = 1", @@ -1014,10 +1024,10 @@ device_epilog(u32 busNo, u32 devNo, ULTRA_SEGMENT_STATE state, u32 cmd, else notifiers = &BusDev_Client_Notifiers; if (needResponse) { - memcpy(&pDevInfo->pendingMsgHdr, msgHdr, - sizeof(CONTROLVM_MESSAGE_HEADER)); + memcpy(&pDevInfo->pending_msg_hdr, msgHdr, + sizeof(struct controlvm_message_header)); } else - pDevInfo->pendingMsgHdr.Id = CONTROLVM_INVALID; + pDevInfo->pending_msg_hdr.id = CONTROLVM_INVALID; down(&NotifierLock); if (response >= 0) { @@ -1030,8 +1040,9 @@ device_epilog(u32 busNo, u32 devNo, ULTRA_SEGMENT_STATE state, u32 cmd, break; case CONTROLVM_DEVICE_CHANGESTATE: /* ServerReady / ServerRunning / SegmentStateRunning */ - if (state.Alive == SegmentStateRunning.Alive && - state.Operating == SegmentStateRunning.Operating) { + if (state.alive == segment_state_running.alive && + state.operating == + segment_state_running.operating) { if (notifiers->device_resume) { (*notifiers->device_resume) (busNo, devNo); @@ -1039,9 +1050,9 @@ device_epilog(u32 busNo, u32 devNo, ULTRA_SEGMENT_STATE state, u32 cmd, } } /* ServerNotReady / ServerLost / SegmentStateStandby */ - else if (state.Alive == SegmentStateStandby.Alive && - state.Operating == - SegmentStateStandby.Operating) { + else if (state.alive == segment_state_standby.alive && + state.operating == + segment_state_standby.operating) { /* technically this is standby case * where server is lost */ @@ -1050,9 +1061,9 @@ device_epilog(u32 busNo, u32 devNo, ULTRA_SEGMENT_STATE state, u32 cmd, devNo); notified = TRUE; } - } else if (state.Alive == SegmentStatePaused.Alive && - state.Operating == - SegmentStatePaused.Operating) { + } else if (state.alive == segment_state_paused.alive && + state.operating == + segment_state_paused.operating) { /* this is lite pause where channel is * still valid just 'pause' of it */ @@ -1079,7 +1090,7 @@ device_epilog(u32 busNo, u32 devNo, ULTRA_SEGMENT_STATE state, u32 cmd, } if (notified) /* The callback function just called above is responsible - * for calling the appropriate VISORCHIPSET_BUSDEV_RESPONDERS + * for calling the appropriate visorchipset_busdev_responders * function, which will call device_responder() */ ; @@ -1089,12 +1100,12 @@ device_epilog(u32 busNo, u32 devNo, ULTRA_SEGMENT_STATE state, u32 cmd, } static void -bus_create(CONTROLVM_MESSAGE *inmsg) +bus_create(struct controlvm_message *inmsg) { - CONTROLVM_MESSAGE_PACKET *cmd = &inmsg->cmd; - ulong busNo = cmd->createBus.busNo; + struct controlvm_message_packet *cmd = &inmsg->cmd; + ulong busNo = cmd->create_bus.bus_no; int rc = CONTROLVM_RESP_SUCCESS; - VISORCHIPSET_BUS_INFO *pBusInfo = NULL; + struct visorchipset_bus_info *pBusInfo = NULL; pBusInfo = findbus(&BusInfoList, busNo); @@ -1106,7 +1117,7 @@ bus_create(CONTROLVM_MESSAGE *inmsg) rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; goto Away; } - pBusInfo = kzalloc(sizeof(VISORCHIPSET_BUS_INFO), GFP_KERNEL); + pBusInfo = kzalloc(sizeof(struct visorchipset_bus_info), GFP_KERNEL); if (pBusInfo == NULL) { LOGERR("CONTROLVM_BUS_CREATE Failed: bus %lu kzalloc failed", busNo); @@ -1117,21 +1128,22 @@ bus_create(CONTROLVM_MESSAGE *inmsg) } INIT_LIST_HEAD(&pBusInfo->entry); - pBusInfo->busNo = busNo; - pBusInfo->devNo = cmd->createBus.deviceCount; + pBusInfo->bus_no = busNo; + pBusInfo->dev_no = cmd->create_bus.dev_count; POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, busNo, POSTCODE_SEVERITY_INFO); - if (inmsg->hdr.Flags.testMessage == 1) - pBusInfo->chanInfo.addrType = ADDRTYPE_localTest; + if (inmsg->hdr.flags.test_message == 1) + pBusInfo->chan_info.addr_type = ADDRTYPE_LOCALTEST; else - pBusInfo->chanInfo.addrType = ADDRTYPE_localPhysical; + pBusInfo->chan_info.addr_type = ADDRTYPE_LOCALPHYSICAL; - pBusInfo->flags.server = inmsg->hdr.Flags.server; - pBusInfo->chanInfo.channelAddr = cmd->createBus.channelAddr; - pBusInfo->chanInfo.nChannelBytes = cmd->createBus.channelBytes; - pBusInfo->chanInfo.channelTypeGuid = cmd->createBus.busDataTypeGuid; - pBusInfo->chanInfo.channelInstGuid = cmd->createBus.busInstGuid; + pBusInfo->flags.server = inmsg->hdr.flags.server; + pBusInfo->chan_info.channel_addr = cmd->create_bus.channel_addr; + pBusInfo->chan_info.n_channel_bytes = cmd->create_bus.channel_bytes; + pBusInfo->chan_info.channel_type_uuid = + cmd->create_bus.bus_data_type_uuid; + pBusInfo->chan_info.channel_inst_uuid = cmd->create_bus.bus_inst_uuid; list_add(&pBusInfo->entry, &BusInfoList); @@ -1139,15 +1151,15 @@ bus_create(CONTROLVM_MESSAGE *inmsg) Away: bus_epilog(busNo, CONTROLVM_BUS_CREATE, &inmsg->hdr, - rc, inmsg->hdr.Flags.responseExpected == 1); + rc, inmsg->hdr.flags.response_expected == 1); } static void -bus_destroy(CONTROLVM_MESSAGE *inmsg) +bus_destroy(struct controlvm_message *inmsg) { - CONTROLVM_MESSAGE_PACKET *cmd = &inmsg->cmd; - ulong busNo = cmd->destroyBus.busNo; - VISORCHIPSET_BUS_INFO *pBusInfo; + struct controlvm_message_packet *cmd = &inmsg->cmd; + ulong busNo = cmd->destroy_bus.bus_no; + struct visorchipset_bus_info *pBusInfo; int rc = CONTROLVM_RESP_SUCCESS; pBusInfo = findbus(&BusInfoList, busNo); @@ -1165,19 +1177,19 @@ bus_destroy(CONTROLVM_MESSAGE *inmsg) Away: bus_epilog(busNo, CONTROLVM_BUS_DESTROY, &inmsg->hdr, - rc, inmsg->hdr.Flags.responseExpected == 1); + rc, inmsg->hdr.flags.response_expected == 1); } static void -bus_configure(CONTROLVM_MESSAGE *inmsg, PARSER_CONTEXT *parser_ctx) +bus_configure(struct controlvm_message *inmsg, PARSER_CONTEXT *parser_ctx) { - CONTROLVM_MESSAGE_PACKET *cmd = &inmsg->cmd; - ulong busNo = cmd->configureBus.busNo; - VISORCHIPSET_BUS_INFO *pBusInfo = NULL; + struct controlvm_message_packet *cmd = &inmsg->cmd; + ulong busNo = cmd->configure_bus.bus_no; + struct visorchipset_bus_info *pBusInfo = NULL; int rc = CONTROLVM_RESP_SUCCESS; char s[99]; - busNo = cmd->configureBus.busNo; + busNo = cmd->configure_bus.bus_no; POSTCODE_LINUX_3(BUS_CONFIGURE_ENTRY_PC, busNo, POSTCODE_SEVERITY_INFO); pBusInfo = findbus(&BusInfoList, busNo); @@ -1198,35 +1210,35 @@ bus_configure(CONTROLVM_MESSAGE *inmsg, PARSER_CONTEXT *parser_ctx) goto Away; } /* TBD - add this check to other commands also... */ - if (pBusInfo->pendingMsgHdr.Id != CONTROLVM_INVALID) { + if (pBusInfo->pending_msg_hdr.id != CONTROLVM_INVALID) { LOGERR("CONTROLVM_BUS_CONFIGURE Failed: bus %lu MsgId=%u outstanding", - busNo, (uint) pBusInfo->pendingMsgHdr.Id); + busNo, (uint) pBusInfo->pending_msg_hdr.id); POSTCODE_LINUX_3(BUS_CONFIGURE_FAILURE_PC, busNo, POSTCODE_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT; goto Away; } - pBusInfo->partitionHandle = cmd->configureBus.guestHandle; - pBusInfo->partitionGuid = parser_id_get(parser_ctx); + pBusInfo->partition_handle = cmd->configure_bus.guest_handle; + pBusInfo->partition_uuid = parser_id_get(parser_ctx); parser_param_start(parser_ctx, PARSERSTRING_NAME); pBusInfo->name = parser_string_get(parser_ctx); - visorchannel_uuid_id(&pBusInfo->partitionGuid, s); + visorchannel_uuid_id(&pBusInfo->partition_uuid, s); POSTCODE_LINUX_3(BUS_CONFIGURE_EXIT_PC, busNo, POSTCODE_SEVERITY_INFO); Away: bus_epilog(busNo, CONTROLVM_BUS_CONFIGURE, &inmsg->hdr, - rc, inmsg->hdr.Flags.responseExpected == 1); + rc, inmsg->hdr.flags.response_expected == 1); } static void -my_device_create(CONTROLVM_MESSAGE *inmsg) +my_device_create(struct controlvm_message *inmsg) { - CONTROLVM_MESSAGE_PACKET *cmd = &inmsg->cmd; - ulong busNo = cmd->createDevice.busNo; - ulong devNo = cmd->createDevice.devNo; - VISORCHIPSET_DEVICE_INFO *pDevInfo = NULL; - VISORCHIPSET_BUS_INFO *pBusInfo = NULL; + struct controlvm_message_packet *cmd = &inmsg->cmd; + ulong busNo = cmd->create_device.bus_no; + ulong devNo = cmd->create_device.dev_no; + struct visorchipset_device_info *pDevInfo = NULL; + struct visorchipset_bus_info *pBusInfo = NULL; int rc = CONTROLVM_RESP_SUCCESS; pDevInfo = finddevice(&DevInfoList, busNo, devNo); @@ -1255,7 +1267,7 @@ my_device_create(CONTROLVM_MESSAGE *inmsg) rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; goto Away; } - pDevInfo = kzalloc(sizeof(VISORCHIPSET_DEVICE_INFO), GFP_KERNEL); + pDevInfo = kzalloc(sizeof(struct visorchipset_device_info), GFP_KERNEL); if (pDevInfo == NULL) { LOGERR("CONTROLVM_DEVICE_CREATE Failed: busNo=%lu, devNo=%lu kmaloc failed", busNo, devNo); @@ -1266,45 +1278,47 @@ my_device_create(CONTROLVM_MESSAGE *inmsg) } INIT_LIST_HEAD(&pDevInfo->entry); - pDevInfo->busNo = busNo; - pDevInfo->devNo = devNo; - pDevInfo->devInstGuid = cmd->createDevice.devInstGuid; + pDevInfo->bus_no = busNo; + pDevInfo->dev_no = devNo; + pDevInfo->dev_inst_uuid = cmd->create_device.dev_inst_uuid; POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, devNo, busNo, POSTCODE_SEVERITY_INFO); - if (inmsg->hdr.Flags.testMessage == 1) - pDevInfo->chanInfo.addrType = ADDRTYPE_localTest; + if (inmsg->hdr.flags.test_message == 1) + pDevInfo->chan_info.addr_type = ADDRTYPE_LOCALTEST; else - pDevInfo->chanInfo.addrType = ADDRTYPE_localPhysical; - pDevInfo->chanInfo.channelAddr = cmd->createDevice.channelAddr; - pDevInfo->chanInfo.nChannelBytes = cmd->createDevice.channelBytes; - pDevInfo->chanInfo.channelTypeGuid = cmd->createDevice.dataTypeGuid; - pDevInfo->chanInfo.intr = cmd->createDevice.intr; + pDevInfo->chan_info.addr_type = ADDRTYPE_LOCALPHYSICAL; + pDevInfo->chan_info.channel_addr = cmd->create_device.channel_addr; + pDevInfo->chan_info.n_channel_bytes = cmd->create_device.channel_bytes; + pDevInfo->chan_info.channel_type_uuid = + cmd->create_device.data_type_uuid; + pDevInfo->chan_info.intr = cmd->create_device.intr; list_add(&pDevInfo->entry, &DevInfoList); POSTCODE_LINUX_4(DEVICE_CREATE_EXIT_PC, devNo, busNo, POSTCODE_SEVERITY_INFO); Away: /* get the bus and devNo for DiagPool channel */ - if (is_diagpool_channel(pDevInfo->chanInfo.channelTypeGuid)) { + if (pDevInfo && + is_diagpool_channel(pDevInfo->chan_info.channel_type_uuid)) { g_diagpoolBusNo = busNo; g_diagpoolDevNo = devNo; LOGINF("CONTROLVM_DEVICE_CREATE for DiagPool channel: busNo=%lu, devNo=%lu", g_diagpoolBusNo, g_diagpoolDevNo); } - device_epilog(busNo, devNo, SegmentStateRunning, + device_epilog(busNo, devNo, segment_state_running, CONTROLVM_DEVICE_CREATE, &inmsg->hdr, rc, - inmsg->hdr.Flags.responseExpected == 1, - FOR_VISORBUS(pDevInfo->chanInfo.channelTypeGuid)); + inmsg->hdr.flags.response_expected == 1, + FOR_VISORBUS(pDevInfo->chan_info.channel_type_uuid)); } static void -my_device_changestate(CONTROLVM_MESSAGE *inmsg) +my_device_changestate(struct controlvm_message *inmsg) { - CONTROLVM_MESSAGE_PACKET *cmd = &inmsg->cmd; - ulong busNo = cmd->deviceChangeState.busNo; - ulong devNo = cmd->deviceChangeState.devNo; - ULTRA_SEGMENT_STATE state = cmd->deviceChangeState.state; - VISORCHIPSET_DEVICE_INFO *pDevInfo = NULL; + struct controlvm_message_packet *cmd = &inmsg->cmd; + ulong busNo = cmd->device_change_state.bus_no; + ulong devNo = cmd->device_change_state.dev_no; + struct spar_segment_state state = cmd->device_change_state.state; + struct visorchipset_device_info *pDevInfo = NULL; int rc = CONTROLVM_RESP_SUCCESS; pDevInfo = finddevice(&DevInfoList, busNo, devNo); @@ -1327,17 +1341,18 @@ Away: if ((rc >= CONTROLVM_RESP_SUCCESS) && pDevInfo) device_epilog(busNo, devNo, state, CONTROLVM_DEVICE_CHANGESTATE, &inmsg->hdr, rc, - inmsg->hdr.Flags.responseExpected == 1, - FOR_VISORBUS(pDevInfo->chanInfo.channelTypeGuid)); + inmsg->hdr.flags.response_expected == 1, + FOR_VISORBUS( + pDevInfo->chan_info.channel_type_uuid)); } static void -my_device_destroy(CONTROLVM_MESSAGE *inmsg) +my_device_destroy(struct controlvm_message *inmsg) { - CONTROLVM_MESSAGE_PACKET *cmd = &inmsg->cmd; - ulong busNo = cmd->destroyDevice.busNo; - ulong devNo = cmd->destroyDevice.devNo; - VISORCHIPSET_DEVICE_INFO *pDevInfo = NULL; + struct controlvm_message_packet *cmd = &inmsg->cmd; + ulong busNo = cmd->destroy_device.bus_no; + ulong devNo = cmd->destroy_device.dev_no; + struct visorchipset_device_info *pDevInfo = NULL; int rc = CONTROLVM_RESP_SUCCESS; pDevInfo = finddevice(&DevInfoList, busNo, devNo); @@ -1355,10 +1370,11 @@ my_device_destroy(CONTROLVM_MESSAGE *inmsg) Away: if ((rc >= CONTROLVM_RESP_SUCCESS) && pDevInfo) - device_epilog(busNo, devNo, SegmentStateRunning, + device_epilog(busNo, devNo, segment_state_running, CONTROLVM_DEVICE_DESTROY, &inmsg->hdr, rc, - inmsg->hdr.Flags.responseExpected == 1, - FOR_VISORBUS(pDevInfo->chanInfo.channelTypeGuid)); + inmsg->hdr.flags.response_expected == 1, + FOR_VISORBUS( + pDevInfo->chan_info.channel_type_uuid)); } /* When provided with the physical address of the controlvm channel @@ -1382,7 +1398,7 @@ initialize_controlvm_payload_info(HOSTADDRESS phys_addr, u64 offset, u32 bytes, } memset(info, 0, sizeof(CONTROLVM_PAYLOAD_INFO)); if ((offset == 0) || (bytes == 0)) { - LOGERR("CONTROLVM_PAYLOAD_INIT Failed: RequestPayloadOffset=%llu RequestPayloadBytes=%llu!", + LOGERR("CONTROLVM_PAYLOAD_INIT Failed: request_payload_offset=%llu request_payload_bytes=%llu!", (u64) offset, (u64) bytes); rc = -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID; goto Away; @@ -1429,8 +1445,8 @@ initialize_controlvm_payload(void) u32 payloadBytes = 0; if (visorchannel_read(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - RequestPayloadOffset), + offsetof(struct spar_controlvm_channel_protocol, + request_payload_offset), &payloadOffset, sizeof(payloadOffset)) < 0) { LOGERR("CONTROLVM_PAYLOAD_INIT Failed to read controlvm channel!"); POSTCODE_LINUX_2(CONTROLVM_INIT_FAILURE_PC, @@ -1438,8 +1454,8 @@ initialize_controlvm_payload(void) return; } if (visorchannel_read(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - RequestPayloadBytes), + offsetof(struct spar_controlvm_channel_protocol, + request_payload_bytes), &payloadBytes, sizeof(payloadBytes)) < 0) { LOGERR("CONTROLVM_PAYLOAD_INIT Failed to read controlvm channel!"); POSTCODE_LINUX_2(CONTROLVM_INIT_FAILURE_PC, @@ -1487,15 +1503,15 @@ visorchipset_chipset_notready(void) EXPORT_SYMBOL_GPL(visorchipset_chipset_notready); static void -chipset_ready(CONTROLVM_MESSAGE_HEADER *msgHdr) +chipset_ready(struct controlvm_message_header *msgHdr) { int rc = visorchipset_chipset_ready(); if (rc != CONTROLVM_RESP_SUCCESS) rc = -rc; - if (msgHdr->Flags.responseExpected && !visorchipset_holdchipsetready) + if (msgHdr->flags.response_expected && !visorchipset_holdchipsetready) controlvm_respond(msgHdr, rc); - if (msgHdr->Flags.responseExpected && visorchipset_holdchipsetready) { + if (msgHdr->flags.response_expected && visorchipset_holdchipsetready) { /* Send CHIPSET_READY response when all modules have been loaded * and disks mounted for the partition */ @@ -1505,24 +1521,24 @@ chipset_ready(CONTROLVM_MESSAGE_HEADER *msgHdr) } static void -chipset_selftest(CONTROLVM_MESSAGE_HEADER *msgHdr) +chipset_selftest(struct controlvm_message_header *msgHdr) { int rc = visorchipset_chipset_selftest(); if (rc != CONTROLVM_RESP_SUCCESS) rc = -rc; - if (msgHdr->Flags.responseExpected) + if (msgHdr->flags.response_expected) controlvm_respond(msgHdr, rc); } static void -chipset_notready(CONTROLVM_MESSAGE_HEADER *msgHdr) +chipset_notready(struct controlvm_message_header *msgHdr) { int rc = visorchipset_chipset_notready(); if (rc != CONTROLVM_RESP_SUCCESS) rc = -rc; - if (msgHdr->Flags.responseExpected) + if (msgHdr->flags.response_expected) controlvm_respond(msgHdr, rc); } @@ -1530,13 +1546,14 @@ chipset_notready(CONTROLVM_MESSAGE_HEADER *msgHdr) * CONTROLVM_QUEUE_EVENT queue in the controlvm channel. */ static BOOL -read_controlvm_event(CONTROLVM_MESSAGE *msg) +read_controlvm_event(struct controlvm_message *msg) { if (visorchannel_signalremove(ControlVm_channel, CONTROLVM_QUEUE_EVENT, msg)) { /* got a message */ - if (msg->hdr.Flags.testMessage == 1) { - LOGERR("ignoring bad CONTROLVM_QUEUE_EVENT msg with controlvm_msg_id=0x%x because Flags.testMessage is nonsensical (=1)", msg->hdr.Id); + if (msg->hdr.flags.test_message == 1) { + LOGERR("ignoring bad CONTROLVM_QUEUE_EVENT msg with controlvm_msg_id=0x%x because Flags.testMessage is nonsensical (=1)", + msg->hdr.id); return FALSE; } return TRUE; @@ -1586,7 +1603,7 @@ parahotplug_next_expiration(void) * CONTROLVM_MESSAGE that we can stick on a list */ static struct parahotplug_request * -parahotplug_request_create(CONTROLVM_MESSAGE *msg) +parahotplug_request_create(struct controlvm_message *msg) { struct parahotplug_request *req = kmalloc(sizeof(struct parahotplug_request), @@ -1618,7 +1635,7 @@ parahotplug_request_destroy(struct parahotplug_request *req) static void parahotplug_request_kickoff(struct parahotplug_request *req) { - CONTROLVM_MESSAGE_PACKET *cmd = &req->msg.cmd; + struct controlvm_message_packet *cmd = &req->msg.cmd; char env_cmd[40], env_id[40], env_state[40], env_bus[40], env_dev[40], env_func[40]; char *envp[] = { @@ -1628,18 +1645,19 @@ parahotplug_request_kickoff(struct parahotplug_request *req) sprintf(env_cmd, "SPAR_PARAHOTPLUG=1"); sprintf(env_id, "SPAR_PARAHOTPLUG_ID=%d", req->id); sprintf(env_state, "SPAR_PARAHOTPLUG_STATE=%d", - cmd->deviceChangeState.state.Active); + cmd->device_change_state.state.active); sprintf(env_bus, "SPAR_PARAHOTPLUG_BUS=%d", - cmd->deviceChangeState.busNo); + cmd->device_change_state.bus_no); sprintf(env_dev, "SPAR_PARAHOTPLUG_DEVICE=%d", - cmd->deviceChangeState.devNo >> 3); + cmd->device_change_state.dev_no >> 3); sprintf(env_func, "SPAR_PARAHOTPLUG_FUNCTION=%d", - cmd->deviceChangeState.devNo & 0x7); + cmd->device_change_state.dev_no & 0x7); LOGINF("parahotplug_request_kickoff: state=%d, bdf=%d/%d/%d, id=%u\n", - cmd->deviceChangeState.state.Active, - cmd->deviceChangeState.busNo, cmd->deviceChangeState.devNo >> 3, - cmd->deviceChangeState.devNo & 7, req->id); + cmd->device_change_state.state.active, + cmd->device_change_state.bus_no, + cmd->device_change_state.dev_no >> 3, + cmd->device_change_state.dev_no & 7, req->id); kobject_uevent_env(&Visorchipset_platform_device.dev.kobj, KOBJ_CHANGE, envp); @@ -1662,11 +1680,11 @@ parahotplug_process_list(void) list_entry(pos, struct parahotplug_request, list); if (time_after_eq(jiffies, req->expiration)) { list_del(pos); - if (req->msg.hdr.Flags.responseExpected) + if (req->msg.hdr.flags.response_expected) controlvm_respond_physdev_changestate( &req->msg.hdr, CONTROLVM_RESP_ERROR_DEVICE_UDEV_TIMEOUT, - req->msg.cmd.deviceChangeState.state); + req->msg.cmd.device_change_state.state); parahotplug_request_destroy(req); } } @@ -1697,11 +1715,11 @@ parahotplug_request_complete(int id, u16 active) */ list_del(pos); spin_unlock(&Parahotplug_request_list_lock); - req->msg.cmd.deviceChangeState.state.Active = active; - if (req->msg.hdr.Flags.responseExpected) + req->msg.cmd.device_change_state.state.active = active; + if (req->msg.hdr.flags.response_expected) controlvm_respond_physdev_changestate( &req->msg.hdr, CONTROLVM_RESP_SUCCESS, - req->msg.cmd.deviceChangeState.state); + req->msg.cmd.device_change_state.state); parahotplug_request_destroy(req); return 0; } @@ -1715,7 +1733,7 @@ parahotplug_request_complete(int id, u16 active) * Enables or disables a PCI device by kicking off a udev script */ static void -parahotplug_process_message(CONTROLVM_MESSAGE *inmsg) +parahotplug_process_message(struct controlvm_message *inmsg) { struct parahotplug_request *req; @@ -1726,7 +1744,7 @@ parahotplug_process_message(CONTROLVM_MESSAGE *inmsg) return; } - if (inmsg->cmd.deviceChangeState.state.Active) { + if (inmsg->cmd.device_change_state.state.active) { /* For enable messages, just respond with success * right away. This is a bit of a hack, but there are * issues with the early enable messages we get (with @@ -1738,9 +1756,8 @@ parahotplug_process_message(CONTROLVM_MESSAGE *inmsg) */ parahotplug_request_kickoff(req); controlvm_respond_physdev_changestate(&inmsg->hdr, - CONTROLVM_RESP_SUCCESS, - inmsg->cmd. - deviceChangeState.state); + CONTROLVM_RESP_SUCCESS, inmsg->cmd. + device_change_state.state); parahotplug_request_destroy(req); } else { /* For disable messages, add the request to the @@ -1768,23 +1785,23 @@ parahotplug_process_message(CONTROLVM_MESSAGE *inmsg) * either successfully or with an error. */ static BOOL -handle_command(CONTROLVM_MESSAGE inmsg, HOSTADDRESS channel_addr) +handle_command(struct controlvm_message inmsg, HOSTADDRESS channel_addr) { - CONTROLVM_MESSAGE_PACKET *cmd = &inmsg.cmd; + struct controlvm_message_packet *cmd = &inmsg.cmd; u64 parametersAddr = 0; u32 parametersBytes = 0; PARSER_CONTEXT *parser_ctx = NULL; BOOL isLocalAddr = FALSE; - CONTROLVM_MESSAGE ackmsg; + struct controlvm_message ackmsg; /* create parsing context if necessary */ - isLocalAddr = (inmsg.hdr.Flags.testMessage == 1); + isLocalAddr = (inmsg.hdr.flags.test_message == 1); if (channel_addr == 0) { LOGERR("HUH? channel_addr is 0!"); return TRUE; } - parametersAddr = channel_addr + inmsg.hdr.PayloadVmOffset; - parametersBytes = inmsg.hdr.PayloadBytes; + parametersAddr = channel_addr + inmsg.hdr.payload_vm_offset; + parametersBytes = inmsg.hdr.payload_bytes; /* Parameter and channel addresses within test messages actually lie * within our OS-controlled memory. We need to know that, because it @@ -1802,7 +1819,7 @@ handle_command(CONTROLVM_MESSAGE inmsg, HOSTADDRESS channel_addr) return FALSE; } LOGWRN("parsing failed"); - LOGWRN("inmsg.hdr.Id=0x%lx", (ulong) inmsg.hdr.Id); + LOGWRN("inmsg.hdr.Id=0x%lx", (ulong) inmsg.hdr.id); LOGWRN("parametersAddr=0x%llx", (u64) parametersAddr); LOGWRN("parametersBytes=%lu", (ulong) parametersBytes); LOGWRN("isLocalAddr=%d", isLocalAddr); @@ -1818,45 +1835,45 @@ handle_command(CONTROLVM_MESSAGE inmsg, HOSTADDRESS channel_addr) (ControlVm_channel, CONTROLVM_QUEUE_ACK, &ackmsg))) LOGWRN("failed to send ACK failed"); } - switch (inmsg.hdr.Id) { + switch (inmsg.hdr.id) { case CONTROLVM_CHIPSET_INIT: LOGINF("CHIPSET_INIT(#busses=%lu,#switches=%lu)", - (ulong) inmsg.cmd.initChipset.busCount, - (ulong) inmsg.cmd.initChipset.switchCount); + (ulong) inmsg.cmd.init_chipset.bus_count, + (ulong) inmsg.cmd.init_chipset.switch_count); chipset_init(&inmsg); break; case CONTROLVM_BUS_CREATE: LOGINF("BUS_CREATE(%lu,#devs=%lu)", - (ulong) cmd->createBus.busNo, - (ulong) cmd->createBus.deviceCount); + (ulong) cmd->create_bus.bus_no, + (ulong) cmd->create_bus.dev_count); bus_create(&inmsg); break; case CONTROLVM_BUS_DESTROY: - LOGINF("BUS_DESTROY(%lu)", (ulong) cmd->destroyBus.busNo); + LOGINF("BUS_DESTROY(%lu)", (ulong) cmd->destroy_bus.bus_no); bus_destroy(&inmsg); break; case CONTROLVM_BUS_CONFIGURE: - LOGINF("BUS_CONFIGURE(%lu)", (ulong) cmd->configureBus.busNo); + LOGINF("BUS_CONFIGURE(%lu)", (ulong) cmd->configure_bus.bus_no); bus_configure(&inmsg, parser_ctx); break; case CONTROLVM_DEVICE_CREATE: LOGINF("DEVICE_CREATE(%lu,%lu)", - (ulong) cmd->createDevice.busNo, - (ulong) cmd->createDevice.devNo); + (ulong) cmd->create_device.bus_no, + (ulong) cmd->create_device.dev_no); my_device_create(&inmsg); break; case CONTROLVM_DEVICE_CHANGESTATE: - if (cmd->deviceChangeState.flags.physicalDevice) { + if (cmd->device_change_state.flags.phys_device) { LOGINF("DEVICE_CHANGESTATE for physical device (%lu,%lu, active=%lu)", - (ulong) cmd->deviceChangeState.busNo, - (ulong) cmd->deviceChangeState.devNo, - (ulong) cmd->deviceChangeState.state.Active); + (ulong) cmd->device_change_state.bus_no, + (ulong) cmd->device_change_state.dev_no, + (ulong) cmd->device_change_state.state.active); parahotplug_process_message(&inmsg); } else { LOGINF("DEVICE_CHANGESTATE for virtual device (%lu,%lu, state.Alive=0x%lx)", - (ulong) cmd->deviceChangeState.busNo, - (ulong) cmd->deviceChangeState.devNo, - (ulong) cmd->deviceChangeState.state.Alive); + (ulong) cmd->device_change_state.bus_no, + (ulong) cmd->device_change_state.dev_no, + (ulong) cmd->device_change_state.state.alive); /* save the hdr and cmd structures for later use */ /* when sending back the response to Command */ my_device_changestate(&inmsg); @@ -1867,16 +1884,16 @@ handle_command(CONTROLVM_MESSAGE inmsg, HOSTADDRESS channel_addr) break; case CONTROLVM_DEVICE_DESTROY: LOGINF("DEVICE_DESTROY(%lu,%lu)", - (ulong) cmd->destroyDevice.busNo, - (ulong) cmd->destroyDevice.devNo); + (ulong) cmd->destroy_device.bus_no, + (ulong) cmd->destroy_device.dev_no); my_device_destroy(&inmsg); break; case CONTROLVM_DEVICE_CONFIGURE: LOGINF("DEVICE_CONFIGURE(%lu,%lu)", - (ulong) cmd->configureDevice.busNo, - (ulong) cmd->configureDevice.devNo); + (ulong) cmd->configure_device.bus_no, + (ulong) cmd->configure_device.dev_no); /* no op for now, just send a respond that we passed */ - if (inmsg.hdr.Flags.responseExpected) + if (inmsg.hdr.flags.response_expected) controlvm_respond(&inmsg.hdr, CONTROLVM_RESP_SUCCESS); break; case CONTROLVM_CHIPSET_READY: @@ -1892,8 +1909,8 @@ handle_command(CONTROLVM_MESSAGE inmsg, HOSTADDRESS channel_addr) chipset_notready(&inmsg.hdr); break; default: - LOGERR("unrecognized controlvm cmd=%d", (int) inmsg.hdr.Id); - if (inmsg.hdr.Flags.responseExpected) + LOGERR("unrecognized controlvm cmd=%d", (int) inmsg.hdr.id); + if (inmsg.hdr.flags.response_expected) controlvm_respond(&inmsg.hdr, -CONTROLVM_RESP_ERROR_MESSAGE_ID_UNKNOWN); break; @@ -1923,8 +1940,7 @@ static HOSTADDRESS controlvm_get_channel_address(void) static void controlvm_periodic_work(struct work_struct *work) { - VISORCHIPSET_CHANNEL_INFO chanInfo; - CONTROLVM_MESSAGE inmsg; + struct controlvm_message inmsg; BOOL gotACommand = FALSE; BOOL handle_command_failed = FALSE; static u64 Poll_Count; @@ -1938,8 +1954,6 @@ controlvm_periodic_work(struct work_struct *work) if (visorchipset_clientregwait && !clientregistered) goto Away; - memset(&chanInfo, 0, sizeof(VISORCHIPSET_CHANNEL_INFO)); - Poll_Count++; if (Poll_Count >= 250) ; /* keep going */ @@ -1950,24 +1964,24 @@ controlvm_periodic_work(struct work_struct *work) * should be sent */ if (visorchipset_holdchipsetready - && (g_ChipSetMsgHdr.Id != CONTROLVM_INVALID)) { + && (g_ChipSetMsgHdr.id != CONTROLVM_INVALID)) { if (check_chipset_events() == 1) { LOGINF("Sending CHIPSET_READY response"); controlvm_respond(&g_ChipSetMsgHdr, 0); clear_chipset_events(); memset(&g_ChipSetMsgHdr, 0, - sizeof(CONTROLVM_MESSAGE_HEADER)); + sizeof(struct controlvm_message_header)); } } while (visorchannel_signalremove(ControlVm_channel, CONTROLVM_QUEUE_RESPONSE, &inmsg)) { - if (inmsg.hdr.PayloadMaxBytes != 0) { + if (inmsg.hdr.payload_max_bytes != 0) { LOGERR("Payload of size %lu returned @%lu with unexpected message id %d.", - (ulong) inmsg.hdr.PayloadMaxBytes, - (ulong) inmsg.hdr.PayloadVmOffset, - inmsg.hdr.Id); + (ulong) inmsg.hdr.payload_max_bytes, + (ulong) inmsg.hdr.payload_vm_offset, + inmsg.hdr.id); } } if (!gotACommand) { @@ -2033,9 +2047,9 @@ static void setup_crash_devices_work_queue(struct work_struct *work) { - CONTROLVM_MESSAGE localCrashCreateBusMsg; - CONTROLVM_MESSAGE localCrashCreateDevMsg; - CONTROLVM_MESSAGE msg; + struct controlvm_message localCrashCreateBusMsg; + struct controlvm_message localCrashCreateDevMsg; + struct controlvm_message msg; u32 localSavedCrashMsgOffset; u16 localSavedCrashMsgCount; @@ -2052,16 +2066,16 @@ setup_crash_devices_work_queue(struct work_struct *work) POSTCODE_LINUX_2(CRASH_DEV_ENTRY_PC, POSTCODE_SEVERITY_INFO); /* send init chipset msg */ - msg.hdr.Id = CONTROLVM_CHIPSET_INIT; - msg.cmd.initChipset.busCount = 23; - msg.cmd.initChipset.switchCount = 0; + msg.hdr.id = CONTROLVM_CHIPSET_INIT; + msg.cmd.init_chipset.bus_count = 23; + msg.cmd.init_chipset.switch_count = 0; chipset_init(&msg); /* get saved message count */ if (visorchannel_read(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - SavedCrashMsgCount), + offsetof(struct spar_controlvm_channel_protocol, + saved_crash_message_count), &localSavedCrashMsgCount, sizeof(u16)) < 0) { LOGERR("failed to get Saved Message Count"); POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, @@ -2080,8 +2094,8 @@ setup_crash_devices_work_queue(struct work_struct *work) /* get saved crash message offset */ if (visorchannel_read(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - SavedCrashMsgOffset), + offsetof(struct spar_controlvm_channel_protocol, + saved_crash_message_offset), &localSavedCrashMsgOffset, sizeof(u32)) < 0) { LOGERR("failed to get Saved Message Offset"); POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, @@ -2093,7 +2107,7 @@ setup_crash_devices_work_queue(struct work_struct *work) if (visorchannel_read(ControlVm_channel, localSavedCrashMsgOffset, &localCrashCreateBusMsg, - sizeof(CONTROLVM_MESSAGE)) < 0) { + sizeof(struct controlvm_message)) < 0) { LOGERR("CRASH_DEV_RD_BUS_FAIULRE: Failed to read CrashCreateBusMsg!"); POSTCODE_LINUX_2(CRASH_DEV_RD_BUS_FAIULRE_PC, POSTCODE_SEVERITY_ERR); @@ -2103,9 +2117,9 @@ setup_crash_devices_work_queue(struct work_struct *work) /* read create device message for storage device */ if (visorchannel_read(ControlVm_channel, localSavedCrashMsgOffset + - sizeof(CONTROLVM_MESSAGE), + sizeof(struct controlvm_message), &localCrashCreateDevMsg, - sizeof(CONTROLVM_MESSAGE)) < 0) { + sizeof(struct controlvm_message)) < 0) { LOGERR("CRASH_DEV_RD_DEV_FAIULRE: Failed to read CrashCreateDevMsg!"); POSTCODE_LINUX_2(CRASH_DEV_RD_DEV_FAIULRE_PC, POSTCODE_SEVERITY_ERR); @@ -2113,7 +2127,7 @@ setup_crash_devices_work_queue(struct work_struct *work) } /* reuse IOVM create bus message */ - if (localCrashCreateBusMsg.cmd.createBus.channelAddr != 0) + if (localCrashCreateBusMsg.cmd.create_bus.channel_addr != 0) bus_create(&localCrashCreateBusMsg); else { LOGERR("CrashCreateBusMsg is null, no dump will be taken"); @@ -2123,7 +2137,7 @@ setup_crash_devices_work_queue(struct work_struct *work) } /* reuse create device message for storage device */ - if (localCrashCreateDevMsg.cmd.createDevice.channelAddr != 0) + if (localCrashCreateDevMsg.cmd.create_device.channel_addr != 0) my_device_create(&localCrashCreateDevMsg); else { LOGERR("CrashCreateDevMsg is null, no dump will be taken"); @@ -2168,12 +2182,12 @@ device_destroy_response(ulong busNo, ulong devNo, int response) } void -visorchipset_device_pause_response(ulong busNo, ulong devNo, int response) +visorchipset_device_pause_response(ulong bus_no, ulong dev_no, int response) { device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE, - busNo, devNo, response, - SegmentStateStandby); + bus_no, dev_no, response, + segment_state_standby); } EXPORT_SYMBOL_GPL(visorchipset_device_pause_response); @@ -2182,30 +2196,30 @@ device_resume_response(ulong busNo, ulong devNo, int response) { device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE, busNo, devNo, response, - SegmentStateRunning); + segment_state_running); } BOOL -visorchipset_get_bus_info(ulong busNo, VISORCHIPSET_BUS_INFO *busInfo) +visorchipset_get_bus_info(ulong bus_no, struct visorchipset_bus_info *bus_info) { - void *p = findbus(&BusInfoList, busNo); + void *p = findbus(&BusInfoList, bus_no); if (!p) { - LOGERR("(%lu) failed", busNo); + LOGERR("(%lu) failed", bus_no); return FALSE; } - memcpy(busInfo, p, sizeof(VISORCHIPSET_BUS_INFO)); + memcpy(bus_info, p, sizeof(struct visorchipset_bus_info)); return TRUE; } EXPORT_SYMBOL_GPL(visorchipset_get_bus_info); BOOL -visorchipset_set_bus_context(ulong busNo, void *context) +visorchipset_set_bus_context(ulong bus_no, void *context) { - VISORCHIPSET_BUS_INFO *p = findbus(&BusInfoList, busNo); + struct visorchipset_bus_info *p = findbus(&BusInfoList, bus_no); if (!p) { - LOGERR("(%lu) failed", busNo); + LOGERR("(%lu) failed", bus_no); return FALSE; } p->bus_driver_context = context; @@ -2214,27 +2228,28 @@ visorchipset_set_bus_context(ulong busNo, void *context) EXPORT_SYMBOL_GPL(visorchipset_set_bus_context); BOOL -visorchipset_get_device_info(ulong busNo, ulong devNo, - VISORCHIPSET_DEVICE_INFO *devInfo) +visorchipset_get_device_info(ulong bus_no, ulong dev_no, + struct visorchipset_device_info *dev_info) { - void *p = finddevice(&DevInfoList, busNo, devNo); + void *p = finddevice(&DevInfoList, bus_no, dev_no); if (!p) { - LOGERR("(%lu,%lu) failed", busNo, devNo); + LOGERR("(%lu,%lu) failed", bus_no, dev_no); return FALSE; } - memcpy(devInfo, p, sizeof(VISORCHIPSET_DEVICE_INFO)); + memcpy(dev_info, p, sizeof(struct visorchipset_device_info)); return TRUE; } EXPORT_SYMBOL_GPL(visorchipset_get_device_info); BOOL -visorchipset_set_device_context(ulong busNo, ulong devNo, void *context) +visorchipset_set_device_context(ulong bus_no, ulong dev_no, void *context) { - VISORCHIPSET_DEVICE_INFO *p = finddevice(&DevInfoList, busNo, devNo); + struct visorchipset_device_info *p = + finddevice(&DevInfoList, bus_no, dev_no); if (!p) { - LOGERR("(%lu,%lu) failed", busNo, devNo); + LOGERR("(%lu,%lu) failed", bus_no, dev_no); return FALSE; } p->bus_driver_context = context; @@ -2377,11 +2392,10 @@ visorchipset_init(void) ControlVm_channel = visorchannel_create_with_lock (addr, - sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL), - UltraControlvmChannelProtocolGuid); - if (ULTRA_CONTROLVM_CHANNEL_OK_CLIENT - (visorchannel_get_header(ControlVm_channel), - NULL)) { + sizeof(struct spar_controlvm_channel_protocol), + spar_controlvm_channel_protocol_uuid); + if (SPAR_CONTROLVM_CHANNEL_OK_CLIENT( + visorchannel_get_header(ControlVm_channel))) { LOGINF("Channel %s (ControlVm) discovered", visorchannel_id(ControlVm_channel, s)); initialize_controlvm_payload(); @@ -2404,11 +2418,11 @@ visorchipset_init(void) goto Away; } - memset(&g_DiagMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER)); + memset(&g_DiagMsgHdr, 0, sizeof(struct controlvm_message_header)); - memset(&g_ChipSetMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER)); + memset(&g_ChipSetMsgHdr, 0, sizeof(struct controlvm_message_header)); - memset(&g_DelDumpMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER)); + memset(&g_DelDumpMsgHdr, 0, sizeof(struct controlvm_message_header)); Putfile_buffer_list_pool = kmem_cache_create(Putfile_buffer_list_pool_name, @@ -2497,11 +2511,11 @@ visorchipset_exit(void) cleanup_controlvm_structures(); - memset(&g_DiagMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER)); + memset(&g_DiagMsgHdr, 0, sizeof(struct controlvm_message_header)); - memset(&g_ChipSetMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER)); + memset(&g_ChipSetMsgHdr, 0, sizeof(struct controlvm_message_header)); - memset(&g_DelDumpMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER)); + memset(&g_DelDumpMsgHdr, 0, sizeof(struct controlvm_message_header)); LOGINF("Channel %s (ControlVm) disconnected", visorchannel_id(ControlVm_channel, s)); diff --git a/drivers/staging/unisys/visorutil/charqueue.c b/drivers/staging/unisys/visorutil/charqueue.c index 22241c7b4f7f..1ce7003c3a90 100644 --- a/drivers/staging/unisys/visorutil/charqueue.c +++ b/drivers/staging/unisys/visorutil/charqueue.c @@ -25,9 +25,7 @@ #define IS_EMPTY(charqueue) (charqueue->head == charqueue->tail) - - -struct CHARQUEUE_Tag { +struct charqueue { int alloc_size; int nslots; spinlock_t lock; @@ -35,12 +33,10 @@ struct CHARQUEUE_Tag { unsigned char buf[0]; }; - - -CHARQUEUE *visor_charqueue_create(ulong nslots) +struct charqueue *visor_charqueue_create(ulong nslots) { - int alloc_size = sizeof(CHARQUEUE) + nslots + 1; - CHARQUEUE *cq = kmalloc(alloc_size, GFP_KERNEL|__GFP_NORETRY); + int alloc_size = sizeof(struct charqueue) + nslots + 1; + struct charqueue *cq = kmalloc(alloc_size, GFP_KERNEL|__GFP_NORETRY); if (cq == NULL) { ERRDRV("visor_charqueue_create allocation failed (alloc_size=%d)", @@ -49,15 +45,14 @@ CHARQUEUE *visor_charqueue_create(ulong nslots) } cq->alloc_size = alloc_size; cq->nslots = nslots; - cq->head = cq->tail = 0; + cq->head = 0; + cq->tail = 0; spin_lock_init(&cq->lock); return cq; } EXPORT_SYMBOL_GPL(visor_charqueue_create); - - -void visor_charqueue_enqueue(CHARQUEUE *charqueue, unsigned char c) +void visor_charqueue_enqueue(struct charqueue *charqueue, unsigned char c) { int alloc_slots = charqueue->nslots+1; /* 1 slot is always empty */ @@ -71,9 +66,7 @@ void visor_charqueue_enqueue(CHARQUEUE *charqueue, unsigned char c) } EXPORT_SYMBOL_GPL(visor_charqueue_enqueue); - - -BOOL visor_charqueue_is_empty(CHARQUEUE *charqueue) +BOOL visor_charqueue_is_empty(struct charqueue *charqueue) { BOOL b; @@ -84,9 +77,7 @@ BOOL visor_charqueue_is_empty(CHARQUEUE *charqueue) } EXPORT_SYMBOL_GPL(visor_charqueue_is_empty); - - -static int charqueue_dequeue_1(CHARQUEUE *charqueue) +static int charqueue_dequeue_1(struct charqueue *charqueue) { int alloc_slots = charqueue->nslots + 1; /* 1 slot is always empty */ @@ -96,9 +87,7 @@ static int charqueue_dequeue_1(CHARQUEUE *charqueue) return charqueue->buf[charqueue->tail]; } - - -int charqueue_dequeue(CHARQUEUE *charqueue) +int charqueue_dequeue(struct charqueue *charqueue) { int rc; @@ -108,9 +97,8 @@ int charqueue_dequeue(CHARQUEUE *charqueue) return rc; } - - -int visor_charqueue_dequeue_n(CHARQUEUE *charqueue, unsigned char *buf, int n) +int visor_charqueue_dequeue_n(struct charqueue *charqueue, unsigned char *buf, + int n) { int rc, counter = 0, c; @@ -132,9 +120,7 @@ int visor_charqueue_dequeue_n(CHARQUEUE *charqueue, unsigned char *buf, int n) } EXPORT_SYMBOL_GPL(visor_charqueue_dequeue_n); - - -void visor_charqueue_destroy(CHARQUEUE *charqueue) +void visor_charqueue_destroy(struct charqueue *charqueue) { if (charqueue == NULL) return; diff --git a/drivers/staging/unisys/visorutil/charqueue.h b/drivers/staging/unisys/visorutil/charqueue.h index d6f16587a364..56c1f79a54b0 100644 --- a/drivers/staging/unisys/visorutil/charqueue.h +++ b/drivers/staging/unisys/visorutil/charqueue.h @@ -21,17 +21,18 @@ #include "uniklog.h" #include "timskmod.h" -/* CHARQUEUE is an opaque structure to users. +/* struct charqueue is an opaque structure to users. * Fields are declared only in the implementation .c files. */ -typedef struct CHARQUEUE_Tag CHARQUEUE; +struct charqueue; -CHARQUEUE *visor_charqueue_create(ulong nslots); -void visor_charqueue_enqueue(CHARQUEUE *charqueue, unsigned char c); -int charqueue_dequeue(CHARQUEUE *charqueue); -int visor_charqueue_dequeue_n(CHARQUEUE *charqueue, unsigned char *buf, int n); -BOOL visor_charqueue_is_empty(CHARQUEUE *charqueue); -void visor_charqueue_destroy(CHARQUEUE *charqueue); +struct charqueue *visor_charqueue_create(ulong nslots); +void visor_charqueue_enqueue(struct charqueue *charqueue, unsigned char c); +int charqueue_dequeue(struct charqueue *charqueue); +int visor_charqueue_dequeue_n(struct charqueue *charqueue, unsigned char *buf, + int n); +BOOL visor_charqueue_is_empty(struct charqueue *charqueue); +void visor_charqueue_destroy(struct charqueue *charqueue); #endif diff --git a/drivers/staging/unisys/visorutil/easyproc.c b/drivers/staging/unisys/visorutil/easyproc.c index 3b388494e2af..40f1ae9a155c 100644 --- a/drivers/staging/unisys/visorutil/easyproc.c +++ b/drivers/staging/unisys/visorutil/easyproc.c @@ -254,9 +254,9 @@ void visor_easyproc_CreateDeviceProperty(struct easyproc_device_info *p, } strcpy(px->property_name, property_name); if (px->procEntry == NULL) { - ERRDEVX(p->devno, "failed to register /proc/%s/device/%d/%s entry", - p->pdriver->ProcId, p->devno, property_name - ); + ERRDEVX(p->devno, + "failed to register /proc/%s/device/%d/%s entry", + p->pdriver->ProcId, p->devno, property_name); return; } px->show_device_property_info = show_property_info; diff --git a/drivers/staging/unisys/visorutil/memregion.h b/drivers/staging/unisys/visorutil/memregion.h index f4a65d2fcf02..0c3eebcf6d50 100644 --- a/drivers/staging/unisys/visorutil/memregion.h +++ b/drivers/staging/unisys/visorutil/memregion.h @@ -20,24 +20,24 @@ #include "timskmod.h" -/* MEMREGION is an opaque structure to users. +/* struct memregion is an opaque structure to users. * Fields are declared only in the implementation .c files. */ -typedef struct MEMREGION_Tag MEMREGION; +struct memregion; -MEMREGION *visor_memregion_create(HOSTADDRESS physaddr, ulong nbytes); -MEMREGION *visor_memregion_create_overlapped(MEMREGION *parent, - ulong offset, ulong nbytes); -int visor_memregion_resize(MEMREGION *memregion, ulong newsize); -int visor_memregion_read(MEMREGION *memregion, - ulong offset, void *dest, ulong nbytes); -int visor_memregion_write(MEMREGION *memregion, +struct memregion *visor_memregion_create(HOSTADDRESS physaddr, ulong nbytes); +struct memregion *visor_memregion_create_overlapped(struct memregion *parent, + ulong offset, ulong nbytes); +int visor_memregion_resize(struct memregion *memregion, ulong newsize); +int visor_memregion_read(struct memregion *memregion, + ulong offset, void *dest, ulong nbytes); +int visor_memregion_write(struct memregion *memregion, ulong offset, void *src, ulong nbytes); -void visor_memregion_destroy(MEMREGION *memregion); -HOSTADDRESS visor_memregion_get_physaddr(MEMREGION *memregion); -ulong visor_memregion_get_nbytes(MEMREGION *memregion); -void memregion_dump(MEMREGION *memregion, char *s, +void visor_memregion_destroy(struct memregion *memregion); +HOSTADDRESS visor_memregion_get_physaddr(struct memregion *memregion); +ulong visor_memregion_get_nbytes(struct memregion *memregion); +void memregion_dump(struct memregion *memregion, char *s, ulong off, ulong len, struct seq_file *seq); -void __iomem *visor_memregion_get_pointer(MEMREGION *memregion); +void __iomem *visor_memregion_get_pointer(struct memregion *memregion); #endif diff --git a/drivers/staging/unisys/visorutil/memregion_direct.c b/drivers/staging/unisys/visorutil/memregion_direct.c index 65bc07b947db..33522cc8c22c 100644 --- a/drivers/staging/unisys/visorutil/memregion_direct.c +++ b/drivers/staging/unisys/visorutil/memregion_direct.c @@ -26,7 +26,7 @@ #define MYDRVNAME "memregion" -struct MEMREGION_Tag { +struct memregion { HOSTADDRESS physaddr; ulong nbytes; void __iomem *mapped; @@ -34,15 +34,15 @@ struct MEMREGION_Tag { BOOL overlapped; }; -static BOOL mapit(MEMREGION *memregion); -static void unmapit(MEMREGION *memregion); +static BOOL mapit(struct memregion *memregion); +static void unmapit(struct memregion *memregion); -MEMREGION * +struct memregion * visor_memregion_create(HOSTADDRESS physaddr, ulong nbytes) { - MEMREGION *rc = NULL; - MEMREGION *memregion = kzalloc(sizeof(MEMREGION), - GFP_KERNEL | __GFP_NORETRY); + struct memregion *rc = NULL; + struct memregion *memregion = kzalloc(sizeof(*memregion), + GFP_KERNEL | __GFP_NORETRY); if (memregion == NULL) { ERRDRV("visor_memregion_create allocation failed"); return NULL; @@ -52,24 +52,23 @@ visor_memregion_create(HOSTADDRESS physaddr, ulong nbytes) memregion->overlapped = FALSE; if (!mapit(memregion)) { rc = NULL; - goto Away; + goto cleanup; } rc = memregion; -Away: +cleanup: if (rc == NULL) { - if (memregion != NULL) { - visor_memregion_destroy(memregion); - memregion = NULL; - } + visor_memregion_destroy(memregion); + memregion = NULL; } return rc; } EXPORT_SYMBOL_GPL(visor_memregion_create); -MEMREGION * -visor_memregion_create_overlapped(MEMREGION *parent, ulong offset, ulong nbytes) +struct memregion * +visor_memregion_create_overlapped(struct memregion *parent, ulong offset, + ulong nbytes) { - MEMREGION *memregion = NULL; + struct memregion *memregion = NULL; if (parent == NULL) { ERRDRV("%s parent is NULL", __func__); @@ -85,7 +84,7 @@ visor_memregion_create_overlapped(MEMREGION *parent, ulong offset, ulong nbytes) __func__, offset, nbytes); return NULL; } - memregion = kzalloc(sizeof(MEMREGION), GFP_KERNEL|__GFP_NORETRY); + memregion = kzalloc(sizeof(*memregion), GFP_KERNEL|__GFP_NORETRY); if (memregion == NULL) { ERRDRV("%s allocation failed", __func__); return NULL; @@ -93,23 +92,23 @@ visor_memregion_create_overlapped(MEMREGION *parent, ulong offset, ulong nbytes) memregion->physaddr = parent->physaddr + offset; memregion->nbytes = nbytes; - memregion->mapped = ((u8 __iomem *) (parent->mapped)) + offset; + memregion->mapped = ((u8 __iomem *)(parent->mapped)) + offset; memregion->requested = FALSE; memregion->overlapped = TRUE; return memregion; } EXPORT_SYMBOL_GPL(visor_memregion_create_overlapped); - static BOOL -mapit(MEMREGION *memregion) +mapit(struct memregion *memregion) { - ulong physaddr = (ulong) (memregion->physaddr); + ulong physaddr = (ulong)(memregion->physaddr); ulong nbytes = memregion->nbytes; memregion->requested = FALSE; if (!request_mem_region(physaddr, nbytes, MYDRVNAME)) - ERRDRV("cannot reserve channel memory @0x%lx for 0x%lx-- no big deal", physaddr, nbytes); + ERRDRV("cannot reserve channel memory @0x%lx for 0x%lx-- no big deal", + physaddr, nbytes); else memregion->requested = TRUE; memregion->mapped = ioremap_cache(physaddr, nbytes); @@ -122,42 +121,42 @@ mapit(MEMREGION *memregion) } static void -unmapit(MEMREGION *memregion) +unmapit(struct memregion *memregion) { if (memregion->mapped != NULL) { iounmap(memregion->mapped); memregion->mapped = NULL; } if (memregion->requested) { - release_mem_region((ulong) (memregion->physaddr), + release_mem_region((ulong)(memregion->physaddr), memregion->nbytes); memregion->requested = FALSE; } } HOSTADDRESS -visor_memregion_get_physaddr(MEMREGION *memregion) +visor_memregion_get_physaddr(struct memregion *memregion) { return memregion->physaddr; } EXPORT_SYMBOL_GPL(visor_memregion_get_physaddr); ulong -visor_memregion_get_nbytes(MEMREGION *memregion) +visor_memregion_get_nbytes(struct memregion *memregion) { return memregion->nbytes; } EXPORT_SYMBOL_GPL(visor_memregion_get_nbytes); void __iomem * -visor_memregion_get_pointer(MEMREGION *memregion) +visor_memregion_get_pointer(struct memregion *memregion) { return memregion->mapped; } EXPORT_SYMBOL_GPL(visor_memregion_get_pointer); int -visor_memregion_resize(MEMREGION *memregion, ulong newsize) +visor_memregion_resize(struct memregion *memregion, ulong newsize) { if (newsize == memregion->nbytes) return 0; @@ -176,10 +175,9 @@ visor_memregion_resize(MEMREGION *memregion, ulong newsize) } EXPORT_SYMBOL_GPL(visor_memregion_resize); - static int memregion_readwrite(BOOL is_write, - MEMREGION *memregion, ulong offset, + struct memregion *memregion, ulong offset, void *local, ulong nbytes) { if (offset + nbytes > memregion->nbytes) { @@ -195,7 +193,7 @@ memregion_readwrite(BOOL is_write, } int -visor_memregion_read(MEMREGION *memregion, ulong offset, void *dest, +visor_memregion_read(struct memregion *memregion, ulong offset, void *dest, ulong nbytes) { return memregion_readwrite(FALSE, memregion, offset, dest, nbytes); @@ -203,7 +201,7 @@ visor_memregion_read(MEMREGION *memregion, ulong offset, void *dest, EXPORT_SYMBOL_GPL(visor_memregion_read); int -visor_memregion_write(MEMREGION *memregion, ulong offset, void *src, +visor_memregion_write(struct memregion *memregion, ulong offset, void *src, ulong nbytes) { return memregion_readwrite(TRUE, memregion, offset, src, nbytes); @@ -211,7 +209,7 @@ visor_memregion_write(MEMREGION *memregion, ulong offset, void *src, EXPORT_SYMBOL_GPL(visor_memregion_write); void -visor_memregion_destroy(MEMREGION *memregion) +visor_memregion_destroy(struct memregion *memregion) { if (memregion == NULL) return; diff --git a/drivers/staging/unisys/visorutil/periodic_work.c b/drivers/staging/unisys/visorutil/periodic_work.c index 3dd1c04d0e14..0908bf929401 100644 --- a/drivers/staging/unisys/visorutil/periodic_work.c +++ b/drivers/staging/unisys/visorutil/periodic_work.c @@ -25,8 +25,6 @@ #define MYDRVNAME "periodic_work" - - struct periodic_work { rwlock_t lock; struct delayed_work work; @@ -39,8 +37,6 @@ struct periodic_work { const char *devnam; }; - - static void periodic_work_func(struct work_struct *work) { struct periodic_work *pw; @@ -49,8 +45,6 @@ static void periodic_work_func(struct work_struct *work) (*pw->workfunc)(pw->workfuncarg); } - - struct periodic_work *visor_periodic_work_create(ulong jiffy_interval, struct workqueue_struct *workqueue, void (*workfunc)(void *), @@ -73,16 +67,12 @@ struct periodic_work *visor_periodic_work_create(ulong jiffy_interval, } EXPORT_SYMBOL_GPL(visor_periodic_work_create); - - void visor_periodic_work_destroy(struct periodic_work *pw) { kfree(pw); } EXPORT_SYMBOL_GPL(visor_periodic_work_destroy); - - /** Call this from your periodic work worker function to schedule the next * call. * If this function returns FALSE, there was a failure and the @@ -112,8 +102,6 @@ unlock: } EXPORT_SYMBOL_GPL(visor_periodic_work_nextperiod); - - /** This function returns TRUE iff new periodic work was actually started. * If this function returns FALSE, then no work was started * (either because it was already started, or because of a failure). @@ -145,13 +133,9 @@ BOOL visor_periodic_work_start(struct periodic_work *pw) unlock: write_unlock(&pw->lock); return rc; - } EXPORT_SYMBOL_GPL(visor_periodic_work_start); - - - /** This function returns TRUE iff your call actually stopped the periodic * work. * @@ -223,8 +207,9 @@ BOOL visor_periodic_work_stop(struct periodic_work *pw) */ SLEEPJIFFIES(10); write_lock(&pw->lock); - } else + } else { pw->want_to_stop = FALSE; + } } write_unlock(&pw->lock); return stopped_something; diff --git a/drivers/staging/unisys/visorutil/procobjecttree.c b/drivers/staging/unisys/visorutil/procobjecttree.c index c476036f7382..195772d22c9e 100644 --- a/drivers/staging/unisys/visorutil/procobjecttree.c +++ b/drivers/staging/unisys/visorutil/procobjecttree.c @@ -320,19 +320,18 @@ void visor_proc_DestroyObject(MYPROCOBJECT *obj) kfree(obj->procDirProperties); obj->procDirProperties = NULL; } - if (obj->procDirPropertyContexts != NULL) { - kfree(obj->procDirPropertyContexts); - obj->procDirPropertyContexts = NULL; - } + + kfree(obj->procDirPropertyContexts); + obj->procDirPropertyContexts = NULL; + if (obj->procDir != NULL) { if (obj->name != NULL) remove_proc_entry(obj->name, type->procDir); obj->procDir = NULL; } - if (obj->name != NULL) { - kfree(obj->name); - obj->name = NULL; - } + + kfree(obj->name); + obj->name = NULL; kfree(obj); } EXPORT_SYMBOL_GPL(visor_proc_DestroyObject); diff --git a/drivers/staging/unisys/visorutil/visorkmodutils.c b/drivers/staging/unisys/visorutil/visorkmodutils.c index d6815f9e1337..556e2642d2d9 100644 --- a/drivers/staging/unisys/visorutil/visorkmodutils.c +++ b/drivers/staging/unisys/visorutil/visorkmodutils.c @@ -36,18 +36,7 @@ int unisys_spar_platform; EXPORT_SYMBOL_GPL(unisys_spar_platform); -/** Callers to interfaces that set __GFP_NORETRY flag below - * must check for a NULL (error) result as we are telling the - * kernel interface that it is okay to fail. - */ - -void *kmalloc_kernel(size_t siz) -{ - return kmalloc(siz, GFP_KERNEL | __GFP_NORETRY); -} - -static __init uint32_t -visorutil_spar_detect(void) +static __init uint32_t visorutil_spar_detect(void) { unsigned int eax, ebx, ecx, edx; @@ -57,22 +46,19 @@ visorutil_spar_detect(void) return (ebx == UNISYS_SPAR_ID_EBX) && (ecx == UNISYS_SPAR_ID_ECX) && (edx == UNISYS_SPAR_ID_EDX); - } else + } else { return 0; - + } } - - - -static __init int -visorutil_mod_init(void) +static __init int visorutil_mod_init(void) { if (visorutil_spar_detect()) { unisys_spar_platform = TRUE; return 0; - } else + } else { return -ENODEV; + } } static __exit void diff --git a/drivers/staging/vme/devices/Kconfig b/drivers/staging/vme/devices/Kconfig index 8e8bbb1dcd9b..1d2ff0cc41f1 100644 --- a/drivers/staging/vme/devices/Kconfig +++ b/drivers/staging/vme/devices/Kconfig @@ -8,6 +8,9 @@ config VME_USER VME windows in a manner at least semi-compatible with the interface provided with the original driver at <http://www.vmelinux.org/>. + To compile this driver as a module, choose M here. The module will + be called vme_user. If unsure, say N. + config VME_PIO2 tristate "GE PIO2 VME" depends on STAGING && GPIOLIB diff --git a/drivers/staging/vme/devices/vme_pio2_gpio.c b/drivers/staging/vme/devices/vme_pio2_gpio.c index c64776f71809..da34d5529f51 100644 --- a/drivers/staging/vme/devices/vme_pio2_gpio.c +++ b/drivers/staging/vme/devices/vme_pio2_gpio.c @@ -191,11 +191,11 @@ int pio2_gpio_init(struct pio2_card *card) int retval = 0; char *label; - label = kmalloc(PIO2_NUM_CHANNELS, GFP_KERNEL); + label = kasprintf(GFP_KERNEL, + "%s@%s", driver_name, dev_name(&card->vdev->dev)); if (label == NULL) return -ENOMEM; - sprintf(label, "%s@%s", driver_name, dev_name(&card->vdev->dev)); card->gc.label = label; card->gc.ngpio = PIO2_NUM_CHANNELS; diff --git a/drivers/staging/vt6655/80211hdr.h b/drivers/staging/vt6655/80211hdr.h deleted file mode 100644 index 36e14ec50564..000000000000 --- a/drivers/staging/vt6655/80211hdr.h +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: 80211hdr.h - * - * Purpose: 802.11 MAC headers related pre-defines and macros. - * - * - * Author: Lyndon Chen - * - * Date: Apr 8, 2002 - * - */ - -#ifndef __80211HDR_H__ -#define __80211HDR_H__ - -#include "ttype.h" - -/* bit type */ -#define BIT0 0x00000001 -#define BIT1 0x00000002 -#define BIT2 0x00000004 -#define BIT3 0x00000008 -#define BIT4 0x00000010 -#define BIT5 0x00000020 -#define BIT6 0x00000040 -#define BIT7 0x00000080 -#define BIT8 0x00000100 -#define BIT9 0x00000200 -#define BIT10 0x00000400 -#define BIT11 0x00000800 -#define BIT12 0x00001000 -#define BIT13 0x00002000 -#define BIT14 0x00004000 -#define BIT15 0x00008000 -#define BIT16 0x00010000 -#define BIT17 0x00020000 -#define BIT18 0x00040000 -#define BIT19 0x00080000 -#define BIT20 0x00100000 -#define BIT21 0x00200000 -#define BIT22 0x00400000 -#define BIT23 0x00800000 -#define BIT24 0x01000000 -#define BIT25 0x02000000 -#define BIT26 0x04000000 -#define BIT27 0x08000000 -#define BIT28 0x10000000 -#define BIT29 0x20000000 -#define BIT30 0x40000000 -#define BIT31 0x80000000 - -/* 802.11 frame related, defined as 802.11 spec */ -#define WLAN_ADDR_LEN 6 -#define WLAN_CRC_LEN 4 -#define WLAN_CRC32_LEN 4 -#define WLAN_FCS_LEN 4 -#define WLAN_BSSID_LEN 6 -#define WLAN_BSS_TS_LEN 8 -#define WLAN_HDR_ADDR2_LEN 16 -#define WLAN_HDR_ADDR3_LEN 24 -#define WLAN_HDR_ADDR4_LEN 30 -#define WLAN_IEHDR_LEN 2 -#define WLAN_SSID_MAXLEN 32 -#define WLAN_RATES_MAXLEN 16 -#define WLAN_RATES_MAXLEN_11B 4 -#define WLAN_RSN_MAXLEN 32 -#define WLAN_DATA_MAXLEN 2312 -#define WLAN_A3FR_MAXLEN (WLAN_HDR_ADDR3_LEN + WLAN_DATA_MAXLEN + \ - WLAN_CRC_LEN) - -#define WLAN_BEACON_FR_MAXLEN WLAN_A3FR_MAXLEN -#define WLAN_ATIM_FR_MAXLEN (WLAN_HDR_ADDR3_LEN + 0) -#define WLAN_NULLDATA_FR_MAXLEN (WLAN_HDR_ADDR3_LEN + 0) -#define WLAN_DISASSOC_FR_MAXLEN (WLAN_HDR_ADDR3_LEN + 2) -#define WLAN_ASSOCREQ_FR_MAXLEN WLAN_A3FR_MAXLEN -#define WLAN_ASSOCRESP_FR_MAXLEN WLAN_A3FR_MAXLEN -#define WLAN_REASSOCREQ_FR_MAXLEN WLAN_A3FR_MAXLEN -#define WLAN_REASSOCRESP_FR_MAXLEN WLAN_A3FR_MAXLEN -#define WLAN_PROBEREQ_FR_MAXLEN WLAN_A3FR_MAXLEN -#define WLAN_PROBERESP_FR_MAXLEN WLAN_A3FR_MAXLEN -#define WLAN_AUTHEN_FR_MAXLEN WLAN_A3FR_MAXLEN -#define WLAN_DEAUTHEN_FR_MAXLEN (WLAN_HDR_ADDR3_LEN + 2) - -#define WLAN_WEP_NKEYS 4 -#define WLAN_WEP40_KEYLEN 5 -#define WLAN_WEP104_KEYLEN 13 -#define WLAN_WEP232_KEYLEN 29 -#define WLAN_WEPMAX_KEYLEN 32 -#define WLAN_CHALLENGE_IE_MAXLEN 255 -#define WLAN_CHALLENGE_IE_LEN 130 -#define WLAN_CHALLENGE_LEN 128 -#define WLAN_WEP_IV_LEN 4 -#define WLAN_WEP_ICV_LEN 4 -#define WLAN_FRAGS_MAX 16 - -/* Frame Type */ -#define WLAN_TYPE_MGR 0x00 -#define WLAN_TYPE_CTL 0x01 -#define WLAN_TYPE_DATA 0x02 - -#define WLAN_FTYPE_MGMT 0x00 -#define WLAN_FTYPE_CTL 0x01 -#define WLAN_FTYPE_DATA 0x02 - -/* Frame Subtypes */ -#define WLAN_FSTYPE_ASSOCREQ 0x00 -#define WLAN_FSTYPE_ASSOCRESP 0x01 -#define WLAN_FSTYPE_REASSOCREQ 0x02 -#define WLAN_FSTYPE_REASSOCRESP 0x03 -#define WLAN_FSTYPE_PROBEREQ 0x04 -#define WLAN_FSTYPE_PROBERESP 0x05 -#define WLAN_FSTYPE_BEACON 0x08 -#define WLAN_FSTYPE_ATIM 0x09 -#define WLAN_FSTYPE_DISASSOC 0x0a -#define WLAN_FSTYPE_AUTHEN 0x0b -#define WLAN_FSTYPE_DEAUTHEN 0x0c -#define WLAN_FSTYPE_ACTION 0x0d - -/* Control */ -#define WLAN_FSTYPE_PSPOLL 0x0a -#define WLAN_FSTYPE_RTS 0x0b -#define WLAN_FSTYPE_CTS 0x0c -#define WLAN_FSTYPE_ACK 0x0d -#define WLAN_FSTYPE_CFEND 0x0e -#define WLAN_FSTYPE_CFENDCFACK 0x0f - -/* Data */ -#define WLAN_FSTYPE_DATAONLY 0x00 -#define WLAN_FSTYPE_DATA_CFACK 0x01 -#define WLAN_FSTYPE_DATA_CFPOLL 0x02 -#define WLAN_FSTYPE_DATA_CFACK_CFPOLL 0x03 -#define WLAN_FSTYPE_NULL 0x04 -#define WLAN_FSTYPE_CFACK 0x05 -#define WLAN_FSTYPE_CFPOLL 0x06 -#define WLAN_FSTYPE_CFACK_CFPOLL 0x07 - -#ifdef __BIG_ENDIAN - -/* GET & SET Frame Control bit */ -#define WLAN_GET_FC_PRVER(n) (((unsigned short)(n) >> 8) & (BIT0 | BIT1)) -#define WLAN_GET_FC_FTYPE(n) ((((unsigned short)(n) >> 8) & (BIT2 | BIT3)) >> 2) -#define WLAN_GET_FC_FSTYPE(n) ((((unsigned short)(n) >> 8) & (BIT4|BIT5|BIT6|BIT7)) >> 4) -#define WLAN_GET_FC_TODS(n) ((((unsigned short)(n) << 8) & (BIT8)) >> 8) -#define WLAN_GET_FC_FROMDS(n) ((((unsigned short)(n) << 8) & (BIT9)) >> 9) -#define WLAN_GET_FC_MOREFRAG(n) ((((unsigned short)(n) << 8) & (BIT10)) >> 10) -#define WLAN_GET_FC_RETRY(n) ((((unsigned short)(n) << 8) & (BIT11)) >> 11) -#define WLAN_GET_FC_PWRMGT(n) ((((unsigned short)(n) << 8) & (BIT12)) >> 12) -#define WLAN_GET_FC_MOREDATA(n) ((((unsigned short)(n) << 8) & (BIT13)) >> 13) -#define WLAN_GET_FC_ISWEP(n) ((((unsigned short)(n) << 8) & (BIT14)) >> 14) -#define WLAN_GET_FC_ORDER(n) ((((unsigned short)(n) << 8) & (BIT15)) >> 15) - -/* Sequence Field bit */ -#define WLAN_GET_SEQ_FRGNUM(n) (((unsigned short)(n) >> 8) & (BIT0|BIT1|BIT2|BIT3)) -#define WLAN_GET_SEQ_SEQNUM(n) ((((unsigned short)(n) >> 8) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4) - -/* Capability Field bit */ -#define WLAN_GET_CAP_INFO_ESS(n) (((n) >> 8) & BIT0) -#define WLAN_GET_CAP_INFO_IBSS(n) ((((n) >> 8) & BIT1) >> 1) -#define WLAN_GET_CAP_INFO_CFPOLLABLE(n) ((((n) >> 8) & BIT2) >> 2) -#define WLAN_GET_CAP_INFO_CFPOLLREQ(n) ((((n) >> 8) & BIT3) >> 3) -#define WLAN_GET_CAP_INFO_PRIVACY(n) ((((n) >> 8) & BIT4) >> 4) -#define WLAN_GET_CAP_INFO_SHORTPREAMBLE(n) ((((n) >> 8) & BIT5) >> 5) -#define WLAN_GET_CAP_INFO_PBCC(n) ((((n) >> 8) & BIT6) >> 6) -#define WLAN_GET_CAP_INFO_AGILITY(n) ((((n) >> 8) & BIT7) >> 7) -#define WLAN_GET_CAP_INFO_SPECTRUMMNG(n) ((((n)) & BIT8) >> 10) -#define WLAN_GET_CAP_INFO_SHORTSLOTTIME(n) ((((n)) & BIT10) >> 10) -#define WLAN_GET_CAP_INFO_DSSSOFDM(n) ((((n)) & BIT13) >> 13) -#define WLAN_GET_CAP_INFO_GRPACK(n) ((((n)) & BIT14) >> 14) - -#else - -/* GET & SET Frame Control bit */ -#define WLAN_GET_FC_PRVER(n) (((unsigned short)(n)) & (BIT0 | BIT1)) -#define WLAN_GET_FC_FTYPE(n) ((((unsigned short)(n)) & (BIT2 | BIT3)) >> 2) -#define WLAN_GET_FC_FSTYPE(n) ((((unsigned short)(n)) & (BIT4|BIT5|BIT6|BIT7)) >> 4) -#define WLAN_GET_FC_TODS(n) ((((unsigned short)(n)) & (BIT8)) >> 8) -#define WLAN_GET_FC_FROMDS(n) ((((unsigned short)(n)) & (BIT9)) >> 9) -#define WLAN_GET_FC_MOREFRAG(n) ((((unsigned short)(n)) & (BIT10)) >> 10) -#define WLAN_GET_FC_RETRY(n) ((((unsigned short)(n)) & (BIT11)) >> 11) -#define WLAN_GET_FC_PWRMGT(n) ((((unsigned short)(n)) & (BIT12)) >> 12) -#define WLAN_GET_FC_MOREDATA(n) ((((unsigned short)(n)) & (BIT13)) >> 13) -#define WLAN_GET_FC_ISWEP(n) ((((unsigned short)(n)) & (BIT14)) >> 14) -#define WLAN_GET_FC_ORDER(n) ((((unsigned short)(n)) & (BIT15)) >> 15) - -/* Sequence Field bit */ -#define WLAN_GET_SEQ_FRGNUM(n) (((unsigned short)(n)) & (BIT0|BIT1|BIT2|BIT3)) -#define WLAN_GET_SEQ_SEQNUM(n) ((((unsigned short)(n)) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4) - -/* Capability Field bit */ -#define WLAN_GET_CAP_INFO_ESS(n) ((n) & BIT0) -#define WLAN_GET_CAP_INFO_IBSS(n) (((n) & BIT1) >> 1) -#define WLAN_GET_CAP_INFO_CFPOLLABLE(n) (((n) & BIT2) >> 2) -#define WLAN_GET_CAP_INFO_CFPOLLREQ(n) (((n) & BIT3) >> 3) -#define WLAN_GET_CAP_INFO_PRIVACY(n) (((n) & BIT4) >> 4) -#define WLAN_GET_CAP_INFO_SHORTPREAMBLE(n) (((n) & BIT5) >> 5) -#define WLAN_GET_CAP_INFO_PBCC(n) (((n) & BIT6) >> 6) -#define WLAN_GET_CAP_INFO_AGILITY(n) (((n) & BIT7) >> 7) -#define WLAN_GET_CAP_INFO_SPECTRUMMNG(n) (((n) & BIT8) >> 10) -#define WLAN_GET_CAP_INFO_SHORTSLOTTIME(n) (((n) & BIT10) >> 10) -#define WLAN_GET_CAP_INFO_DSSSOFDM(n) (((n) & BIT13) >> 13) -#define WLAN_GET_CAP_INFO_GRPACK(n) (((n) & BIT14) >> 14) - -#endif /*#ifdef __BIG_ENDIAN */ - -#define WLAN_SET_CAP_INFO_ESS(n) (n) -#define WLAN_SET_CAP_INFO_IBSS(n) ((n) << 1) -#define WLAN_SET_CAP_INFO_CFPOLLABLE(n) ((n) << 2) -#define WLAN_SET_CAP_INFO_CFPOLLREQ(n) ((n) << 3) -#define WLAN_SET_CAP_INFO_PRIVACY(n) ((n) << 4) -#define WLAN_SET_CAP_INFO_SHORTPREAMBLE(n) ((n) << 5) -#define WLAN_SET_CAP_INFO_SPECTRUMMNG(n) ((n) << 8) -#define WLAN_SET_CAP_INFO_PBCC(n) ((n) << 6) -#define WLAN_SET_CAP_INFO_AGILITY(n) ((n) << 7) -#define WLAN_SET_CAP_INFO_SHORTSLOTTIME(n) ((n) << 10) -#define WLAN_SET_CAP_INFO_DSSSOFDM(n) ((n) << 13) -#define WLAN_SET_CAP_INFO_GRPACK(n) ((n) << 14) - -#define WLAN_SET_FC_PRVER(n) ((unsigned short)(n)) -#define WLAN_SET_FC_FTYPE(n) (((unsigned short)(n)) << 2) -#define WLAN_SET_FC_FSTYPE(n) (((unsigned short)(n)) << 4) -#define WLAN_SET_FC_TODS(n) (((unsigned short)(n)) << 8) -#define WLAN_SET_FC_FROMDS(n) (((unsigned short)(n)) << 9) -#define WLAN_SET_FC_MOREFRAG(n) (((unsigned short)(n)) << 10) -#define WLAN_SET_FC_RETRY(n) (((unsigned short)(n)) << 11) -#define WLAN_SET_FC_PWRMGT(n) (((unsigned short)(n)) << 12) -#define WLAN_SET_FC_MOREDATA(n) (((unsigned short)(n)) << 13) -#define WLAN_SET_FC_ISWEP(n) (((unsigned short)(n)) << 14) -#define WLAN_SET_FC_ORDER(n) (((unsigned short)(n)) << 15) - -#define WLAN_SET_SEQ_FRGNUM(n) ((unsigned short)(n)) -#define WLAN_SET_SEQ_SEQNUM(n) (((unsigned short)(n)) << 4) - -/* ERP Field bit */ - -#define WLAN_GET_ERP_NONERP_PRESENT(n) ((n) & BIT0) -#define WLAN_GET_ERP_USE_PROTECTION(n) (((n) & BIT1) >> 1) -#define WLAN_GET_ERP_BARKER_MODE(n) (((n) & BIT2) >> 2) - -#define WLAN_SET_ERP_NONERP_PRESENT(n) (n) -#define WLAN_SET_ERP_USE_PROTECTION(n) ((n) << 1) -#define WLAN_SET_ERP_BARKER_MODE(n) ((n) << 2) - -/* Support & Basic Rates field */ -#define WLAN_MGMT_IS_BASICRATE(b) ((b) & BIT7) -#define WLAN_MGMT_GET_RATE(b) ((b) & ~BIT7) - -/* TIM field */ -#define WLAN_MGMT_IS_MULTICAST_TIM(b) ((b) & BIT0) -#define WLAN_MGMT_GET_TIM_OFFSET(b) (((b) & ~BIT0) >> 1) - -/* 3-Addr & 4-Addr */ -#define WLAN_HDR_A3_DATA_PTR(p) (((unsigned char *)(p)) + WLAN_HDR_ADDR3_LEN) -#define WLAN_HDR_A4_DATA_PTR(p) (((unsigned char *)(p)) + WLAN_HDR_ADDR4_LEN) - -/* IEEE ADDR */ -#define IEEE_ADDR_UNIVERSAL 0x02 -#define IEEE_ADDR_GROUP 0x01 - -typedef struct { - unsigned char abyAddr[6]; -} IEEE_ADDR, *PIEEE_ADDR; - -/* 802.11 Header Format */ - -typedef struct tagWLAN_80211HDR_A2 { - unsigned short wFrameCtl; - unsigned short wDurationID; - unsigned char abyAddr1[WLAN_ADDR_LEN]; - unsigned char abyAddr2[WLAN_ADDR_LEN]; -} __attribute__ ((__packed__)) -WLAN_80211HDR_A2, *PWLAN_80211HDR_A2; - -typedef struct tagWLAN_80211HDR_A3 { - unsigned short wFrameCtl; - unsigned short wDurationID; - unsigned char abyAddr1[WLAN_ADDR_LEN]; - unsigned char abyAddr2[WLAN_ADDR_LEN]; - unsigned char abyAddr3[WLAN_ADDR_LEN]; - unsigned short wSeqCtl; -} __attribute__ ((__packed__)) -WLAN_80211HDR_A3, *PWLAN_80211HDR_A3; - -typedef struct tagWLAN_80211HDR_A4 { - unsigned short wFrameCtl; - unsigned short wDurationID; - unsigned char abyAddr1[WLAN_ADDR_LEN]; - unsigned char abyAddr2[WLAN_ADDR_LEN]; - unsigned char abyAddr3[WLAN_ADDR_LEN]; - unsigned short wSeqCtl; - unsigned char abyAddr4[WLAN_ADDR_LEN]; -} __attribute__ ((__packed__)) -WLAN_80211HDR_A4, *PWLAN_80211HDR_A4; - -typedef union tagUWLAN_80211HDR { - WLAN_80211HDR_A2 sA2; - WLAN_80211HDR_A3 sA3; - WLAN_80211HDR_A4 sA4; -} UWLAN_80211HDR, *PUWLAN_80211HDR; - -#endif /* __80211HDR_H__ */ diff --git a/drivers/staging/vt6655/80211mgr.c b/drivers/staging/vt6655/80211mgr.c deleted file mode 100644 index 7d2c6472ec9a..000000000000 --- a/drivers/staging/vt6655/80211mgr.c +++ /dev/null @@ -1,1019 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: 80211mgr.c - * - * Purpose: Handles the 802.11 management support functions - * - * Author: Lyndon Chen - * - * Date: May 8, 2002 - * - * Functions: - * vMgrEncodeBeacon - Encode the Beacon frame - * vMgrDecodeBeacon - Decode the Beacon frame - * vMgrEncodeIBSSATIM - Encode the IBSS ATIM frame - * vMgrDecodeIBSSATIM - Decode the IBSS ATIM frame - * vMgrEncodeDisassociation - Encode the Disassociation frame - * vMgrDecodeDisassociation - Decode the Disassociation frame - * vMgrEncodeAssocRequest - Encode the Association request frame - * vMgrDecodeAssocRequest - Decode the Association request frame - * vMgrEncodeAssocResponse - Encode the Association response frame - * vMgrDecodeAssocResponse - Decode the Association response frame - * vMgrEncodeReAssocRequest - Encode the ReAssociation request frame - * vMgrDecodeReAssocRequest - Decode the ReAssociation request frame - * vMgrEncodeProbeRequest - Encode the Probe request frame - * vMgrDecodeProbeRequest - Decode the Probe request frame - * vMgrEncodeProbeResponse - Encode the Probe response frame - * vMgrDecodeProbeResponse - Decode the Probe response frame - * vMgrEncodeAuthen - Encode the Authentication frame - * vMgrDecodeAuthen - Decode the Authentication frame - * vMgrEncodeDeauthen - Encode the DeAuthentication frame - * vMgrDecodeDeauthen - Decode the DeAuthentication frame - * vMgrEncodeReassocResponse - Encode the Reassociation response frame - * vMgrDecodeReassocResponse - Decode the Reassociation response frame - * - * Revision History: - * - */ - -#include "tmacro.h" -#include "tether.h" -#include "80211mgr.h" -#include "80211hdr.h" -#include "device.h" -#include "wpa.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -/*+ - * - * Routine Description: - * Encode Beacon frame body offset - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeBeacon( - PWLAN_FR_BEACON pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pqwTimestamp = (__le64 *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_BEACON_OFF_TS); - pFrame->pwBeaconInterval = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_BEACON_OFF_BCN_INT); - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_BEACON_OFF_CAPINFO); - - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_BEACON_OFF_SSID; -} - -/*+ - * - * Routine Description: - * Decode Beacon frame body offset - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeBeacon( - PWLAN_FR_BEACON pFrame -) -{ - PWLAN_IE pItem; - - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pqwTimestamp = (__le64 *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_BEACON_OFF_TS); - pFrame->pwBeaconInterval = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_BEACON_OFF_BCN_INT); - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_BEACON_OFF_CAPINFO); - - /* Information elements */ - pItem = (PWLAN_IE)((unsigned char *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))) + - WLAN_BEACON_OFF_SSID); - while (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) { - switch (pItem->byElementID) { - case WLAN_EID_SSID: - if (pFrame->pSSID == NULL) - pFrame->pSSID = (PWLAN_IE_SSID)pItem; - break; - case WLAN_EID_SUPP_RATES: - if (pFrame->pSuppRates == NULL) - pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem; - break; - case WLAN_EID_FH_PARMS: - /* pFrame->pFHParms = (PWLAN_IE_FH_PARMS)pItem; */ - break; - case WLAN_EID_DS_PARMS: - if (pFrame->pDSParms == NULL) - pFrame->pDSParms = (PWLAN_IE_DS_PARMS)pItem; - break; - case WLAN_EID_CF_PARMS: - if (pFrame->pCFParms == NULL) - pFrame->pCFParms = (PWLAN_IE_CF_PARMS)pItem; - break; - case WLAN_EID_IBSS_PARMS: - if (pFrame->pIBSSParms == NULL) - pFrame->pIBSSParms = (PWLAN_IE_IBSS_PARMS)pItem; - break; - case WLAN_EID_TIM: - if (pFrame->pTIM == NULL) - pFrame->pTIM = (PWLAN_IE_TIM)pItem; - break; - - case WLAN_EID_RSN: - if (pFrame->pRSN == NULL) - pFrame->pRSN = (PWLAN_IE_RSN)pItem; - break; - case WLAN_EID_RSN_WPA: - if (pFrame->pRSNWPA == NULL) { - if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true) - pFrame->pRSNWPA = - (PWLAN_IE_RSN_EXT)pItem; - } - break; - - case WLAN_EID_ERP: - if (pFrame->pERP == NULL) - pFrame->pERP = (PWLAN_IE_ERP)pItem; - break; - case WLAN_EID_EXTSUPP_RATES: - if (pFrame->pExtSuppRates == NULL) - pFrame->pExtSuppRates = - (PWLAN_IE_SUPP_RATES)pItem; - break; - - case WLAN_EID_COUNTRY: /* 7 */ - if (pFrame->pIE_Country == NULL) - pFrame->pIE_Country = (PWLAN_IE_COUNTRY)pItem; - break; - - case WLAN_EID_PWR_CONSTRAINT: /* 32 */ - if (pFrame->pIE_PowerConstraint == NULL) - pFrame->pIE_PowerConstraint = - (PWLAN_IE_PW_CONST)pItem; - break; - - case WLAN_EID_CH_SWITCH: /* 37 */ - if (pFrame->pIE_CHSW == NULL) - pFrame->pIE_CHSW = (PWLAN_IE_CH_SW)pItem; - break; - - case WLAN_EID_QUIET: /* 40 */ - if (pFrame->pIE_Quiet == NULL) - pFrame->pIE_Quiet = (PWLAN_IE_QUIET)pItem; - break; - - case WLAN_EID_IBSS_DFS: - if (pFrame->pIE_IBSSDFS == NULL) - pFrame->pIE_IBSSDFS = (PWLAN_IE_IBSS_DFS)pItem; - break; - - default: - pr_debug("Unrecognized EID=%dd in beacon decode\n", - pItem->byElementID); - break; - - } - pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); - } -} - -/*+ - * - * Routine Description: - * Encode IBSS ATIM - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeIBSSATIM( - PWLAN_FR_IBSSATIM pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - pFrame->len = WLAN_HDR_ADDR3_LEN; -} - -/*+ - * - * Routine Description: - * Decode IBSS ATIM - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeIBSSATIM( - PWLAN_FR_IBSSATIM pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; -} - -/*+ - * - * Routine Description: - * Encode Disassociation - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeDisassociation( - PWLAN_FR_DISASSOC pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwReason = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_DISASSOC_OFF_REASON); - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DISASSOC_OFF_REASON + - sizeof(*(pFrame->pwReason)); -} - -/*+ - * - * Routine Description: - * Decode Disassociation - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeDisassociation( - PWLAN_FR_DISASSOC pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwReason = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_DISASSOC_OFF_REASON); -} - -/*+ - * - * Routine Description: - * Encode Association Request - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeAssocRequest( - PWLAN_FR_ASSOCREQ pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - /* Fixed Fields */ - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCREQ_OFF_CAP_INFO); - pFrame->pwListenInterval = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCREQ_OFF_LISTEN_INT); - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCREQ_OFF_LISTEN_INT + - sizeof(*(pFrame->pwListenInterval)); -} - -/*+ - * - * Routine Description: (AP) - * Decode Association Request - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeAssocRequest( - PWLAN_FR_ASSOCREQ pFrame -) -{ - PWLAN_IE pItem; - - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - /* Fixed Fields */ - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCREQ_OFF_CAP_INFO); - pFrame->pwListenInterval = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCREQ_OFF_LISTEN_INT); - - /* Information elements */ - pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_ASSOCREQ_OFF_SSID); - - while (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) { - switch (pItem->byElementID) { - case WLAN_EID_SSID: - if (pFrame->pSSID == NULL) - pFrame->pSSID = (PWLAN_IE_SSID)pItem; - break; - case WLAN_EID_SUPP_RATES: - if (pFrame->pSuppRates == NULL) - pFrame->pSuppRates = - (PWLAN_IE_SUPP_RATES)pItem; - break; - - case WLAN_EID_RSN: - if (pFrame->pRSN == NULL) - pFrame->pRSN = (PWLAN_IE_RSN)pItem; - break; - case WLAN_EID_RSN_WPA: - if (pFrame->pRSNWPA == NULL) { - if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true) - pFrame->pRSNWPA = - (PWLAN_IE_RSN_EXT)pItem; - } - break; - case WLAN_EID_EXTSUPP_RATES: - if (pFrame->pExtSuppRates == NULL) - pFrame->pExtSuppRates = - (PWLAN_IE_SUPP_RATES)pItem; - break; - - default: - pr_debug("Unrecognized EID=%dd in assocreq decode\n", - pItem->byElementID); - break; - } - pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); - } -} - -/*+ - * - * Routine Description: (AP) - * Encode Association Response - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeAssocResponse( - PWLAN_FR_ASSOCRESP pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCRESP_OFF_CAP_INFO); - pFrame->pwStatus = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCRESP_OFF_STATUS); - pFrame->pwAid = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCRESP_OFF_AID); - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCRESP_OFF_AID + - sizeof(*(pFrame->pwAid)); -} - -/*+ - * - * Routine Description: - * Decode Association Response - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeAssocResponse( - PWLAN_FR_ASSOCRESP pFrame -) -{ - PWLAN_IE pItem; - - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCRESP_OFF_CAP_INFO); - pFrame->pwStatus = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCRESP_OFF_STATUS); - pFrame->pwAid = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCRESP_OFF_AID); - - /* Information elements */ - pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCRESP_OFF_SUPP_RATES); - - pItem = (PWLAN_IE)(pFrame->pSuppRates); - pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); - - if ((((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) && - (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) { - pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem; - pr_debug("pFrame->pExtSuppRates=[%p]\n", pItem); - } else { - pFrame->pExtSuppRates = NULL; - } -} - -/*+ - * - * Routine Description: - * Encode Reassociation Request - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeReassocRequest( - PWLAN_FR_REASSOCREQ pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCREQ_OFF_CAP_INFO); - pFrame->pwListenInterval = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCREQ_OFF_LISTEN_INT); - pFrame->pAddrCurrAP = (PIEEE_ADDR) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCREQ_OFF_CURR_AP); - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_REASSOCREQ_OFF_CURR_AP + - sizeof(*(pFrame->pAddrCurrAP)); -} - -/*+ - * - * Routine Description: (AP) - * Decode Reassociation Request - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeReassocRequest( - PWLAN_FR_REASSOCREQ pFrame -) -{ - PWLAN_IE pItem; - - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCREQ_OFF_CAP_INFO); - pFrame->pwListenInterval = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCREQ_OFF_LISTEN_INT); - pFrame->pAddrCurrAP = (PIEEE_ADDR) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCREQ_OFF_CURR_AP); - - /* Information elements */ - pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_REASSOCREQ_OFF_SSID); - - while (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) { - switch (pItem->byElementID) { - case WLAN_EID_SSID: - if (pFrame->pSSID == NULL) - pFrame->pSSID = (PWLAN_IE_SSID)pItem; - break; - case WLAN_EID_SUPP_RATES: - if (pFrame->pSuppRates == NULL) - pFrame->pSuppRates = - (PWLAN_IE_SUPP_RATES)pItem; - break; - - case WLAN_EID_RSN: - if (pFrame->pRSN == NULL) - pFrame->pRSN = (PWLAN_IE_RSN)pItem; - break; - case WLAN_EID_RSN_WPA: - if (pFrame->pRSNWPA == NULL) { - if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true) - pFrame->pRSNWPA = - (PWLAN_IE_RSN_EXT)pItem; - } - break; - - case WLAN_EID_EXTSUPP_RATES: - if (pFrame->pExtSuppRates == NULL) - pFrame->pExtSuppRates = - (PWLAN_IE_SUPP_RATES)pItem; - break; - default: - pr_debug("Unrecognized EID=%dd in reassocreq decode\n", - pItem->byElementID); - break; - } - pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); - } -} - -/*+ - * - * Routine Description: - * Encode Probe Request - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeProbeRequest( - PWLAN_FR_PROBEREQ pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - pFrame->len = WLAN_HDR_ADDR3_LEN; -} - -/*+ - * - * Routine Description: - * Decode Probe Request - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeProbeRequest( - PWLAN_FR_PROBEREQ pFrame -) -{ - PWLAN_IE pItem; - - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Information elements */ - pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))); - - while (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) { - switch (pItem->byElementID) { - case WLAN_EID_SSID: - if (pFrame->pSSID == NULL) - pFrame->pSSID = (PWLAN_IE_SSID)pItem; - break; - - case WLAN_EID_SUPP_RATES: - if (pFrame->pSuppRates == NULL) - pFrame->pSuppRates = - (PWLAN_IE_SUPP_RATES)pItem; - break; - - case WLAN_EID_EXTSUPP_RATES: - if (pFrame->pExtSuppRates == NULL) - pFrame->pExtSuppRates = - (PWLAN_IE_SUPP_RATES)pItem; - break; - - default: - pr_debug("Bad EID=%dd in probereq\n", - pItem->byElementID); - break; - } - - pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); - } -} - -/*+ - * - * Routine Description: - * Encode Probe Response - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeProbeResponse( - PWLAN_FR_PROBERESP pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pqwTimestamp = (__le64 *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_PROBERESP_OFF_TS); - pFrame->pwBeaconInterval = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_PROBERESP_OFF_BCN_INT); - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_PROBERESP_OFF_CAP_INFO); - - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_PROBERESP_OFF_CAP_INFO + - sizeof(*(pFrame->pwCapInfo)); -} - -/*+ - * - * Routine Description: - * Decode Probe Response - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeProbeResponse( - PWLAN_FR_PROBERESP pFrame -) -{ - PWLAN_IE pItem; - - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pqwTimestamp = (__le64 *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_PROBERESP_OFF_TS); - pFrame->pwBeaconInterval = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_PROBERESP_OFF_BCN_INT); - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_PROBERESP_OFF_CAP_INFO); - - /* Information elements */ - pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_PROBERESP_OFF_SSID); - - while (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) { - switch (pItem->byElementID) { - case WLAN_EID_SSID: - if (pFrame->pSSID == NULL) - pFrame->pSSID = (PWLAN_IE_SSID)pItem; - break; - case WLAN_EID_SUPP_RATES: - if (pFrame->pSuppRates == NULL) - pFrame->pSuppRates = - (PWLAN_IE_SUPP_RATES)pItem; - break; - case WLAN_EID_FH_PARMS: - break; - case WLAN_EID_DS_PARMS: - if (pFrame->pDSParms == NULL) - pFrame->pDSParms = (PWLAN_IE_DS_PARMS)pItem; - break; - case WLAN_EID_CF_PARMS: - if (pFrame->pCFParms == NULL) - pFrame->pCFParms = (PWLAN_IE_CF_PARMS)pItem; - break; - case WLAN_EID_IBSS_PARMS: - if (pFrame->pIBSSParms == NULL) - pFrame->pIBSSParms = - (PWLAN_IE_IBSS_PARMS)pItem; - break; - - case WLAN_EID_RSN: - if (pFrame->pRSN == NULL) - pFrame->pRSN = (PWLAN_IE_RSN)pItem; - break; - case WLAN_EID_RSN_WPA: - if (pFrame->pRSNWPA == NULL) { - if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true) - pFrame->pRSNWPA = - (PWLAN_IE_RSN_EXT)pItem; - } - break; - case WLAN_EID_ERP: - if (pFrame->pERP == NULL) - pFrame->pERP = (PWLAN_IE_ERP)pItem; - break; - case WLAN_EID_EXTSUPP_RATES: - if (pFrame->pExtSuppRates == NULL) - pFrame->pExtSuppRates = - (PWLAN_IE_SUPP_RATES)pItem; - break; - - case WLAN_EID_COUNTRY: /* 7 */ - if (pFrame->pIE_Country == NULL) - pFrame->pIE_Country = (PWLAN_IE_COUNTRY)pItem; - break; - - case WLAN_EID_PWR_CONSTRAINT: /* 32 */ - if (pFrame->pIE_PowerConstraint == NULL) - pFrame->pIE_PowerConstraint = - (PWLAN_IE_PW_CONST)pItem; - break; - - case WLAN_EID_CH_SWITCH: /* 37 */ - if (pFrame->pIE_CHSW == NULL) - pFrame->pIE_CHSW = (PWLAN_IE_CH_SW)pItem; - break; - - case WLAN_EID_QUIET: /* 40 */ - if (pFrame->pIE_Quiet == NULL) - pFrame->pIE_Quiet = (PWLAN_IE_QUIET)pItem; - break; - - case WLAN_EID_IBSS_DFS: - if (pFrame->pIE_IBSSDFS == NULL) - pFrame->pIE_IBSSDFS = (PWLAN_IE_IBSS_DFS)pItem; - break; - - default: - pr_debug("Bad EID=%dd in proberesp\n", - pItem->byElementID); - break; - } - - pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); - } -} - -/*+ - * - * Routine Description: - * Encode Authentication frame - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeAuthen( - PWLAN_FR_AUTHEN pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwAuthAlgorithm = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_AUTHEN_OFF_AUTH_ALG); - pFrame->pwAuthSequence = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_AUTHEN_OFF_AUTH_SEQ); - pFrame->pwStatus = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_AUTHEN_OFF_STATUS); - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_AUTHEN_OFF_STATUS + - sizeof(*(pFrame->pwStatus)); -} - -/*+ - * - * Routine Description: - * Decode Authentication - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeAuthen( - PWLAN_FR_AUTHEN pFrame -) -{ - PWLAN_IE pItem; - - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwAuthAlgorithm = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_AUTHEN_OFF_AUTH_ALG); - pFrame->pwAuthSequence = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_AUTHEN_OFF_AUTH_SEQ); - pFrame->pwStatus = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_AUTHEN_OFF_STATUS); - - /* Information elements */ - pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_AUTHEN_OFF_CHALLENGE); - - if (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len) && - pItem->byElementID == WLAN_EID_CHALLENGE) - pFrame->pChallenge = (PWLAN_IE_CHALLENGE)pItem; -} - -/*+ - * - * Routine Description: - * Encode Authentication - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeDeauthen( - PWLAN_FR_DEAUTHEN pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwReason = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_DEAUTHEN_OFF_REASON); - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DEAUTHEN_OFF_REASON + - sizeof(*(pFrame->pwReason)); -} - -/*+ - * - * Routine Description: - * Decode Deauthentication - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeDeauthen( - PWLAN_FR_DEAUTHEN pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwReason = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_DEAUTHEN_OFF_REASON); -} - -/*+ - * - * Routine Description: (AP) - * Encode Reassociation Response - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeReassocResponse( - PWLAN_FR_REASSOCRESP pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCRESP_OFF_CAP_INFO); - pFrame->pwStatus = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCRESP_OFF_STATUS); - pFrame->pwAid = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCRESP_OFF_AID); - - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_REASSOCRESP_OFF_AID + - sizeof(*(pFrame->pwAid)); -} - -/*+ - * - * Routine Description: - * Decode Reassociation Response - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeReassocResponse( - PWLAN_FR_REASSOCRESP pFrame -) -{ - PWLAN_IE pItem; - - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCRESP_OFF_CAP_INFO); - pFrame->pwStatus = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCRESP_OFF_STATUS); - pFrame->pwAid = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCRESP_OFF_AID); - - /* Information elements */ - pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCRESP_OFF_SUPP_RATES); - - pItem = (PWLAN_IE)(pFrame->pSuppRates); - pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); - - if ((((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) && - (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) { - pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem; - } -} diff --git a/drivers/staging/vt6655/80211mgr.h b/drivers/staging/vt6655/80211mgr.h deleted file mode 100644 index d462a8af087b..000000000000 --- a/drivers/staging/vt6655/80211mgr.h +++ /dev/null @@ -1,725 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: 80211mgr.h - * - * Purpose: 802.11 management frames pre-defines. - * - * - * Author: Lyndon Chen - * - * Date: May 8, 2002 - * - */ - -#ifndef __80211MGR_H__ -#define __80211MGR_H__ - -#include <linux/types.h> -#include "linux/ieee80211.h" - -#include "ttype.h" -#include "80211hdr.h" - -#define WLAN_MIN_ARRAY 1 - -/* Information Element ID value */ -#define WLAN_EID_FH_PARMS 2 -#define WLAN_EID_DS_PARMS 3 -#define WLAN_EID_CF_PARMS 4 -#define WLAN_EID_IBSS_PARMS 6 -#define WLAN_EID_TPC_REQ 34 -#define WLAN_EID_TPC_REP 35 -#define WLAN_EID_SUPP_CH 36 -#define WLAN_EID_CH_SWITCH 37 -#define WLAN_EID_MEASURE_REQ 38 -#define WLAN_EID_MEASURE_REP 39 -#define WLAN_EID_QUIET 40 -#define WLAN_EID_IBSS_DFS 41 -#define WLAN_EID_ERP 42 -/* reference 802.11i 7.3.2 table 20 */ -#define WLAN_EID_EXTSUPP_RATES 50 -/* reference WiFi WPA spec. */ -#define WLAN_EID_RSN_WPA 221 - -#define WLAN_EID_ERP_NONERP_PRESENT 0x01 -#define WLAN_EID_ERP_USE_PROTECTION 0x02 -#define WLAN_EID_ERP_BARKER_MODE 0x04 - -/* Reason Codes */ -#define WLAN_MGMT_REASON_RSVD 0 -#define WLAN_MGMT_REASON_UNSPEC 1 -#define WLAN_MGMT_REASON_PRIOR_AUTH_INVALID 2 -#define WLAN_MGMT_REASON_DEAUTH_LEAVING 3 -#define WLAN_MGMT_REASON_DISASSOC_INACTIVE 4 -#define WLAN_MGMT_REASON_DISASSOC_AP_BUSY 5 -#define WLAN_MGMT_REASON_CLASS2_NONAUTH 6 -#define WLAN_MGMT_REASON_CLASS3_NONASSOC 7 -#define WLAN_MGMT_REASON_DISASSOC_STA_HASLEFT 8 -#define WLAN_MGMT_REASON_CANT_ASSOC_NONAUTH 9 -#define WLAN_MGMT_REASON_DISASSOC_PWR_CAP_UNACCEPT 10 -#define WLAN_MGMT_REASON_DISASSOC_SUPP_CH_UNACCEPT 11 -#define WLAN_MGMT_REASON_INVALID_IE 13 -#define WLAN_MGMT_REASON_MIC_FAILURE 14 -#define WLAN_MGMT_REASON_4WAY_HANDSHAKE_TIMEOUT 15 -#define WLAN_MGMT_REASON_GRPKEY_UPDATE_TIMEOUT 16 -#define WLAN_MGMT_REASON_4WAY_INFO_DIFFERENT 17 -#define WLAN_MGMT_REASON_MULTCAST_CIPHER_INVALID 18 -#define WLAN_MGMT_REASON_UNCAST_CIPHER_INVALID 19 -#define WLAN_MGMT_REASON_AKMP_INVALID 20 -#define WLAN_MGMT_REASON_RSNE_UNSUPPORTED 21 -#define WLAN_MGMT_REASON_RSNE_CAP_INVALID 22 -#define WLAN_MGMT_REASON_80211X_AUTH_FAILED 23 - -/* Status Codes */ -#define WLAN_MGMT_STATUS_SUCCESS 0 -#define WLAN_MGMT_STATUS_UNSPEC_FAILURE 1 -#define WLAN_MGMT_STATUS_CAPS_UNSUPPORTED 10 -#define WLAN_MGMT_STATUS_REASSOC_NO_ASSOC 11 -#define WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC 12 -#define WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG 13 -#define WLAN_MGMT_STATUS_RX_AUTH_NOSEQ 14 -#define WLAN_MGMT_STATUS_CHALLENGE_FAIL 15 -#define WLAN_MGMT_STATUS_AUTH_TIMEOUT 16 -#define WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY 17 -#define WLAN_MGMT_STATUS_ASSOC_DENIED_RATES 18 -#define WLAN_MGMT_STATUS_ASSOC_DENIED_SHORTPREAMBLE 19 -#define WLAN_MGMT_STATUS_ASSOC_DENIED_PBCC 20 -#define WLAN_MGMT_STATUS_ASSOC_DENIED_AGILITY 21 - -/* reference 802.11h 7.3.1.9 */ -#define WLAN_MGMT_STATUS_ASSOC_REJECT_BCS_SPECTRUM_MNG 22 -#define WLAN_MGMT_STATUS_ASSOC_REJECT_BCS_PWR_CAP 23 -#define WLAN_MGMT_STATUS_ASSOC_REJECT_BCS_SUPP_CH 24 -/* reference 802.11g 7.3.1.9 */ -#define WLAN_MGMT_STATUS_SHORTSLOTTIME_UNSUPPORTED 25 -#define WLAN_MGMT_STATUS_DSSSOFDM_UNSUPPORTED 26 -/* reference 802.11i 3.7.1.9 table 19 */ -#define WLAN_MGMT_STATUS_INVALID_IE 40 -#define WLAN_MGMT_STATUS_GROUP_CIPHER_INVALID 41 -#define WLAN_MGMT_STATUS_PAIRWISE_CIPHER_INVALID 42 -#define WLAN_MGMT_STATUS_AKMP_INVALID 43 -#define WLAN_MGMT_STATUS_UNSUPPORT_RSN_IE_VER 44 -#define WLAN_MGMT_STATUS_INVALID_RSN_IE_CAP 45 -#define WLAN_MGMT_STATUS_CIPHER_REJECT 46 - -/* Auth Algorithm */ -#define WLAN_AUTH_ALG_OPENSYSTEM 0 -#define WLAN_AUTH_ALG_SHAREDKEY 1 - -/* Management Frame Field Offsets */ -/* Note: Not all fields are listed because of variable lengths. */ -/* Note: These offsets are from the start of the frame data */ - -#define WLAN_BEACON_OFF_TS 0 -#define WLAN_BEACON_OFF_BCN_INT 8 -#define WLAN_BEACON_OFF_CAPINFO 10 -#define WLAN_BEACON_OFF_SSID 12 - -#define WLAN_DISASSOC_OFF_REASON 0 - -#define WLAN_ASSOCREQ_OFF_CAP_INFO 0 -#define WLAN_ASSOCREQ_OFF_LISTEN_INT 2 -#define WLAN_ASSOCREQ_OFF_SSID 4 - -#define WLAN_ASSOCRESP_OFF_CAP_INFO 0 -#define WLAN_ASSOCRESP_OFF_STATUS 2 -#define WLAN_ASSOCRESP_OFF_AID 4 -#define WLAN_ASSOCRESP_OFF_SUPP_RATES 6 - -#define WLAN_REASSOCREQ_OFF_CAP_INFO 0 -#define WLAN_REASSOCREQ_OFF_LISTEN_INT 2 -#define WLAN_REASSOCREQ_OFF_CURR_AP 4 -#define WLAN_REASSOCREQ_OFF_SSID 10 - -#define WLAN_REASSOCRESP_OFF_CAP_INFO 0 -#define WLAN_REASSOCRESP_OFF_STATUS 2 -#define WLAN_REASSOCRESP_OFF_AID 4 -#define WLAN_REASSOCRESP_OFF_SUPP_RATES 6 - -#define WLAN_PROBEREQ_OFF_SSID 0 - -#define WLAN_PROBERESP_OFF_TS 0 -#define WLAN_PROBERESP_OFF_BCN_INT 8 -#define WLAN_PROBERESP_OFF_CAP_INFO 10 -#define WLAN_PROBERESP_OFF_SSID 12 - -#define WLAN_AUTHEN_OFF_AUTH_ALG 0 -#define WLAN_AUTHEN_OFF_AUTH_SEQ 2 -#define WLAN_AUTHEN_OFF_STATUS 4 -#define WLAN_AUTHEN_OFF_CHALLENGE 6 - -#define WLAN_DEAUTHEN_OFF_REASON 0 - -/* Cipher Suite Selectors defined in 802.11i */ -#define WLAN_11i_CSS_USE_GROUP 0 -#define WLAN_11i_CSS_WEP40 1 -#define WLAN_11i_CSS_TKIP 2 -#define WLAN_11i_CSS_CCMP 4 -#define WLAN_11i_CSS_WEP104 5 -#define WLAN_11i_CSS_UNKNOWN 255 - -/* Authentication and Key Management Suite Selectors defined in 802.11i */ -#define WLAN_11i_AKMSS_802_1X 1 -#define WLAN_11i_AKMSS_PSK 2 -#define WLAN_11i_AKMSS_UNKNOWN 255 - -/* Measurement type definitions reference ieee 802.11h Table 20b */ -#define MEASURE_TYPE_BASIC 0 -#define MEASURE_TYPE_CCA 1 -#define MEASURE_TYPE_RPI 2 - -/* Measurement request mode definitions reference ieee 802.11h Figure 46h */ -#define MEASURE_MODE_ENABLE 0x02 -#define MEASURE_MODE_REQ 0x04 -#define MEASURE_MODE_REP 0x08 - -/* Measurement report mode definitions reference ieee 802.11h Figure 46m */ -#define MEASURE_MODE_LATE 0x01 -#define MEASURE_MODE_INCAPABLE 0x02 -#define MEASURE_MODE_REFUSED 0x04 - -/* Information Element Types */ - -#pragma pack(1) -typedef struct tagWLAN_IE { - unsigned char byElementID; - unsigned char len; -} __attribute__ ((__packed__)) -WLAN_IE, *PWLAN_IE; - -/* Service Set Identity (SSID) */ -#pragma pack(1) -typedef struct tagWLAN_IE_SSID { - unsigned char byElementID; - unsigned char len; - unsigned char abySSID[1]; -} __attribute__ ((__packed__)) -WLAN_IE_SSID, *PWLAN_IE_SSID; - -/* Supported Rates */ -#pragma pack(1) -typedef struct tagWLAN_IE_SUPP_RATES { - unsigned char byElementID; - unsigned char len; - unsigned char abyRates[1]; -} __attribute__ ((__packed__)) -WLAN_IE_SUPP_RATES, *PWLAN_IE_SUPP_RATES; - -/* FH Parameter Set */ -#pragma pack(1) -typedef struct _WLAN_IE_FH_PARMS { - unsigned char byElementID; - unsigned char len; - unsigned short wDwellTime; - unsigned char byHopSet; - unsigned char byHopPattern; - unsigned char byHopIndex; -} WLAN_IE_FH_PARMS, *PWLAN_IE_FH_PARMS; - -/* DS Parameter Set */ -#pragma pack(1) -typedef struct tagWLAN_IE_DS_PARMS { - unsigned char byElementID; - unsigned char len; - unsigned char byCurrChannel; -} __attribute__ ((__packed__)) -WLAN_IE_DS_PARMS, *PWLAN_IE_DS_PARMS; - -/* CF Parameter Set */ -#pragma pack(1) -typedef struct tagWLAN_IE_CF_PARMS { - unsigned char byElementID; - unsigned char len; - unsigned char byCFPCount; - unsigned char byCFPPeriod; - unsigned short wCFPMaxDuration; - unsigned short wCFPDurRemaining; -} __attribute__ ((__packed__)) -WLAN_IE_CF_PARMS, *PWLAN_IE_CF_PARMS; - -/* TIM */ -#pragma pack(1) -typedef struct tagWLAN_IE_TIM { - unsigned char byElementID; - unsigned char len; - unsigned char byDTIMCount; - unsigned char byDTIMPeriod; - unsigned char byBitMapCtl; - unsigned char byVirtBitMap[1]; -} __attribute__ ((__packed__)) -WLAN_IE_TIM, *PWLAN_IE_TIM; - -/* IBSS Parameter Set */ -#pragma pack(1) -typedef struct tagWLAN_IE_IBSS_PARMS { - unsigned char byElementID; - unsigned char len; - unsigned short wATIMWindow; -} __attribute__ ((__packed__)) -WLAN_IE_IBSS_PARMS, *PWLAN_IE_IBSS_PARMS; - -/* Challenge Text */ -#pragma pack(1) -typedef struct tagWLAN_IE_CHALLENGE { - unsigned char byElementID; - unsigned char len; - unsigned char abyChallenge[1]; -} __attribute__ ((__packed__)) -WLAN_IE_CHALLENGE, *PWLAN_IE_CHALLENGE; - -#pragma pack(1) -typedef struct tagWLAN_IE_RSN_EXT { - unsigned char byElementID; - unsigned char len; - unsigned char abyOUI[4]; - unsigned short wVersion; - unsigned char abyMulticast[4]; - unsigned short wPKCount; - struct { - unsigned char abyOUI[4]; - } PKSList[1]; /* the rest is variable so need to */ - /* overlay ieauth structure */ -} WLAN_IE_RSN_EXT, *PWLAN_IE_RSN_EXT; - -#pragma pack(1) -typedef struct tagWLAN_IE_RSN_AUTH { - unsigned short wAuthCount; - struct { - unsigned char abyOUI[4]; - } AuthKSList[1]; -} WLAN_IE_RSN_AUTH, *PWLAN_IE_RSN_AUTH; - -/* RSN Identity */ -#pragma pack(1) -typedef struct tagWLAN_IE_RSN { - unsigned char byElementID; - unsigned char len; - unsigned short wVersion; - unsigned char abyRSN[WLAN_MIN_ARRAY]; -} WLAN_IE_RSN, *PWLAN_IE_RSN; - -/* ERP */ -#pragma pack(1) -typedef struct tagWLAN_IE_ERP { - unsigned char byElementID; - unsigned char len; - unsigned char byContext; -} __attribute__ ((__packed__)) -WLAN_IE_ERP, *PWLAN_IE_ERP; - -#pragma pack(1) -typedef struct _MEASEURE_REQ { - unsigned char byChannel; - unsigned char abyStartTime[8]; - unsigned char abyDuration[2]; -} MEASEURE_REQ, *PMEASEURE_REQ, - MEASEURE_REQ_BASIC, *PMEASEURE_REQ_BASIC, - MEASEURE_REQ_CCA, *PMEASEURE_REQ_CCA, - MEASEURE_REQ_RPI, *PMEASEURE_REQ_RPI; - -typedef struct _MEASEURE_REP_BASIC { - unsigned char byChannel; - unsigned char abyStartTime[8]; - unsigned char abyDuration[2]; - unsigned char byMap; -} MEASEURE_REP_BASIC, *PMEASEURE_REP_BASIC; - -typedef struct _MEASEURE_REP_CCA { - unsigned char byChannel; - unsigned char abyStartTime[8]; - unsigned char abyDuration[2]; - unsigned char byCCABusyFraction; -} MEASEURE_REP_CCA, *PMEASEURE_REP_CCA; - -typedef struct _MEASEURE_REP_RPI { - unsigned char byChannel; - unsigned char abyStartTime[8]; - unsigned char abyDuration[2]; - unsigned char abyRPIdensity[8]; -} MEASEURE_REP_RPI, *PMEASEURE_REP_RPI; - -typedef union _MEASEURE_REP { - MEASEURE_REP_BASIC sBasic; - MEASEURE_REP_CCA sCCA; - MEASEURE_REP_RPI sRPI; -} MEASEURE_REP, *PMEASEURE_REP; - -typedef struct _WLAN_IE_MEASURE_REQ { - unsigned char byElementID; - unsigned char len; - unsigned char byToken; - unsigned char byMode; - unsigned char byType; - MEASEURE_REQ sReq; -} WLAN_IE_MEASURE_REQ, *PWLAN_IE_MEASURE_REQ; - -typedef struct _WLAN_IE_MEASURE_REP { - unsigned char byElementID; - unsigned char len; - unsigned char byToken; - unsigned char byMode; - unsigned char byType; - MEASEURE_REP sRep; -} WLAN_IE_MEASURE_REP, *PWLAN_IE_MEASURE_REP; - -typedef struct _WLAN_IE_CH_SW { - unsigned char byElementID; - unsigned char len; - unsigned char byMode; - unsigned char byChannel; - unsigned char byCount; -} WLAN_IE_CH_SW, *PWLAN_IE_CH_SW; - -typedef struct _WLAN_IE_QUIET { - unsigned char byElementID; - unsigned char len; - unsigned char byQuietCount; - unsigned char byQuietPeriod; - unsigned char abyQuietDuration[2]; - unsigned char abyQuietOffset[2]; -} WLAN_IE_QUIET, *PWLAN_IE_QUIET; - -typedef struct _WLAN_IE_COUNTRY { - unsigned char byElementID; - unsigned char len; - unsigned char abyCountryString[3]; - unsigned char abyCountryInfo[3]; -} WLAN_IE_COUNTRY, *PWLAN_IE_COUNTRY; - -typedef struct _WLAN_IE_PW_CONST { - unsigned char byElementID; - unsigned char len; - unsigned char byPower; -} WLAN_IE_PW_CONST, *PWLAN_IE_PW_CONST; - -typedef struct _WLAN_IE_PW_CAP { - unsigned char byElementID; - unsigned char len; - unsigned char byMinPower; - unsigned char byMaxPower; -} WLAN_IE_PW_CAP, *PWLAN_IE_PW_CAP; - -typedef struct _WLAN_IE_SUPP_CH { - unsigned char byElementID; - unsigned char len; - unsigned char abyChannelTuple[2]; -} WLAN_IE_SUPP_CH, *PWLAN_IE_SUPP_CH; - -typedef struct _WLAN_IE_TPC_REQ { - unsigned char byElementID; - unsigned char len; -} WLAN_IE_TPC_REQ, *PWLAN_IE_TPC_REQ; - -typedef struct _WLAN_IE_TPC_REP { - unsigned char byElementID; - unsigned char len; - unsigned char byTxPower; - unsigned char byLinkMargin; -} WLAN_IE_TPC_REP, *PWLAN_IE_TPC_REP; - -typedef struct _WLAN_IE_IBSS_DFS { - unsigned char byElementID; - unsigned char len; - unsigned char abyDFSOwner[6]; - unsigned char byDFSRecovery; - unsigned char abyChannelMap[2]; -} WLAN_IE_IBSS_DFS, *PWLAN_IE_IBSS_DFS; - -#pragma pack() - -/* Frame Types */ -/* prototype structure, all mgmt frame types will start with these members */ -typedef struct tagWLAN_FR_MGMT { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; -} WLAN_FR_MGMT, *PWLAN_FR_MGMT; - -/* Beacon frame */ -typedef struct tagWLAN_FR_BEACON { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - __le64 *pqwTimestamp; - unsigned short *pwBeaconInterval; - unsigned short *pwCapInfo; - PWLAN_IE_SSID pSSID; - PWLAN_IE_SUPP_RATES pSuppRates; - PWLAN_IE_DS_PARMS pDSParms; - PWLAN_IE_CF_PARMS pCFParms; - PWLAN_IE_TIM pTIM; - PWLAN_IE_IBSS_PARMS pIBSSParms; - PWLAN_IE_RSN pRSN; - PWLAN_IE_RSN_EXT pRSNWPA; - PWLAN_IE_ERP pERP; - PWLAN_IE_SUPP_RATES pExtSuppRates; - PWLAN_IE_COUNTRY pIE_Country; - PWLAN_IE_PW_CONST pIE_PowerConstraint; - PWLAN_IE_CH_SW pIE_CHSW; - PWLAN_IE_IBSS_DFS pIE_IBSSDFS; - PWLAN_IE_QUIET pIE_Quiet; -} WLAN_FR_BEACON, *PWLAN_FR_BEACON; - -/* IBSS ATIM frame */ -typedef struct tagWLAN_FR_IBSSATIM { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; -} WLAN_FR_IBSSATIM, *PWLAN_FR_IBSSATIM; - -/* Disassociation */ -typedef struct tagWLAN_FR_DISASSOC { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - unsigned short *pwReason; -} WLAN_FR_DISASSOC, *PWLAN_FR_DISASSOC; - -/* Association Request */ -typedef struct tagWLAN_FR_ASSOCREQ { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - unsigned short *pwCapInfo; - unsigned short *pwListenInterval; - PWLAN_IE_SSID pSSID; - PWLAN_IE_SUPP_RATES pSuppRates; - PWLAN_IE_RSN pRSN; - PWLAN_IE_RSN_EXT pRSNWPA; - PWLAN_IE_SUPP_RATES pExtSuppRates; - PWLAN_IE_PW_CAP pCurrPowerCap; - PWLAN_IE_SUPP_CH pCurrSuppCh; -} WLAN_FR_ASSOCREQ, *PWLAN_FR_ASSOCREQ; - -/* Association Response */ -typedef struct tagWLAN_FR_ASSOCRESP { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - unsigned short *pwCapInfo; - unsigned short *pwStatus; - unsigned short *pwAid; - PWLAN_IE_SUPP_RATES pSuppRates; - PWLAN_IE_SUPP_RATES pExtSuppRates; -} WLAN_FR_ASSOCRESP, *PWLAN_FR_ASSOCRESP; - -/* Reassociation Request */ -typedef struct tagWLAN_FR_REASSOCREQ { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - unsigned short *pwCapInfo; - unsigned short *pwListenInterval; - PIEEE_ADDR pAddrCurrAP; - PWLAN_IE_SSID pSSID; - PWLAN_IE_SUPP_RATES pSuppRates; - PWLAN_IE_RSN pRSN; - PWLAN_IE_RSN_EXT pRSNWPA; - PWLAN_IE_SUPP_RATES pExtSuppRates; -} WLAN_FR_REASSOCREQ, *PWLAN_FR_REASSOCREQ; - -/* Reassociation Response */ -typedef struct tagWLAN_FR_REASSOCRESP { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - unsigned short *pwCapInfo; - unsigned short *pwStatus; - unsigned short *pwAid; - PWLAN_IE_SUPP_RATES pSuppRates; - PWLAN_IE_SUPP_RATES pExtSuppRates; -} WLAN_FR_REASSOCRESP, *PWLAN_FR_REASSOCRESP; - -/* Probe Request */ -typedef struct tagWLAN_FR_PROBEREQ { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - PWLAN_IE_SSID pSSID; - PWLAN_IE_SUPP_RATES pSuppRates; - PWLAN_IE_SUPP_RATES pExtSuppRates; -} WLAN_FR_PROBEREQ, *PWLAN_FR_PROBEREQ; - -/* Probe Response */ -typedef struct tagWLAN_FR_PROBERESP { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - __le64 *pqwTimestamp; - unsigned short *pwBeaconInterval; - unsigned short *pwCapInfo; - PWLAN_IE_SSID pSSID; - PWLAN_IE_SUPP_RATES pSuppRates; - PWLAN_IE_DS_PARMS pDSParms; - PWLAN_IE_CF_PARMS pCFParms; - PWLAN_IE_IBSS_PARMS pIBSSParms; - PWLAN_IE_RSN pRSN; - PWLAN_IE_RSN_EXT pRSNWPA; - PWLAN_IE_ERP pERP; - PWLAN_IE_SUPP_RATES pExtSuppRates; - PWLAN_IE_COUNTRY pIE_Country; - PWLAN_IE_PW_CONST pIE_PowerConstraint; - PWLAN_IE_CH_SW pIE_CHSW; - PWLAN_IE_IBSS_DFS pIE_IBSSDFS; - PWLAN_IE_QUIET pIE_Quiet; -} WLAN_FR_PROBERESP, *PWLAN_FR_PROBERESP; - -/* Authentication */ -typedef struct tagWLAN_FR_AUTHEN { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - unsigned short *pwAuthAlgorithm; - unsigned short *pwAuthSequence; - unsigned short *pwStatus; - PWLAN_IE_CHALLENGE pChallenge; -} WLAN_FR_AUTHEN, *PWLAN_FR_AUTHEN; - -/* Deauthenication */ -typedef struct tagWLAN_FR_DEAUTHEN { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - unsigned short *pwReason; -} WLAN_FR_DEAUTHEN, *PWLAN_FR_DEAUTHEN; - -void -vMgrEncodeBeacon( - PWLAN_FR_BEACON pFrame -); - -void -vMgrDecodeBeacon( - PWLAN_FR_BEACON pFrame -); - -void -vMgrEncodeIBSSATIM( - PWLAN_FR_IBSSATIM pFrame -); - -void -vMgrDecodeIBSSATIM( - PWLAN_FR_IBSSATIM pFrame -); - -void -vMgrEncodeDisassociation( - PWLAN_FR_DISASSOC pFrame -); - -void -vMgrDecodeDisassociation( - PWLAN_FR_DISASSOC pFrame -); - -void -vMgrEncodeAssocRequest( - PWLAN_FR_ASSOCREQ pFrame -); - -void -vMgrDecodeAssocRequest( - PWLAN_FR_ASSOCREQ pFrame -); - -void -vMgrEncodeAssocResponse( - PWLAN_FR_ASSOCRESP pFrame -); - -void -vMgrDecodeAssocResponse( - PWLAN_FR_ASSOCRESP pFrame -); - -void -vMgrEncodeReassocRequest( - PWLAN_FR_REASSOCREQ pFrame -); - -void -vMgrDecodeReassocRequest( - PWLAN_FR_REASSOCREQ pFrame -); - -void -vMgrEncodeProbeRequest( - PWLAN_FR_PROBEREQ pFrame -); - -void -vMgrDecodeProbeRequest( - PWLAN_FR_PROBEREQ pFrame -); - -void -vMgrEncodeProbeResponse( - PWLAN_FR_PROBERESP pFrame -); - -void -vMgrDecodeProbeResponse( - PWLAN_FR_PROBERESP pFrame -); - -void -vMgrEncodeAuthen( - PWLAN_FR_AUTHEN pFrame -); - -void -vMgrDecodeAuthen( - PWLAN_FR_AUTHEN pFrame -); - -void -vMgrEncodeDeauthen( - PWLAN_FR_DEAUTHEN pFrame -); - -void -vMgrDecodeDeauthen( - PWLAN_FR_DEAUTHEN pFrame -); - -void -vMgrEncodeReassocResponse( - PWLAN_FR_REASSOCRESP pFrame -); - -void -vMgrDecodeReassocResponse( - PWLAN_FR_REASSOCRESP pFrame -); - -#endif/* __80211MGR_H__ */ diff --git a/drivers/staging/vt6655/IEEE11h.c b/drivers/staging/vt6655/IEEE11h.c deleted file mode 100644 index 180a27cc74d7..000000000000 --- a/drivers/staging/vt6655/IEEE11h.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 1996, 2005 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: IEEE11h.c - * - * Purpose: - * - * Functions: - * - * Revision History: - * - * Author: Yiching Chen - * - * Date: Mar. 31, 2005 - * - */ - -#include "ttype.h" -#include "tmacro.h" -#include "tether.h" -#include "IEEE11h.h" -#include "device.h" -#include "wmgr.h" -#include "rxtx.h" -#include "channel.h" - -/*--------------------- Static Definitions -------------------------*/ - -#pragma pack(1) - -typedef struct _WLAN_FRAME_ACTION { - WLAN_80211HDR_A3 Header; - unsigned char byCategory; - unsigned char byAction; - unsigned char abyVars[1]; -} WLAN_FRAME_ACTION, *PWLAN_FRAME_ACTION; - -typedef struct _WLAN_FRAME_MSRREQ { - WLAN_80211HDR_A3 Header; - unsigned char byCategory; - unsigned char byAction; - unsigned char byDialogToken; - WLAN_IE_MEASURE_REQ sMSRReqEIDs[1]; -} WLAN_FRAME_MSRREQ, *PWLAN_FRAME_MSRREQ; - -typedef struct _WLAN_FRAME_MSRREP { - WLAN_80211HDR_A3 Header; - unsigned char byCategory; - unsigned char byAction; - unsigned char byDialogToken; - WLAN_IE_MEASURE_REP sMSRRepEIDs[1]; -} WLAN_FRAME_MSRREP, *PWLAN_FRAME_MSRREP; - -typedef struct _WLAN_FRAME_TPCREQ { - WLAN_80211HDR_A3 Header; - unsigned char byCategory; - unsigned char byAction; - unsigned char byDialogToken; - WLAN_IE_TPC_REQ sTPCReqEIDs; -} WLAN_FRAME_TPCREQ, *PWLAN_FRAME_TPCREQ; - -typedef struct _WLAN_FRAME_TPCREP { - WLAN_80211HDR_A3 Header; - unsigned char byCategory; - unsigned char byAction; - unsigned char byDialogToken; - WLAN_IE_TPC_REP sTPCRepEIDs; -} WLAN_FRAME_TPCREP, *PWLAN_FRAME_TPCREP; - -#pragma pack() - -/* action field reference ieee 802.11h Table 20e */ -#define ACTION_MSRREQ 0 -#define ACTION_MSRREP 1 -#define ACTION_TPCREQ 2 -#define ACTION_TPCREP 3 -#define ACTION_CHSW 4 - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -bool IEEE11hbMSRRepTx(void *pMgmtHandle) -{ - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; - PWLAN_FRAME_MSRREP pMSRRep = (PWLAN_FRAME_MSRREP) - (pMgmt->abyCurrentMSRRep + sizeof(STxMgmtPacket)); - size_t uLength = 0; - PSTxMgmtPacket pTxPacket = NULL; - - pTxPacket = (PSTxMgmtPacket)pMgmt->abyCurrentMSRRep; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + - sizeof(STxMgmtPacket)); - - pMSRRep->Header.wFrameCtl = (WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION) -); - - memcpy(pMSRRep->Header.abyAddr1, ((PWLAN_FRAME_MSRREQ) - (pMgmt->abyCurrentMSRReq))->Header.abyAddr2, WLAN_ADDR_LEN); - memcpy(pMSRRep->Header.abyAddr2, - CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN); - memcpy(pMSRRep->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - pMSRRep->byCategory = 0; - pMSRRep->byAction = 1; - pMSRRep->byDialogToken = ((PWLAN_FRAME_MSRREQ) - (pMgmt->abyCurrentMSRReq))->byDialogToken; - - uLength = pMgmt->uLengthOfRepEIDs + offsetof(WLAN_FRAME_MSRREP, - sMSRRepEIDs); - - pTxPacket->cbMPDULen = uLength; - pTxPacket->cbPayloadLen = uLength - WLAN_HDR_ADDR3_LEN; - if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING) - return false; - return true; -} diff --git a/drivers/staging/vt6655/IEEE11h.h b/drivers/staging/vt6655/IEEE11h.h deleted file mode 100644 index 551922022b19..000000000000 --- a/drivers/staging/vt6655/IEEE11h.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 1996, 2005 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: IEEE11h.h - * - * Purpose: Defines the macros, types, and functions for dealing - * with IEEE 802.11h. - * - * Author: Yiching Chen - * - * Date: Mar. 31, 2005 - * - */ - -#ifndef __IEEE11h_H__ -#define __IEEE11h_H__ - -#include "ttype.h" -#include "80211hdr.h" -#include "80211mgr.h" - -bool IEEE11hbMSRRepTx( - void *pMgmtHandle -); - -#endif // __IEEE11h_H__ diff --git a/drivers/staging/vt6655/Kconfig b/drivers/staging/vt6655/Kconfig index c3ba693a8cad..77cfc708c516 100644 --- a/drivers/staging/vt6655/Kconfig +++ b/drivers/staging/vt6655/Kconfig @@ -1,8 +1,6 @@ config VT6655 tristate "VIA Technologies VT6655 support" - depends on PCI && WLAN && m - select WIRELESS_EXT - select WEXT_PRIV + depends on PCI && MAC80211 && m ---help--- This is a vendor-written driver for VIA VT6655. diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile index f7544a6cb63e..115b951bf0d9 100644 --- a/drivers/staging/vt6655/Makefile +++ b/drivers/staging/vt6655/Makefile @@ -7,33 +7,12 @@ vt6655_stage-y += device_main.o \ channel.o \ mac.o \ baseband.o \ - wctl.o \ - 80211mgr.o \ - wcmd.o \ - wmgr.o \ - bssdb.o \ rxtx.o \ dpc.o \ power.o \ - datarate.o \ srom.o \ mib.o \ - rc4.o \ - tether.o \ - tcrc.o \ - ioctl.o \ - hostap.o \ - wpa.o \ key.o \ - tkip.o \ - michael.o \ - wroute.o \ - rf.o \ - iwctl.o \ - wpactl.o \ - wpa2.o \ - aes_ccmp.o \ - vntwifi.o \ - IEEE11h.o + rf.o obj-$(CONFIG_VT6655) += vt6655_stage.o diff --git a/drivers/staging/vt6655/aes_ccmp.c b/drivers/staging/vt6655/aes_ccmp.c deleted file mode 100644 index 1dfcfcb3c69c..000000000000 --- a/drivers/staging/vt6655/aes_ccmp.c +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: aes_ccmp.c - * - * Purpose: AES_CCMP decryption - * - * Author: Warren Hsu - * - * Date: Feb 15, 2005 - * - * Functions: - * AESbGenCCMP - Parsing RX-packet - * - * - * Revision History: - * - */ - -#include "device.h" -#include "80211hdr.h" -#include "aes_ccmp.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/* - * SBOX Table - */ - -static unsigned char sbox_table[256] = { - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 -}; - -static unsigned char dot2_table[256] = { - 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, - 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, - 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, - 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, - 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, - 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, - 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, - 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, - 0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05, - 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25, - 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, - 0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65, - 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85, - 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, - 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5, - 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5 -}; - -static unsigned char dot3_table[256] = { - 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11, - 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, - 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71, - 0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41, - 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, - 0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1, - 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1, - 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, - 0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a, - 0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba, - 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, - 0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda, - 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a, - 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, - 0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a, - 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a -}; - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -static void xor_128(unsigned char *a, unsigned char *b, unsigned char *out) -{ - unsigned long *dwPtrA = (unsigned long *)a; - unsigned long *dwPtrB = (unsigned long *)b; - unsigned long *dwPtrOut = (unsigned long *)out; - - (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); - (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); - (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); - (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); -} - -static void xor_32(unsigned char *a, unsigned char *b, unsigned char *out) -{ - unsigned long *dwPtrA = (unsigned long *)a; - unsigned long *dwPtrB = (unsigned long *)b; - unsigned long *dwPtrOut = (unsigned long *)out; - - (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); -} - -static void AddRoundKey(unsigned char *key, int round) -{ - unsigned char sbox_key[4]; - unsigned char rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; - - sbox_key[0] = sbox_table[key[13]]; - sbox_key[1] = sbox_table[key[14]]; - sbox_key[2] = sbox_table[key[15]]; - sbox_key[3] = sbox_table[key[12]]; - - key[0] = key[0] ^ rcon_table[round]; - xor_32(&key[0], sbox_key, &key[0]); - - xor_32(&key[4], &key[0], &key[4]); - xor_32(&key[8], &key[4], &key[8]); - xor_32(&key[12], &key[8], &key[12]); -} - -static void SubBytes(unsigned char *in, unsigned char *out) -{ - int i; - - for (i = 0; i < 16; i++) - out[i] = sbox_table[in[i]]; -} - -static void ShiftRows(unsigned char *in, unsigned char *out) -{ - out[0] = in[0]; - out[1] = in[5]; - out[2] = in[10]; - out[3] = in[15]; - out[4] = in[4]; - out[5] = in[9]; - out[6] = in[14]; - out[7] = in[3]; - out[8] = in[8]; - out[9] = in[13]; - out[10] = in[2]; - out[11] = in[7]; - out[12] = in[12]; - out[13] = in[1]; - out[14] = in[6]; - out[15] = in[11]; -} - -static void MixColumns(unsigned char *in, unsigned char *out) -{ - out[0] = dot2_table[in[0]] ^ dot3_table[in[1]] ^ in[2] ^ in[3]; - out[1] = in[0] ^ dot2_table[in[1]] ^ dot3_table[in[2]] ^ in[3]; - out[2] = in[0] ^ in[1] ^ dot2_table[in[2]] ^ dot3_table[in[3]]; - out[3] = dot3_table[in[0]] ^ in[1] ^ in[2] ^ dot2_table[in[3]]; -} - -static void AESv128(unsigned char *key, unsigned char *data, unsigned char *ciphertext) -{ - int i; - int round; - unsigned char TmpdataA[16]; - unsigned char TmpdataB[16]; - unsigned char abyRoundKey[16]; - - for (i = 0; i < 16; i++) - abyRoundKey[i] = key[i]; - - for (round = 0; round < 11; round++) { - if (round == 0) { - xor_128(abyRoundKey, data, ciphertext); - AddRoundKey(abyRoundKey, round); - } else if (round == 10) { - SubBytes(ciphertext, TmpdataA); - ShiftRows(TmpdataA, TmpdataB); - xor_128(TmpdataB, abyRoundKey, ciphertext); - } else /* round 1 ~ 9 */{ - SubBytes(ciphertext, TmpdataA); - ShiftRows(TmpdataA, TmpdataB); - MixColumns(&TmpdataB[0], &TmpdataA[0]); - MixColumns(&TmpdataB[4], &TmpdataA[4]); - MixColumns(&TmpdataB[8], &TmpdataA[8]); - MixColumns(&TmpdataB[12], &TmpdataA[12]); - xor_128(TmpdataA, abyRoundKey, ciphertext); - AddRoundKey(abyRoundKey, round); - } - } -} - -/* - * Description: AES decryption - * - * Parameters: - * In: - * pbyRxKey - The key used to decrypt - * pbyFrame - Starting address of packet header - * wFrameSize - Total packet size including CRC - * Out: - * none - * - * Return Value: MIC compare result - * - */ -bool AESbGenCCMP(unsigned char *pbyRxKey, unsigned char *pbyFrame, unsigned short wFrameSize) -{ - unsigned char abyNonce[13]; - unsigned char MIC_IV[16]; - unsigned char MIC_HDR1[16]; - unsigned char MIC_HDR2[16]; - unsigned char abyMIC[16]; - unsigned char abyCTRPLD[16]; - unsigned char abyTmp[16]; - unsigned char abyPlainText[16]; - unsigned char abyLastCipher[16]; - - PS802_11Header pMACHeader = (PS802_11Header) pbyFrame; - unsigned char *pbyIV; - unsigned char *pbyPayload; - unsigned short wHLen = 22; - unsigned short wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN;/* 8 is IV, 8 is MIC, 4 is CRC */ - bool bA4 = false; - unsigned char byTmp; - unsigned short wCnt; - int ii, jj, kk; - - pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; - if (WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) && - WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame)) { - bA4 = true; - pbyIV += 6; /* 6 is 802.11 address4 */ - wHLen += 6; - wPayloadSize -= 6; - } - pbyPayload = pbyIV + 8; /* IV-length */ - - abyNonce[0] = 0x00; /* now is 0, if Qos here will be priority */ - memcpy(&(abyNonce[1]), pMACHeader->abyAddr2, ETH_ALEN); - abyNonce[7] = pbyIV[7]; - abyNonce[8] = pbyIV[6]; - abyNonce[9] = pbyIV[5]; - abyNonce[10] = pbyIV[4]; - abyNonce[11] = pbyIV[1]; - abyNonce[12] = pbyIV[0]; - - /* MIC_IV */ - MIC_IV[0] = 0x59; - memcpy(&(MIC_IV[1]), &(abyNonce[0]), 13); - MIC_IV[14] = (unsigned char)(wPayloadSize >> 8); - MIC_IV[15] = (unsigned char)(wPayloadSize & 0xff); - - /* MIC_HDR1 */ - MIC_HDR1[0] = (unsigned char)(wHLen >> 8); - MIC_HDR1[1] = (unsigned char)(wHLen & 0xff); - byTmp = (unsigned char)(pMACHeader->wFrameCtl & 0xff); - MIC_HDR1[2] = byTmp & 0x8f; - byTmp = (unsigned char)(pMACHeader->wFrameCtl >> 8); - byTmp &= 0x87; - MIC_HDR1[3] = byTmp | 0x40; - memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, ETH_ALEN); - memcpy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, ETH_ALEN); - - /* MIC_HDR2 */ - memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, ETH_ALEN); - byTmp = (unsigned char)(pMACHeader->wSeqCtl & 0xff); - MIC_HDR2[6] = byTmp & 0x0f; - MIC_HDR2[7] = 0; - if (bA4) { - memcpy(&(MIC_HDR2[8]), pMACHeader->abyAddr4, ETH_ALEN); - } else { - MIC_HDR2[8] = 0x00; - MIC_HDR2[9] = 0x00; - MIC_HDR2[10] = 0x00; - MIC_HDR2[11] = 0x00; - MIC_HDR2[12] = 0x00; - MIC_HDR2[13] = 0x00; - } - MIC_HDR2[14] = 0x00; - MIC_HDR2[15] = 0x00; - - /* CCMP */ - AESv128(pbyRxKey, MIC_IV, abyMIC); - for (kk = 0; kk < 16; kk++) - abyTmp[kk] = MIC_HDR1[kk] ^ abyMIC[kk]; - AESv128(pbyRxKey, abyTmp, abyMIC); - for (kk = 0; kk < 16; kk++) - abyTmp[kk] = MIC_HDR2[kk] ^ abyMIC[kk]; - AESv128(pbyRxKey, abyTmp, abyMIC); - - wCnt = 1; - abyCTRPLD[0] = 0x01; - memcpy(&(abyCTRPLD[1]), &(abyNonce[0]), 13); - - for (jj = wPayloadSize; jj > 16; jj = jj - 16) { - abyCTRPLD[14] = (unsigned char)(wCnt >> 8); - abyCTRPLD[15] = (unsigned char)(wCnt & 0xff); - - AESv128(pbyRxKey, abyCTRPLD, abyTmp); - - for (kk = 0; kk < 16; kk++) - abyPlainText[kk] = abyTmp[kk] ^ pbyPayload[kk]; - for (kk = 0; kk < 16; kk++) - abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk]; - AESv128(pbyRxKey, abyTmp, abyMIC); - - memcpy(pbyPayload, abyPlainText, 16); - wCnt++; - pbyPayload += 16; - } /* for wPayloadSize */ - - /* last payload */ - memcpy(&(abyLastCipher[0]), pbyPayload, jj); - for (ii = jj; ii < 16; ii++) - abyLastCipher[ii] = 0x00; - - abyCTRPLD[14] = (unsigned char)(wCnt >> 8); - abyCTRPLD[15] = (unsigned char)(wCnt & 0xff); - - AESv128(pbyRxKey, abyCTRPLD, abyTmp); - for (kk = 0; kk < 16; kk++) - abyPlainText[kk] = abyTmp[kk] ^ abyLastCipher[kk]; - memcpy(pbyPayload, abyPlainText, jj); - pbyPayload += jj; - - /* for MIC calculation */ - for (ii = jj; ii < 16; ii++) - abyPlainText[ii] = 0x00; - for (kk = 0; kk < 16; kk++) - abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk]; - AESv128(pbyRxKey, abyTmp, abyMIC); - - /* =>above is the calculate MIC */ - /* -------------------------------------------- */ - - wCnt = 0; - abyCTRPLD[14] = (unsigned char)(wCnt >> 8); - abyCTRPLD[15] = (unsigned char)(wCnt & 0xff); - AESv128(pbyRxKey, abyCTRPLD, abyTmp); - for (kk = 0; kk < 8; kk++) - abyTmp[kk] = abyTmp[kk] ^ pbyPayload[kk]; - /* =>above is the dec-MIC from packet */ - /* -------------------------------------------- */ - - return !memcmp(abyMIC, abyTmp, 8); -} diff --git a/drivers/staging/vt6655/aes_ccmp.h b/drivers/staging/vt6655/aes_ccmp.h deleted file mode 100644 index fe0c506205d5..000000000000 --- a/drivers/staging/vt6655/aes_ccmp.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: aes_ccmp.h - * - * Purpose: AES_CCMP Decryption - * - * Author: Warren Hsu - * - * Date: Feb 15, 2005 - * - */ - -#ifndef __AES_H__ -#define __AES_H__ - -#include "ttype.h" - -bool AESbGenCCMP(unsigned char *pbyRxKey, unsigned char *pbyFrame, unsigned short wFrameSize); - -#endif /* __AES_H__ */ diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index de54923e8861..f8c5fc371c4c 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -30,12 +30,7 @@ * BBvCaculateParameter - Caculate PhyLength, PhyService and Phy Signal parameter for baseband Tx * BBbReadEmbedded - Embedded read baseband register via MAC * BBbWriteEmbedded - Embedded write baseband register via MAC - * BBbIsRegBitsOn - Test if baseband register bits on - * BBbIsRegBitsOff - Test if baseband register bits off * BBbVT3253Init - VIA VT3253 baseband chip init code - * BBvReadAllRegs - Read All Baseband Registers - * BBvLoopbackOn - Turn on BaseBand Loopback mode - * BBvLoopbackOff - Turn off BaseBand Loopback mode * * Revision History: * 06-10-2003 Bryan YC Fan: Re-write codes to support VT3253 spec. @@ -50,7 +45,6 @@ */ #include "tmacro.h" -#include "tether.h" #include "mac.h" #include "baseband.h" #include "srom.h" @@ -1708,39 +1702,39 @@ static const unsigned short awcFrameTime[MAX_RATE] = { static unsigned long -s_ulGetRatio(struct vnt_private *pDevice); +s_ulGetRatio(struct vnt_private *priv); static void s_vChangeAntenna( - struct vnt_private *pDevice + struct vnt_private *priv ); static void s_vChangeAntenna( - struct vnt_private *pDevice + struct vnt_private *priv ) { - if (pDevice->dwRxAntennaSel == 0) { - pDevice->dwRxAntennaSel = 1; - if (pDevice->bTxRxAntInv == true) - BBvSetRxAntennaMode(pDevice->PortOffset, ANT_A); + if (priv->dwRxAntennaSel == 0) { + priv->dwRxAntennaSel = 1; + if (priv->bTxRxAntInv == true) + BBvSetRxAntennaMode(priv, ANT_A); else - BBvSetRxAntennaMode(pDevice->PortOffset, ANT_B); + BBvSetRxAntennaMode(priv, ANT_B); } else { - pDevice->dwRxAntennaSel = 0; - if (pDevice->bTxRxAntInv == true) - BBvSetRxAntennaMode(pDevice->PortOffset, ANT_B); + priv->dwRxAntennaSel = 0; + if (priv->bTxRxAntInv == true) + BBvSetRxAntennaMode(priv, ANT_B); else - BBvSetRxAntennaMode(pDevice->PortOffset, ANT_A); + BBvSetRxAntennaMode(priv, ANT_A); } - if (pDevice->dwTxAntennaSel == 0) { - pDevice->dwTxAntennaSel = 1; - BBvSetTxAntennaMode(pDevice->PortOffset, ANT_B); + if (priv->dwTxAntennaSel == 0) { + priv->dwTxAntennaSel = 1; + BBvSetTxAntennaMode(priv, ANT_B); } else { - pDevice->dwTxAntennaSel = 0; - BBvSetTxAntennaMode(pDevice->PortOffset, ANT_A); + priv->dwTxAntennaSel = 0; + BBvSetTxAntennaMode(priv, ANT_A); } } @@ -1792,18 +1786,17 @@ BBuGetFrameTime( uFrameTime++; return uPreamble + uFrameTime; - } else { - uFrameTime = (cbFrameLength * 8 + 22) / uRate; /* ???????? */ - uTmp = ((uFrameTime * uRate) - 22) / 8; - if (cbFrameLength != uTmp) - uFrameTime++; + } + uFrameTime = (cbFrameLength * 8 + 22) / uRate; /* ???????? */ + uTmp = ((uFrameTime * uRate) - 22) / 8; + if (cbFrameLength != uTmp) + uFrameTime++; - uFrameTime = uFrameTime * 4; /* ??????? */ - if (byPktType != PK_TYPE_11A) - uFrameTime += 6; /* ?????? */ + uFrameTime = uFrameTime * 4; /* ??????? */ + if (byPktType != PK_TYPE_11A) + uFrameTime += 6; /* ?????? */ - return 20 + uFrameTime; /* ?????? */ - } + return 20 + uFrameTime; /* ?????? */ } /* @@ -1968,8 +1961,10 @@ void vnt_get_phy_field(struct vnt_private *priv, u32 frame_length, * Return Value: true if succeeded; false if failed. * */ -bool BBbReadEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char *pbyData) +bool BBbReadEmbedded(struct vnt_private *priv, + unsigned char byBBAddr, unsigned char *pbyData) { + void __iomem *dwIoBase = priv->PortOffset; unsigned short ww; unsigned char byValue; @@ -2010,8 +2005,10 @@ bool BBbReadEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned ch * Return Value: true if succeeded; false if failed. * */ -bool BBbWriteEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char byData) +bool BBbWriteEmbedded(struct vnt_private *priv, + unsigned char byBBAddr, unsigned char byData) { + void __iomem *dwIoBase = priv->PortOffset; unsigned short ww; unsigned char byValue; @@ -2038,50 +2035,6 @@ bool BBbWriteEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned c } /* - * Description: Test if all bits are set for the Baseband register - * - * Parameters: - * In: - * dwIoBase - I/O base address - * byBBAddr - address of register in Baseband - * byTestBits - TestBits - * Out: - * none - * - * Return Value: true if all TestBits are set; false otherwise. - * - */ -bool BBbIsRegBitsOn(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char byTestBits) -{ - unsigned char byOrgData; - - BBbReadEmbedded(dwIoBase, byBBAddr, &byOrgData); - return (byOrgData & byTestBits) == byTestBits; -} - -/* - * Description: Test if all bits are clear for the Baseband register - * - * Parameters: - * In: - * dwIoBase - I/O base address - * byBBAddr - address of register in Baseband - * byTestBits - TestBits - * Out: - * none - * - * Return Value: true if all TestBits are clear; false otherwise. - * - */ -bool BBbIsRegBitsOff(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char byTestBits) -{ - unsigned char byOrgData; - - BBbReadEmbedded(dwIoBase, byBBAddr, &byOrgData); - return (byOrgData & byTestBits) == 0; -} - -/* * Description: VIA VT3253 Baseband chip init function * * Parameters: @@ -2096,126 +2049,126 @@ bool BBbIsRegBitsOff(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned ch * */ -bool BBbVT3253Init(struct vnt_private *pDevice) +bool BBbVT3253Init(struct vnt_private *priv) { bool bResult = true; int ii; - void __iomem *dwIoBase = pDevice->PortOffset; - unsigned char byRFType = pDevice->byRFType; - unsigned char byLocalID = pDevice->byLocalID; + void __iomem *dwIoBase = priv->PortOffset; + unsigned char byRFType = priv->byRFType; + unsigned char byLocalID = priv->byLocalID; if (byRFType == RF_RFMD2959) { if (byLocalID <= REV_ID_VT3253_A1) { for (ii = 0; ii < CB_VT3253_INIT_FOR_RFMD; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253InitTab_RFMD[ii][0], byVT3253InitTab_RFMD[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253InitTab_RFMD[ii][0], byVT3253InitTab_RFMD[ii][1]); } else { for (ii = 0; ii < CB_VT3253B0_INIT_FOR_RFMD; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_RFMD[ii][0], byVT3253B0_RFMD[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253B0_RFMD[ii][0], byVT3253B0_RFMD[ii][1]); for (ii = 0; ii < CB_VT3253B0_AGC_FOR_RFMD2959; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AGC4_RFMD2959[ii][0], byVT3253B0_AGC4_RFMD2959[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253B0_AGC4_RFMD2959[ii][0], byVT3253B0_AGC4_RFMD2959[ii][1]); VNSvOutPortD(dwIoBase + MAC_REG_ITRTMSET, 0x23); - MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT0); + MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT(0)); } - pDevice->abyBBVGA[0] = 0x18; - pDevice->abyBBVGA[1] = 0x0A; - pDevice->abyBBVGA[2] = 0x0; - pDevice->abyBBVGA[3] = 0x0; - pDevice->ldBmThreshold[0] = -70; - pDevice->ldBmThreshold[1] = -50; - pDevice->ldBmThreshold[2] = 0; - pDevice->ldBmThreshold[3] = 0; + priv->abyBBVGA[0] = 0x18; + priv->abyBBVGA[1] = 0x0A; + priv->abyBBVGA[2] = 0x0; + priv->abyBBVGA[3] = 0x0; + priv->ldBmThreshold[0] = -70; + priv->ldBmThreshold[1] = -50; + priv->ldBmThreshold[2] = 0; + priv->ldBmThreshold[3] = 0; } else if ((byRFType == RF_AIROHA) || (byRFType == RF_AL2230S)) { for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AIROHA2230[ii][0], byVT3253B0_AIROHA2230[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253B0_AIROHA2230[ii][0], byVT3253B0_AIROHA2230[ii][1]); for (ii = 0; ii < CB_VT3253B0_AGC; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); - - pDevice->abyBBVGA[0] = 0x1C; - pDevice->abyBBVGA[1] = 0x10; - pDevice->abyBBVGA[2] = 0x0; - pDevice->abyBBVGA[3] = 0x0; - pDevice->ldBmThreshold[0] = -70; - pDevice->ldBmThreshold[1] = -48; - pDevice->ldBmThreshold[2] = 0; - pDevice->ldBmThreshold[3] = 0; + bResult &= BBbWriteEmbedded(priv, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); + + priv->abyBBVGA[0] = 0x1C; + priv->abyBBVGA[1] = 0x10; + priv->abyBBVGA[2] = 0x0; + priv->abyBBVGA[3] = 0x0; + priv->ldBmThreshold[0] = -70; + priv->ldBmThreshold[1] = -48; + priv->ldBmThreshold[2] = 0; + priv->ldBmThreshold[3] = 0; } else if (byRFType == RF_UW2451) { for (ii = 0; ii < CB_VT3253B0_INIT_FOR_UW2451; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_UW2451[ii][0], byVT3253B0_UW2451[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253B0_UW2451[ii][0], byVT3253B0_UW2451[ii][1]); for (ii = 0; ii < CB_VT3253B0_AGC; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); VNSvOutPortB(dwIoBase + MAC_REG_ITRTMSET, 0x23); - MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT0); - - pDevice->abyBBVGA[0] = 0x14; - pDevice->abyBBVGA[1] = 0x0A; - pDevice->abyBBVGA[2] = 0x0; - pDevice->abyBBVGA[3] = 0x0; - pDevice->ldBmThreshold[0] = -60; - pDevice->ldBmThreshold[1] = -50; - pDevice->ldBmThreshold[2] = 0; - pDevice->ldBmThreshold[3] = 0; + MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT(0)); + + priv->abyBBVGA[0] = 0x14; + priv->abyBBVGA[1] = 0x0A; + priv->abyBBVGA[2] = 0x0; + priv->abyBBVGA[3] = 0x0; + priv->ldBmThreshold[0] = -60; + priv->ldBmThreshold[1] = -50; + priv->ldBmThreshold[2] = 0; + priv->ldBmThreshold[3] = 0; } else if (byRFType == RF_UW2452) { for (ii = 0; ii < CB_VT3253B0_INIT_FOR_UW2451; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_UW2451[ii][0], byVT3253B0_UW2451[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253B0_UW2451[ii][0], byVT3253B0_UW2451[ii][1]); /* Init ANT B select,TX Config CR09 = 0x61->0x45, 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted) */ /*bResult &= BBbWriteEmbedded(dwIoBase,0x09,0x41);*/ /* Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted) */ /*bResult &= BBbWriteEmbedded(dwIoBase,0x0a,0x28);*/ /* Select VC1/VC2, CR215 = 0x02->0x06 */ - bResult &= BBbWriteEmbedded(dwIoBase, 0xd7, 0x06); + bResult &= BBbWriteEmbedded(priv, 0xd7, 0x06); /* {{RobertYu:20050125, request by Jack */ - bResult &= BBbWriteEmbedded(dwIoBase, 0x90, 0x20); - bResult &= BBbWriteEmbedded(dwIoBase, 0x97, 0xeb); + bResult &= BBbWriteEmbedded(priv, 0x90, 0x20); + bResult &= BBbWriteEmbedded(priv, 0x97, 0xeb); /* }} */ /* {{RobertYu:20050221, request by Jack */ - bResult &= BBbWriteEmbedded(dwIoBase, 0xa6, 0x00); - bResult &= BBbWriteEmbedded(dwIoBase, 0xa8, 0x30); + bResult &= BBbWriteEmbedded(priv, 0xa6, 0x00); + bResult &= BBbWriteEmbedded(priv, 0xa8, 0x30); /* }} */ - bResult &= BBbWriteEmbedded(dwIoBase, 0xb0, 0x58); + bResult &= BBbWriteEmbedded(priv, 0xb0, 0x58); for (ii = 0; ii < CB_VT3253B0_AGC; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); - - pDevice->abyBBVGA[0] = 0x14; - pDevice->abyBBVGA[1] = 0x0A; - pDevice->abyBBVGA[2] = 0x0; - pDevice->abyBBVGA[3] = 0x0; - pDevice->ldBmThreshold[0] = -60; - pDevice->ldBmThreshold[1] = -50; - pDevice->ldBmThreshold[2] = 0; - pDevice->ldBmThreshold[3] = 0; + bResult &= BBbWriteEmbedded(priv, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); + + priv->abyBBVGA[0] = 0x14; + priv->abyBBVGA[1] = 0x0A; + priv->abyBBVGA[2] = 0x0; + priv->abyBBVGA[3] = 0x0; + priv->ldBmThreshold[0] = -60; + priv->ldBmThreshold[1] = -50; + priv->ldBmThreshold[2] = 0; + priv->ldBmThreshold[3] = 0; /* }} RobertYu */ } else if (byRFType == RF_VT3226) { for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AIROHA2230[ii][0], byVT3253B0_AIROHA2230[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253B0_AIROHA2230[ii][0], byVT3253B0_AIROHA2230[ii][1]); for (ii = 0; ii < CB_VT3253B0_AGC; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); - - pDevice->abyBBVGA[0] = 0x1C; - pDevice->abyBBVGA[1] = 0x10; - pDevice->abyBBVGA[2] = 0x0; - pDevice->abyBBVGA[3] = 0x0; - pDevice->ldBmThreshold[0] = -70; - pDevice->ldBmThreshold[1] = -48; - pDevice->ldBmThreshold[2] = 0; - pDevice->ldBmThreshold[3] = 0; + bResult &= BBbWriteEmbedded(priv, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); + + priv->abyBBVGA[0] = 0x1C; + priv->abyBBVGA[1] = 0x10; + priv->abyBBVGA[2] = 0x0; + priv->abyBBVGA[3] = 0x0; + priv->ldBmThreshold[0] = -70; + priv->ldBmThreshold[1] = -48; + priv->ldBmThreshold[2] = 0; + priv->ldBmThreshold[3] = 0; /* Fix VT3226 DFC system timing issue */ MACvSetRFLE_LatchBase(dwIoBase); /* {{ RobertYu: 20050104 */ } else if (byRFType == RF_AIROHA7230) { for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AIROHA2230[ii][0], byVT3253B0_AIROHA2230[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253B0_AIROHA2230[ii][0], byVT3253B0_AIROHA2230[ii][1]); /* {{ RobertYu:20050223, request by JerryChung */ @@ -2224,154 +2177,41 @@ bool BBbVT3253Init(struct vnt_private *pDevice) /* Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted) */ /*bResult &= BBbWriteEmbedded(dwIoBase,0x0a,0x28);*/ /* Select VC1/VC2, CR215 = 0x02->0x06 */ - bResult &= BBbWriteEmbedded(dwIoBase, 0xd7, 0x06); + bResult &= BBbWriteEmbedded(priv, 0xd7, 0x06); /* }} */ for (ii = 0; ii < CB_VT3253B0_AGC; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); - - pDevice->abyBBVGA[0] = 0x1C; - pDevice->abyBBVGA[1] = 0x10; - pDevice->abyBBVGA[2] = 0x0; - pDevice->abyBBVGA[3] = 0x0; - pDevice->ldBmThreshold[0] = -70; - pDevice->ldBmThreshold[1] = -48; - pDevice->ldBmThreshold[2] = 0; - pDevice->ldBmThreshold[3] = 0; + bResult &= BBbWriteEmbedded(priv, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); + + priv->abyBBVGA[0] = 0x1C; + priv->abyBBVGA[1] = 0x10; + priv->abyBBVGA[2] = 0x0; + priv->abyBBVGA[3] = 0x0; + priv->ldBmThreshold[0] = -70; + priv->ldBmThreshold[1] = -48; + priv->ldBmThreshold[2] = 0; + priv->ldBmThreshold[3] = 0; /* }} RobertYu */ } else { /* No VGA Table now */ - pDevice->bUpdateBBVGA = false; - pDevice->abyBBVGA[0] = 0x1C; + priv->bUpdateBBVGA = false; + priv->abyBBVGA[0] = 0x1C; } if (byLocalID > REV_ID_VT3253_A1) { - BBbWriteEmbedded(dwIoBase, 0x04, 0x7F); - BBbWriteEmbedded(dwIoBase, 0x0D, 0x01); + BBbWriteEmbedded(priv, 0x04, 0x7F); + BBbWriteEmbedded(priv, 0x0D, 0x01); } return bResult; } /* - * Description: Read All Baseband Registers - * - * Parameters: - * In: - * dwIoBase - I/O base address - * pbyBBRegs - Point to struct that stores Baseband Registers - * Out: - * none - * - * Return Value: none - * - */ -void BBvReadAllRegs(void __iomem *dwIoBase, unsigned char *pbyBBRegs) -{ - int ii; - unsigned char byBase = 1; - - for (ii = 0; ii < BB_MAX_CONTEXT_SIZE; ii++) { - BBbReadEmbedded(dwIoBase, (unsigned char)(ii*byBase), pbyBBRegs); - pbyBBRegs += byBase; - } -} - -/* - * Description: Turn on BaseBand Loopback mode - * - * Parameters: - * In: - * dwIoBase - I/O base address - * bCCK - If CCK is set - * Out: - * none - * - * Return Value: none - * - */ - -void BBvLoopbackOn(struct vnt_private *pDevice) -{ - unsigned char byData; - void __iomem *dwIoBase = pDevice->PortOffset; - - /* CR C9 = 0x00 */ - BBbReadEmbedded(dwIoBase, 0xC9, &pDevice->byBBCRc9); /* CR201 */ - BBbWriteEmbedded(dwIoBase, 0xC9, 0); - BBbReadEmbedded(dwIoBase, 0x4D, &pDevice->byBBCR4d); /* CR77 */ - BBbWriteEmbedded(dwIoBase, 0x4D, 0x90); - - /* CR 88 = 0x02(CCK), 0x03(OFDM) */ - BBbReadEmbedded(dwIoBase, 0x88, &pDevice->byBBCR88); /* CR136 */ - - if (pDevice->uConnectionRate <= RATE_11M) { /* CCK */ - /* Enable internal digital loopback: CR33 |= 0000 0001 */ - BBbReadEmbedded(dwIoBase, 0x21, &byData); /* CR33 */ - BBbWriteEmbedded(dwIoBase, 0x21, (unsigned char)(byData | 0x01)); /* CR33 */ - /* CR154 = 0x00 */ - BBbWriteEmbedded(dwIoBase, 0x9A, 0); /* CR154 */ - - BBbWriteEmbedded(dwIoBase, 0x88, 0x02); /* CR239 */ - } else { /* OFDM */ - /* Enable internal digital loopback:CR154 |= 0000 0001 */ - BBbReadEmbedded(dwIoBase, 0x9A, &byData); /* CR154 */ - BBbWriteEmbedded(dwIoBase, 0x9A, (unsigned char)(byData | 0x01)); /* CR154 */ - /* CR33 = 0x00 */ - BBbWriteEmbedded(dwIoBase, 0x21, 0); /* CR33 */ - - BBbWriteEmbedded(dwIoBase, 0x88, 0x03); /* CR239 */ - } - - /* CR14 = 0x00 */ - BBbWriteEmbedded(dwIoBase, 0x0E, 0); /* CR14 */ - - /* Disable TX_IQUN */ - BBbReadEmbedded(pDevice->PortOffset, 0x09, &pDevice->byBBCR09); - BBbWriteEmbedded(pDevice->PortOffset, 0x09, (unsigned char)(pDevice->byBBCR09 & 0xDE)); -} - -/* - * Description: Turn off BaseBand Loopback mode - * - * Parameters: - * In: - * pDevice - Device Structure - * - * Out: - * none - * - * Return Value: none - * - */ -void BBvLoopbackOff(struct vnt_private *pDevice) -{ - unsigned char byData; - void __iomem *dwIoBase = pDevice->PortOffset; - - BBbWriteEmbedded(dwIoBase, 0xC9, pDevice->byBBCRc9); /* CR201 */ - BBbWriteEmbedded(dwIoBase, 0x88, pDevice->byBBCR88); /* CR136 */ - BBbWriteEmbedded(dwIoBase, 0x09, pDevice->byBBCR09); /* CR136 */ - BBbWriteEmbedded(dwIoBase, 0x4D, pDevice->byBBCR4d); /* CR77 */ - - if (pDevice->uConnectionRate <= RATE_11M) { /* CCK */ - /* Set the CR33 Bit2 to disable internal Loopback. */ - BBbReadEmbedded(dwIoBase, 0x21, &byData);/* CR33 */ - BBbWriteEmbedded(dwIoBase, 0x21, (unsigned char)(byData & 0xFE)); /* CR33 */ - } else { /* OFDM */ - BBbReadEmbedded(dwIoBase, 0x9A, &byData); /* CR154 */ - BBbWriteEmbedded(dwIoBase, 0x9A, (unsigned char)(byData & 0xFE)); /* CR154 */ - } - BBbReadEmbedded(dwIoBase, 0x0E, &byData); /* CR14 */ - BBbWriteEmbedded(dwIoBase, 0x0E, (unsigned char)(byData | 0x80)); /* CR14 */ -} - -/* * Description: Set ShortSlotTime mode * * Parameters: * In: - * pDevice - Device Structure + * priv - Device Structure * Out: * none * @@ -2379,42 +2219,42 @@ void BBvLoopbackOff(struct vnt_private *pDevice) * */ void -BBvSetShortSlotTime(struct vnt_private *pDevice) +BBvSetShortSlotTime(struct vnt_private *priv) { unsigned char byBBRxConf = 0; unsigned char byBBVGA = 0; - BBbReadEmbedded(pDevice->PortOffset, 0x0A, &byBBRxConf); /* CR10 */ + BBbReadEmbedded(priv, 0x0A, &byBBRxConf); /* CR10 */ - if (pDevice->bShortSlotTime) + if (priv->bShortSlotTime) byBBRxConf &= 0xDF; /* 1101 1111 */ else byBBRxConf |= 0x20; /* 0010 0000 */ /* patch for 3253B0 Baseband with Cardbus module */ - BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byBBVGA); - if (byBBVGA == pDevice->abyBBVGA[0]) + BBbReadEmbedded(priv, 0xE7, &byBBVGA); + if (byBBVGA == priv->abyBBVGA[0]) byBBRxConf |= 0x20; /* 0010 0000 */ - BBbWriteEmbedded(pDevice->PortOffset, 0x0A, byBBRxConf); /* CR10 */ + BBbWriteEmbedded(priv, 0x0A, byBBRxConf); /* CR10 */ } -void BBvSetVGAGainOffset(struct vnt_private *pDevice, unsigned char byData) +void BBvSetVGAGainOffset(struct vnt_private *priv, unsigned char byData) { unsigned char byBBRxConf = 0; - BBbWriteEmbedded(pDevice->PortOffset, 0xE7, byData); + BBbWriteEmbedded(priv, 0xE7, byData); - BBbReadEmbedded(pDevice->PortOffset, 0x0A, &byBBRxConf); /* CR10 */ + BBbReadEmbedded(priv, 0x0A, &byBBRxConf); /* CR10 */ /* patch for 3253B0 Baseband with Cardbus module */ - if (byData == pDevice->abyBBVGA[0]) + if (byData == priv->abyBBVGA[0]) byBBRxConf |= 0x20; /* 0010 0000 */ - else if (pDevice->bShortSlotTime) + else if (priv->bShortSlotTime) byBBRxConf &= 0xDF; /* 1101 1111 */ else byBBRxConf |= 0x20; /* 0010 0000 */ - pDevice->byBBVGACurrent = byData; - BBbWriteEmbedded(pDevice->PortOffset, 0x0A, byBBRxConf); /* CR10 */ + priv->byBBVGACurrent = byData; + BBbWriteEmbedded(priv, 0x0A, byBBRxConf); /* CR10 */ } /* @@ -2430,12 +2270,12 @@ void BBvSetVGAGainOffset(struct vnt_private *pDevice, unsigned char byData) * */ void -BBvSoftwareReset(void __iomem *dwIoBase) +BBvSoftwareReset(struct vnt_private *priv) { - BBbWriteEmbedded(dwIoBase, 0x50, 0x40); - BBbWriteEmbedded(dwIoBase, 0x50, 0); - BBbWriteEmbedded(dwIoBase, 0x9C, 0x01); - BBbWriteEmbedded(dwIoBase, 0x9C, 0); + BBbWriteEmbedded(priv, 0x50, 0x40); + BBbWriteEmbedded(priv, 0x50, 0); + BBbWriteEmbedded(priv, 0x9C, 0x01); + BBbWriteEmbedded(priv, 0x9C, 0); } /* @@ -2451,13 +2291,13 @@ BBvSoftwareReset(void __iomem *dwIoBase) * */ void -BBvPowerSaveModeON(void __iomem *dwIoBase) +BBvPowerSaveModeON(struct vnt_private *priv) { unsigned char byOrgData; - BBbReadEmbedded(dwIoBase, 0x0D, &byOrgData); - byOrgData |= BIT0; - BBbWriteEmbedded(dwIoBase, 0x0D, byOrgData); + BBbReadEmbedded(priv, 0x0D, &byOrgData); + byOrgData |= BIT(0); + BBbWriteEmbedded(priv, 0x0D, byOrgData); } /* @@ -2473,13 +2313,13 @@ BBvPowerSaveModeON(void __iomem *dwIoBase) * */ void -BBvPowerSaveModeOFF(void __iomem *dwIoBase) +BBvPowerSaveModeOFF(struct vnt_private *priv) { unsigned char byOrgData; - BBbReadEmbedded(dwIoBase, 0x0D, &byOrgData); - byOrgData &= ~(BIT0); - BBbWriteEmbedded(dwIoBase, 0x0D, byOrgData); + BBbReadEmbedded(priv, 0x0D, &byOrgData); + byOrgData &= ~(BIT(0)); + BBbWriteEmbedded(priv, 0x0D, byOrgData); } /* @@ -2487,7 +2327,7 @@ BBvPowerSaveModeOFF(void __iomem *dwIoBase) * * Parameters: * In: - * pDevice - Device Structure + * priv - Device Structure * byAntennaMode - Antenna Mode * Out: * none @@ -2497,11 +2337,11 @@ BBvPowerSaveModeOFF(void __iomem *dwIoBase) */ void -BBvSetTxAntennaMode(void __iomem *dwIoBase, unsigned char byAntennaMode) +BBvSetTxAntennaMode(struct vnt_private *priv, unsigned char byAntennaMode) { unsigned char byBBTxConf; - BBbReadEmbedded(dwIoBase, 0x09, &byBBTxConf); /* CR09 */ + BBbReadEmbedded(priv, 0x09, &byBBTxConf); /* CR09 */ if (byAntennaMode == ANT_DIVERSITY) { /* bit 1 is diversity */ byBBTxConf |= 0x02; @@ -2512,7 +2352,7 @@ BBvSetTxAntennaMode(void __iomem *dwIoBase, unsigned char byAntennaMode) byBBTxConf &= 0xFD; /* 1111 1101 */ byBBTxConf |= 0x04; } - BBbWriteEmbedded(dwIoBase, 0x09, byBBTxConf); /* CR09 */ + BBbWriteEmbedded(priv, 0x09, byBBTxConf); /* CR09 */ } /* @@ -2520,7 +2360,7 @@ BBvSetTxAntennaMode(void __iomem *dwIoBase, unsigned char byAntennaMode) * * Parameters: * In: - * pDevice - Device Structure + * priv - Device Structure * byAntennaMode - Antenna Mode * Out: * none @@ -2530,11 +2370,11 @@ BBvSetTxAntennaMode(void __iomem *dwIoBase, unsigned char byAntennaMode) */ void -BBvSetRxAntennaMode(void __iomem *dwIoBase, unsigned char byAntennaMode) +BBvSetRxAntennaMode(struct vnt_private *priv, unsigned char byAntennaMode) { unsigned char byBBRxConf; - BBbReadEmbedded(dwIoBase, 0x0A, &byBBRxConf); /* CR10 */ + BBbReadEmbedded(priv, 0x0A, &byBBRxConf); /* CR10 */ if (byAntennaMode == ANT_DIVERSITY) { byBBRxConf |= 0x01; @@ -2544,7 +2384,7 @@ BBvSetRxAntennaMode(void __iomem *dwIoBase, unsigned char byAntennaMode) byBBRxConf &= 0xFE; /* 1111 1110 */ byBBRxConf |= 0x02; } - BBbWriteEmbedded(dwIoBase, 0x0A, byBBRxConf); /* CR10 */ + BBbWriteEmbedded(priv, 0x0A, byBBRxConf); /* CR10 */ } /* @@ -2552,7 +2392,7 @@ BBvSetRxAntennaMode(void __iomem *dwIoBase, unsigned char byAntennaMode) * * Parameters: * In: - * pDevice - Device Structure + * priv - Device Structure * Out: * none * @@ -2560,109 +2400,109 @@ BBvSetRxAntennaMode(void __iomem *dwIoBase, unsigned char byAntennaMode) * */ void -BBvSetDeepSleep(void __iomem *dwIoBase, unsigned char byLocalID) +BBvSetDeepSleep(struct vnt_private *priv, unsigned char byLocalID) { - BBbWriteEmbedded(dwIoBase, 0x0C, 0x17); /* CR12 */ - BBbWriteEmbedded(dwIoBase, 0x0D, 0xB9); /* CR13 */ + BBbWriteEmbedded(priv, 0x0C, 0x17); /* CR12 */ + BBbWriteEmbedded(priv, 0x0D, 0xB9); /* CR13 */ } void -BBvExitDeepSleep(void __iomem *dwIoBase, unsigned char byLocalID) +BBvExitDeepSleep(struct vnt_private *priv, unsigned char byLocalID) { - BBbWriteEmbedded(dwIoBase, 0x0C, 0x00); /* CR12 */ - BBbWriteEmbedded(dwIoBase, 0x0D, 0x01); /* CR13 */ + BBbWriteEmbedded(priv, 0x0C, 0x00); /* CR12 */ + BBbWriteEmbedded(priv, 0x0D, 0x01); /* CR13 */ } static unsigned long -s_ulGetRatio(struct vnt_private *pDevice) +s_ulGetRatio(struct vnt_private *priv) { unsigned long ulRatio = 0; unsigned long ulMaxPacket; unsigned long ulPacketNum; /* This is a thousand-ratio */ - ulMaxPacket = pDevice->uNumSQ3[RATE_54M]; - if (pDevice->uNumSQ3[RATE_54M] != 0) { - ulPacketNum = pDevice->uNumSQ3[RATE_54M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + ulMaxPacket = priv->uNumSQ3[RATE_54M]; + if (priv->uNumSQ3[RATE_54M] != 0) { + ulPacketNum = priv->uNumSQ3[RATE_54M]; + ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt); ulRatio += TOP_RATE_54M; } - if (pDevice->uNumSQ3[RATE_48M] > ulMaxPacket) { - ulPacketNum = pDevice->uNumSQ3[RATE_54M] + pDevice->uNumSQ3[RATE_48M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + if (priv->uNumSQ3[RATE_48M] > ulMaxPacket) { + ulPacketNum = priv->uNumSQ3[RATE_54M] + priv->uNumSQ3[RATE_48M]; + ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt); ulRatio += TOP_RATE_48M; - ulMaxPacket = pDevice->uNumSQ3[RATE_48M]; + ulMaxPacket = priv->uNumSQ3[RATE_48M]; } - if (pDevice->uNumSQ3[RATE_36M] > ulMaxPacket) { - ulPacketNum = pDevice->uNumSQ3[RATE_54M] + pDevice->uNumSQ3[RATE_48M] + - pDevice->uNumSQ3[RATE_36M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + if (priv->uNumSQ3[RATE_36M] > ulMaxPacket) { + ulPacketNum = priv->uNumSQ3[RATE_54M] + priv->uNumSQ3[RATE_48M] + + priv->uNumSQ3[RATE_36M]; + ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt); ulRatio += TOP_RATE_36M; - ulMaxPacket = pDevice->uNumSQ3[RATE_36M]; + ulMaxPacket = priv->uNumSQ3[RATE_36M]; } - if (pDevice->uNumSQ3[RATE_24M] > ulMaxPacket) { - ulPacketNum = pDevice->uNumSQ3[RATE_54M] + pDevice->uNumSQ3[RATE_48M] + - pDevice->uNumSQ3[RATE_36M] + pDevice->uNumSQ3[RATE_24M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + if (priv->uNumSQ3[RATE_24M] > ulMaxPacket) { + ulPacketNum = priv->uNumSQ3[RATE_54M] + priv->uNumSQ3[RATE_48M] + + priv->uNumSQ3[RATE_36M] + priv->uNumSQ3[RATE_24M]; + ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt); ulRatio += TOP_RATE_24M; - ulMaxPacket = pDevice->uNumSQ3[RATE_24M]; + ulMaxPacket = priv->uNumSQ3[RATE_24M]; } - if (pDevice->uNumSQ3[RATE_18M] > ulMaxPacket) { - ulPacketNum = pDevice->uNumSQ3[RATE_54M] + pDevice->uNumSQ3[RATE_48M] + - pDevice->uNumSQ3[RATE_36M] + pDevice->uNumSQ3[RATE_24M] + - pDevice->uNumSQ3[RATE_18M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + if (priv->uNumSQ3[RATE_18M] > ulMaxPacket) { + ulPacketNum = priv->uNumSQ3[RATE_54M] + priv->uNumSQ3[RATE_48M] + + priv->uNumSQ3[RATE_36M] + priv->uNumSQ3[RATE_24M] + + priv->uNumSQ3[RATE_18M]; + ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt); ulRatio += TOP_RATE_18M; - ulMaxPacket = pDevice->uNumSQ3[RATE_18M]; + ulMaxPacket = priv->uNumSQ3[RATE_18M]; } - if (pDevice->uNumSQ3[RATE_12M] > ulMaxPacket) { - ulPacketNum = pDevice->uNumSQ3[RATE_54M] + pDevice->uNumSQ3[RATE_48M] + - pDevice->uNumSQ3[RATE_36M] + pDevice->uNumSQ3[RATE_24M] + - pDevice->uNumSQ3[RATE_18M] + pDevice->uNumSQ3[RATE_12M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + if (priv->uNumSQ3[RATE_12M] > ulMaxPacket) { + ulPacketNum = priv->uNumSQ3[RATE_54M] + priv->uNumSQ3[RATE_48M] + + priv->uNumSQ3[RATE_36M] + priv->uNumSQ3[RATE_24M] + + priv->uNumSQ3[RATE_18M] + priv->uNumSQ3[RATE_12M]; + ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt); ulRatio += TOP_RATE_12M; - ulMaxPacket = pDevice->uNumSQ3[RATE_12M]; + ulMaxPacket = priv->uNumSQ3[RATE_12M]; } - if (pDevice->uNumSQ3[RATE_11M] > ulMaxPacket) { - ulPacketNum = pDevice->uDiversityCnt - pDevice->uNumSQ3[RATE_1M] - - pDevice->uNumSQ3[RATE_2M] - pDevice->uNumSQ3[RATE_5M] - - pDevice->uNumSQ3[RATE_6M] - pDevice->uNumSQ3[RATE_9M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + if (priv->uNumSQ3[RATE_11M] > ulMaxPacket) { + ulPacketNum = priv->uDiversityCnt - priv->uNumSQ3[RATE_1M] - + priv->uNumSQ3[RATE_2M] - priv->uNumSQ3[RATE_5M] - + priv->uNumSQ3[RATE_6M] - priv->uNumSQ3[RATE_9M]; + ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt); ulRatio += TOP_RATE_11M; - ulMaxPacket = pDevice->uNumSQ3[RATE_11M]; + ulMaxPacket = priv->uNumSQ3[RATE_11M]; } - if (pDevice->uNumSQ3[RATE_9M] > ulMaxPacket) { - ulPacketNum = pDevice->uDiversityCnt - pDevice->uNumSQ3[RATE_1M] - - pDevice->uNumSQ3[RATE_2M] - pDevice->uNumSQ3[RATE_5M] - - pDevice->uNumSQ3[RATE_6M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + if (priv->uNumSQ3[RATE_9M] > ulMaxPacket) { + ulPacketNum = priv->uDiversityCnt - priv->uNumSQ3[RATE_1M] - + priv->uNumSQ3[RATE_2M] - priv->uNumSQ3[RATE_5M] - + priv->uNumSQ3[RATE_6M]; + ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt); ulRatio += TOP_RATE_9M; - ulMaxPacket = pDevice->uNumSQ3[RATE_9M]; + ulMaxPacket = priv->uNumSQ3[RATE_9M]; } - if (pDevice->uNumSQ3[RATE_6M] > ulMaxPacket) { - ulPacketNum = pDevice->uDiversityCnt - pDevice->uNumSQ3[RATE_1M] - - pDevice->uNumSQ3[RATE_2M] - pDevice->uNumSQ3[RATE_5M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + if (priv->uNumSQ3[RATE_6M] > ulMaxPacket) { + ulPacketNum = priv->uDiversityCnt - priv->uNumSQ3[RATE_1M] - + priv->uNumSQ3[RATE_2M] - priv->uNumSQ3[RATE_5M]; + ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt); ulRatio += TOP_RATE_6M; - ulMaxPacket = pDevice->uNumSQ3[RATE_6M]; + ulMaxPacket = priv->uNumSQ3[RATE_6M]; } - if (pDevice->uNumSQ3[RATE_5M] > ulMaxPacket) { - ulPacketNum = pDevice->uDiversityCnt - pDevice->uNumSQ3[RATE_1M] - - pDevice->uNumSQ3[RATE_2M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + if (priv->uNumSQ3[RATE_5M] > ulMaxPacket) { + ulPacketNum = priv->uDiversityCnt - priv->uNumSQ3[RATE_1M] - + priv->uNumSQ3[RATE_2M]; + ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt); ulRatio += TOP_RATE_55M; - ulMaxPacket = pDevice->uNumSQ3[RATE_5M]; + ulMaxPacket = priv->uNumSQ3[RATE_5M]; } - if (pDevice->uNumSQ3[RATE_2M] > ulMaxPacket) { - ulPacketNum = pDevice->uDiversityCnt - pDevice->uNumSQ3[RATE_1M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + if (priv->uNumSQ3[RATE_2M] > ulMaxPacket) { + ulPacketNum = priv->uDiversityCnt - priv->uNumSQ3[RATE_1M]; + ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt); ulRatio += TOP_RATE_2M; - ulMaxPacket = pDevice->uNumSQ3[RATE_2M]; + ulMaxPacket = priv->uNumSQ3[RATE_2M]; } - if (pDevice->uNumSQ3[RATE_1M] > ulMaxPacket) { - ulPacketNum = pDevice->uDiversityCnt; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + if (priv->uNumSQ3[RATE_1M] > ulMaxPacket) { + ulPacketNum = priv->uDiversityCnt; + ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt); ulRatio += TOP_RATE_1M; } @@ -2670,13 +2510,13 @@ s_ulGetRatio(struct vnt_private *pDevice) } void -BBvClearAntDivSQ3Value(struct vnt_private *pDevice) +BBvClearAntDivSQ3Value(struct vnt_private *priv) { unsigned int ii; - pDevice->uDiversityCnt = 0; + priv->uDiversityCnt = 0; for (ii = 0; ii < MAX_RATE; ii++) - pDevice->uNumSQ3[ii] = 0; + priv->uNumSQ3[ii] = 0; } /* @@ -2684,7 +2524,7 @@ BBvClearAntDivSQ3Value(struct vnt_private *pDevice) * * Parameters: * In: - * pDevice - Device Structure + * priv - Device Structure * byRSR - RSR from received packet * bySQ3 - SQ3 value from received packet * Out: @@ -2694,75 +2534,75 @@ BBvClearAntDivSQ3Value(struct vnt_private *pDevice) * */ -void BBvAntennaDiversity(struct vnt_private *pDevice, +void BBvAntennaDiversity(struct vnt_private *priv, unsigned char byRxRate, unsigned char bySQ3) { - if ((byRxRate >= MAX_RATE) || (pDevice->wAntDiversityMaxRate >= MAX_RATE)) + if ((byRxRate >= MAX_RATE) || (priv->wAntDiversityMaxRate >= MAX_RATE)) return; - pDevice->uDiversityCnt++; + priv->uDiversityCnt++; - pDevice->uNumSQ3[byRxRate]++; + priv->uNumSQ3[byRxRate]++; - if (pDevice->byAntennaState == 0) { - if (pDevice->uDiversityCnt > pDevice->ulDiversityNValue) { + if (priv->byAntennaState == 0) { + if (priv->uDiversityCnt > priv->ulDiversityNValue) { pr_debug("ulDiversityNValue=[%d],54M-[%d]\n", - (int)pDevice->ulDiversityNValue, - (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate]); + (int)priv->ulDiversityNValue, + (int)priv->uNumSQ3[(int)priv->wAntDiversityMaxRate]); - if (pDevice->uNumSQ3[pDevice->wAntDiversityMaxRate] < pDevice->uDiversityCnt/2) { - pDevice->ulRatio_State0 = s_ulGetRatio(pDevice); + if (priv->uNumSQ3[priv->wAntDiversityMaxRate] < priv->uDiversityCnt/2) { + priv->ulRatio_State0 = s_ulGetRatio(priv); pr_debug("SQ3_State0, rate = [%08x]\n", - (int)pDevice->ulRatio_State0); + (int)priv->ulRatio_State0); - if (pDevice->byTMax == 0) + if (priv->byTMax == 0) return; pr_debug("1.[%08x], uNumSQ3[%d]=%d, %d\n", - (int)pDevice->ulRatio_State0, - (int)pDevice->wAntDiversityMaxRate, - (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate], - (int)pDevice->uDiversityCnt); - - s_vChangeAntenna(pDevice); - pDevice->byAntennaState = 1; - del_timer(&pDevice->TimerSQ3Tmax3); - del_timer(&pDevice->TimerSQ3Tmax2); - pDevice->TimerSQ3Tmax1.expires = RUN_AT(pDevice->byTMax * HZ); - add_timer(&pDevice->TimerSQ3Tmax1); + (int)priv->ulRatio_State0, + (int)priv->wAntDiversityMaxRate, + (int)priv->uNumSQ3[(int)priv->wAntDiversityMaxRate], + (int)priv->uDiversityCnt); + + s_vChangeAntenna(priv); + priv->byAntennaState = 1; + del_timer(&priv->TimerSQ3Tmax3); + del_timer(&priv->TimerSQ3Tmax2); + priv->TimerSQ3Tmax1.expires = RUN_AT(priv->byTMax * HZ); + add_timer(&priv->TimerSQ3Tmax1); } else { - pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ); - add_timer(&pDevice->TimerSQ3Tmax3); + priv->TimerSQ3Tmax3.expires = RUN_AT(priv->byTMax3 * HZ); + add_timer(&priv->TimerSQ3Tmax3); } - BBvClearAntDivSQ3Value(pDevice); + BBvClearAntDivSQ3Value(priv); } } else { /* byAntennaState == 1 */ - if (pDevice->uDiversityCnt > pDevice->ulDiversityMValue) { - del_timer(&pDevice->TimerSQ3Tmax1); + if (priv->uDiversityCnt > priv->ulDiversityMValue) { + del_timer(&priv->TimerSQ3Tmax1); - pDevice->ulRatio_State1 = s_ulGetRatio(pDevice); + priv->ulRatio_State1 = s_ulGetRatio(priv); pr_debug("RX:SQ3_State1, rate0 = %08x,rate1 = %08x\n", - (int)pDevice->ulRatio_State0, - (int)pDevice->ulRatio_State1); + (int)priv->ulRatio_State0, + (int)priv->ulRatio_State1); - if (pDevice->ulRatio_State1 < pDevice->ulRatio_State0) { + if (priv->ulRatio_State1 < priv->ulRatio_State0) { pr_debug("2.[%08x][%08x], uNumSQ3[%d]=%d, %d\n", - (int)pDevice->ulRatio_State0, - (int)pDevice->ulRatio_State1, - (int)pDevice->wAntDiversityMaxRate, - (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate], - (int)pDevice->uDiversityCnt); - - s_vChangeAntenna(pDevice); - pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ); - pDevice->TimerSQ3Tmax2.expires = RUN_AT(pDevice->byTMax2 * HZ); - add_timer(&pDevice->TimerSQ3Tmax3); - add_timer(&pDevice->TimerSQ3Tmax2); + (int)priv->ulRatio_State0, + (int)priv->ulRatio_State1, + (int)priv->wAntDiversityMaxRate, + (int)priv->uNumSQ3[(int)priv->wAntDiversityMaxRate], + (int)priv->uDiversityCnt); + + s_vChangeAntenna(priv); + priv->TimerSQ3Tmax3.expires = RUN_AT(priv->byTMax3 * HZ); + priv->TimerSQ3Tmax2.expires = RUN_AT(priv->byTMax2 * HZ); + add_timer(&priv->TimerSQ3Tmax3); + add_timer(&priv->TimerSQ3Tmax2); } - pDevice->byAntennaState = 0; - BBvClearAntDivSQ3Value(pDevice); + priv->byAntennaState = 0; + BBvClearAntDivSQ3Value(priv); } } /* byAntennaState */ } @@ -2783,28 +2623,30 @@ void BBvAntennaDiversity(struct vnt_private *pDevice, void TimerSQ3CallBack( - void *hDeviceContext + unsigned long data ) { - struct vnt_private *pDevice = hDeviceContext; + struct vnt_private *priv = (struct vnt_private *)data; + unsigned long flags; pr_debug("TimerSQ3CallBack...\n"); - spin_lock_irq(&pDevice->lock); + + spin_lock_irqsave(&priv->lock, flags); pr_debug("3.[%08x][%08x], %d\n", - (int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1, - (int)pDevice->uDiversityCnt); + (int)priv->ulRatio_State0, (int)priv->ulRatio_State1, + (int)priv->uDiversityCnt); - s_vChangeAntenna(pDevice); - pDevice->byAntennaState = 0; - BBvClearAntDivSQ3Value(pDevice); + s_vChangeAntenna(priv); + priv->byAntennaState = 0; + BBvClearAntDivSQ3Value(priv); - pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ); - pDevice->TimerSQ3Tmax2.expires = RUN_AT(pDevice->byTMax2 * HZ); - add_timer(&pDevice->TimerSQ3Tmax3); - add_timer(&pDevice->TimerSQ3Tmax2); + priv->TimerSQ3Tmax3.expires = RUN_AT(priv->byTMax3 * HZ); + priv->TimerSQ3Tmax2.expires = RUN_AT(priv->byTMax2 * HZ); + add_timer(&priv->TimerSQ3Tmax3); + add_timer(&priv->TimerSQ3Tmax2); - spin_unlock_irq(&pDevice->lock); + spin_unlock_irqrestore(&priv->lock, flags); } /*+ @@ -2827,43 +2669,46 @@ TimerSQ3CallBack( void TimerState1CallBack( - void *hDeviceContext + unsigned long data ) { - struct vnt_private *pDevice = hDeviceContext; + struct vnt_private *priv = (struct vnt_private *)data; + unsigned long flags; pr_debug("TimerState1CallBack...\n"); - spin_lock_irq(&pDevice->lock); - if (pDevice->uDiversityCnt < pDevice->ulDiversityMValue/100) { - s_vChangeAntenna(pDevice); - pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ); - pDevice->TimerSQ3Tmax2.expires = RUN_AT(pDevice->byTMax2 * HZ); - add_timer(&pDevice->TimerSQ3Tmax3); - add_timer(&pDevice->TimerSQ3Tmax2); + spin_lock_irqsave(&priv->lock, flags); + + if (priv->uDiversityCnt < priv->ulDiversityMValue/100) { + s_vChangeAntenna(priv); + priv->TimerSQ3Tmax3.expires = RUN_AT(priv->byTMax3 * HZ); + priv->TimerSQ3Tmax2.expires = RUN_AT(priv->byTMax2 * HZ); + add_timer(&priv->TimerSQ3Tmax3); + add_timer(&priv->TimerSQ3Tmax2); } else { - pDevice->ulRatio_State1 = s_ulGetRatio(pDevice); + priv->ulRatio_State1 = s_ulGetRatio(priv); pr_debug("SQ3_State1, rate0 = %08x,rate1 = %08x\n", - (int)pDevice->ulRatio_State0, - (int)pDevice->ulRatio_State1); + (int)priv->ulRatio_State0, + (int)priv->ulRatio_State1); - if (pDevice->ulRatio_State1 < pDevice->ulRatio_State0) { + if (priv->ulRatio_State1 < priv->ulRatio_State0) { pr_debug("2.[%08x][%08x], uNumSQ3[%d]=%d, %d\n", - (int)pDevice->ulRatio_State0, - (int)pDevice->ulRatio_State1, - (int)pDevice->wAntDiversityMaxRate, - (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate], - (int)pDevice->uDiversityCnt); - - s_vChangeAntenna(pDevice); - - pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ); - pDevice->TimerSQ3Tmax2.expires = RUN_AT(pDevice->byTMax2 * HZ); - add_timer(&pDevice->TimerSQ3Tmax3); - add_timer(&pDevice->TimerSQ3Tmax2); + (int)priv->ulRatio_State0, + (int)priv->ulRatio_State1, + (int)priv->wAntDiversityMaxRate, + (int)priv->uNumSQ3[(int)priv->wAntDiversityMaxRate], + (int)priv->uDiversityCnt); + + s_vChangeAntenna(priv); + + priv->TimerSQ3Tmax3.expires = RUN_AT(priv->byTMax3 * HZ); + priv->TimerSQ3Tmax2.expires = RUN_AT(priv->byTMax2 * HZ); + add_timer(&priv->TimerSQ3Tmax3); + add_timer(&priv->TimerSQ3Tmax2); } } - pDevice->byAntennaState = 0; - BBvClearAntDivSQ3Value(pDevice); - spin_unlock_irq(&pDevice->lock); + priv->byAntennaState = 0; + BBvClearAntDivSQ3Value(priv); + + spin_unlock_irqrestore(&priv->lock, flags); } diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index 31f2255519cf..d9f6d63e4ab7 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -30,8 +30,6 @@ #ifndef __BASEBAND_H__ #define __BASEBAND_H__ -#include "ttype.h" -#include "tether.h" #include "device.h" /* @@ -79,42 +77,37 @@ BBuGetFrameTime( void vnt_get_phy_field(struct vnt_private *, u32 frame_length, u16 tx_rate, u8 pkt_type, struct vnt_phy_field *); -bool BBbReadEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char *pbyData); -bool BBbWriteEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char byData); +bool BBbReadEmbedded(struct vnt_private *, unsigned char byBBAddr, unsigned char *pbyData); +bool BBbWriteEmbedded(struct vnt_private *, unsigned char byBBAddr, unsigned char byData); -void BBvReadAllRegs(void __iomem *dwIoBase, unsigned char *pbyBBRegs); -void BBvLoopbackOn(struct vnt_private *pDevice); -void BBvLoopbackOff(struct vnt_private *pDevice); -void BBvSetShortSlotTime(struct vnt_private *pDevice); -bool BBbIsRegBitsOn(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char byTestBits); -bool BBbIsRegBitsOff(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char byTestBits); -void BBvSetVGAGainOffset(struct vnt_private *pDevice, unsigned char byData); +void BBvSetShortSlotTime(struct vnt_private *); +void BBvSetVGAGainOffset(struct vnt_private *, unsigned char byData); /* VT3253 Baseband */ -bool BBbVT3253Init(struct vnt_private *pDevice); -void BBvSoftwareReset(void __iomem *dwIoBase); -void BBvPowerSaveModeON(void __iomem *dwIoBase); -void BBvPowerSaveModeOFF(void __iomem *dwIoBase); -void BBvSetTxAntennaMode(void __iomem *dwIoBase, unsigned char byAntennaMode); -void BBvSetRxAntennaMode(void __iomem *dwIoBase, unsigned char byAntennaMode); -void BBvSetDeepSleep(void __iomem *dwIoBase, unsigned char byLocalID); -void BBvExitDeepSleep(void __iomem *dwIoBase, unsigned char byLocalID); +bool BBbVT3253Init(struct vnt_private *); +void BBvSoftwareReset(struct vnt_private *); +void BBvPowerSaveModeON(struct vnt_private *); +void BBvPowerSaveModeOFF(struct vnt_private *); +void BBvSetTxAntennaMode(struct vnt_private *, unsigned char byAntennaMode); +void BBvSetRxAntennaMode(struct vnt_private *, unsigned char byAntennaMode); +void BBvSetDeepSleep(struct vnt_private *, unsigned char byLocalID); +void BBvExitDeepSleep(struct vnt_private *, unsigned char byLocalID); /* timer for antenna diversity */ void TimerSQ3CallBack( - void *hDeviceContext + unsigned long ); void TimerState1CallBack( - void *hDeviceContext + unsigned long ); -void BBvAntennaDiversity(struct vnt_private *pDevice, +void BBvAntennaDiversity(struct vnt_private *, unsigned char byRxRate, unsigned char bySQ3); void -BBvClearAntDivSQ3Value(struct vnt_private *pDevice); +BBvClearAntDivSQ3Value(struct vnt_private *); #endif /* __BASEBAND_H__ */ diff --git a/drivers/staging/vt6655/bssdb.c b/drivers/staging/vt6655/bssdb.c deleted file mode 100644 index 996d3302ce3d..000000000000 --- a/drivers/staging/vt6655/bssdb.c +++ /dev/null @@ -1,1512 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: bssdb.c - * - * Purpose: Handles the Basic Service Set & Node Database functions - * - * Functions: - * BSSpSearchBSSList - Search known BSS list for Desire SSID or BSSID - * BSSvClearBSSList - Clear BSS List - * BSSbInsertToBSSList - Insert a BSS set into known BSS list - * BSSbUpdateToBSSList - Update BSS set in known BSS list - * BSSDBbIsSTAInNodeDB - Search Node DB table to find the index of matched DstAddr - * BSSvCreateOneNode - Allocate an Node for Node DB - * BSSvUpdateAPNode - Update AP Node content in Index 0 of KnownNodeDB - * BSSvSecondCallBack - One second timer callback function to update Node DB info & AP link status - * BSSvUpdateNodeTxCounter - Update Tx attemps, Tx failure counter in Node DB for auto-fall back rate control - * - * Revision History: - * - * Author: Lyndon Chen - * - * Date: July 17, 2002 - * - */ - -#include "ttype.h" -#include "tmacro.h" -#include "tether.h" -#include "device.h" -#include "80211hdr.h" -#include "bssdb.h" -#include "wmgr.h" -#include "datarate.h" -#include "desc.h" -#include "wcmd.h" -#include "wpa.h" -#include "baseband.h" -#include "rf.h" -#include "card.h" -#include "channel.h" -#include "mac.h" -#include "wpa2.h" -#include "iowpa.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ -static const unsigned short awHWRetry0[5][5] = { - {RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M}, - {RATE_24M, RATE_24M, RATE_18M, RATE_12M, RATE_12M}, - {RATE_36M, RATE_36M, RATE_24M, RATE_18M, RATE_18M}, - {RATE_48M, RATE_48M, RATE_36M, RATE_24M, RATE_24M}, - {RATE_54M, RATE_54M, RATE_48M, RATE_36M, RATE_36M} -}; -static const unsigned short awHWRetry1[5][5] = { - {RATE_18M, RATE_18M, RATE_12M, RATE_6M, RATE_6M}, - {RATE_24M, RATE_24M, RATE_18M, RATE_6M, RATE_6M}, - {RATE_36M, RATE_36M, RATE_24M, RATE_12M, RATE_12M}, - {RATE_48M, RATE_48M, RATE_24M, RATE_12M, RATE_12M}, - {RATE_54M, RATE_54M, RATE_36M, RATE_18M, RATE_18M} -}; - -/*--------------------- Static Functions --------------------------*/ - -void s_vCheckSensitivity( - void *hDeviceContext -); - -#ifdef Calcu_LinkQual -void s_uCalculateLinkQual( - void *hDeviceContext -); -#endif - -void s_vCheckPreEDThreshold( - void *hDeviceContext -); -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -/*+ - * - * Routine Description: - * Search known BSS list for Desire SSID or BSSID. - * - * Return Value: - * PTR to KnownBSS or NULL - * - -*/ - -PKnownBSS -BSSpSearchBSSList( - void *hDeviceContext, - unsigned char *pbyDesireBSSID, - unsigned char *pbyDesireSSID, - CARD_PHY_TYPE ePhyType -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned char *pbyBSSID = NULL; - PWLAN_IE_SSID pSSID = NULL; - PKnownBSS pCurrBSS = NULL; - PKnownBSS pSelect = NULL; - unsigned char ZeroBSSID[WLAN_BSSID_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - unsigned int ii = 0; - - if (pbyDesireBSSID != NULL) { - pr_debug("BSSpSearchBSSList BSSID[%pM]\n", pbyDesireBSSID); - if ((!is_broadcast_ether_addr(pbyDesireBSSID)) && - (memcmp(pbyDesireBSSID, ZeroBSSID, 6) != 0)) - pbyBSSID = pbyDesireBSSID; - } - if (pbyDesireSSID != NULL) { - if (((PWLAN_IE_SSID)pbyDesireSSID)->len != 0) - pSSID = (PWLAN_IE_SSID) pbyDesireSSID; - } - - if (pbyBSSID != NULL) { - /* match BSSID first */ - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - pCurrBSS = &(pMgmt->sBSSList[ii]); - if (!pDevice->bLinkPass) - pCurrBSS->bSelected = false; - if ((pCurrBSS->bActive) && - (!pCurrBSS->bSelected)) { - if (ether_addr_equal(pCurrBSS->abyBSSID, - pbyBSSID)) { - if (pSSID != NULL) { - /* compare ssid */ - if (!memcmp(pSSID->abySSID, - ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID, - pSSID->len)) { - if ((pMgmt->eConfigMode == WMAC_CONFIG_AUTO) || - ((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) || - ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) -) { - pCurrBSS->bSelected = true; - return pCurrBSS; - } - } - } else { - if ((pMgmt->eConfigMode == WMAC_CONFIG_AUTO) || - ((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) || - ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) -) { - pCurrBSS->bSelected = true; - return pCurrBSS; - } - } - } - } - } - } else { - /* ignore BSSID */ - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - pCurrBSS = &(pMgmt->sBSSList[ii]); - /* 2007-0721-01<Add>by MikeLiu */ - pCurrBSS->bSelected = false; - if (pCurrBSS->bActive) { - if (pSSID != NULL) { - /* matched SSID */ - if (!!memcmp(pSSID->abySSID, - ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID, - pSSID->len) || - (pSSID->len != ((PWLAN_IE_SSID)pCurrBSS->abySSID)->len)) { - /* SSID not match skip this BSS */ - continue; - } - } - if (((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) || - ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) -) { - /* Type not match skip this BSS */ - pr_debug("BSS type mismatch.... Config[%d] BSS[0x%04x]\n", - pMgmt->eConfigMode, - pCurrBSS->wCapInfo); - continue; - } - - if (ePhyType != PHY_TYPE_AUTO) { - if (((ePhyType == PHY_TYPE_11A) && (PHY_TYPE_11A != pCurrBSS->eNetworkTypeInUse)) || - ((ePhyType != PHY_TYPE_11A) && (PHY_TYPE_11A == pCurrBSS->eNetworkTypeInUse))) { - /* PhyType not match skip this BSS */ - pr_debug("Physical type mismatch.... ePhyType[%d] BSS[%d]\n", - ePhyType, - pCurrBSS->eNetworkTypeInUse); - continue; - } - } - - if (pSelect == NULL) { - pSelect = pCurrBSS; - } else { - /* compare RSSI, select signal strong one */ - if (pCurrBSS->uRSSI < pSelect->uRSSI) - pSelect = pCurrBSS; - } - } - } - if (pSelect != NULL) { - pSelect->bSelected = true; - return pSelect; - } - } - return NULL; -} - -/*+ - * - * Routine Description: - * Clear BSS List - * - * Return Value: - * None. - * - -*/ - -void -BSSvClearBSSList( - void *hDeviceContext, - bool bKeepCurrBSSID -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int ii; - - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - if (bKeepCurrBSSID) { - if (pMgmt->sBSSList[ii].bActive && - ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID, - pMgmt->abyCurrBSSID)) { - continue; - } - } - - if ((pMgmt->sBSSList[ii].bActive) && (pMgmt->sBSSList[ii].uClearCount < BSS_CLEAR_COUNT)) { - pMgmt->sBSSList[ii].uClearCount++; - continue; - } - - pMgmt->sBSSList[ii].bActive = false; - memset(&pMgmt->sBSSList[ii], 0, sizeof(KnownBSS)); - } - BSSvClearAnyBSSJoinRecord(pDevice); -} - -/*+ - * - * Routine Description: - * search BSS list by BSSID & SSID if matched - * - * Return Value: - * true if found. - * - -*/ -PKnownBSS -BSSpAddrIsInBSSList( - void *hDeviceContext, - unsigned char *abyBSSID, - PWLAN_IE_SSID pSSID -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - PKnownBSS pBSSList = NULL; - unsigned int ii; - - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - pBSSList = &(pMgmt->sBSSList[ii]); - if (pBSSList->bActive) { - if (ether_addr_equal(pBSSList->abyBSSID, abyBSSID)) { - if (pSSID->len == ((PWLAN_IE_SSID)pBSSList->abySSID)->len) { - if (memcmp(pSSID->abySSID, - ((PWLAN_IE_SSID)pBSSList->abySSID)->abySSID, - pSSID->len) == 0) - return pBSSList; - } - } - } - } - - return NULL; -}; - -/*+ - * - * Routine Description: - * Insert a BSS set into known BSS list - * - * Return Value: - * true if success. - * - -*/ - -bool -BSSbInsertToBSSList( - void *hDeviceContext, - unsigned char *abyBSSIDAddr, - __le64 qwTimestamp, - unsigned short wBeaconInterval, - unsigned short wCapInfo, - unsigned char byCurrChannel, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pSuppRates, - PWLAN_IE_SUPP_RATES pExtSuppRates, - PERPObject psERP, - PWLAN_IE_RSN pRSN, - PWLAN_IE_RSN_EXT pRSNWPA, - PWLAN_IE_COUNTRY pIE_Country, - PWLAN_IE_QUIET pIE_Quiet, - unsigned int uIELength, - unsigned char *pbyIEs, - void *pRxPacketContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - PSRxMgmtPacket pRxPacket = (PSRxMgmtPacket)pRxPacketContext; - PKnownBSS pBSSList = NULL; - unsigned int ii; - bool bParsingQuiet = false; - PWLAN_IE_QUIET pQuiet = NULL; - - pBSSList = (PKnownBSS)&(pMgmt->sBSSList[0]); - - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - pBSSList = (PKnownBSS)&(pMgmt->sBSSList[ii]); - if (!pBSSList->bActive) - break; - } - - if (ii == MAX_BSS_NUM) { - pr_debug("Get free KnowBSS node failed\n"); - return false; - } - /* save the BSS info */ - pBSSList->bActive = true; - memcpy(pBSSList->abyBSSID, abyBSSIDAddr, WLAN_BSSID_LEN); - pBSSList->qwBSSTimestamp = le64_to_cpu(qwTimestamp); - pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval); - pBSSList->wCapInfo = cpu_to_le16(wCapInfo); - pBSSList->uClearCount = 0; - - if (pSSID->len > WLAN_SSID_MAXLEN) - pSSID->len = WLAN_SSID_MAXLEN; - memcpy(pBSSList->abySSID, pSSID, pSSID->len + WLAN_IEHDR_LEN); - - pBSSList->uChannel = byCurrChannel; - - if (pSuppRates->len > WLAN_RATES_MAXLEN) - pSuppRates->len = WLAN_RATES_MAXLEN; - memcpy(pBSSList->abySuppRates, pSuppRates, pSuppRates->len + WLAN_IEHDR_LEN); - - if (pExtSuppRates != NULL) { - if (pExtSuppRates->len > WLAN_RATES_MAXLEN) - pExtSuppRates->len = WLAN_RATES_MAXLEN; - memcpy(pBSSList->abyExtSuppRates, pExtSuppRates, pExtSuppRates->len + WLAN_IEHDR_LEN); - pr_debug("BSSbInsertToBSSList: pExtSuppRates->len = %d\n", - pExtSuppRates->len); - - } else { - memset(pBSSList->abyExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); - } - pBSSList->sERP.byERP = psERP->byERP; - pBSSList->sERP.bERPExist = psERP->bERPExist; - - /* check if BSS is 802.11a/b/g */ - if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) { - pBSSList->eNetworkTypeInUse = PHY_TYPE_11A; - } else { - if (pBSSList->sERP.bERPExist) - pBSSList->eNetworkTypeInUse = PHY_TYPE_11G; - else - pBSSList->eNetworkTypeInUse = PHY_TYPE_11B; - } - - pBSSList->byRxRate = pRxPacket->byRxRate; - pBSSList->qwLocalTSF = pRxPacket->qwLocalTSF; - pBSSList->uRSSI = pRxPacket->uRSSI; - pBSSList->bySQ = pRxPacket->bySQ; - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - /* assoc with BSS */ - if (pBSSList == pMgmt->pCurrBSS) - bParsingQuiet = true; - } - - WPA_ClearRSN(pBSSList); - - if (pRSNWPA != NULL) { - unsigned int uLen = pRSNWPA->len + 2; - - if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSNWPA - pbyIEs))) { - pBSSList->wWPALen = uLen; - memcpy(pBSSList->byWPAIE, pRSNWPA, uLen); - WPA_ParseRSN(pBSSList, pRSNWPA); - } - } - - WPA2_ClearRSN(pBSSList); - - if (pRSN != NULL) { - unsigned int uLen = pRSN->len + 2; - - if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSN - pbyIEs))) { - pBSSList->wRSNLen = uLen; - memcpy(pBSSList->byRSNIE, pRSN, uLen); - WPA2vParseRSN(pBSSList, pRSN); - } - } - - if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || pBSSList->bWPA2Valid) { - PSKeyItem pTransmitKey = NULL; - bool bIs802_1x = false; - - for (ii = 0; ii < pBSSList->wAKMSSAuthCount; ii++) { - if (pBSSList->abyAKMSSAuthType[ii] == WLAN_11i_AKMSS_802_1X) { - bIs802_1x = true; - break; - } - } - if (bIs802_1x && (pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len) && - (!memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID, pSSID->len))) { - bAdd_PMKID_Candidate((void *)pDevice, pBSSList->abyBSSID, &pBSSList->sRSNCapObj); - - if (pDevice->bLinkPass && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - if (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, PAIRWISE_KEY, &pTransmitKey) || - KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, GROUP_KEY, &pTransmitKey)) { - pDevice->gsPMKIDCandidate.StatusType = Ndis802_11StatusType_PMKID_CandidateList; - pDevice->gsPMKIDCandidate.Version = 1; - - } - - } - } - } - - if (pDevice->bUpdateBBVGA) { - /* monitor if RSSI is too strong */ - pBSSList->byRSSIStatCnt = 0; - RFvRSSITodBm(pDevice, (unsigned char)(pRxPacket->uRSSI), &pBSSList->ldBmMAX); - pBSSList->ldBmAverage[0] = pBSSList->ldBmMAX; - for (ii = 1; ii < RSSI_STAT_COUNT; ii++) - pBSSList->ldBmAverage[ii] = 0; - } - - if ((pIE_Country != NULL) && pMgmt->b11hEnable) { - set_country_info(pMgmt->pAdapter, pBSSList->eNetworkTypeInUse, - pIE_Country); - } - - if (bParsingQuiet && (pIE_Quiet != NULL)) { - if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) && - (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) { - /* valid EID */ - if (pQuiet == NULL) { - pQuiet = (PWLAN_IE_QUIET)pIE_Quiet; - CARDbSetQuiet(pMgmt->pAdapter, - true, - pQuiet->byQuietCount, - pQuiet->byQuietPeriod, - *((unsigned short *)pQuiet->abyQuietDuration), - *((unsigned short *)pQuiet->abyQuietOffset) -); - } else { - pQuiet = (PWLAN_IE_QUIET)pIE_Quiet; - CARDbSetQuiet(pMgmt->pAdapter, - false, - pQuiet->byQuietCount, - pQuiet->byQuietPeriod, - *((unsigned short *)pQuiet->abyQuietDuration), - *((unsigned short *)pQuiet->abyQuietOffset) - ); - } - } - } - - if (bParsingQuiet && (pQuiet != NULL)) - CARDbStartQuiet(pMgmt->pAdapter); - - pBSSList->uIELength = uIELength; - if (pBSSList->uIELength > WLAN_BEACON_FR_MAXLEN) - pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN; - memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength); - - return true; -} - -/*+ - * - * Routine Description: - * Update BSS set in known BSS list - * - * Return Value: - * true if success. - * - -*/ -/* TODO: input structure modify */ - -bool -BSSbUpdateToBSSList( - void *hDeviceContext, - __le64 qwTimestamp, - unsigned short wBeaconInterval, - unsigned short wCapInfo, - unsigned char byCurrChannel, - bool bChannelHit, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pSuppRates, - PWLAN_IE_SUPP_RATES pExtSuppRates, - PERPObject psERP, - PWLAN_IE_RSN pRSN, - PWLAN_IE_RSN_EXT pRSNWPA, - PWLAN_IE_COUNTRY pIE_Country, - PWLAN_IE_QUIET pIE_Quiet, - PKnownBSS pBSSList, - unsigned int uIELength, - unsigned char *pbyIEs, - void *pRxPacketContext -) -{ - int ii; - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - PSRxMgmtPacket pRxPacket = (PSRxMgmtPacket)pRxPacketContext; - long ldBm; - bool bParsingQuiet = false; - PWLAN_IE_QUIET pQuiet = NULL; - - if (pBSSList == NULL) - return false; - - pBSSList->qwBSSTimestamp = le64_to_cpu(qwTimestamp); - pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval); - pBSSList->wCapInfo = cpu_to_le16(wCapInfo); - pBSSList->uClearCount = 0; - pBSSList->uChannel = byCurrChannel; - - if (pSSID->len > WLAN_SSID_MAXLEN) - pSSID->len = WLAN_SSID_MAXLEN; - - if ((pSSID->len != 0) && (pSSID->abySSID[0] != 0)) - memcpy(pBSSList->abySSID, pSSID, pSSID->len + WLAN_IEHDR_LEN); - memcpy(pBSSList->abySuppRates, pSuppRates, pSuppRates->len + WLAN_IEHDR_LEN); - - if (pExtSuppRates != NULL) - memcpy(pBSSList->abyExtSuppRates, pExtSuppRates, pExtSuppRates->len + WLAN_IEHDR_LEN); - else - memset(pBSSList->abyExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); - pBSSList->sERP.byERP = psERP->byERP; - pBSSList->sERP.bERPExist = psERP->bERPExist; - - /* check if BSS is 802.11a/b/g */ - if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) { - pBSSList->eNetworkTypeInUse = PHY_TYPE_11A; - } else { - if (pBSSList->sERP.bERPExist) - pBSSList->eNetworkTypeInUse = PHY_TYPE_11G; - else - pBSSList->eNetworkTypeInUse = PHY_TYPE_11B; - } - - pBSSList->byRxRate = pRxPacket->byRxRate; - pBSSList->qwLocalTSF = pRxPacket->qwLocalTSF; - if (bChannelHit) - pBSSList->uRSSI = pRxPacket->uRSSI; - pBSSList->bySQ = pRxPacket->bySQ; - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - /* assoc with BSS */ - if (pBSSList == pMgmt->pCurrBSS) - bParsingQuiet = true; - } - - WPA_ClearRSN(pBSSList); /* mike update */ - - if (pRSNWPA != NULL) { - unsigned int uLen = pRSNWPA->len + 2; - - if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSNWPA - pbyIEs))) { - pBSSList->wWPALen = uLen; - memcpy(pBSSList->byWPAIE, pRSNWPA, uLen); - WPA_ParseRSN(pBSSList, pRSNWPA); - } - } - - WPA2_ClearRSN(pBSSList); /* mike update */ - - if (pRSN != NULL) { - unsigned int uLen = pRSN->len + 2; - - if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSN - pbyIEs))) { - pBSSList->wRSNLen = uLen; - memcpy(pBSSList->byRSNIE, pRSN, uLen); - WPA2vParseRSN(pBSSList, pRSN); - } - } - - if (pRxPacket->uRSSI != 0) { - RFvRSSITodBm(pDevice, (unsigned char)(pRxPacket->uRSSI), &ldBm); - /* monitor if RSSI is too strong */ - pBSSList->byRSSIStatCnt++; - pBSSList->byRSSIStatCnt %= RSSI_STAT_COUNT; - pBSSList->ldBmAverage[pBSSList->byRSSIStatCnt] = ldBm; - for (ii = 0; ii < RSSI_STAT_COUNT; ii++) { - if (pBSSList->ldBmAverage[ii] != 0) - pBSSList->ldBmMAX = max(pBSSList->ldBmAverage[ii], ldBm); - } - } - - if ((pIE_Country != NULL) && pMgmt->b11hEnable) { - set_country_info(pMgmt->pAdapter, pBSSList->eNetworkTypeInUse, - pIE_Country); - } - - if (bParsingQuiet && (pIE_Quiet != NULL)) { - if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) && - (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) { - /* valid EID */ - if (pQuiet == NULL) { - pQuiet = (PWLAN_IE_QUIET)pIE_Quiet; - CARDbSetQuiet(pMgmt->pAdapter, - true, - pQuiet->byQuietCount, - pQuiet->byQuietPeriod, - *((unsigned short *)pQuiet->abyQuietDuration), - *((unsigned short *)pQuiet->abyQuietOffset) -); - } else { - pQuiet = (PWLAN_IE_QUIET)pIE_Quiet; - CARDbSetQuiet(pMgmt->pAdapter, - false, - pQuiet->byQuietCount, - pQuiet->byQuietPeriod, - *((unsigned short *)pQuiet->abyQuietDuration), - *((unsigned short *)pQuiet->abyQuietOffset) - ); - } - } - } - - if (bParsingQuiet && (pQuiet != NULL)) - CARDbStartQuiet(pMgmt->pAdapter); - - pBSSList->uIELength = uIELength; - if (pBSSList->uIELength > WLAN_BEACON_FR_MAXLEN) - pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN; - memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength); - - return true; -} - -/*+ - * - * Routine Description: - * Search Node DB table to find the index of matched DstAddr - * - * Return Value: - * None - * - -*/ - -bool -BSSDBbIsSTAInNodeDB(void *pMgmtObject, unsigned char *abyDstAddr, - unsigned int *puNodeIndex) -{ - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; - unsigned int ii; - - /* Index = 0 reserved for AP Node */ - for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) { - if (pMgmt->sNodeDBTable[ii].bActive) { - if (ether_addr_equal(abyDstAddr, - pMgmt->sNodeDBTable[ii].abyMACAddr)) { - *puNodeIndex = ii; - return true; - } - } - } - - return false; -}; - -/*+ - * - * Routine Description: - * Find an empty node and allocat it; if there is no empty node, - * then use the most inactive one. - * - * Return Value: - * None - * - -*/ -void -BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int ii; - unsigned int BigestCount = 0; - unsigned int SelectIndex; - struct sk_buff *skb; - /* - * Index = 0 reserved for AP Node (In STA mode) - * Index = 0 reserved for Broadcast/MultiCast (In AP mode) - */ - SelectIndex = 1; - for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) { - if (pMgmt->sNodeDBTable[ii].bActive) { - if (pMgmt->sNodeDBTable[ii].uInActiveCount > BigestCount) { - BigestCount = pMgmt->sNodeDBTable[ii].uInActiveCount; - SelectIndex = ii; - } - } else { - break; - } - } - - /* if not found replace uInActiveCount is largest one */ - if (ii == (MAX_NODE_NUM + 1)) { - *puNodeIndex = SelectIndex; - pr_info("Replace inactive node = %d\n", SelectIndex); - /* clear ps buffer */ - if (pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue.next != NULL) { - while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue)) != NULL) - dev_kfree_skb(skb); - } - } else { - *puNodeIndex = ii; - } - - memset(&pMgmt->sNodeDBTable[*puNodeIndex], 0, sizeof(KnownNodeDB)); - pMgmt->sNodeDBTable[*puNodeIndex].bActive = true; - pMgmt->sNodeDBTable[*puNodeIndex].uRatePollTimeout = FALLBACK_POLL_SECOND; - /* for AP mode PS queue */ - skb_queue_head_init(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue); - pMgmt->sNodeDBTable[*puNodeIndex].byAuthSequence = 0; - pMgmt->sNodeDBTable[*puNodeIndex].wEnQueueCnt = 0; - pr_debug("Create node index = %d\n", ii); - return; -}; - -/*+ - * - * Routine Description: - * Remove Node by NodeIndex - * - * - * Return Value: - * None - * - -*/ -void -BSSvRemoveOneNode( - void *hDeviceContext, - unsigned int uNodeIndex -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; - struct sk_buff *skb; - - while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue)) != NULL) - dev_kfree_skb(skb); - /* clear context */ - memset(&pMgmt->sNodeDBTable[uNodeIndex], 0, sizeof(KnownNodeDB)); - /* clear tx bit map */ - pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[uNodeIndex].wAID >> 3] &= ~byMask[pMgmt->sNodeDBTable[uNodeIndex].wAID & 7]; - - return; -}; -/*+ - * - * Routine Description: - * Update AP Node content in Index 0 of KnownNodeDB - * - * - * Return Value: - * None - * - -*/ - -void -BSSvUpdateAPNode( - void *hDeviceContext, - unsigned short *pwCapInfo, - PWLAN_IE_SUPP_RATES pSuppRates, - PWLAN_IE_SUPP_RATES pExtSuppRates -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int uRateLen = WLAN_RATES_MAXLEN; - - memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB)); - - pMgmt->sNodeDBTable[0].bActive = true; - if (pDevice->eCurrentPHYType == PHY_TYPE_11B) - uRateLen = WLAN_RATES_MAXLEN_11B; - pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - uRateLen); - pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pExtSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, - uRateLen); - RATEvParseMaxRate((void *)pDevice, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, - true, - &(pMgmt->sNodeDBTable[0].wMaxBasicRate), - &(pMgmt->sNodeDBTable[0].wMaxSuppRate), - &(pMgmt->sNodeDBTable[0].wSuppRate), - &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate), - &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate) -); - memcpy(pMgmt->sNodeDBTable[0].abyMACAddr, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); - pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxSuppRate; - pMgmt->sNodeDBTable[0].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*pwCapInfo); - pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND; - netdev_dbg(pDevice->dev, "BSSvUpdateAPNode:MaxSuppRate is %d\n", - pMgmt->sNodeDBTable[0].wMaxSuppRate); - /* auto rate fallback function initiation */ - pr_debug("pMgmt->sNodeDBTable[0].wTxDataRate = %d\n", - pMgmt->sNodeDBTable[0].wTxDataRate); -}; - -/*+ - * - * Routine Description: - * Add Multicast Node content in Index 0 of KnownNodeDB - * - * - * Return Value: - * None - * - -*/ - -void -BSSvAddMulticastNode( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - - if (!pDevice->bEnableHostWEP) - memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB)); - memset(pMgmt->sNodeDBTable[0].abyMACAddr, 0xff, WLAN_ADDR_LEN); - pMgmt->sNodeDBTable[0].bActive = true; - pMgmt->sNodeDBTable[0].bPSEnable = false; - skb_queue_head_init(&pMgmt->sNodeDBTable[0].sTxPSQueue); - RATEvParseMaxRate((void *)pDevice, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, - true, - &(pMgmt->sNodeDBTable[0].wMaxBasicRate), - &(pMgmt->sNodeDBTable[0].wMaxSuppRate), - &(pMgmt->sNodeDBTable[0].wSuppRate), - &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate), - &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate) -); - pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxBasicRate; - netdev_dbg(pDevice->dev, - "BSSvAddMultiCastNode:pMgmt->sNodeDBTable[0].wTxDataRate is %d\n", - pMgmt->sNodeDBTable[0].wTxDataRate); - pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND; -}; - -/*+ - * - * Routine Description: - * - * - * Second call back function to update Node DB info & AP link status - * - * - * Return Value: - * none. - * - -*/ -void -BSSvSecondCallBack( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int ii; - PWLAN_IE_SSID pItemSSID, pCurrSSID; - unsigned int uSleepySTACnt = 0; - unsigned int uNonShortSlotSTACnt = 0; - unsigned int uLongPreambleSTACnt = 0; - viawget_wpa_header *wpahdr; /* DavidWang */ - - spin_lock_irq(&pDevice->lock); - - pDevice->uAssocCount = 0; - - pDevice->byERPFlag &= - ~(WLAN_SET_ERP_BARKER_MODE(1) | WLAN_SET_ERP_NONERP_PRESENT(1)); - - if (pDevice->wUseProtectCntDown > 0) { - pDevice->wUseProtectCntDown--; - } else { - /* disable protect mode */ - pDevice->byERPFlag &= ~(WLAN_SET_ERP_USE_PROTECTION(1)); - } - - if (pDevice->eCommandState == WLAN_ASSOCIATE_WAIT) { - pDevice->byReAssocCount++; - /* 10 sec timeout */ - if ((pDevice->byReAssocCount > 10) && (!pDevice->bLinkPass)) { - netdev_info(pDevice->dev, "Re-association timeout!!!\n"); - pDevice->byReAssocCount = 0; -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - { - union iwreq_data wrqu; - - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n"); - wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); - } -#endif - } else if (pDevice->bLinkPass) - pDevice->byReAssocCount = 0; - } - -#ifdef Calcu_LinkQual - s_uCalculateLinkQual((void *)pDevice); -#endif - - for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) { - if (pMgmt->sNodeDBTable[ii].bActive) { - /* increase in-activity counter */ - pMgmt->sNodeDBTable[ii].uInActiveCount++; - - if (ii > 0) { - if (pMgmt->sNodeDBTable[ii].uInActiveCount > MAX_INACTIVE_COUNT) { - BSSvRemoveOneNode(pDevice, ii); - pr_debug("Inactive timeout [%d] sec, STA index = [%d] remove\n", - MAX_INACTIVE_COUNT, ii); - continue; - } - - if (pMgmt->sNodeDBTable[ii].eNodeState >= NODE_ASSOC) { - pDevice->uAssocCount++; - - /* check if Non ERP exist */ - if (pMgmt->sNodeDBTable[ii].uInActiveCount < ERP_RECOVER_COUNT) { - if (!pMgmt->sNodeDBTable[ii].bShortPreamble) { - pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1); - uLongPreambleSTACnt++; - } - if (!pMgmt->sNodeDBTable[ii].bERPExist) { - pDevice->byERPFlag |= WLAN_SET_ERP_NONERP_PRESENT(1); - pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1); - } - if (!pMgmt->sNodeDBTable[ii].bShortSlotTime) - uNonShortSlotSTACnt++; - } - } - - /* check if any STA in PS mode */ - if (pMgmt->sNodeDBTable[ii].bPSEnable) - uSleepySTACnt++; - - } - - /* rate fallback check */ - if (!pDevice->bFixRate) { - if (ii > 0) { - /* ii = 0 for multicast node (AP & Adhoc) */ - RATEvTxRateFallBack((void *)pDevice, &(pMgmt->sNodeDBTable[ii])); - } else { - /* ii = 0 reserved for unicast AP node (Infra STA) */ - if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) - netdev_dbg(pDevice->dev, - "SecondCallback:Before:TxDataRate is %d\n", - pMgmt->sNodeDBTable[0].wTxDataRate); - RATEvTxRateFallBack((void *)pDevice, &(pMgmt->sNodeDBTable[ii])); - netdev_dbg(pDevice->dev, - "SecondCallback:After:TxDataRate is %d\n", - pMgmt->sNodeDBTable[0].wTxDataRate); - - } - - } - - /* check if pending PS queue */ - if (pMgmt->sNodeDBTable[ii].wEnQueueCnt != 0) { - pr_debug("Index= %d, Queue = %d pending\n", - ii, - pMgmt->sNodeDBTable[ii].wEnQueueCnt); - if ((ii > 0) && (pMgmt->sNodeDBTable[ii].wEnQueueCnt > 15)) { - BSSvRemoveOneNode(pDevice, ii); - pr_info("Pending many queues PS STA Index = %d remove\n", - ii); - continue; - } - } - } - - } - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->eCurrentPHYType == PHY_TYPE_11G)) { - /* on/off protect mode */ - if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)) { - if (!pDevice->bProtectMode) { - MACvEnableProtectMD(pDevice->PortOffset); - pDevice->bProtectMode = true; - } - } else { - if (pDevice->bProtectMode) { - MACvDisableProtectMD(pDevice->PortOffset); - pDevice->bProtectMode = false; - } - } - /* on/off short slot time */ - - if (uNonShortSlotSTACnt > 0) { - if (pDevice->bShortSlotTime) { - pDevice->bShortSlotTime = false; - BBvSetShortSlotTime(pDevice); - vUpdateIFS((void *)pDevice); - } - } else { - if (!pDevice->bShortSlotTime) { - pDevice->bShortSlotTime = true; - BBvSetShortSlotTime(pDevice); - vUpdateIFS((void *)pDevice); - } - } - - /* on/off barker long preamble mode */ - - if (uLongPreambleSTACnt > 0) { - if (!pDevice->bBarkerPreambleMd) { - MACvEnableBarkerPreambleMd(pDevice->PortOffset); - pDevice->bBarkerPreambleMd = true; - } - } else { - if (pDevice->bBarkerPreambleMd) { - MACvDisableBarkerPreambleMd(pDevice->PortOffset); - pDevice->bBarkerPreambleMd = false; - } - } - - } - - /* check if any STA in PS mode, enable DTIM multicast deliver */ - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (uSleepySTACnt > 0) - pMgmt->sNodeDBTable[0].bPSEnable = true; - else - pMgmt->sNodeDBTable[0].bPSEnable = false; - } - - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; - pCurrSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - - if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) || - (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) { - /* assoc with BSS */ - if (pMgmt->sNodeDBTable[0].bActive) { - if (pDevice->bUpdateBBVGA) - s_vCheckPreEDThreshold((void *)pDevice); - - if ((pMgmt->sNodeDBTable[0].uInActiveCount >= (LOST_BEACON_COUNT/2)) && - (pDevice->byBBVGACurrent != pDevice->abyBBVGA[0])) { - pDevice->byBBVGANew = pDevice->abyBBVGA[0]; - bScheduleCommand((void *)pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL); - } - - if (pMgmt->sNodeDBTable[0].uInActiveCount >= LOST_BEACON_COUNT) { - pMgmt->sNodeDBTable[0].bActive = false; - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - pMgmt->eCurrState = WMAC_STATE_IDLE; - netif_stop_queue(pDevice->dev); - pDevice->bLinkPass = false; - pDevice->bRoaming = true; - pr_info("Lost AP beacon [%d] sec, disconnected !\n", - pMgmt->sNodeDBTable[0].uInActiveCount); - if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { - wpahdr = (viawget_wpa_header *)pDevice->skb->data; - wpahdr->type = VIAWGET_DISASSOC_MSG; - wpahdr->resp_ie_len = 0; - wpahdr->req_ie_len = 0; - skb_put(pDevice->skb, sizeof(viawget_wpa_header)); - pDevice->skb->dev = pDevice->wpadev; - skb_reset_mac_header(pDevice->skb); - pDevice->skb->pkt_type = PACKET_HOST; - pDevice->skb->protocol = htons(ETH_P_802_2); - memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); - netif_rx(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - } -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - { - union iwreq_data wrqu; - - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n"); - wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); - } -#endif - } - } else if (pItemSSID->len != 0) { - if (pDevice->uAutoReConnectTime < 10) { - pDevice->uAutoReConnectTime++; -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - /* - * network manager support need not do - * Roaming scan??? - */ - if (pDevice->bWPASuppWextEnabled) - pDevice->uAutoReConnectTime = 0; -#endif - } else { - /* - * mike use old encryption status - * for wpa reauthentication - */ - if (pDevice->bWPADEVUp) - pDevice->eEncryptionStatus = pDevice->eOldEncryptionStatus; - - pr_debug("Roaming ...\n"); - BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); - pMgmt->eScanType = WMAC_SCAN_ACTIVE; - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); - pDevice->uAutoReConnectTime = 0; - } - } - } - - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - /* if adhoc started which essid is NULL string, rescanning */ - if ((pMgmt->eCurrState == WMAC_STATE_STARTED) && (pCurrSSID->len == 0)) { - if (pDevice->uAutoReConnectTime < 10) { - pDevice->uAutoReConnectTime++; - } else { - pr_info("Adhoc re-scanning ...\n"); - pMgmt->eScanType = WMAC_SCAN_ACTIVE; - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); - bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); - pDevice->uAutoReConnectTime = 0; - } - } - if (pMgmt->eCurrState == WMAC_STATE_JOINTED) { - if (pDevice->bUpdateBBVGA) - s_vCheckPreEDThreshold((void *)pDevice); - if (pMgmt->sNodeDBTable[0].uInActiveCount >= ADHOC_LOST_BEACON_COUNT) { - pr_info("Lost other STA beacon [%d] sec, started !\n", - pMgmt->sNodeDBTable[0].uInActiveCount); - pMgmt->sNodeDBTable[0].uInActiveCount = 0; - pMgmt->eCurrState = WMAC_STATE_STARTED; - netif_stop_queue(pDevice->dev); - pDevice->bLinkPass = false; - } - } - } - - spin_unlock_irq(&pDevice->lock); - - pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ); - add_timer(&pMgmt->sTimerSecondCallback); -} - -/*+ - * - * Routine Description: - * - * - * Update Tx attemps, Tx failure counter in Node DB - * - * - * Return Value: - * none. - * - -*/ - -void -BSSvUpdateNodeTxCounter( - void *hDeviceContext, - unsigned char byTsr0, - unsigned char byTsr1, - unsigned char *pbyBuffer, - unsigned int uFIFOHeaderSize -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int uNodeIndex = 0; - unsigned char byTxRetry = (byTsr0 & TSR0_NCR); - PSTxBufHead pTxBufHead; - PS802_11Header pMACHeader; - unsigned short wRate; - unsigned short wFallBackRate = RATE_1M; - unsigned char byFallBack; - unsigned int ii; - - pTxBufHead = (PSTxBufHead) pbyBuffer; - if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_0) - byFallBack = AUTO_FB_0; - else if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_1) - byFallBack = AUTO_FB_1; - else - byFallBack = AUTO_FB_NONE; - wRate = pTxBufHead->wReserved; - - /* Only Unicast using support rates */ - if (pTxBufHead->wFIFOCtl & FIFOCTL_NEEDACK) { - pr_debug("wRate %04X, byTsr0 %02X, byTsr1 %02X\n", - wRate, byTsr0, byTsr1); - if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) { - pMgmt->sNodeDBTable[0].uTxAttempts += 1; - if ((byTsr1 & TSR1_TERR) == 0) { - /* transmit success, TxAttempts at least plus one */ - pMgmt->sNodeDBTable[0].uTxOk[MAX_RATE]++; - if ((byFallBack == AUTO_FB_NONE) || - (wRate < RATE_18M)) { - wFallBackRate = wRate; - } else if (byFallBack == AUTO_FB_0) { - if (byTxRetry < 5) - wFallBackRate = awHWRetry0[wRate-RATE_18M][byTxRetry]; - else - wFallBackRate = awHWRetry0[wRate-RATE_18M][4]; - } else if (byFallBack == AUTO_FB_1) { - if (byTxRetry < 5) - wFallBackRate = awHWRetry1[wRate-RATE_18M][byTxRetry]; - else - wFallBackRate = awHWRetry1[wRate-RATE_18M][4]; - } - pMgmt->sNodeDBTable[0].uTxOk[wFallBackRate]++; - } else { - pMgmt->sNodeDBTable[0].uTxFailures++; - } - pMgmt->sNodeDBTable[0].uTxRetry += byTxRetry; - if (byTxRetry != 0) { - pMgmt->sNodeDBTable[0].uTxFail[MAX_RATE] += byTxRetry; - if ((byFallBack == AUTO_FB_NONE) || - (wRate < RATE_18M)) { - pMgmt->sNodeDBTable[0].uTxFail[wRate] += byTxRetry; - } else if (byFallBack == AUTO_FB_0) { - for (ii = 0; ii < byTxRetry; ii++) { - if (ii < 5) - wFallBackRate = awHWRetry0[wRate-RATE_18M][ii]; - else - wFallBackRate = awHWRetry0[wRate-RATE_18M][4]; - pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++; - } - } else if (byFallBack == AUTO_FB_1) { - for (ii = 0; ii < byTxRetry; ii++) { - if (ii < 5) - wFallBackRate = awHWRetry1[wRate-RATE_18M][ii]; - else - wFallBackRate = awHWRetry1[wRate-RATE_18M][4]; - pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++; - } - } - } - } - - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) || - (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { - pMACHeader = (PS802_11Header)(pbyBuffer + uFIFOHeaderSize); - - if (BSSDBbIsSTAInNodeDB((void *)pMgmt, &(pMACHeader->abyAddr1[0]), &uNodeIndex)) { - pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts += 1; - if ((byTsr1 & TSR1_TERR) == 0) { - /* transmit success, TxAttempts at least plus one */ - pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++; - if ((byFallBack == AUTO_FB_NONE) || - (wRate < RATE_18M)) { - wFallBackRate = wRate; - } else if (byFallBack == AUTO_FB_0) { - if (byTxRetry < 5) - wFallBackRate = awHWRetry0[wRate-RATE_18M][byTxRetry]; - else - wFallBackRate = awHWRetry0[wRate-RATE_18M][4]; - } else if (byFallBack == AUTO_FB_1) { - if (byTxRetry < 5) - wFallBackRate = awHWRetry1[wRate-RATE_18M][byTxRetry]; - else - wFallBackRate = awHWRetry1[wRate-RATE_18M][4]; - } - pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wFallBackRate]++; - } else { - pMgmt->sNodeDBTable[uNodeIndex].uTxFailures++; - } - pMgmt->sNodeDBTable[uNodeIndex].uTxRetry += byTxRetry; - if (byTxRetry != 0) { - pMgmt->sNodeDBTable[uNodeIndex].uTxFail[MAX_RATE] += byTxRetry; - if ((byFallBack == AUTO_FB_NONE) || - (wRate < RATE_18M)) { - pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wRate] += byTxRetry; - } else if (byFallBack == AUTO_FB_0) { - for (ii = 0; ii < byTxRetry; ii++) { - if (ii < 5) - wFallBackRate = awHWRetry0[wRate - RATE_18M][ii]; - else - wFallBackRate = awHWRetry0[wRate - RATE_18M][4]; - pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++; - } - } else if (byFallBack == AUTO_FB_1) { - for (ii = 0; ii < byTxRetry; ii++) { - if (ii < 5) - wFallBackRate = awHWRetry1[wRate-RATE_18M][ii]; - else - wFallBackRate = awHWRetry1[wRate-RATE_18M][4]; - pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++; - } - } - } - } - } - } -} - -/*+ - * - * Routine Description: - * Clear Nodes & skb in DB Table - * - * - * Parameters: - * In: - * hDeviceContext - The adapter context. - * uStartIndex - starting index - * Out: - * none - * - * Return Value: - * None. - * - -*/ - -void -BSSvClearNodeDBTable( - void *hDeviceContext, - unsigned int uStartIndex -) - -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - struct sk_buff *skb; - unsigned int ii; - - for (ii = uStartIndex; ii < (MAX_NODE_NUM + 1); ii++) { - if (pMgmt->sNodeDBTable[ii].bActive) { - /* check if sTxPSQueue has been initial */ - if (pMgmt->sNodeDBTable[ii].sTxPSQueue.next != NULL) { - while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) { - pr_debug("PS skb != NULL %d\n", ii); - dev_kfree_skb(skb); - } - } - memset(&pMgmt->sNodeDBTable[ii], 0, sizeof(KnownNodeDB)); - } - } - - return; -}; - -void s_vCheckSensitivity( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PKnownBSS pBSSList = NULL; - PSMgmtObject pMgmt = pDevice->pMgmt; - int ii; - - if ((pDevice->byLocalID <= REV_ID_VT3253_A1) && (pDevice->byRFType == RF_RFMD2959) && - (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { - return; - } - - if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) || - ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) { - pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID); - if (pBSSList != NULL) { - /* Update BB Reg if RSSI is too strong */ - long LocalldBmAverage = 0; - long uNumofdBm = 0; - - for (ii = 0; ii < RSSI_STAT_COUNT; ii++) { - if (pBSSList->ldBmAverage[ii] != 0) { - uNumofdBm++; - LocalldBmAverage += pBSSList->ldBmAverage[ii]; - } - } - if (uNumofdBm > 0) { - LocalldBmAverage = LocalldBmAverage/uNumofdBm; - for (ii = 0; ii < BB_VGA_LEVEL; ii++) { - pr_debug("LocalldBmAverage:%ld, %ld %02x\n", - LocalldBmAverage, - pDevice->ldBmThreshold[ii], - pDevice->abyBBVGA[ii]); - if (LocalldBmAverage < pDevice->ldBmThreshold[ii]) { - pDevice->byBBVGANew = pDevice->abyBBVGA[ii]; - break; - } - } - if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) { - pDevice->uBBVGADiffCount++; - if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) - bScheduleCommand((void *)pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL); - } else { - pDevice->uBBVGADiffCount = 0; - } - } - } - } -} - -void -BSSvClearAnyBSSJoinRecord( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int ii; - - for (ii = 0; ii < MAX_BSS_NUM; ii++) - pMgmt->sBSSList[ii].bSelected = false; -} - -#ifdef Calcu_LinkQual -void s_uCalculateLinkQual( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - unsigned long TxOkRatio, TxCnt; - unsigned long RxOkRatio, RxCnt; - unsigned long RssiRatio; - long ldBm; - - TxCnt = pDevice->scStatistic.TxNoRetryOkCount + - pDevice->scStatistic.TxRetryOkCount + - pDevice->scStatistic.TxFailCount; - RxCnt = pDevice->scStatistic.RxFcsErrCnt + - pDevice->scStatistic.RxOkCnt; - TxOkRatio = (TxCnt < 6) ? 4000 : ((pDevice->scStatistic.TxNoRetryOkCount * 4000) / TxCnt); - RxOkRatio = (RxCnt < 6) ? 2000 : ((pDevice->scStatistic.RxOkCnt * 2000) / RxCnt); - /* decide link quality */ - if (!pDevice->bLinkPass) { - pDevice->scStatistic.LinkQuality = 0; - pDevice->scStatistic.SignalStren = 0; - } else { - RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm); - if (-ldBm < 50) - RssiRatio = 4000; - else if (-ldBm > 90) - RssiRatio = 0; - else - RssiRatio = (40-(-ldBm-50))*4000/40; - pDevice->scStatistic.SignalStren = RssiRatio/40; - pDevice->scStatistic.LinkQuality = (RssiRatio+TxOkRatio+RxOkRatio)/100; - } - pDevice->scStatistic.RxFcsErrCnt = 0; - pDevice->scStatistic.RxOkCnt = 0; - pDevice->scStatistic.TxFailCount = 0; - pDevice->scStatistic.TxNoRetryOkCount = 0; - pDevice->scStatistic.TxRetryOkCount = 0; -} -#endif - -void s_vCheckPreEDThreshold( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PKnownBSS pBSSList = NULL; - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - - if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) || - ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) { - pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID); - if (pBSSList != NULL) - pDevice->byBBPreEDRSSI = (unsigned char) (~(pBSSList->ldBmAverRange) + 1); - } -} diff --git a/drivers/staging/vt6655/bssdb.h b/drivers/staging/vt6655/bssdb.h deleted file mode 100644 index 5d4dd28b6223..000000000000 --- a/drivers/staging/vt6655/bssdb.h +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: bssdb.h - * - * Purpose: Handles the Basic Service Set & Node Database functions - * - * Author: Lyndon Chen - * - * Date: July 16, 2002 - * - */ - -#ifndef __BSSDB_H__ -#define __BSSDB_H__ - -#include <linux/skbuff.h> -#include "80211hdr.h" -#include "80211mgr.h" -#include "card.h" - -#define MAX_NODE_NUM 64 -#define MAX_BSS_NUM 42 -#define LOST_BEACON_COUNT 10 // 10 sec, XP defined -#define MAX_PS_TX_BUF 32 // sta max power saving tx buf -#define ADHOC_LOST_BEACON_COUNT 30 // 30 sec, beacon lost for adhoc only -#define MAX_INACTIVE_COUNT 300 // 300 sec, inactive STA node refresh - -#define USE_PROTECT_PERIOD 10 // 10 sec, Use protect mode check period -#define ERP_RECOVER_COUNT 30 // 30 sec, ERP support callback check -#define BSS_CLEAR_COUNT 1 - -#define RSSI_STAT_COUNT 10 -#define MAX_CHECK_RSSI_COUNT 8 - -// STA dwflags -#define WLAN_STA_AUTH BIT0 -#define WLAN_STA_ASSOC BIT1 -#define WLAN_STA_PS BIT2 -#define WLAN_STA_TIM BIT3 -// permanent; do not remove entry on expiration -#define WLAN_STA_PERM BIT4 -// If 802.1X is used, this flag is -// controlling whether STA is authorized to -// send and receive non-IEEE 802.1X frames -#define WLAN_STA_AUTHORIZED BIT5 - -#define MAX_RATE 12 - -#define MAX_WPA_IE_LEN 64 - -// -// IEEE 802.11 Structures and definitions -// - -typedef enum _NDIS_802_11_NETWORK_TYPE { - Ndis802_11FH, - Ndis802_11DS, - Ndis802_11OFDM5, - Ndis802_11OFDM24, - Ndis802_11NetworkTypeMax // not a real type, defined as an upper bound -} NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE; - -typedef struct tagSERPObject { - bool bERPExist; - unsigned char byERP; -} ERPObject, *PERPObject; - -typedef struct tagSRSNCapObject { - bool bRSNCapExist; - unsigned short wRSNCap; -} SRSNCapObject, *PSRSNCapObject; - -// BSS info(AP) -#pragma pack(1) -typedef struct tagKnownBSS { - bool bActive; - unsigned char abyBSSID[WLAN_BSSID_LEN]; - unsigned int uChannel; - unsigned char abySuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - unsigned char abyExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - unsigned int uRSSI; - unsigned char bySQ; - unsigned short wBeaconInterval; - unsigned short wCapInfo; - unsigned char abySSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - unsigned char byRxRate; - - unsigned char byRSSIStatCnt; - long ldBmMAX; - long ldBmAverage[RSSI_STAT_COUNT]; - long ldBmAverRange; - bool bSelected; - - bool bWPAValid; - unsigned char byGKType; - unsigned char abyPKType[4]; - unsigned short wPKCount; - unsigned char abyAuthType[4]; - unsigned short wAuthCount; - unsigned char byDefaultK_as_PK; - unsigned char byReplayIdx; - - bool bWPA2Valid; - unsigned char byCSSGK; - unsigned short wCSSPKCount; - unsigned char abyCSSPK[4]; - unsigned short wAKMSSAuthCount; - unsigned char abyAKMSSAuthType[4]; - - unsigned char byWPAIE[MAX_WPA_IE_LEN]; - unsigned char byRSNIE[MAX_WPA_IE_LEN]; - unsigned short wWPALen; - unsigned short wRSNLen; - - unsigned int uClearCount; - unsigned int uIELength; - u64 qwBSSTimestamp; - u64 qwLocalTSF; - - CARD_PHY_TYPE eNetworkTypeInUse; - - ERPObject sERP; - SRSNCapObject sRSNCapObj; - unsigned char abyIEs[1024]; -} __attribute__ ((__packed__)) -KnownBSS , *PKnownBSS; - -#pragma pack() - -typedef enum tagNODE_STATE { - NODE_FREE, - NODE_AGED, - NODE_KNOWN, - NODE_AUTH, - NODE_ASSOC -} NODE_STATE, *PNODE_STATE; - -// STA node info -typedef struct tagKnownNodeDB { - bool bActive; - unsigned char abyMACAddr[WLAN_ADDR_LEN]; - unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN]; - unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN]; - unsigned short wTxDataRate; - bool bShortPreamble; - bool bERPExist; - bool bShortSlotTime; - unsigned int uInActiveCount; - unsigned short wMaxBasicRate; //Get from byTopOFDMBasicRate or byTopCCKBasicRate which depends on packetTyp. - unsigned short wMaxSuppRate; //Records the highest supported rate getting from SuppRates IE and ExtSuppRates IE in Beacon. - unsigned short wSuppRate; - unsigned char byTopOFDMBasicRate;//Records the highest basic rate in OFDM mode - unsigned char byTopCCKBasicRate; //Records the highest basic rate in CCK mode - - // For AP mode - struct sk_buff_head sTxPSQueue; - unsigned short wCapInfo; - unsigned short wListenInterval; - unsigned short wAID; - NODE_STATE eNodeState; - bool bPSEnable; - bool bRxPSPoll; - unsigned char byAuthSequence; - unsigned long ulLastRxJiffer; - unsigned char bySuppRate; - unsigned long dwFlags; - unsigned short wEnQueueCnt; - - bool bOnFly; - unsigned long long KeyRSC; - unsigned char byKeyIndex; - unsigned long dwKeyIndex; - unsigned char byCipherSuite; - unsigned long dwTSC47_16; - unsigned short wTSC15_0; - unsigned int uWepKeyLength; - unsigned char abyWepKey[WLAN_WEPMAX_KEYLEN]; - // Auto rate fallback vars - bool bIsInFallback; - unsigned int uAverageRSSI; - unsigned int uRateRecoveryTimeout; - unsigned int uRatePollTimeout; - unsigned int uTxFailures; - unsigned int uTxAttempts; - - unsigned int uTxRetry; - unsigned int uFailureRatio; - unsigned int uRetryRatio; - unsigned int uTxOk[MAX_RATE+1]; - unsigned int uTxFail[MAX_RATE+1]; - unsigned int uTimeCount; -} KnownNodeDB, *PKnownNodeDB; - -PKnownBSS -BSSpSearchBSSList( - void *hDeviceContext, - unsigned char *pbyDesireBSSID, - unsigned char *pbyDesireSSID, - CARD_PHY_TYPE ePhyType -); - -PKnownBSS -BSSpAddrIsInBSSList( - void *hDeviceContext, - unsigned char *abyBSSID, - PWLAN_IE_SSID pSSID -); - -void -BSSvClearBSSList( - void *hDeviceContext, - bool bKeepCurrBSSID -); - -bool -BSSbInsertToBSSList( - void *hDeviceContext, - unsigned char *abyBSSIDAddr, - __le64 qwTimestamp, - unsigned short wBeaconInterval, - unsigned short wCapInfo, - unsigned char byCurrChannel, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pSuppRates, - PWLAN_IE_SUPP_RATES pExtSuppRates, - PERPObject psERP, - PWLAN_IE_RSN pRSN, - PWLAN_IE_RSN_EXT pRSNWPA, - PWLAN_IE_COUNTRY pIE_Country, - PWLAN_IE_QUIET pIE_Quiet, - unsigned int uIELength, - unsigned char *pbyIEs, - void *pRxPacketContext -); - -bool -BSSbUpdateToBSSList( - void *hDeviceContext, - __le64 qwTimestamp, - unsigned short wBeaconInterval, - unsigned short wCapInfo, - unsigned char byCurrChannel, - bool bChannelHit, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pSuppRates, - PWLAN_IE_SUPP_RATES pExtSuppRates, - PERPObject psERP, - PWLAN_IE_RSN pRSN, - PWLAN_IE_RSN_EXT pRSNWPA, - PWLAN_IE_COUNTRY pIE_Country, - PWLAN_IE_QUIET pIE_Quiet, - PKnownBSS pBSSList, - unsigned int uIELength, - unsigned char *pbyIEs, - void *pRxPacketContext -); - -bool -BSSDBbIsSTAInNodeDB(void *hDeviceContext, unsigned char *abyDstAddr, - unsigned int *puNodeIndex); - -void -BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex); - -void -BSSvUpdateAPNode( - void *hDeviceContext, - unsigned short *pwCapInfo, - PWLAN_IE_SUPP_RATES pItemRates, - PWLAN_IE_SUPP_RATES pExtSuppRates -); - -void -BSSvSecondCallBack( - void *hDeviceContext -); - -void -BSSvUpdateNodeTxCounter( - void *hDeviceContext, - unsigned char byTsr0, - unsigned char byTsr1, - unsigned char *pbyBuffer, - unsigned int uFIFOHeaderSize -); - -void -BSSvRemoveOneNode( - void *hDeviceContext, - unsigned int uNodeIndex -); - -void -BSSvAddMulticastNode( - void *hDeviceContext -); - -void -BSSvClearNodeDBTable( - void *hDeviceContext, - unsigned int uStartIndex -); - -void -BSSvClearAnyBSSJoinRecord( - void *hDeviceContext -); - -#endif //__BSSDB_H__ diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 5a6950264bdc..a0796405c308 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -21,7 +21,6 @@ * Functions: * s_vSafeResetTx - Rest Tx * CARDvSetRSPINF - Set RSPINF - * vUpdateIFS - Update slotTime,SIFS,DIFS, and EIFS * CARDvUpdateBasicTopRate - Update BasicTopRate * CARDbAddBasicRate - Add to BasicRateSet * CARDbIsOFDMinBasicRate - Check if any OFDM rate is in BasicRateSet @@ -34,8 +33,6 @@ * CARDvUpdateNextTBTT - Sync. NIC Beacon time * CARDbRadioPowerOff - Turn Off NIC Radio Power * CARDbRadioPowerOn - Turn On NIC Radio Power - * CARDbSetWEPMode - Set NIC Wep mode - * CARDbSetTxPower - Set NIC tx power * * Revision History: * 06-10-2003 Bryan YC Fan: Re-write codes to support VT3253 spec. @@ -50,38 +47,24 @@ #include "mac.h" #include "desc.h" #include "rf.h" -#include "vntwifi.h" #include "power.h" -#include "key.h" -#include "rc4.h" -#include "country.h" -#include "channel.h" /*--------------------- Static Definitions -------------------------*/ -#define C_SIFS_A 16 // micro sec. +#define C_SIFS_A 16 /* micro sec. */ #define C_SIFS_BG 10 -#define C_EIFS 80 // micro sec. +#define C_EIFS 80 /* micro sec. */ -#define C_SLOT_SHORT 9 // micro sec. +#define C_SLOT_SHORT 9 /* micro sec. */ #define C_SLOT_LONG 20 -#define C_CWMIN_A 15 // slot time +#define C_CWMIN_A 15 /* slot time */ #define C_CWMIN_B 31 -#define C_CWMAX 1023 // slot time +#define C_CWMAX 1023 /* slot time */ -#define WAIT_BEACON_TX_DOWN_TMO 3 // Times - -//1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M -static unsigned char abyDefaultSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C}; -//6M, 9M, 12M, 48M -static unsigned char abyDefaultExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60}; -//6M, 9M, 12M, 18M, 24M, 36M, 48M, 54M -static unsigned char abyDefaultSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; -//1M, 2M, 5M, 11M, -static unsigned char abyDefaultSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16}; +#define WAIT_BEACON_TX_DOWN_TMO 3 /* Times */ /*--------------------- Static Variables --------------------------*/ @@ -94,7 +77,7 @@ static void s_vCalculateOFDMRParameter( unsigned char byRate, - CARD_PHY_TYPE ePHYType, + u8 bb_type, unsigned char *pbyTxRate, unsigned char *pbyRsvTime ); @@ -113,20 +96,19 @@ s_vCalculateOFDMRParameter( * pbyRsvTime - pointer to RSPINF RsvTime field * * Return Value: none - * */ static void s_vCalculateOFDMRParameter( unsigned char byRate, - CARD_PHY_TYPE ePHYType, + u8 bb_type, unsigned char *pbyTxRate, unsigned char *pbyRsvTime ) { switch (byRate) { case RATE_6M: - if (ePHYType == PHY_TYPE_11A) {//5GHZ + if (bb_type == BB_TYPE_11A) { /* 5GHZ */ *pbyTxRate = 0x9B; *pbyRsvTime = 44; } else { @@ -136,7 +118,7 @@ s_vCalculateOFDMRParameter( break; case RATE_9M: - if (ePHYType == PHY_TYPE_11A) {//5GHZ + if (bb_type == BB_TYPE_11A) { /* 5GHZ */ *pbyTxRate = 0x9F; *pbyRsvTime = 36; } else { @@ -146,7 +128,7 @@ s_vCalculateOFDMRParameter( break; case RATE_12M: - if (ePHYType == PHY_TYPE_11A) {//5GHZ + if (bb_type == BB_TYPE_11A) { /* 5GHZ */ *pbyTxRate = 0x9A; *pbyRsvTime = 32; } else { @@ -156,7 +138,7 @@ s_vCalculateOFDMRParameter( break; case RATE_18M: - if (ePHYType == PHY_TYPE_11A) {//5GHZ + if (bb_type == BB_TYPE_11A) { /* 5GHZ */ *pbyTxRate = 0x9E; *pbyRsvTime = 28; } else { @@ -166,7 +148,7 @@ s_vCalculateOFDMRParameter( break; case RATE_36M: - if (ePHYType == PHY_TYPE_11A) {//5GHZ + if (bb_type == BB_TYPE_11A) { /* 5GHZ */ *pbyTxRate = 0x9D; *pbyRsvTime = 24; } else { @@ -176,7 +158,7 @@ s_vCalculateOFDMRParameter( break; case RATE_48M: - if (ePHYType == PHY_TYPE_11A) {//5GHZ + if (bb_type == BB_TYPE_11A) { /* 5GHZ */ *pbyTxRate = 0x98; *pbyRsvTime = 24; } else { @@ -186,7 +168,7 @@ s_vCalculateOFDMRParameter( break; case RATE_54M: - if (ePHYType == PHY_TYPE_11A) {//5GHZ + if (bb_type == BB_TYPE_11A) { /* 5GHZ */ *pbyTxRate = 0x9C; *pbyRsvTime = 24; } else { @@ -197,7 +179,7 @@ s_vCalculateOFDMRParameter( case RATE_24M: default: - if (ePHYType == PHY_TYPE_11A) {//5GHZ + if (bb_type == BB_TYPE_11A) { /* 5GHZ */ *pbyTxRate = 0x99; *pbyRsvTime = 28; } else { @@ -208,167 +190,9 @@ s_vCalculateOFDMRParameter( } } -/* - * Description: Set RSPINF - * - * Parameters: - * In: - * pDevice - The adapter to be set - * Out: - * none - * - * Return Value: None. - * - */ -static -void -s_vSetRSPINF(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, - void *pvSupportRateIEs, void *pvExtSupportRateIEs) -{ - union vnt_phy_field_swap phy; - unsigned char byTxRate = 0, byRsvTime = 0; // For OFDM - - //Set to Page1 - MACvSelectPage1(pDevice->PortOffset); - - /* RSPINF_b_1 */ - vnt_get_phy_field(pDevice, - 14, - VNTWIFIbyGetACKTxRate(RATE_1M, pvSupportRateIEs, pvExtSupportRateIEs), - PK_TYPE_11B, - &phy.field_read); - - /* swap over to get correct write order */ - swap(phy.swap[0], phy.swap[1]); - - VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_1, phy.field_write); - - /* RSPINF_b_2 */ - vnt_get_phy_field(pDevice, 14, - VNTWIFIbyGetACKTxRate(RATE_2M, pvSupportRateIEs, pvExtSupportRateIEs), - PK_TYPE_11B, &phy.field_read); - - swap(phy.swap[0], phy.swap[1]); - - VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_2, phy.field_write); - - /* RSPINF_b_5 */ - vnt_get_phy_field(pDevice, 14, - VNTWIFIbyGetACKTxRate(RATE_5M, pvSupportRateIEs, pvExtSupportRateIEs), - PK_TYPE_11B, &phy.field_read); - - swap(phy.swap[0], phy.swap[1]); - - VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_5, phy.field_write); - - /* RSPINF_b_11 */ - vnt_get_phy_field(pDevice, 14, - VNTWIFIbyGetACKTxRate(RATE_11M, pvSupportRateIEs, pvExtSupportRateIEs), - PK_TYPE_11B, &phy.field_read); - - swap(phy.swap[0], phy.swap[1]); - - VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_11, phy.field_write); - - //RSPINF_a_6 - s_vCalculateOFDMRParameter(RATE_6M, - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_6, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_9 - s_vCalculateOFDMRParameter(RATE_9M, - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_9, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_12 - s_vCalculateOFDMRParameter(RATE_12M, - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_12, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_18 - s_vCalculateOFDMRParameter(RATE_18M, - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_18, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_24 - s_vCalculateOFDMRParameter(RATE_24M, - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_24, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_36 - s_vCalculateOFDMRParameter( - VNTWIFIbyGetACKTxRate(RATE_36M, pvSupportRateIEs, pvExtSupportRateIEs), - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_36, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_48 - s_vCalculateOFDMRParameter( - VNTWIFIbyGetACKTxRate(RATE_48M, pvSupportRateIEs, pvExtSupportRateIEs), - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_48, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_54 - s_vCalculateOFDMRParameter( - VNTWIFIbyGetACKTxRate(RATE_54M, pvSupportRateIEs, pvExtSupportRateIEs), - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_54, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_72 - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_72, MAKEWORD(byTxRate, byRsvTime)); - //Set to Page0 - MACvSelectPage0(pDevice->PortOffset); -} - /*--------------------- Export Functions --------------------------*/ /* - * Description: Get Card short preamble option value - * - * Parameters: - * In: - * pDevice - The adapter to be set - * Out: - * none - * - * Return Value: true if short preamble; otherwise false - * - */ -bool CARDbIsShortPreamble(struct vnt_private *pDevice) -{ - - if (pDevice->byPreambleType == 0) - return false; - - return true; -} - -/* - * Description: Get Card short slot time option value - * - * Parameters: - * In: - * pDevice - The adapter to be set - * Out: - * none - * - * Return Value: true if short slot time; otherwise false - * - */ -bool CARDbIsShorSlotTime(struct vnt_private *pDevice) -{ - - return pDevice->bShortSlotTime; -} - -/* * Description: Update IFS * * Parameters: @@ -378,138 +202,118 @@ bool CARDbIsShorSlotTime(struct vnt_private *pDevice) * none * * Return Value: None. - * */ -bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, - unsigned short wCapInfo, unsigned char byERPField, - void *pvSupportRateIEs, void *pvExtSupportRateIEs) +bool CARDbSetPhyParameter(struct vnt_private *pDevice, u8 bb_type) { unsigned char byCWMaxMin = 0; unsigned char bySlot = 0; unsigned char bySIFS = 0; unsigned char byDIFS = 0; unsigned char byData; - PWLAN_IE_SUPP_RATES pSupportRates = (PWLAN_IE_SUPP_RATES) pvSupportRateIEs; - PWLAN_IE_SUPP_RATES pExtSupportRates = (PWLAN_IE_SUPP_RATES) pvExtSupportRateIEs; - - //Set SIFS, DIFS, EIFS, SlotTime, CwMin - if (ePHYType == PHY_TYPE_11A) { - if (pSupportRates == NULL) - pSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultSuppRatesA; + int i; + /* Set SIFS, DIFS, EIFS, SlotTime, CwMin */ + if (bb_type == BB_TYPE_11A) { if (pDevice->byRFType == RF_AIROHA7230) { - // AL7230 use single PAPE and connect to PAPE_2.4G + /* AL7230 use single PAPE and connect to PAPE_2.4G */ MACvSetBBType(pDevice->PortOffset, BB_TYPE_11G); pDevice->abyBBVGA[0] = 0x20; pDevice->abyBBVGA[2] = 0x10; pDevice->abyBBVGA[3] = 0x10; - BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); + BBbReadEmbedded(pDevice, 0xE7, &byData); if (byData == 0x1C) - BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); + BBbWriteEmbedded(pDevice, 0xE7, pDevice->abyBBVGA[0]); } else if (pDevice->byRFType == RF_UW2452) { MACvSetBBType(pDevice->PortOffset, BB_TYPE_11A); pDevice->abyBBVGA[0] = 0x18; - BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); + BBbReadEmbedded(pDevice, 0xE7, &byData); if (byData == 0x14) { - BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); - BBbWriteEmbedded(pDevice->PortOffset, 0xE1, 0x57); + BBbWriteEmbedded(pDevice, 0xE7, pDevice->abyBBVGA[0]); + BBbWriteEmbedded(pDevice, 0xE1, 0x57); } } else { MACvSetBBType(pDevice->PortOffset, BB_TYPE_11A); } - BBbWriteEmbedded(pDevice->PortOffset, 0x88, 0x03); + BBbWriteEmbedded(pDevice, 0x88, 0x03); bySlot = C_SLOT_SHORT; bySIFS = C_SIFS_A; byDIFS = C_SIFS_A + 2*C_SLOT_SHORT; byCWMaxMin = 0xA4; - } else if (ePHYType == PHY_TYPE_11B) { - if (pSupportRates == NULL) - pSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultSuppRatesB; - + } else if (bb_type == BB_TYPE_11B) { MACvSetBBType(pDevice->PortOffset, BB_TYPE_11B); if (pDevice->byRFType == RF_AIROHA7230) { pDevice->abyBBVGA[0] = 0x1C; pDevice->abyBBVGA[2] = 0x00; pDevice->abyBBVGA[3] = 0x00; - BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); + BBbReadEmbedded(pDevice, 0xE7, &byData); if (byData == 0x20) - BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); + BBbWriteEmbedded(pDevice, 0xE7, pDevice->abyBBVGA[0]); } else if (pDevice->byRFType == RF_UW2452) { pDevice->abyBBVGA[0] = 0x14; - BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); + BBbReadEmbedded(pDevice, 0xE7, &byData); if (byData == 0x18) { - BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); - BBbWriteEmbedded(pDevice->PortOffset, 0xE1, 0xD3); + BBbWriteEmbedded(pDevice, 0xE7, pDevice->abyBBVGA[0]); + BBbWriteEmbedded(pDevice, 0xE1, 0xD3); } } - BBbWriteEmbedded(pDevice->PortOffset, 0x88, 0x02); + BBbWriteEmbedded(pDevice, 0x88, 0x02); bySlot = C_SLOT_LONG; bySIFS = C_SIFS_BG; byDIFS = C_SIFS_BG + 2*C_SLOT_LONG; byCWMaxMin = 0xA5; - } else {// PK_TYPE_11GA & PK_TYPE_11GB - if (pSupportRates == NULL) { - pSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultSuppRatesG; - pExtSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultExtSuppRatesG; - } + } else { /* PK_TYPE_11GA & PK_TYPE_11GB */ MACvSetBBType(pDevice->PortOffset, BB_TYPE_11G); if (pDevice->byRFType == RF_AIROHA7230) { pDevice->abyBBVGA[0] = 0x1C; pDevice->abyBBVGA[2] = 0x00; pDevice->abyBBVGA[3] = 0x00; - BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); + BBbReadEmbedded(pDevice, 0xE7, &byData); if (byData == 0x20) - BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); + BBbWriteEmbedded(pDevice, 0xE7, pDevice->abyBBVGA[0]); } else if (pDevice->byRFType == RF_UW2452) { pDevice->abyBBVGA[0] = 0x14; - BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); + BBbReadEmbedded(pDevice, 0xE7, &byData); if (byData == 0x18) { - BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); - BBbWriteEmbedded(pDevice->PortOffset, 0xE1, 0xD3); + BBbWriteEmbedded(pDevice, 0xE7, pDevice->abyBBVGA[0]); + BBbWriteEmbedded(pDevice, 0xE1, 0xD3); } } - BBbWriteEmbedded(pDevice->PortOffset, 0x88, 0x08); + BBbWriteEmbedded(pDevice, 0x88, 0x08); bySIFS = C_SIFS_BG; - if (VNTWIFIbIsShortSlotTime(wCapInfo)) { + + if (pDevice->bShortSlotTime) { bySlot = C_SLOT_SHORT; byDIFS = C_SIFS_BG + 2*C_SLOT_SHORT; } else { bySlot = C_SLOT_LONG; byDIFS = C_SIFS_BG + 2*C_SLOT_LONG; } - if (VNTWIFIbyGetMaxSupportRate(pSupportRates, pExtSupportRates) > RATE_11M) - byCWMaxMin = 0xA4; - else - byCWMaxMin = 0xA5; - - if (pDevice->bProtectMode != VNTWIFIbIsProtectMode(byERPField)) { - pDevice->bProtectMode = VNTWIFIbIsProtectMode(byERPField); - if (pDevice->bProtectMode) - MACvEnableProtectMD(pDevice->PortOffset); - else - MACvDisableProtectMD(pDevice->PortOffset); - } - if (pDevice->bBarkerPreambleMd != VNTWIFIbIsBarkerMode(byERPField)) { - pDevice->bBarkerPreambleMd = VNTWIFIbIsBarkerMode(byERPField); - if (pDevice->bBarkerPreambleMd) - MACvEnableBarkerPreambleMd(pDevice->PortOffset); - else - MACvDisableBarkerPreambleMd(pDevice->PortOffset); + byCWMaxMin = 0xa4; + + for (i = RATE_54M; i >= RATE_6M; i--) { + if (pDevice->basic_rates & ((u32)(0x1 << i))) { + byCWMaxMin |= 0x1; + break; + } } } if (pDevice->byRFType == RF_RFMD2959) { - // bcs TX_PE will reserve 3 us - // hardware's processing time here is 2 us. + /* + * bcs TX_PE will reserve 3 us hardware's processing + * time here is 2 us. + */ bySIFS -= 3; byDIFS -= 3; - //{{ RobertYu: 20041202 - //// TX_PE will reserve 3 us for MAX2829 A mode only, it is for better TX throughput - //// MAC will need 2 us to process, so the SIFS, DIFS can be shorter by 2 us. + /* + * TX_PE will reserve 3 us for MAX2829 A mode only, it is for + * better TX throughput; MAC will need 2 us to process, so the + * SIFS, DIFS can be shorter by 2 us. + */ } if (pDevice->bySIFS != bySIFS) { @@ -527,10 +331,6 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, if (pDevice->bySlot != bySlot) { pDevice->bySlot = bySlot; VNSvOutPortB(pDevice->PortOffset + MAC_REG_SLOT, pDevice->bySlot); - if (pDevice->bySlot == C_SLOT_SHORT) - pDevice->bShortSlotTime = true; - else - pDevice->bShortSlotTime = false; BBvSetShortSlotTime(pDevice); } @@ -538,14 +338,11 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, pDevice->byCWMaxMin = byCWMaxMin; VNSvOutPortB(pDevice->PortOffset + MAC_REG_CWMAXMIN0, pDevice->byCWMaxMin); } - if (VNTWIFIbIsShortPreamble(wCapInfo)) - pDevice->byPreambleType = pDevice->byShortPreamble; - else - pDevice->byPreambleType = 0; - s_vSetRSPINF(pDevice, ePHYType, pSupportRates, pExtSupportRates); - pDevice->eCurrentPHYType = ePHYType; - // set for NDIS OID_802_11SUPPORTED_RATES + pDevice->byPacketType = CARDbyGetPktType(pDevice); + + CARDvSetRSPINF(pDevice, bb_type); + return true; } @@ -563,7 +360,6 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, * none * * Return Value: none - * */ bool CARDbUpdateTSF(struct vnt_private *pDevice, unsigned char byRxRate, u64 qwBSSTimestamp, u64 qwLocalTSF) @@ -572,8 +368,7 @@ bool CARDbUpdateTSF(struct vnt_private *pDevice, unsigned char byRxRate, if (qwBSSTimestamp != qwLocalTSF) { qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp, qwLocalTSF); - // adjust TSF - // HW's TSF add TSF Offset reg + /* adjust TSF, HW's TSF add TSF Offset reg */ VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST, (u32)qwTSFOffset); VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST + 4, (u32)(qwTSFOffset >> 32)); MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_TSFSYNCEN); @@ -593,21 +388,20 @@ bool CARDbUpdateTSF(struct vnt_private *pDevice, unsigned char byRxRate, * none * * Return Value: true if succeed; otherwise false - * */ bool CARDbSetBeaconPeriod(struct vnt_private *pDevice, unsigned short wBeaconInterval) { u64 qwNextTBTT = 0; - CARDbGetCurrentTSF(pDevice->PortOffset, &qwNextTBTT); //Get Local TSF counter + CARDbGetCurrentTSF(pDevice, &qwNextTBTT); /* Get Local TSF counter */ qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval); - // set HW beacon interval + /* set HW beacon interval */ VNSvOutPortW(pDevice->PortOffset + MAC_REG_BI, wBeaconInterval); pDevice->wBeaconInterval = wBeaconInterval; - // Set NextTBTT + /* Set NextTBTT */ VNSvOutPortD(pDevice->PortOffset + MAC_REG_NEXTTBTT, (u32)qwNextTBTT); VNSvOutPortD(pDevice->PortOffset + MAC_REG_NEXTTBTT + 4, (u32)(qwNextTBTT >> 32)); MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); @@ -616,225 +410,6 @@ bool CARDbSetBeaconPeriod(struct vnt_private *pDevice, } /* - * Description: Card Stop Hardware Tx - * - * Parameters: - * In: - * pDeviceHandler - The adapter to be set - * ePktType - Packet type to stop - * Out: - * none - * - * Return Value: true if all data packet complete; otherwise false. - * - */ -bool CARDbStopTxPacket(struct vnt_private *pDevice, CARD_PKT_TYPE ePktType) -{ - - if (ePktType == PKT_TYPE_802_11_ALL) { - pDevice->bStopBeacon = true; - pDevice->bStopTx0Pkt = true; - pDevice->bStopDataPkt = true; - } else if (ePktType == PKT_TYPE_802_11_BCN) { - pDevice->bStopBeacon = true; - } else if (ePktType == PKT_TYPE_802_11_MNG) { - pDevice->bStopTx0Pkt = true; - } else if (ePktType == PKT_TYPE_802_11_DATA) { - pDevice->bStopDataPkt = true; - } - - if (pDevice->bStopBeacon == true) { - if (pDevice->bIsBeaconBufReadySet == true) { - if (pDevice->cbBeaconBufReadySetCnt < WAIT_BEACON_TX_DOWN_TMO) { - pDevice->cbBeaconBufReadySetCnt++; - return false; - } - } - pDevice->bIsBeaconBufReadySet = false; - pDevice->cbBeaconBufReadySetCnt = 0; - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); - } - // wait all TD0 complete - if (pDevice->bStopTx0Pkt == true) { - if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) - return false; - } - // wait all Data TD complete - if (pDevice->bStopDataPkt == true) { - if (pDevice->iTDUsed[TYPE_AC0DMA] != 0) - return false; - } - - return true; -} - -/* - * Description: Card Start Hardware Tx - * - * Parameters: - * In: - * pDeviceHandler - The adapter to be set - * ePktType - Packet type to start - * Out: - * none - * - * Return Value: true if success; false if failed. - * - */ -bool CARDbStartTxPacket(struct vnt_private *pDevice, CARD_PKT_TYPE ePktType) -{ - - if (ePktType == PKT_TYPE_802_11_ALL) { - pDevice->bStopBeacon = false; - pDevice->bStopTx0Pkt = false; - pDevice->bStopDataPkt = false; - } else if (ePktType == PKT_TYPE_802_11_BCN) { - pDevice->bStopBeacon = false; - } else if (ePktType == PKT_TYPE_802_11_MNG) { - pDevice->bStopTx0Pkt = false; - } else if (ePktType == PKT_TYPE_802_11_DATA) { - pDevice->bStopDataPkt = false; - } - - if ((pDevice->bStopBeacon == false) && - (pDevice->bBeaconBufReady == true) && - (pDevice->op_mode == NL80211_IFTYPE_ADHOC)) { - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); - } - - return true; -} - -/* - * Description: Card Set BSSID value - * - * Parameters: - * In: - * pDeviceHandler - The adapter to be set - * pbyBSSID - pointer to BSSID field - * bAdhoc - flag to indicate IBSS - * Out: - * none - * - * Return Value: true if success; false if failed. - * - */ -bool CARDbSetBSSID(struct vnt_private *pDevice, - unsigned char *pbyBSSID, enum nl80211_iftype op_mode) -{ - - MACvWriteBSSIDAddress(pDevice->PortOffset, pbyBSSID); - memcpy(pDevice->abyBSSID, pbyBSSID, WLAN_BSSID_LEN); - if (op_mode == NL80211_IFTYPE_ADHOC) - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_ADHOC); - else - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_ADHOC); - - if (op_mode == NL80211_IFTYPE_AP) - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_AP); - else - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_AP); - - if (op_mode == NL80211_IFTYPE_UNSPECIFIED) { - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID); - pDevice->bBSSIDFilter = false; - pDevice->byRxMode &= ~RCR_BSSID; - pr_debug("wcmd: rx_mode = %x\n", pDevice->byRxMode); - } else { - if (is_zero_ether_addr(pDevice->abyBSSID) == false) { - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID); - pDevice->bBSSIDFilter = true; - pDevice->byRxMode |= RCR_BSSID; - } - pr_debug("wmgr: rx_mode = %x\n", pDevice->byRxMode); - } - // Adopt BSS state in Adapter Device Object - pDevice->op_mode = op_mode; - return true; -} - -/* - * Description: Card indicate status - * - * Parameters: - * In: - * pDeviceHandler - The adapter to be set - * eStatus - Status - * Out: - * none - * - * Return Value: true if success; false if failed. - * - */ - -/* - * Description: Save Assoc info. contain in assoc. response frame - * - * Parameters: - * In: - * pDevice - The adapter to be set - * wCapabilityInfo - Capability information - * wStatus - Status code - * wAID - Assoc. ID - * uLen - Length of IEs - * pbyIEs - pointer to IEs - * Out: - * none - * - * Return Value: true if succeed; otherwise false - * - */ -bool CARDbSetTxDataRate( - struct vnt_private *pDevice, - unsigned short wDataRate -) -{ - - pDevice->wCurrentRate = wDataRate; - return true; -} - -/*+ - * - * Routine Description: - * Consider to power down when no more packets to tx or rx. - * - * Parameters: - * In: - * pDevice - The adapter to be set - * Out: - * none - * - * Return Value: true if power down success; otherwise false - * - -*/ -bool -CARDbPowerDown( - struct vnt_private *pDevice -) -{ - unsigned int uIdx; - - // check if already in Doze mode - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) - return true; - - // Froce PSEN on - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN); - - // check if all TD are empty, - - for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx++) { - if (pDevice->iTDUsed[uIdx] != 0) - return false; - } - - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_GO2DOZE); - pr_debug("Go to Doze ZZZZZZZZZZZZZZZ\n"); - return true; -} - -/* * Description: Turn off Radio power * * Parameters: @@ -844,7 +419,6 @@ CARDbPowerDown( * none * * Return Value: true if success; otherwise false - * */ bool CARDbRadioPowerOff(struct vnt_private *pDevice) { @@ -861,7 +435,7 @@ bool CARDbRadioPowerOff(struct vnt_private *pDevice) case RF_AIROHA: case RF_AL2230S: - case RF_AIROHA7230: //RobertYu:20050104 + case RF_AIROHA7230: MACvWordRegBitsOff(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE2); MACvWordRegBitsOff(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); break; @@ -870,12 +444,11 @@ bool CARDbRadioPowerOff(struct vnt_private *pDevice) MACvRegBitsOff(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON); - BBvSetDeepSleep(pDevice->PortOffset, pDevice->byLocalID); + BBvSetDeepSleep(pDevice, pDevice->byLocalID); pDevice->bRadioOff = true; - //2007-0409-03,<Add> by chester pr_debug("chester power off\n"); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); //LED issue + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); /* LED issue */ return bResult; } @@ -889,7 +462,6 @@ bool CARDbRadioPowerOff(struct vnt_private *pDevice) * none * * Return Value: true if success; otherwise false - * */ bool CARDbRadioPowerOn(struct vnt_private *pDevice) { @@ -907,7 +479,7 @@ bool CARDbRadioPowerOn(struct vnt_private *pDevice) pr_debug("chester pbRadioOff\n"); return true; } - BBvExitDeepSleep(pDevice->PortOffset, pDevice->byLocalID); + BBvExitDeepSleep(pDevice, pDevice->byLocalID); MACvRegBitsOn(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON); @@ -919,7 +491,7 @@ bool CARDbRadioPowerOn(struct vnt_private *pDevice) case RF_AIROHA: case RF_AL2230S: - case RF_AIROHA7230: //RobertYu:20050104 + case RF_AIROHA7230: MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3)); break; @@ -927,493 +499,11 @@ bool CARDbRadioPowerOn(struct vnt_private *pDevice) } pDevice->bRadioOff = false; -// 2007-0409-03,<Add> by chester pr_debug("chester power on\n"); - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); //LED issue + MACvRegBitsOff(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); /* LED issue */ return bResult; } -bool CARDbRemoveKey(struct vnt_private *pDevice, unsigned char *pbyBSSID) -{ - - KeybRemoveAllKey(&(pDevice->sKey), pbyBSSID, pDevice->PortOffset); - return true; -} - -/* - * - * Description: - * Add BSSID in PMKID Candidate list. - * - * Parameters: - * In: - * hDeviceContext - device structure point - * pbyBSSID - BSSID address for adding - * wRSNCap - BSS's RSN capability - * Out: - * none - * - * Return Value: none. - * - -*/ -bool -CARDbAdd_PMKID_Candidate( - struct vnt_private *pDevice, - unsigned char *pbyBSSID, - bool bRSNCapExist, - unsigned short wRSNCap -) -{ - struct pmkid_candidate *pCandidateList; - unsigned int ii = 0; - - pr_debug("bAdd_PMKID_Candidate START: (%d)\n", - (int)pDevice->gsPMKIDCandidate.NumCandidates); - - if (pDevice->gsPMKIDCandidate.NumCandidates >= MAX_PMKIDLIST) { - pr_debug("vFlush_PMKID_Candidate: 3\n"); - memset(&pDevice->gsPMKIDCandidate, 0, sizeof(SPMKIDCandidateEvent)); - } - - for (ii = 0; ii < 6; ii++) - pr_debug("%02X ", *(pbyBSSID + ii)); - - pr_debug("\n"); - - // Update Old Candidate - for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) { - pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii]; - if (!memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) { - if (bRSNCapExist && (wRSNCap & BIT0)) - pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; - else - pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); - - return true; - } - } - - // New Candidate - pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates]; - if (bRSNCapExist && (wRSNCap & BIT0)) - pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; - else - pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); - - memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN); - pDevice->gsPMKIDCandidate.NumCandidates++; - pr_debug("NumCandidates:%d\n", - (int)pDevice->gsPMKIDCandidate.NumCandidates); - return true; -} - -void * -CARDpGetCurrentAddress( - struct vnt_private *pDevice -) -{ - - return pDevice->abyCurrentNetAddr; -} - -/* - * - * Description: - * Start Spectrum Measure defined in 802.11h - * - * Parameters: - * In: - * hDeviceContext - device structure point - * Out: - * none - * - * Return Value: none. - * - -*/ -bool -CARDbStartMeasure( - struct vnt_private *pDevice, - void *pvMeasureEIDs, - unsigned int uNumOfMeasureEIDs -) -{ - PWLAN_IE_MEASURE_REQ pEID = (PWLAN_IE_MEASURE_REQ) pvMeasureEIDs; - u64 qwCurrTSF; - u64 qwStartTSF; - bool bExpired = true; - unsigned short wDuration = 0; - - if ((pEID == NULL) || - (uNumOfMeasureEIDs == 0)) { - return true; - } - CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF); - if (pDevice->bMeasureInProgress == true) { - pDevice->bMeasureInProgress = false; - VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byOrgRCR); - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, pDevice->dwOrgMAR0); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR4, pDevice->dwOrgMAR4); - // clear measure control - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN); - MACvSelectPage0(pDevice->PortOffset); - set_channel(pDevice, pDevice->byOrgChannel); - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); - MACvSelectPage0(pDevice->PortOffset); - } - pDevice->uNumOfMeasureEIDs = uNumOfMeasureEIDs; - - do { - pDevice->pCurrMeasureEID = pEID; - pEID++; - pDevice->uNumOfMeasureEIDs--; - - if (pDevice->byLocalID > REV_ID_VT3253_B1) { - qwStartTSF = *((u64 *)(pDevice->pCurrMeasureEID->sReq.abyStartTime)); - wDuration = *((unsigned short *)(pDevice->pCurrMeasureEID->sReq.abyDuration)); - wDuration += 1; // 1 TU for channel switching - - if (qwStartTSF == 0) { - // start immediately by setting start TSF == current TSF + 2 TU - qwStartTSF = qwCurrTSF + 2048; - - bExpired = false; - break; - } else { - // start at setting start TSF - 1TU(for channel switching) - qwStartTSF -= 1024; - } - - if (qwCurrTSF < qwStartTSF) { - bExpired = false; - break; - } - VNTWIFIbMeasureReport(pDevice->pMgmt, - false, - pDevice->pCurrMeasureEID, - MEASURE_MODE_LATE, - pDevice->byBasicMap, - pDevice->byCCAFraction, - pDevice->abyRPIs - ); - } else { - // hardware do not support measure - VNTWIFIbMeasureReport(pDevice->pMgmt, - false, - pDevice->pCurrMeasureEID, - MEASURE_MODE_INCAPABLE, - pDevice->byBasicMap, - pDevice->byCCAFraction, - pDevice->abyRPIs - ); - } - } while (pDevice->uNumOfMeasureEIDs != 0); - - if (!bExpired) { - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MSRSTART, (u32)qwStartTSF); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MSRSTART + 4, (u32)(qwStartTSF >> 32)); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_MSRDURATION, wDuration); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN); - MACvSelectPage0(pDevice->PortOffset); - } else { - // all measure start time expired we should complete action - VNTWIFIbMeasureReport(pDevice->pMgmt, - true, - NULL, - 0, - pDevice->byBasicMap, - pDevice->byCCAFraction, - pDevice->abyRPIs - ); - } - return true; -} - -/* - * - * Description: - * Do Channel Switch defined in 802.11h - * - * Parameters: - * In: - * hDeviceContext - device structure point - * Out: - * none - * - * Return Value: none. - * - -*/ -bool -CARDbChannelSwitch( - struct vnt_private *pDevice, - unsigned char byMode, - unsigned char byNewChannel, - unsigned char byCount -) -{ - bool bResult = true; - - if (byCount == 0) { - bResult = set_channel(pDevice, byNewChannel); - VNTWIFIbChannelSwitch(pDevice->pMgmt, byNewChannel); - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); - MACvSelectPage0(pDevice->PortOffset); - return bResult; - } - pDevice->byChannelSwitchCount = byCount; - pDevice->byNewChannel = byNewChannel; - pDevice->bChannelSwitch = true; - if (byMode == 1) - bResult = CARDbStopTxPacket(pDevice, PKT_TYPE_802_11_ALL); - - return bResult; -} - -/* - * - * Description: - * Handle Quiet EID defined in 802.11h - * - * Parameters: - * In: - * hDeviceContext - device structure point - * Out: - * none - * - * Return Value: none. - * - -*/ -bool -CARDbSetQuiet( - struct vnt_private *pDevice, - bool bResetQuiet, - unsigned char byQuietCount, - unsigned char byQuietPeriod, - unsigned short wQuietDuration, - unsigned short wQuietOffset -) -{ - unsigned int ii = 0; - - if (bResetQuiet) { - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN)); - for (ii = 0; ii < MAX_QUIET_COUNT; ii++) - pDevice->sQuiet[ii].bEnable = false; - - pDevice->uQuietEnqueue = 0; - pDevice->bEnableFirstQuiet = false; - pDevice->bQuietEnable = false; - pDevice->byQuietStartCount = byQuietCount; - } - if (pDevice->sQuiet[pDevice->uQuietEnqueue].bEnable == false) { - pDevice->sQuiet[pDevice->uQuietEnqueue].bEnable = true; - pDevice->sQuiet[pDevice->uQuietEnqueue].byPeriod = byQuietPeriod; - pDevice->sQuiet[pDevice->uQuietEnqueue].wDuration = wQuietDuration; - pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime = (unsigned long) byQuietCount; - pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime *= pDevice->wBeaconInterval; - pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime += wQuietOffset; - pDevice->uQuietEnqueue++; - pDevice->uQuietEnqueue %= MAX_QUIET_COUNT; - if (pDevice->byQuietStartCount < byQuietCount) - pDevice->byQuietStartCount = byQuietCount; - } - return true; -} - -/* - * - * Description: - * Do Quiet, It will be called by either ISR(after start) - * or VNTWIFI(before start) so we do not need a SPINLOCK - * - * Parameters: - * In: - * hDeviceContext - device structure point - * Out: - * none - * - * Return Value: none. - * - -*/ -bool -CARDbStartQuiet( - struct vnt_private *pDevice -) -{ - unsigned int ii = 0; - unsigned long dwStartTime = 0xFFFFFFFF; - unsigned int uCurrentQuietIndex = 0; - unsigned long dwNextTime = 0; - unsigned long dwGap = 0; - unsigned long dwDuration = 0; - - for (ii = 0; ii < MAX_QUIET_COUNT; ii++) { - if ((pDevice->sQuiet[ii].bEnable == true) && - (dwStartTime > pDevice->sQuiet[ii].dwStartTime)) { - dwStartTime = pDevice->sQuiet[ii].dwStartTime; - uCurrentQuietIndex = ii; - } - } - if (dwStartTime == 0xFFFFFFFF) { - // no more quiet - pDevice->bQuietEnable = false; - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN)); - } else { - if (pDevice->bQuietEnable == false) { - // first quiet - pDevice->byQuietStartCount--; - dwNextTime = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime; - dwNextTime %= pDevice->wBeaconInterval; - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETINIT, (unsigned short) dwNextTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETDUR, (unsigned short) pDevice->sQuiet[uCurrentQuietIndex].wDuration); - if (pDevice->byQuietStartCount == 0) { - pDevice->bEnableFirstQuiet = false; - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN)); - } else { - pDevice->bEnableFirstQuiet = true; - } - MACvSelectPage0(pDevice->PortOffset); - } else { - if (pDevice->dwCurrentQuietEndTime > pDevice->sQuiet[uCurrentQuietIndex].dwStartTime) { - // overlap with previous Quiet - dwGap = pDevice->dwCurrentQuietEndTime - pDevice->sQuiet[uCurrentQuietIndex].dwStartTime; - if (dwGap >= pDevice->sQuiet[uCurrentQuietIndex].wDuration) { - // return false to indicate next quiet expired, should call this function again - return false; - } - dwDuration = pDevice->sQuiet[uCurrentQuietIndex].wDuration - dwGap; - dwGap = 0; - } else { - dwGap = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime - pDevice->dwCurrentQuietEndTime; - dwDuration = pDevice->sQuiet[uCurrentQuietIndex].wDuration; - } - // set GAP and Next duration - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETGAP, (unsigned short) dwGap); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETDUR, (unsigned short) dwDuration); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_QUIETRPT); - MACvSelectPage0(pDevice->PortOffset); - } - pDevice->bQuietEnable = true; - pDevice->dwCurrentQuietEndTime = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime; - pDevice->dwCurrentQuietEndTime += pDevice->sQuiet[uCurrentQuietIndex].wDuration; - if (pDevice->sQuiet[uCurrentQuietIndex].byPeriod == 0) { - // not period disable current quiet element - pDevice->sQuiet[uCurrentQuietIndex].bEnable = false; - } else { - // set next period start time - dwNextTime = (unsigned long) pDevice->sQuiet[uCurrentQuietIndex].byPeriod; - dwNextTime *= pDevice->wBeaconInterval; - pDevice->sQuiet[uCurrentQuietIndex].dwStartTime = dwNextTime; - } - if (pDevice->dwCurrentQuietEndTime > 0x80010000) { - // decreament all time to avoid wrap around - for (ii = 0; ii < MAX_QUIET_COUNT; ii++) { - if (pDevice->sQuiet[ii].bEnable == true) - pDevice->sQuiet[ii].dwStartTime -= 0x80000000; - - } - pDevice->dwCurrentQuietEndTime -= 0x80000000; - } - } - return true; -} - -/* - * - * Description: - * Set Local Power Constraint - * - * Parameters: - * In: - * hDeviceContext - device structure point - * Out: - * none - * - * Return Value: none. - * - -*/ -void -CARDvSetPowerConstraint( - struct vnt_private *pDevice, - unsigned char byChannel, - char byPower -) -{ - - if (byChannel > CB_MAX_CHANNEL_24G) { - if (pDevice->bCountryInfo5G == true) - pDevice->abyLocalPwr[byChannel] = pDevice->abyRegPwr[byChannel] - byPower; - - } else { - if (pDevice->bCountryInfo24G == true) - pDevice->abyLocalPwr[byChannel] = pDevice->abyRegPwr[byChannel] - byPower; - - } -} - -/* - * - * Description: - * Set Local Power Constraint - * - * Parameters: - * In: - * hDeviceContext - device structure point - * Out: - * none - * - * Return Value: none. - * - -*/ -void -CARDvGetPowerCapability( - struct vnt_private *pDevice, - unsigned char *pbyMinPower, - unsigned char *pbyMaxPower -) -{ - unsigned char byDec = 0; - - *pbyMaxPower = pDevice->abyOFDMDefaultPwr[pDevice->byCurrentCh]; - byDec = pDevice->abyOFDMPwrTbl[pDevice->byCurrentCh]; - if (pDevice->byRFType == RF_UW2452) { - byDec *= 3; - byDec >>= 1; - } else { - byDec <<= 1; - } - *pbyMinPower = pDevice->abyOFDMDefaultPwr[pDevice->byCurrentCh] - byDec; -} - -/* - * - * Description: - * Get Current Tx Power - * - * Parameters: - * In: - * hDeviceContext - device structure point - * Out: - * none - * - * Return Value: none. - * - */ -char -CARDbyGetTransmitPower( - struct vnt_private *pDevice -) -{ - - return pDevice->byCurPwrdBm; -} - -//xxx void CARDvSafeResetTx( struct vnt_private *pDevice @@ -1422,7 +512,7 @@ CARDvSafeResetTx( unsigned int uu; PSTxDesc pCurrTD; - // initialize TD index + /* initialize TD index */ pDevice->apTailTD[0] = pDevice->apCurrTD[0] = &(pDevice->apTD0Rings[0]); pDevice->apTailTD[1] = pDevice->apCurrTD[1] = &(pDevice->apTD1Rings[0]); @@ -1432,28 +522,27 @@ CARDvSafeResetTx( for (uu = 0; uu < pDevice->sOpts.nTxDescs[0]; uu++) { pCurrTD = &(pDevice->apTD0Rings[uu]); pCurrTD->m_td0TD0.f1Owner = OWNED_BY_HOST; - // init all Tx Packet pointer to NULL + /* init all Tx Packet pointer to NULL */ } for (uu = 0; uu < pDevice->sOpts.nTxDescs[1]; uu++) { pCurrTD = &(pDevice->apTD1Rings[uu]); pCurrTD->m_td0TD0.f1Owner = OWNED_BY_HOST; - // init all Tx Packet pointer to NULL + /* init all Tx Packet pointer to NULL */ } - // set MAC TD pointer + /* set MAC TD pointer */ MACvSetCurrTXDescAddr(TYPE_TXDMA0, pDevice->PortOffset, (pDevice->td0_pool_dma)); MACvSetCurrTXDescAddr(TYPE_AC0DMA, pDevice->PortOffset, (pDevice->td1_pool_dma)); - // set MAC Beacon TX pointer + /* set MAC Beacon TX pointer */ MACvSetCurrBCNTxDescAddr(pDevice->PortOffset, (pDevice->tx_beacon_dma)); } -/*+ - * +/* * Description: * Reset Rx * @@ -1464,8 +553,7 @@ CARDvSafeResetTx( * none * * Return Value: none - * - -*/ + */ void CARDvSafeResetRx( struct vnt_private *pDevice @@ -1474,11 +562,11 @@ CARDvSafeResetRx( unsigned int uu; PSRxDesc pDesc; - // initialize RD index + /* initialize RD index */ pDevice->pCurrRD[0] = &(pDevice->aRD0Ring[0]); pDevice->pCurrRD[1] = &(pDevice->aRD1Ring[0]); - // init state, all RD is chip's + /* init state, all RD is chip's */ for (uu = 0; uu < pDevice->sOpts.nRxDescs0; uu++) { pDesc = &(pDevice->aRD0Ring[uu]); pDesc->m_rd0RD0.wResCount = (unsigned short)(pDevice->rx_buf_sz); @@ -1486,7 +574,7 @@ CARDvSafeResetRx( pDesc->m_rd1RD1.wReqCount = (unsigned short)(pDevice->rx_buf_sz); } - // init state, all RD is chip's + /* init state, all RD is chip's */ for (uu = 0; uu < pDevice->sOpts.nRxDescs1; uu++) { pDesc = &(pDevice->aRD1Ring[uu]); pDesc->m_rd0RD0.wResCount = (unsigned short)(pDevice->rx_buf_sz); @@ -1494,13 +582,10 @@ CARDvSafeResetRx( pDesc->m_rd1RD1.wReqCount = (unsigned short)(pDevice->rx_buf_sz); } - pDevice->cbDFCB = CB_MAX_RX_FRAG; - pDevice->cbFreeDFCB = pDevice->cbDFCB; - - // set perPkt mode + /* set perPkt mode */ MACvRx0PerPktMode(pDevice->PortOffset); MACvRx1PerPktMode(pDevice->PortOffset); - // set MAC RD pointer + /* set MAC RD pointer */ MACvSetCurrRx0DescAddr(pDevice->PortOffset, pDevice->rd0_pool_dma); @@ -1519,7 +604,6 @@ CARDvSafeResetRx( * none * * Return Value: response Control frame rate - * */ static unsigned short CARDwGetCCKControlRate(struct vnt_private *pDevice, unsigned short wRateIdx) @@ -1527,7 +611,7 @@ static unsigned short CARDwGetCCKControlRate(struct vnt_private *pDevice, unsigned int ui = (unsigned int) wRateIdx; while (ui > RATE_1M) { - if (pDevice->wBasicRate & ((unsigned short)1 << ui)) + if (pDevice->basic_rates & ((u32)0x1 << ui)) return (unsigned short)ui; ui--; @@ -1546,14 +630,13 @@ static unsigned short CARDwGetCCKControlRate(struct vnt_private *pDevice, * none * * Return Value: response Control frame rate - * */ static unsigned short CARDwGetOFDMControlRate(struct vnt_private *pDevice, unsigned short wRateIdx) { unsigned int ui = (unsigned int) wRateIdx; - pr_debug("BASIC RATE: %X\n", pDevice->wBasicRate); + pr_debug("BASIC RATE: %X\n", pDevice->basic_rates); if (!CARDbIsOFDMinBasicRate((void *)pDevice)) { pr_debug("CARDwGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx); @@ -1562,7 +645,7 @@ static unsigned short CARDwGetOFDMControlRate(struct vnt_private *pDevice, return wRateIdx; } while (ui > RATE_11M) { - if (pDevice->wBasicRate & ((unsigned short)1 << ui)) { + if (pDevice->basic_rates & ((u32)0x1 << ui)) { pr_debug("CARDwGetOFDMControlRate : %d\n", ui); return (unsigned short)ui; } @@ -1582,14 +665,13 @@ static unsigned short CARDwGetOFDMControlRate(struct vnt_private *pDevice, * none * * Return Value: None. - * */ -void CARDvSetRSPINF(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType) +void CARDvSetRSPINF(struct vnt_private *pDevice, u8 bb_type) { union vnt_phy_field_swap phy; - unsigned char byTxRate, byRsvTime; //For OFDM + unsigned char byTxRate, byRsvTime; /* For OFDM */ - //Set to Page1 + /* Set to Page1 */ MACvSelectPage1(pDevice->PortOffset); /* RSPINF_b_1 */ @@ -1629,136 +711,72 @@ void CARDvSetRSPINF(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType) VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_11, phy.field_write); - //RSPINF_a_6 + /* RSPINF_a_6 */ s_vCalculateOFDMRParameter(RATE_6M, - ePHYType, + bb_type, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_6, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_9 + /* RSPINF_a_9 */ s_vCalculateOFDMRParameter(RATE_9M, - ePHYType, + bb_type, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_9, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_12 + /* RSPINF_a_12 */ s_vCalculateOFDMRParameter(RATE_12M, - ePHYType, + bb_type, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_12, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_18 + /* RSPINF_a_18 */ s_vCalculateOFDMRParameter(RATE_18M, - ePHYType, + bb_type, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_18, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_24 + /* RSPINF_a_24 */ s_vCalculateOFDMRParameter(RATE_24M, - ePHYType, + bb_type, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_24, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_36 + /* RSPINF_a_36 */ s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_36M), - ePHYType, + bb_type, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_36, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_48 + /* RSPINF_a_48 */ s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_48M), - ePHYType, + bb_type, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_48, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_54 + /* RSPINF_a_54 */ s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_54M), - ePHYType, + bb_type, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_54, MAKEWORD(byTxRate, byRsvTime)); - - //RSPINF_a_72 + /* RSPINF_a_72 */ s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_54M), - ePHYType, + bb_type, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_72, MAKEWORD(byTxRate, byRsvTime)); - //Set to Page0 + /* Set to Page0 */ MACvSelectPage0(pDevice->PortOffset); } -/* - * Description: Update IFS - * - * Parameters: - * In: - * pDevice - The adapter to be set - * Out: - * none - * - * Return Value: None. - * - */ -void vUpdateIFS(struct vnt_private *pDevice) -{ - /* Set SIFS, DIFS, EIFS, SlotTime, CwMin */ - - unsigned char byMaxMin = 0; - - if (pDevice->byPacketType == PK_TYPE_11A) {//0000 0000 0000 0000,11a - pDevice->uSlot = C_SLOT_SHORT; - pDevice->uSIFS = C_SIFS_A; - pDevice->uDIFS = C_SIFS_A + 2*C_SLOT_SHORT; - pDevice->uCwMin = C_CWMIN_A; - byMaxMin = 4; - } else if (pDevice->byPacketType == PK_TYPE_11B) {//0000 0001 0000 0000,11b - pDevice->uSlot = C_SLOT_LONG; - pDevice->uSIFS = C_SIFS_BG; - pDevice->uDIFS = C_SIFS_BG + 2*C_SLOT_LONG; - pDevice->uCwMin = C_CWMIN_B; - byMaxMin = 5; - } else { // PK_TYPE_11GA & PK_TYPE_11GB - pDevice->uSIFS = C_SIFS_BG; - if (pDevice->bShortSlotTime) - pDevice->uSlot = C_SLOT_SHORT; - else - pDevice->uSlot = C_SLOT_LONG; - - pDevice->uDIFS = C_SIFS_BG + 2*pDevice->uSlot; - if (pDevice->wBasicRate & 0x0150) { //0000 0001 0101 0000,24M,12M,6M - pDevice->uCwMin = C_CWMIN_A; - byMaxMin = 4; - } else { - pDevice->uCwMin = C_CWMIN_B; - byMaxMin = 5; - } - } - - pDevice->uCwMax = C_CWMAX; - pDevice->uEIFS = C_EIFS; - if (pDevice->byRFType == RF_RFMD2959) { - // bcs TX_PE will reserve 3 us - VNSvOutPortB(pDevice->PortOffset + MAC_REG_SIFS, (unsigned char)(pDevice->uSIFS - 3)); - VNSvOutPortB(pDevice->PortOffset + MAC_REG_DIFS, (unsigned char)(pDevice->uDIFS - 3)); - } else { - VNSvOutPortB(pDevice->PortOffset + MAC_REG_SIFS, (unsigned char)pDevice->uSIFS); - VNSvOutPortB(pDevice->PortOffset + MAC_REG_DIFS, (unsigned char)pDevice->uDIFS); - } - VNSvOutPortB(pDevice->PortOffset + MAC_REG_EIFS, (unsigned char)pDevice->uEIFS); - VNSvOutPortB(pDevice->PortOffset + MAC_REG_SLOT, (unsigned char)pDevice->uSlot); - byMaxMin |= 0xA0;//1010 1111,C_CWMAX = 1023 - VNSvOutPortB(pDevice->PortOffset + MAC_REG_CWMAXMIN0, (unsigned char)byMaxMin); -} - void CARDvUpdateBasicTopRate(struct vnt_private *pDevice) { unsigned char byTopOFDM = RATE_24M, byTopCCK = RATE_1M; unsigned char ii; - //Determines the highest basic rate. + /* Determines the highest basic rate. */ for (ii = RATE_54M; ii >= RATE_6M; ii--) { - if ((pDevice->wBasicRate) & ((unsigned short)(1<<ii))) { + if ((pDevice->basic_rates) & ((u32)(1 << ii))) { byTopOFDM = ii; break; } @@ -1766,7 +784,7 @@ void CARDvUpdateBasicTopRate(struct vnt_private *pDevice) pDevice->byTopOFDMBasicRate = byTopOFDM; for (ii = RATE_11M;; ii--) { - if ((pDevice->wBasicRate) & ((unsigned short)(1<<ii))) { + if ((pDevice->basic_rates) & ((u32)(1 << ii))) { byTopCCK = ii; break; } @@ -1776,24 +794,12 @@ void CARDvUpdateBasicTopRate(struct vnt_private *pDevice) pDevice->byTopCCKBasicRate = byTopCCK; } -bool CARDbAddBasicRate(struct vnt_private *pDevice, unsigned short wRateIdx) -{ - unsigned short wRate = (unsigned short)(1<<wRateIdx); - - pDevice->wBasicRate |= wRate; - - //Determines the highest basic rate. - CARDvUpdateBasicTopRate((void *)pDevice); - - return true; -} - bool CARDbIsOFDMinBasicRate(struct vnt_private *pDevice) { int ii; for (ii = RATE_54M; ii >= RATE_6M; ii--) { - if ((pDevice->wBasicRate) & ((unsigned short)(1 << ii))) + if ((pDevice->basic_rates) & ((u32)(1 << ii))) return true; } return false; @@ -1821,10 +827,11 @@ unsigned char CARDbyGetPktType(struct vnt_private *pDevice) * none * * Return Value: none - * */ -void CARDvSetLoopbackMode(void __iomem *dwIoBase, unsigned short wLoopbackMode) +void CARDvSetLoopbackMode(struct vnt_private *priv, unsigned short wLoopbackMode) { + void __iomem *dwIoBase = priv->PortOffset; + switch (wLoopbackMode) { case CARD_LB_NONE: case CARD_LB_MAC: @@ -1834,9 +841,9 @@ void CARDvSetLoopbackMode(void __iomem *dwIoBase, unsigned short wLoopbackMode) ASSERT(false); break; } - // set MAC loopback + /* set MAC loopback */ MACvSetLoopbackMode(dwIoBase, LOBYTE(wLoopbackMode)); - // set Baseband loopback + /* set Baseband loopback */ } /* @@ -1849,12 +856,11 @@ void CARDvSetLoopbackMode(void __iomem *dwIoBase, unsigned short wLoopbackMode) * none * * Return Value: none - * */ bool CARDbSoftwareReset(struct vnt_private *pDevice) { - // reset MAC + /* reset MAC */ if (!MACbSafeSoftwareReset(pDevice->PortOffset)) return false; @@ -1874,7 +880,6 @@ bool CARDbSoftwareReset(struct vnt_private *pDevice) * none * * Return Value: TSF Offset value - * */ u64 CARDqGetTSFOffset(unsigned char byRxRate, u64 qwTSF1, u64 qwTSF2) { @@ -1901,10 +906,10 @@ u64 CARDqGetTSFOffset(unsigned char byRxRate, u64 qwTSF1, u64 qwTSF2) * qwCurrTSF - Current TSF counter * * Return Value: true if success; otherwise false - * */ -bool CARDbGetCurrentTSF(void __iomem *dwIoBase, u64 *pqwCurrTSF) +bool CARDbGetCurrentTSF(struct vnt_private *priv, u64 *pqwCurrTSF) { + void __iomem *dwIoBase = priv->PortOffset; unsigned short ww; unsigned char byData; @@ -1934,17 +939,12 @@ bool CARDbGetCurrentTSF(void __iomem *dwIoBase, u64 *pqwCurrTSF) * qwCurrTSF - Current TSF counter * * Return Value: TSF value of next Beacon - * */ u64 CARDqGetNextTBTT(u64 qwTSF, unsigned short wBeaconInterval) { u32 beacon_int; beacon_int = wBeaconInterval * 1024; - - /* Next TBTT = - * ((local_current_TSF / beacon_interval) + 1) * beacon_interval - */ if (beacon_int) { do_div(qwTSF, beacon_int); qwTSF += 1; @@ -1966,16 +966,16 @@ u64 CARDqGetNextTBTT(u64 qwTSF, unsigned short wBeaconInterval) * none * * Return Value: none - * */ -void CARDvSetFirstNextTBTT(void __iomem *dwIoBase, unsigned short wBeaconInterval) +void CARDvSetFirstNextTBTT(struct vnt_private *priv, unsigned short wBeaconInterval) { + void __iomem *dwIoBase = priv->PortOffset; u64 qwNextTBTT = 0; - CARDbGetCurrentTSF(dwIoBase, &qwNextTBTT); //Get Local TSF counter + CARDbGetCurrentTSF(priv, &qwNextTBTT); /* Get Local TSF counter */ qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval); - // Set NextTBTT + /* Set NextTBTT */ VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, (u32)qwNextTBTT); VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, (u32)(qwNextTBTT >> 32)); MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); @@ -1994,12 +994,13 @@ void CARDvSetFirstNextTBTT(void __iomem *dwIoBase, unsigned short wBeaconInterva * none * * Return Value: none - * */ -void CARDvUpdateNextTBTT(void __iomem *dwIoBase, u64 qwTSF, unsigned short wBeaconInterval) +void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 qwTSF, unsigned short wBeaconInterval) { + void __iomem *dwIoBase = priv->PortOffset; + qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval); - // Set NextTBTT + /* Set NextTBTT */ VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, (u32)qwTSF); VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, (u32)(qwTSF >> 32)); MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h index 96f5b6c46e82..2dfc41952271 100644 --- a/drivers/staging/vt6655/card.h +++ b/drivers/staging/vt6655/card.h @@ -29,35 +29,28 @@ #ifndef __CARD_H__ #define __CARD_H__ -#include "ttype.h" #include <linux/types.h> #include <linux/nl80211.h> -// -// Loopback mode -// -// LOBYTE is MAC LB mode, HIBYTE is MII LB mode +/* + * Loopback mode + * + * LOBYTE is MAC LB mode, HIBYTE is MII LB mode + */ #define CARD_LB_NONE MAKEWORD(MAC_LB_NONE, 0) -#define CARD_LB_MAC MAKEWORD(MAC_LB_INTERNAL, 0) // PHY must ISO, avoid MAC loopback packet go out +#define CARD_LB_MAC MAKEWORD(MAC_LB_INTERNAL, 0) /* PHY must ISO, avoid MAC loopback packet go out */ #define CARD_LB_PHY MAKEWORD(MAC_LB_EXT, 0) -#define DEFAULT_MSDU_LIFETIME 512 // ms -#define DEFAULT_MSDU_LIFETIME_RES_64us 8000 // 64us +#define DEFAULT_MSDU_LIFETIME 512 /* ms */ +#define DEFAULT_MSDU_LIFETIME_RES_64us 8000 /* 64us */ -#define DEFAULT_MGN_LIFETIME 8 // ms -#define DEFAULT_MGN_LIFETIME_RES_64us 125 // 64us +#define DEFAULT_MGN_LIFETIME 8 /* ms */ +#define DEFAULT_MGN_LIFETIME_RES_64us 125 /* 64us */ #define CB_MAX_CHANNEL_24G 14 #define CB_MAX_CHANNEL_5G 42 #define CB_MAX_CHANNEL (CB_MAX_CHANNEL_24G+CB_MAX_CHANNEL_5G) -typedef enum _CARD_PHY_TYPE { - PHY_TYPE_AUTO, - PHY_TYPE_11B, - PHY_TYPE_11G, - PHY_TYPE_11A -} CARD_PHY_TYPE, *PCARD_PHY_TYPE; - typedef enum _CARD_PKT_TYPE { PKT_TYPE_802_11_BCN, PKT_TYPE_802_11_MNG, @@ -73,103 +66,24 @@ typedef enum _CARD_STATUS_TYPE { struct vnt_private; -void CARDvSetRSPINF(struct vnt_private *, CARD_PHY_TYPE ePHYType); -void vUpdateIFS(struct vnt_private *); +void CARDvSetRSPINF(struct vnt_private *, u8); void CARDvUpdateBasicTopRate(struct vnt_private *); -bool CARDbAddBasicRate(struct vnt_private *, unsigned short wRateIdx); bool CARDbIsOFDMinBasicRate(struct vnt_private *); -void CARDvSetLoopbackMode(void __iomem *dwIoBase, unsigned short wLoopbackMode); +void CARDvSetLoopbackMode(struct vnt_private *, unsigned short wLoopbackMode); bool CARDbSoftwareReset(struct vnt_private *); -void CARDvSetFirstNextTBTT(void __iomem *dwIoBase, unsigned short wBeaconInterval); -void CARDvUpdateNextTBTT(void __iomem *dwIoBase, u64 qwTSF, unsigned short wBeaconInterval); -bool CARDbGetCurrentTSF(void __iomem *dwIoBase, u64 *pqwCurrTSF); +void CARDvSetFirstNextTBTT(struct vnt_private *, unsigned short wBeaconInterval); +void CARDvUpdateNextTBTT(struct vnt_private *, u64 qwTSF, unsigned short wBeaconInterval); +bool CARDbGetCurrentTSF(struct vnt_private *, u64 *pqwCurrTSF); u64 CARDqGetNextTBTT(u64 qwTSF, unsigned short wBeaconInterval); u64 CARDqGetTSFOffset(unsigned char byRxRate, u64 qwTSF1, u64 qwTSF2); -bool CARDbSetTxPower(struct vnt_private *, unsigned long ulTxPower); unsigned char CARDbyGetPktType(struct vnt_private *); void CARDvSafeResetTx(struct vnt_private *); void CARDvSafeResetRx(struct vnt_private *); bool CARDbRadioPowerOff(struct vnt_private *); bool CARDbRadioPowerOn(struct vnt_private *); -bool CARDbIsShortPreamble(struct vnt_private *); -bool CARDbIsShorSlotTime(struct vnt_private *); -bool CARDbSetPhyParameter(struct vnt_private *, CARD_PHY_TYPE ePHYType, - unsigned short wCapInfo, unsigned char byERPField, - void *pvSupportRateIEs, void *pvExtSupportRateIEs); +bool CARDbSetPhyParameter(struct vnt_private *, u8); bool CARDbUpdateTSF(struct vnt_private *, unsigned char byRxRate, u64 qwBSSTimestamp, u64 qwLocalTSF); -bool CARDbStopTxPacket(struct vnt_private *, CARD_PKT_TYPE ePktType); -bool CARDbStartTxPacket(struct vnt_private *, CARD_PKT_TYPE ePktType); bool CARDbSetBeaconPeriod(struct vnt_private *, unsigned short wBeaconInterval); -bool CARDbSetBSSID(struct vnt_private *, - unsigned char *pbyBSSID, enum nl80211_iftype); - -bool CARDbPowerDown(struct vnt_private *); - -bool CARDbSetTxDataRate(struct vnt_private *, unsigned short wDataRate); - -bool CARDbRemoveKey(struct vnt_private *, unsigned char *pbyBSSID); - -bool -CARDbAdd_PMKID_Candidate( - struct vnt_private *, - unsigned char *pbyBSSID, - bool bRSNCapExist, - unsigned short wRSNCap -); - -void * -CARDpGetCurrentAddress( - struct vnt_private * -); - -bool -CARDbStartMeasure( - struct vnt_private *, - void *pvMeasureEIDs, - unsigned int uNumOfMeasureEIDs -); - -bool -CARDbChannelSwitch( - struct vnt_private *, - unsigned char byMode, - unsigned char byNewChannel, - unsigned char byCount -); - -bool -CARDbSetQuiet( - struct vnt_private *, - bool bResetQuiet, - unsigned char byQuietCount, - unsigned char byQuietPeriod, - unsigned short wQuietDuration, - unsigned short wQuietOffset -); - -bool -CARDbStartQuiet( - struct vnt_private * -); - -void -CARDvSetPowerConstraint( - struct vnt_private *, - unsigned char byChannel, - char byPower -); - -void -CARDvGetPowerCapability( - struct vnt_private *, - unsigned char *pbyMinPower, - unsigned char *pbyMaxPower -); - -char -CARDbyGetTransmitPower( - struct vnt_private * -); -#endif // __CARD_H__ +#endif /* __CARD_H__ */ diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c index 4ce964ba14b7..70f870541f92 100644 --- a/drivers/staging/vt6655/channel.c +++ b/drivers/staging/vt6655/channel.c @@ -21,494 +21,148 @@ */ #include "baseband.h" -#include "country.h" #include "channel.h" #include "device.h" #include "rf.h" -/*--------------------- Static Definitions -------------------------*/ - -#define CARD_MAX_CHANNEL_TBL 56 - -/*--------------------- Static Variables --------------------------*/ - -static SChannelTblElement sChannelTbl[CARD_MAX_CHANNEL_TBL + 1] = -{ - {0, 0, false, 0}, - {1, 2412, true, 0}, - {2, 2417, true, 0}, - {3, 2422, true, 0}, - {4, 2427, true, 0}, - {5, 2432, true, 0}, - {6, 2437, true, 0}, - {7, 2442, true, 0}, - {8, 2447, true, 0}, - {9, 2452, true, 0}, - {10, 2457, true, 0}, - {11, 2462, true, 0}, - {12, 2467, true, 0}, - {13, 2472, true, 0}, - {14, 2484, true, 0}, - {183, 4915, true, 0}, - {184, 4920, true, 0}, - {185, 4925, true, 0}, - {187, 4935, true, 0}, - {188, 4940, true, 0}, - {189, 4945, true, 0}, - {192, 4960, true, 0}, - {196, 4980, true, 0}, - {7, 5035, true, 0}, - {8, 5040, true, 0}, - {9, 5045, true, 0}, - {11, 5055, true, 0}, - {12, 5060, true, 0}, - {16, 5080, true, 0}, - {34, 5170, true, 0}, - {36, 5180, true, 0}, - {38, 5190, true, 0}, - {40, 5200, true, 0}, - {42, 5210, true, 0}, - {44, 5220, true, 0}, - {46, 5230, true, 0}, - {48, 5240, true, 0}, - {52, 5260, true, 0}, - {56, 5280, true, 0}, - {60, 5300, true, 0}, - {64, 5320, true, 0}, - {100, 5500, true, 0}, - {104, 5520, true, 0}, - {108, 5540, true, 0}, - {112, 5560, true, 0}, - {116, 5580, true, 0}, - {120, 5600, true, 0}, - {124, 5620, true, 0}, - {128, 5640, true, 0}, - {132, 5660, true, 0}, - {136, 5680, true, 0}, - {140, 5700, true, 0}, - {149, 5745, true, 0}, - {153, 5765, true, 0}, - {157, 5785, true, 0}, - {161, 5805, true, 0}, - {165, 5825, true, 0} +static struct ieee80211_rate vnt_rates_bg[] = { + { .bitrate = 10, .hw_value = RATE_1M }, + { .bitrate = 20, .hw_value = RATE_2M }, + { .bitrate = 55, .hw_value = RATE_5M }, + { .bitrate = 110, .hw_value = RATE_11M }, + { .bitrate = 60, .hw_value = RATE_6M }, + { .bitrate = 90, .hw_value = RATE_9M }, + { .bitrate = 120, .hw_value = RATE_12M }, + { .bitrate = 180, .hw_value = RATE_18M }, + { .bitrate = 240, .hw_value = RATE_24M }, + { .bitrate = 360, .hw_value = RATE_36M }, + { .bitrate = 480, .hw_value = RATE_48M }, + { .bitrate = 540, .hw_value = RATE_54M }, }; -/************************************************************************ - * The Radar regulation rules for each country - ************************************************************************/ -static struct -{ - unsigned char byChannelCountryCode; /* The country code */ - char chCountryCode[2]; - unsigned char bChannelIdxList[CB_MAX_CHANNEL]; /* Available channels Index */ - unsigned char byPower[CB_MAX_CHANNEL]; -} ChannelRuleTab[] = -{ -/************************************************************************ - * This table is based on Athero driver rules - ************************************************************************/ -/* Country Available channels, ended with 0 */ -/* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 */ - {CCODE_FCC, {'U' , 'S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_TELEC, {'J' , 'P'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 23, 0, 0, 23, 0, 23, 23, 0, 23, 0, 0, 23, 23, 23, 0, 23, 0, 23, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_ETSI, {'E' , 'U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_RESV3, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESV4, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESV5, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESV6, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESV7, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESV8, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESV9, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESVa, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESVb, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESVc, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESVd, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESVe, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_ALLBAND, {' ' , ' '}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_ALBANIA, {'A' , 'L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_ALGERIA, {'D' , 'Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_ARGENTINA, {'A' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 0} }, - {CCODE_ARMENIA, {'A' , 'M'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_AUSTRALIA, {'A' , 'U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_AUSTRIA, {'A' , 'T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 15, 0, 15, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_AZERBAIJAN, {'A' , 'Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_BAHRAIN, {'B' , 'H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_BELARUS, {'B' , 'Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_BELGIUM, {'B' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_BELIZE, {'B' , 'Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_BOLIVIA, {'B' , 'O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_BRAZIL, {'B' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_BRUNEI_DARUSSALAM, {'B' , 'N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_BULGARIA, {'B' , 'G'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 0, 0, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0} }, - {CCODE_CANADA, {'C' , 'A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_CHILE, {'C' , 'L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17} }, - {CCODE_CHINA, {'C' , 'N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_COLOMBIA, {'C' , 'O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_COSTA_RICA, {'C' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_CROATIA, {'H' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_CYPRUS, {'C' , 'Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_CZECH, {'C' , 'Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_DENMARK, {'D' , 'K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_DOMINICAN_REPUBLIC, {'D' , 'O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_ECUADOR, {'E' , 'C'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_EGYPT, {'E' , 'G'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_EL_SALVADOR, {'S' , 'V'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_ESTONIA, {'E' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_FINLAND, {'F' , 'I'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_FRANCE, {'F' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_GERMANY, {'D' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_GREECE, {'G' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_GEORGIA, {'G' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_GUATEMALA, {'G' , 'T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_HONDURAS, {'H' , 'N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_HONG_KONG, {'H' , 'K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_HUNGARY, {'H' , 'U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_ICELAND, {'I' , 'S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_INDIA, {'I' , 'N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_INDONESIA, {'I' , 'D'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_IRAN, {'I' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_IRELAND, {'I' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_ITALY, {'I' , 'T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_ISRAEL, {'I' , 'L'}, { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_JAPAN, {'J' , 'P'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_JORDAN, {'J' , 'O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_KAZAKHSTAN, {'K' , 'Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_KUWAIT, {'K' , 'W'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_LATVIA, {'L' , 'V'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_LEBANON, {'L' , 'B'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_LEICHTENSTEIN, {'L' , 'I'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_LITHUANIA, {'L' , 'T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_LUXEMBURG, {'L' , 'U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_MACAU, {'M' , 'O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_MACEDONIA, {'M' , 'K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_MALTA, {'M' , 'T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 0} }, - {CCODE_MALAYSIA, {'M' , 'Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_MEXICO, {'M' , 'X'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_MONACO, {'M' , 'C'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_MOROCCO, {'M' , 'A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_NETHERLANDS, {'N' , 'L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_NEW_ZEALAND, {'N' , 'Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_NORTH_KOREA, {'K' , 'P'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} }, - {CCODE_NORWAY, {'N' , 'O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_OMAN, {'O' , 'M'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_PAKISTAN, {'P' , 'K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_PANAMA, {'P' , 'A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_PERU, {'P' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_PHILIPPINES, {'P' , 'H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_POLAND, {'P' , 'L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_PORTUGAL, {'P' , 'T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_PUERTO_RICO, {'P' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_QATAR, {'Q' , 'A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_ROMANIA, {'R' , 'O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RUSSIA, {'R' , 'U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_SAUDI_ARABIA, {'S' , 'A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_SINGAPORE, {'S' , 'G'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 20} }, - {CCODE_SLOVAKIA, {'S' , 'K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 0} }, - {CCODE_SLOVENIA, {'S' , 'I'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_SOUTH_AFRICA, {'Z' , 'A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_SOUTH_KOREA, {'K' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} }, - {CCODE_SPAIN, {'E' , 'S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 0} }, - {CCODE_SWEDEN, {'S' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_SWITZERLAND, {'C' , 'H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_SYRIA, {'S' , 'Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_TAIWAN, {'T' , 'W'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 0} }, - {CCODE_THAILAND, {'T' , 'H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} }, - {CCODE_TRINIDAD_TOBAGO, {'T' , 'T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_TUNISIA, {'T' , 'N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_TURKEY, {'T' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_UK, {'G' , 'B'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_UKRAINE, {'U' , 'A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_UNITED_ARAB_EMIRATES, {'A' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_UNITED_STATES, {'U' , 'S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_URUGUAY, {'U' , 'Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} }, - {CCODE_UZBEKISTAN, {'U' , 'Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_VENEZUELA, {'V' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} }, - {CCODE_VIETNAM, {'V' , 'N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_YEMEN, {'Y' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_ZIMBABWE, {'Z' , 'W'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_JAPAN_W52_W53, {'J' , 'J'}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_MAX, {'U' , 'N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} } -/* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 */ +static struct ieee80211_rate vnt_rates_a[] = { + { .bitrate = 60, .hw_value = RATE_6M }, + { .bitrate = 90, .hw_value = RATE_9M }, + { .bitrate = 120, .hw_value = RATE_12M }, + { .bitrate = 180, .hw_value = RATE_18M }, + { .bitrate = 240, .hw_value = RATE_24M }, + { .bitrate = 360, .hw_value = RATE_36M }, + { .bitrate = 480, .hw_value = RATE_48M }, + { .bitrate = 540, .hw_value = RATE_54M }, }; -/*--------------------- Export Functions --------------------------*/ - -/** - * is_channel_valid() - Is Country Channel Valid - * @ChanneIndex: defined as VT3253 MAC channel: - * 1 = 2.4G channel 1 - * 2 = 2.4G channel 2 - * ... - * 14 = 2.4G channel 14 - * 15 = 4.9G channel 183 - * 16 = 4.9G channel 184 - * ..... - * Output: true if the specified 5GHz band is allowed to be used, - * false otherwise. - * 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22) - * - * 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64, - * 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56) - */ - -bool is_channel_valid(unsigned int ChannelIndex) -{ - bool bValid; - - bValid = false; - /* - * If Channel Index is invalid, return invalid - */ - if ((ChannelIndex > CB_MAX_CHANNEL) || - (ChannelIndex == 0)) { - bValid = false; - goto exit; - } +static struct ieee80211_channel vnt_channels_2ghz[] = { + { .center_freq = 2412, .hw_value = 1 }, + { .center_freq = 2417, .hw_value = 2 }, + { .center_freq = 2422, .hw_value = 3 }, + { .center_freq = 2427, .hw_value = 4 }, + { .center_freq = 2432, .hw_value = 5 }, + { .center_freq = 2437, .hw_value = 6 }, + { .center_freq = 2442, .hw_value = 7 }, + { .center_freq = 2447, .hw_value = 8 }, + { .center_freq = 2452, .hw_value = 9 }, + { .center_freq = 2457, .hw_value = 10 }, + { .center_freq = 2462, .hw_value = 11 }, + { .center_freq = 2467, .hw_value = 12 }, + { .center_freq = 2472, .hw_value = 13 }, + { .center_freq = 2484, .hw_value = 14 } +}; - bValid = sChannelTbl[ChannelIndex].bValid; +static struct ieee80211_channel vnt_channels_5ghz[] = { + { .center_freq = 4915, .hw_value = 15 }, + { .center_freq = 4920, .hw_value = 16 }, + { .center_freq = 4925, .hw_value = 17 }, + { .center_freq = 4935, .hw_value = 18 }, + { .center_freq = 4940, .hw_value = 19 }, + { .center_freq = 4945, .hw_value = 20 }, + { .center_freq = 4960, .hw_value = 21 }, + { .center_freq = 4980, .hw_value = 22 }, + { .center_freq = 5035, .hw_value = 23 }, + { .center_freq = 5040, .hw_value = 24 }, + { .center_freq = 5045, .hw_value = 25 }, + { .center_freq = 5055, .hw_value = 26 }, + { .center_freq = 5060, .hw_value = 27 }, + { .center_freq = 5080, .hw_value = 28 }, + { .center_freq = 5170, .hw_value = 29 }, + { .center_freq = 5180, .hw_value = 30 }, + { .center_freq = 5190, .hw_value = 31 }, + { .center_freq = 5200, .hw_value = 32 }, + { .center_freq = 5210, .hw_value = 33 }, + { .center_freq = 5220, .hw_value = 34 }, + { .center_freq = 5230, .hw_value = 35 }, + { .center_freq = 5240, .hw_value = 36 }, + { .center_freq = 5260, .hw_value = 37 }, + { .center_freq = 5280, .hw_value = 38 }, + { .center_freq = 5300, .hw_value = 39 }, + { .center_freq = 5320, .hw_value = 40 }, + { .center_freq = 5500, .hw_value = 41 }, + { .center_freq = 5520, .hw_value = 42 }, + { .center_freq = 5540, .hw_value = 43 }, + { .center_freq = 5560, .hw_value = 44 }, + { .center_freq = 5580, .hw_value = 45 }, + { .center_freq = 5600, .hw_value = 46 }, + { .center_freq = 5620, .hw_value = 47 }, + { .center_freq = 5640, .hw_value = 48 }, + { .center_freq = 5660, .hw_value = 49 }, + { .center_freq = 5680, .hw_value = 50 }, + { .center_freq = 5700, .hw_value = 51 }, + { .center_freq = 5745, .hw_value = 52 }, + { .center_freq = 5765, .hw_value = 53 }, + { .center_freq = 5785, .hw_value = 54 }, + { .center_freq = 5805, .hw_value = 55 }, + { .center_freq = 5825, .hw_value = 56 } +}; -exit: - return bValid; -} +static struct ieee80211_supported_band vnt_supported_2ghz_band = { + .channels = vnt_channels_2ghz, + .n_channels = ARRAY_SIZE(vnt_channels_2ghz), + .bitrates = vnt_rates_bg, + .n_bitrates = ARRAY_SIZE(vnt_rates_bg), +}; -/** - * channel_get_list() - Get Available Channel List for a given country - * @CountryCode: The country code defined in country.h - * - * Output: - * pbyChannelTable: (QWORD *) correspondent bit mask - * of available channels - * 0x0000000000000001 means channel 1 is supported - * 0x0000000000000003 means channel 1,2 are supported - * 0x000000000000000F means channel 1,2,..15 are supported - */ +static struct ieee80211_supported_band vnt_supported_5ghz_band = { + .channels = vnt_channels_5ghz, + .n_channels = ARRAY_SIZE(vnt_channels_5ghz), + .bitrates = vnt_rates_a, + .n_bitrates = ARRAY_SIZE(vnt_rates_a), +}; -bool channel_get_list(unsigned int uCountryCodeIdx, unsigned char *pbyChannelTable) +void vnt_init_bands(struct vnt_private *priv) { - if (uCountryCodeIdx >= CCODE_MAX) - return false; - - memcpy(pbyChannelTable, ChannelRuleTab[uCountryCodeIdx].bChannelIdxList, CB_MAX_CHANNEL); - - return true; -} + struct ieee80211_channel *ch; + int i; -void init_channel_table(void *pDeviceHandler) -{ - struct vnt_private *pDevice = pDeviceHandler; - bool bMultiBand = false; - unsigned int ii; + switch (priv->byRFType) { + case RF_AIROHA7230: + case RF_UW2452: + case RF_NOTHING: + default: + ch = vnt_channels_5ghz; - for (ii = 1; ii <= CARD_MAX_CHANNEL_TBL; ii++) - sChannelTbl[ii].bValid = false; + for (i = 0; i < ARRAY_SIZE(vnt_channels_5ghz); i++) { + ch[i].max_power = 0x3f; + ch[i].flags = IEEE80211_CHAN_NO_HT40; + } - switch (pDevice->byRFType) { + priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = + &vnt_supported_5ghz_band; + /* fallthrough */ case RF_RFMD2959: case RF_AIROHA: case RF_AL2230S: case RF_UW2451: case RF_VT3226: - bMultiBand = false; - break; - case RF_AIROHA7230: - case RF_UW2452: - case RF_NOTHING: - default: - bMultiBand = true; - break; - } + ch = vnt_channels_2ghz; - if ((pDevice->dwDiagRefCount != 0) || pDevice->b11hEnable) { - if (bMultiBand) { - for (ii = 0; ii < CARD_MAX_CHANNEL_TBL; ii++) { - sChannelTbl[ii + 1].bValid = true; - pDevice->abyRegPwr[ii + 1] = pDevice->abyOFDMDefaultPwr[ii + 1]; - pDevice->abyLocalPwr[ii + 1] = pDevice->abyOFDMDefaultPwr[ii + 1]; - } - for (ii = 0; ii < CHANNEL_MAX_24G; ii++) { - pDevice->abyRegPwr[ii + 1] = pDevice->abyCCKDefaultPwr[ii + 1]; - pDevice->abyLocalPwr[ii + 1] = pDevice->abyCCKDefaultPwr[ii + 1]; - } - } else { - for (ii = 0; ii < CHANNEL_MAX_24G; ii++) { - //2008-8-4 <add> by chester - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) { - sChannelTbl[ii + 1].bValid = true; - pDevice->abyRegPwr[ii + 1] = pDevice->abyCCKDefaultPwr[ii + 1]; - pDevice->abyLocalPwr[ii + 1] = pDevice->abyCCKDefaultPwr[ii + 1]; - } - } - } - } else if (pDevice->byZoneType <= CCODE_MAX) { - if (bMultiBand) { - for (ii = 0; ii < CARD_MAX_CHANNEL_TBL; ii++) { - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) { - sChannelTbl[ii + 1].bValid = true; - pDevice->abyRegPwr[ii + 1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii]; - pDevice->abyLocalPwr[ii + 1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii]; - } - } - } else { - for (ii = 0; ii < CHANNEL_MAX_24G; ii++) { - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) { - sChannelTbl[ii + 1].bValid = true; - pDevice->abyRegPwr[ii + 1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii]; - pDevice->abyLocalPwr[ii + 1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii]; - } - } + for (i = 0; i < ARRAY_SIZE(vnt_channels_2ghz); i++) { + ch[i].max_power = 0x3f; + ch[i].flags = IEEE80211_CHAN_NO_HT40; } - } - - pr_info("Zone=[%d][%c][%c]!!\n", - pDevice->byZoneType, - ChannelRuleTab[pDevice->byZoneType].chCountryCode[0], - ChannelRuleTab[pDevice->byZoneType].chCountryCode[1]); - - for (ii = 0; ii < CARD_MAX_CHANNEL_TBL; ii++) { - if (pDevice->abyRegPwr[ii + 1] == 0) - pDevice->abyRegPwr[ii + 1] = pDevice->abyOFDMDefaultPwr[ii + 1]; - if (pDevice->abyLocalPwr[ii + 1] == 0) - pDevice->abyLocalPwr[ii + 1] = pDevice->abyOFDMDefaultPwr[ii + 1]; - } -} - -unsigned char get_channel_mapping(void *pDeviceHandler, unsigned char byChannelNumber, CARD_PHY_TYPE ePhyType) -{ - unsigned int ii; - - if ((ePhyType == PHY_TYPE_11B) || (ePhyType == PHY_TYPE_11G)) - return byChannelNumber; - for (ii = (CB_MAX_CHANNEL_24G + 1); ii <= CB_MAX_CHANNEL;) { - if (sChannelTbl[ii].byChannelNumber == byChannelNumber) - return (unsigned char) ii; - ii++; + priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = + &vnt_supported_2ghz_band; + break; } - return 0; -} - -unsigned char get_channel_number(void *pDeviceHandler, unsigned char byChannelIndex) -{ - return sChannelTbl[byChannelIndex].byChannelNumber; } /** @@ -528,37 +182,35 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel) if (pDevice->byCurrentCh == uConnectionChannel) return bResult; - if (!sChannelTbl[uConnectionChannel].bValid) - return false; + /* Set VGA to max sensitivity */ + if (pDevice->bUpdateBBVGA && + pDevice->byBBVGACurrent != pDevice->abyBBVGA[0]) { + pDevice->byBBVGACurrent = pDevice->abyBBVGA[0]; - if ((uConnectionChannel > CB_MAX_CHANNEL_24G) && - (pDevice->eCurrentPHYType != PHY_TYPE_11A)) { - CARDbSetPhyParameter(pDevice, PHY_TYPE_11A, 0, 0, NULL, NULL); - } else if ((uConnectionChannel <= CB_MAX_CHANNEL_24G) && - (pDevice->eCurrentPHYType == PHY_TYPE_11A)) { - CARDbSetPhyParameter(pDevice, PHY_TYPE_11G, 0, 0, NULL, NULL); + BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent); } - // clear NAV + + /* clear NAV */ MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MACCR, MACCR_CLRNAV); - //{{ RobertYu: 20041202 - //// TX_PE will reserve 3 us for MAX2829 A mode only, it is for better TX throughput + /* TX_PE will reserve 3 us for MAX2829 A mode only, it is for better TX throughput */ if (pDevice->byRFType == RF_AIROHA7230) - RFbAL7230SelectChannelPostProcess(pDevice->PortOffset, pDevice->byCurrentCh, (unsigned char)uConnectionChannel); - //}} RobertYu + RFbAL7230SelectChannelPostProcess(pDevice, pDevice->byCurrentCh, + (unsigned char)uConnectionChannel); pDevice->byCurrentCh = (unsigned char)uConnectionChannel; - bResult &= RFbSelectChannel(pDevice->PortOffset, pDevice->byRFType, (unsigned char)uConnectionChannel); + bResult &= RFbSelectChannel(pDevice, pDevice->byRFType, + (unsigned char)uConnectionChannel); - // Init Synthesizer Table + /* Init Synthesizer Table */ if (pDevice->bEnablePSMode) - RFvWriteWakeProgSyn(pDevice->PortOffset, pDevice->byRFType, uConnectionChannel); + RFvWriteWakeProgSyn(pDevice, pDevice->byRFType, uConnectionChannel); - BBvSoftwareReset(pDevice->PortOffset); + BBvSoftwareReset(pDevice); if (pDevice->byLocalID > REV_ID_VT3253_B1) { - // set HW default power register + /* set HW default power register */ MACvSelectPage1(pDevice->PortOffset); RFbSetPower(pDevice, RATE_1M, pDevice->byCurrentCh); VNSvOutPortB(pDevice->PortOffset + MAC_REG_PWRCCK, pDevice->byCurPwr); @@ -567,242 +219,10 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel) MACvSelectPage0(pDevice->PortOffset); } - if (pDevice->eCurrentPHYType == PHY_TYPE_11B) + if (pDevice->byBBType == BB_TYPE_11B) RFbSetPower(pDevice, RATE_1M, pDevice->byCurrentCh); else RFbSetPower(pDevice, RATE_6M, pDevice->byCurrentCh); return bResult; } - -/** - * set_country_info() - Set Channel Info of Country - * - * Return Value: none. - * - */ - -void set_country_info(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, void *pIE) -{ - struct vnt_private *pDevice = pDeviceHandler; - unsigned int ii = 0; - unsigned int uu = 0; - unsigned int step = 0; - unsigned int uNumOfCountryInfo = 0; - unsigned char byCh = 0; - PWLAN_IE_COUNTRY pIE_Country = (PWLAN_IE_COUNTRY) pIE; - - uNumOfCountryInfo = (pIE_Country->len - 3); - uNumOfCountryInfo /= 3; - - if (ePHYType == PHY_TYPE_11A) { - pDevice->bCountryInfo5G = true; - for (ii = CB_MAX_CHANNEL_24G + 1; ii <= CARD_MAX_CHANNEL_TBL; ii++) - sChannelTbl[ii].bValid = false; - - step = 4; - } else { - pDevice->bCountryInfo24G = true; - for (ii = 1; ii <= CB_MAX_CHANNEL_24G; ii++) - sChannelTbl[ii].bValid = false; - - step = 1; - } - pDevice->abyCountryCode[0] = pIE_Country->abyCountryString[0]; - pDevice->abyCountryCode[1] = pIE_Country->abyCountryString[1]; - pDevice->abyCountryCode[2] = pIE_Country->abyCountryString[2]; - - for (ii = 0; ii < uNumOfCountryInfo; ii++) { - for (uu = 0; uu < pIE_Country->abyCountryInfo[ii*3+1]; uu++) { - byCh = get_channel_mapping(pDevice, (unsigned char)(pIE_Country->abyCountryInfo[ii*3]+step*uu), ePHYType); - sChannelTbl[byCh].bValid = true; - pDevice->abyRegPwr[byCh] = pIE_Country->abyCountryInfo[ii*3+2]; - } - } -} - -/** - * - * set_support_channels() - Set Support Channels IE defined in 802.11h - * - * @hDeviceContext: device structure point - * - * Return Value: none. - * - */ - -unsigned char set_support_channels(void *pDeviceHandler, unsigned char *pbyIEs) -{ - struct vnt_private *pDevice = pDeviceHandler; - unsigned int ii; - unsigned char byCount; - PWLAN_IE_SUPP_CH pIE = (PWLAN_IE_SUPP_CH) pbyIEs; - unsigned char *pbyChTupple; - unsigned char byLen = 0; - - pIE->byElementID = WLAN_EID_SUPP_CH; - pIE->len = 0; - pbyChTupple = pIE->abyChannelTuple; - byLen = 2; - // lower band - byCount = 0; - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[28] == true) { - for (ii = 28; ii < 36; ii += 2) { - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == true) - byCount++; - } - - *pbyChTupple++ = 34; - *pbyChTupple++ = byCount; - byLen += 2; - } else if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[29] == true) { - for (ii = 29; ii < 36; ii += 2) { - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == true) - byCount++; - } - - *pbyChTupple++ = 36; - *pbyChTupple++ = byCount; - byLen += 2; - } - // middle band - byCount = 0; - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[36] == true) { - for (ii = 36; ii < 40; ii++) { - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == true) - byCount++; - } - - *pbyChTupple++ = 52; - *pbyChTupple++ = byCount; - byLen += 2; - } - // higher band - byCount = 0; - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[40] == true) { - for (ii = 40; ii < 51; ii++) { - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == true) - byCount++; - } - - *pbyChTupple++ = 100; - *pbyChTupple++ = byCount; - byLen += 2; - } else if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[51] == true) { - for (ii = 51; ii < 56; ii++) { - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == true) - byCount++; - } - - *pbyChTupple++ = 149; - *pbyChTupple++ = byCount; - byLen += 2; - } - pIE->len += (byLen - 2); - return byLen; -} - -void set_country_IE(void *pDeviceHandler, void *pIE) -{ - struct vnt_private *pDevice = pDeviceHandler; - unsigned int ii; - PWLAN_IE_COUNTRY pIECountry = (PWLAN_IE_COUNTRY) pIE; - - pIECountry->byElementID = WLAN_EID_COUNTRY; - pIECountry->len = 0; - pIECountry->abyCountryString[0] = ChannelRuleTab[pDevice->byZoneType].chCountryCode[0]; - pIECountry->abyCountryString[1] = ChannelRuleTab[pDevice->byZoneType].chCountryCode[1]; - pIECountry->abyCountryString[2] = ' '; - for (ii = CB_MAX_CHANNEL_24G; ii < CB_MAX_CHANNEL; ii++) { - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) { - pIECountry->abyCountryInfo[pIECountry->len++] = sChannelTbl[ii + 1].byChannelNumber; - pIECountry->abyCountryInfo[pIECountry->len++] = 1; - pIECountry->abyCountryInfo[pIECountry->len++] = ChannelRuleTab[pDevice->byZoneType].byPower[ii]; - } - } - pIECountry->len += 3; -} - -bool get_channel_map_info(void *pDeviceHandler, unsigned int uChannelIndex, - unsigned char *pbyChannelNumber, unsigned char *pbyMap) -{ - if (uChannelIndex > CB_MAX_CHANNEL) - return false; - - *pbyChannelNumber = sChannelTbl[uChannelIndex].byChannelNumber; - *pbyMap = sChannelTbl[uChannelIndex].byMAP; - return sChannelTbl[uChannelIndex].bValid; -} - -void set_channel_map_info(void *pDeviceHandler, unsigned int uChannelIndex, - unsigned char byMap) -{ - if (uChannelIndex > CB_MAX_CHANNEL) - return; - - sChannelTbl[uChannelIndex].byMAP |= byMap; -} - -void clear_channel_map_info(void *pDeviceHandler) -{ - unsigned int ii = 0; - - for (ii = 1; ii <= CB_MAX_CHANNEL; ii++) - sChannelTbl[ii].byMAP = 0; -} - -unsigned char auto_channel_select(void *pDeviceHandler, CARD_PHY_TYPE ePHYType) -{ - unsigned int ii = 0; - unsigned char byOptionChannel = 0; - int aiWeight[CB_MAX_CHANNEL_24G + 1] = {-1000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - - if (ePHYType == PHY_TYPE_11A) { - for (ii = CB_MAX_CHANNEL_24G + 1; ii <= CB_MAX_CHANNEL; ii++) { - if (sChannelTbl[ii].bValid) { - if (byOptionChannel == 0) - byOptionChannel = (unsigned char) ii; - - if (sChannelTbl[ii].byMAP == 0) - return (unsigned char) ii; - else if (!(sChannelTbl[ii].byMAP & 0x08)) - byOptionChannel = (unsigned char) ii; - } - } - } else { - byOptionChannel = 0; - for (ii = 1; ii <= CB_MAX_CHANNEL_24G; ii++) { - if (sChannelTbl[ii].bValid) { - if (sChannelTbl[ii].byMAP == 0) { - aiWeight[ii] += 100; - } else if (sChannelTbl[ii].byMAP & 0x01) { - if (ii > 3) - aiWeight[ii - 3] -= 10; - - if (ii > 2) - aiWeight[ii - 2] -= 20; - - if (ii > 1) - aiWeight[ii - 1] -= 40; - - aiWeight[ii] -= 80; - if (ii < CB_MAX_CHANNEL_24G) - aiWeight[ii + 1] -= 40; - - if (ii < (CB_MAX_CHANNEL_24G - 1)) - aiWeight[ii+2] -= 20; - - if (ii < (CB_MAX_CHANNEL_24G - 2)) - aiWeight[ii+3] -= 10; - } - } - } - for (ii = 1; ii <= CB_MAX_CHANNEL_24G; ii++) { - if (sChannelTbl[ii].bValid && - (aiWeight[ii] > aiWeight[byOptionChannel])) { - byOptionChannel = (unsigned char) ii; - } - } - } - return byOptionChannel; -} diff --git a/drivers/staging/vt6655/channel.h b/drivers/staging/vt6655/channel.h index 4f44c8a3d3cf..4f4264e23462 100644 --- a/drivers/staging/vt6655/channel.h +++ b/drivers/staging/vt6655/channel.h @@ -23,30 +23,10 @@ #ifndef _CHANNEL_H_ #define _CHANNEL_H_ -#include "ttype.h" #include "card.h" -typedef struct tagSChannelTblElement { - unsigned char byChannelNumber; - unsigned int uFrequency; - bool bValid; - unsigned char byMAP; -} SChannelTblElement, *PSChannelTblElement; +void vnt_init_bands(struct vnt_private *); -bool is_channel_valid(unsigned int CountryCode); -void init_channel_table(void *pDeviceHandler); -unsigned char get_channel_mapping(void *pDeviceHandler, unsigned char byChannelNumber, CARD_PHY_TYPE ePhyType); -bool channel_get_list(unsigned int uCountryCodeIdx, unsigned char *pbyChannelTable); -unsigned char get_channel_number(void *pDeviceHandler, unsigned char byChannelIndex); bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel); -void set_country_info(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, void *pIE); -unsigned char set_support_channels(void *pDeviceHandler, unsigned char *pbyIEs); -void set_country_IE(void *pDeviceHandler, void *pIE); -bool get_channel_map_info(void *pDeviceHandler, unsigned int uChannelIndex, - unsigned char *pbyChannelNumber, unsigned char *pbyMap); -void set_channel_map_info(void *pDeviceHandler, unsigned int uChannelIndex, - unsigned char byMap); -void clear_channel_map_info(void *pDeviceHandler); -unsigned char auto_channel_select(void *pDeviceHandler, CARD_PHY_TYPE ePHYType); #endif /* _CHANNEL_H_ */ diff --git a/drivers/staging/vt6655/country.h b/drivers/staging/vt6655/country.h deleted file mode 100644 index 2365fb13b033..000000000000 --- a/drivers/staging/vt6655/country.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: country.h - * - * Purpose: Country Code information - * - * Author: Lucas Lin - * - * Date: Dec 23, 2004 - * - */ - -#ifndef __COUNTRY_H__ -#define __COUNTRY_H__ - -#include "ttype.h" - -/************************************************************************ - * The definition here should be complied with the INF country order - * Please check with VNWL.inf/VNWL64.inf/VNWL*.inf - ************************************************************************/ -typedef enum _COUNTRY_CODE { - CCODE_FCC = 0, - CCODE_TELEC, - CCODE_ETSI, - CCODE_RESV3, - CCODE_RESV4, - CCODE_RESV5, - CCODE_RESV6, - CCODE_RESV7, - CCODE_RESV8, - CCODE_RESV9, - CCODE_RESVa, - CCODE_RESVb, - CCODE_RESVc, - CCODE_RESVd, - CCODE_RESVe, - CCODE_ALLBAND, - CCODE_ALBANIA, - CCODE_ALGERIA, - CCODE_ARGENTINA, - CCODE_ARMENIA, - CCODE_AUSTRALIA, - CCODE_AUSTRIA, - CCODE_AZERBAIJAN, - CCODE_BAHRAIN, - CCODE_BELARUS, - CCODE_BELGIUM, - CCODE_BELIZE, - CCODE_BOLIVIA, - CCODE_BRAZIL, - CCODE_BRUNEI_DARUSSALAM, - CCODE_BULGARIA, - CCODE_CANADA, - CCODE_CHILE, - CCODE_CHINA, - CCODE_COLOMBIA, - CCODE_COSTA_RICA, - CCODE_CROATIA, - CCODE_CYPRUS, - CCODE_CZECH, - CCODE_DENMARK, - CCODE_DOMINICAN_REPUBLIC, - CCODE_ECUADOR, - CCODE_EGYPT, - CCODE_EL_SALVADOR, - CCODE_ESTONIA, - CCODE_FINLAND, - CCODE_FRANCE, - CCODE_GERMANY, - CCODE_GREECE, - CCODE_GEORGIA, - CCODE_GUATEMALA, - CCODE_HONDURAS, - CCODE_HONG_KONG, - CCODE_HUNGARY, - CCODE_ICELAND, - CCODE_INDIA, - CCODE_INDONESIA, - CCODE_IRAN, - CCODE_IRELAND, - CCODE_ITALY, - CCODE_ISRAEL, - CCODE_JAPAN, - CCODE_JORDAN, - CCODE_KAZAKHSTAN, - CCODE_KUWAIT, - CCODE_LATVIA, - CCODE_LEBANON, - CCODE_LEICHTENSTEIN, - CCODE_LITHUANIA, - CCODE_LUXEMBURG, - CCODE_MACAU, - CCODE_MACEDONIA, - CCODE_MALTA, - CCODE_MALAYSIA, - CCODE_MEXICO, - CCODE_MONACO, - CCODE_MOROCCO, - CCODE_NETHERLANDS, - CCODE_NEW_ZEALAND, - CCODE_NORTH_KOREA, - CCODE_NORWAY, - CCODE_OMAN, - CCODE_PAKISTAN, - CCODE_PANAMA, - CCODE_PERU, - CCODE_PHILIPPINES, - CCODE_POLAND, - CCODE_PORTUGAL, - CCODE_PUERTO_RICO, - CCODE_QATAR, - CCODE_ROMANIA, - CCODE_RUSSIA, - CCODE_SAUDI_ARABIA, - CCODE_SINGAPORE, - CCODE_SLOVAKIA, - CCODE_SLOVENIA, - CCODE_SOUTH_AFRICA, - CCODE_SOUTH_KOREA, - CCODE_SPAIN, - CCODE_SWEDEN, - CCODE_SWITZERLAND, - CCODE_SYRIA, - CCODE_TAIWAN, - CCODE_THAILAND, - CCODE_TRINIDAD_TOBAGO, - CCODE_TUNISIA, - CCODE_TURKEY, - CCODE_UK, - CCODE_UKRAINE, - CCODE_UNITED_ARAB_EMIRATES, - CCODE_UNITED_STATES, - CCODE_URUGUAY, - CCODE_UZBEKISTAN, - CCODE_VENEZUELA, - CCODE_VIETNAM, - CCODE_YEMEN, - CCODE_ZIMBABWE, - CCODE_JAPAN_W52_W53, - CCODE_MAX -} COUNTRY_CODE; - -#endif /* __COUNTRY_H__ */ diff --git a/drivers/staging/vt6655/datarate.c b/drivers/staging/vt6655/datarate.c deleted file mode 100644 index 52907a4fae9d..000000000000 --- a/drivers/staging/vt6655/datarate.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: datarate.c - * - * Purpose: Handles the auto fallback & data rates functions - * - * Author: Lyndon Chen - * - * Date: July 17, 2002 - * - * Functions: - * RATEvParseMaxRate - Parsing the highest basic & support rate in rate field of frame - * RATEvTxRateFallBack - Rate fallback Algorithm Implementaion - * RATEuSetIE- Set rate IE field. - * - * Revision History: - * - */ - -#include "ttype.h" -#include "tmacro.h" -#include "mac.h" -#include "80211mgr.h" -#include "bssdb.h" -#include "datarate.h" -#include "card.h" -#include "baseband.h" -#include "srom.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -extern unsigned short TxRate_iwconfig; /* 2008-5-8 <add> by chester */ -/*--------------------- Static Variables --------------------------*/ -static const unsigned char acbyIERate[MAX_RATE] = { -0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C -}; - -#define AUTORATE_TXOK_CNT 0x0400 -#define AUTORATE_TXFAIL_CNT 0x0064 -#define AUTORATE_TIMEOUT 10 - -/*--------------------- Static Functions --------------------------*/ - -void s_vResetCounter( - PKnownNodeDB psNodeDBTable -); - -void -s_vResetCounter( - PKnownNodeDB psNodeDBTable -) -{ - unsigned char ii; - - /* clear statistic counter for auto_rate */ - for (ii = 0; ii <= MAX_RATE; ii++) { - psNodeDBTable->uTxOk[ii] = 0; - psNodeDBTable->uTxFail[ii] = 0; - } -} - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -/*+ - * - * Description: - * Get RateIdx from the value in SuppRates IE or ExtSuppRates IE - * - * Parameters: - * In: - * unsigned char - Rate value in SuppRates IE or ExtSuppRates IE - * Out: - * none - * - * Return Value: RateIdx - * - -*/ -unsigned char -DATARATEbyGetRateIdx( - unsigned char byRate -) -{ - unsigned char ii; - - /* Erase basicRate flag. */ - byRate = byRate & 0x7F;/* 0111 1111 */ - - for (ii = 0; ii < MAX_RATE; ii++) { - if (acbyIERate[ii] == byRate) - return ii; - } - return 0; -} - -/*+ - * - * Routine Description: - * Rate fallback Algorithm Implementation - * - * Parameters: - * In: - * pDevice - Pointer to the adapter - * psNodeDBTable - Pointer to Node Data Base - * Out: - * none - * - * Return Value: none - * - -*/ -#define AUTORATE_TXCNT_THRESHOLD 20 -#define AUTORATE_INC_THRESHOLD 30 - -/*+ - * - * Description: - * Get RateIdx from the value in SuppRates IE or ExtSuppRates IE - * - * Parameters: - * In: - * unsigned char - Rate value in SuppRates IE or ExtSuppRates IE - * Out: - * none - * - * Return Value: RateIdx - * - -*/ -unsigned short -wGetRateIdx( - unsigned char byRate -) -{ - unsigned short ii; - - /* Erase basicRate flag. */ - byRate = byRate & 0x7F;/* 0111 1111 */ - - for (ii = 0; ii < MAX_RATE; ii++) { - if (acbyIERate[ii] == byRate) - return ii; - } - - return 0; -} - -/*+ - * - * Description: - * Parsing the highest basic & support rate in rate field of frame. - * - * Parameters: - * In: - * pDevice - Pointer to the adapter - * pItemRates - Pointer to Rate field defined in 802.11 spec. - * pItemExtRates - Pointer to Extended Rate field defined in 802.11 spec. - * Out: - * pwMaxBasicRate - Maximum Basic Rate - * pwMaxSuppRate - Maximum Supported Rate - * pbyTopCCKRate - Maximum Basic Rate in CCK mode - * pbyTopOFDMRate - Maximum Basic Rate in OFDM mode - * - * Return Value: none - * - -*/ -void -RATEvParseMaxRate( - void *pDeviceHandler, - PWLAN_IE_SUPP_RATES pItemRates, - PWLAN_IE_SUPP_RATES pItemExtRates, - bool bUpdateBasicRate, - unsigned short *pwMaxBasicRate, - unsigned short *pwMaxSuppRate, - unsigned short *pwSuppRate, - unsigned char *pbyTopCCKRate, - unsigned char *pbyTopOFDMRate -) -{ - struct vnt_private *pDevice = pDeviceHandler; - unsigned int ii; - unsigned char byHighSuppRate = 0; - unsigned char byRate = 0; - unsigned short wOldBasicRate = pDevice->wBasicRate; - unsigned int uRateLen; - - if (pItemRates == NULL) - return; - - *pwSuppRate = 0; - uRateLen = pItemRates->len; - - pr_debug("ParseMaxRate Len: %d\n", uRateLen); - if (pDevice->eCurrentPHYType != PHY_TYPE_11B) { - if (uRateLen > WLAN_RATES_MAXLEN) - uRateLen = WLAN_RATES_MAXLEN; - } else { - if (uRateLen > WLAN_RATES_MAXLEN_11B) - uRateLen = WLAN_RATES_MAXLEN_11B; - } - - for (ii = 0; ii < uRateLen; ii++) { - byRate = (unsigned char)(pItemRates->abyRates[ii]); - if (WLAN_MGMT_IS_BASICRATE(byRate) && bUpdateBasicRate) { - /* Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate */ - CARDbAddBasicRate((void *)pDevice, wGetRateIdx(byRate)); - pr_debug("ParseMaxRate AddBasicRate: %d\n", - wGetRateIdx(byRate)); - } - byRate = (unsigned char)(pItemRates->abyRates[ii]&0x7F); - if (byHighSuppRate == 0) - byHighSuppRate = byRate; - if (byRate > byHighSuppRate) - byHighSuppRate = byRate; - *pwSuppRate |= (1<<wGetRateIdx(byRate)); - } - if ((pItemExtRates != NULL) && (pItemExtRates->byElementID == WLAN_EID_EXTSUPP_RATES) && - (pDevice->eCurrentPHYType != PHY_TYPE_11B)) { - unsigned int uExtRateLen = pItemExtRates->len; - - if (uExtRateLen > WLAN_RATES_MAXLEN) - uExtRateLen = WLAN_RATES_MAXLEN; - - for (ii = 0; ii < uExtRateLen; ii++) { - byRate = (unsigned char)(pItemExtRates->abyRates[ii]); - /* select highest basic rate */ - if (WLAN_MGMT_IS_BASICRATE(pItemExtRates->abyRates[ii])) { - /* Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate */ - CARDbAddBasicRate((void *)pDevice, wGetRateIdx(byRate)); - pr_debug("ParseMaxRate AddBasicRate: %d\n", - wGetRateIdx(byRate)); - } - byRate = (unsigned char)(pItemExtRates->abyRates[ii]&0x7F); - if (byHighSuppRate == 0) - byHighSuppRate = byRate; - if (byRate > byHighSuppRate) - byHighSuppRate = byRate; - *pwSuppRate |= (1<<wGetRateIdx(byRate)); - } - } - - if ((pDevice->byPacketType == PK_TYPE_11GB) && CARDbIsOFDMinBasicRate((void *)pDevice)) - pDevice->byPacketType = PK_TYPE_11GA; - - *pbyTopCCKRate = pDevice->byTopCCKBasicRate; - *pbyTopOFDMRate = pDevice->byTopOFDMBasicRate; - *pwMaxSuppRate = wGetRateIdx(byHighSuppRate); - if ((pDevice->byPacketType == PK_TYPE_11B) || (pDevice->byPacketType == PK_TYPE_11GB)) - *pwMaxBasicRate = pDevice->byTopCCKBasicRate; - else - *pwMaxBasicRate = pDevice->byTopOFDMBasicRate; - if (wOldBasicRate != pDevice->wBasicRate) - CARDvSetRSPINF((void *)pDevice, pDevice->eCurrentPHYType); - - pr_debug("Exit ParseMaxRate\n"); -} - -/*+ - * - * Routine Description: - * Rate fallback Algorithm Implementaion - * - * Parameters: - * In: - * pDevice - Pointer to the adapter - * psNodeDBTable - Pointer to Node Data Base - * Out: - * none - * - * Return Value: none - * - -*/ -#define AUTORATE_TXCNT_THRESHOLD 20 -#define AUTORATE_INC_THRESHOLD 30 - -void -RATEvTxRateFallBack( - void *pDeviceHandler, - PKnownNodeDB psNodeDBTable -) -{ - struct vnt_private *pDevice = pDeviceHandler; - unsigned short wIdxDownRate = 0; - unsigned int ii; - bool bAutoRate[MAX_RATE] = {true, true, true, true, false, false, true, true, true, true, true, true}; - unsigned long dwThroughputTbl[MAX_RATE] = {10, 20, 55, 110, 60, 90, 120, 180, 240, 360, 480, 540}; - unsigned long dwThroughput = 0; - unsigned short wIdxUpRate = 0; - unsigned long dwTxDiff = 0; - - if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) - /* Don't do Fallback when scanning Channel */ - return; - - psNodeDBTable->uTimeCount++; - - if (psNodeDBTable->uTxFail[MAX_RATE] > psNodeDBTable->uTxOk[MAX_RATE]) - dwTxDiff = psNodeDBTable->uTxFail[MAX_RATE] - psNodeDBTable->uTxOk[MAX_RATE]; - - if ((psNodeDBTable->uTxOk[MAX_RATE] < AUTORATE_TXOK_CNT) && - (dwTxDiff < AUTORATE_TXFAIL_CNT) && - (psNodeDBTable->uTimeCount < AUTORATE_TIMEOUT)) { - return; - } - - if (psNodeDBTable->uTimeCount >= AUTORATE_TIMEOUT) - psNodeDBTable->uTimeCount = 0; - - for (ii = 0; ii < MAX_RATE; ii++) { - if (psNodeDBTable->wSuppRate & (0x0001<<ii)) { - if (bAutoRate[ii]) - wIdxUpRate = (unsigned short) ii; - - } else { - bAutoRate[ii] = false; - } - } - - for (ii = 0; ii <= psNodeDBTable->wTxDataRate; ii++) { - if ((psNodeDBTable->uTxOk[ii] != 0) || - (psNodeDBTable->uTxFail[ii] != 0)) { - dwThroughputTbl[ii] *= psNodeDBTable->uTxOk[ii]; - if (ii < RATE_11M) - psNodeDBTable->uTxFail[ii] *= 4; - - dwThroughputTbl[ii] /= (psNodeDBTable->uTxOk[ii] + psNodeDBTable->uTxFail[ii]); - } - } - dwThroughput = dwThroughputTbl[psNodeDBTable->wTxDataRate]; - - wIdxDownRate = psNodeDBTable->wTxDataRate; - for (ii = psNodeDBTable->wTxDataRate; ii > 0;) { - ii--; - if ((dwThroughputTbl[ii] > dwThroughput) && bAutoRate[ii]) { - dwThroughput = dwThroughputTbl[ii]; - wIdxDownRate = (unsigned short) ii; - } - } - psNodeDBTable->wTxDataRate = wIdxDownRate; - if (psNodeDBTable->uTxOk[MAX_RATE]) { - if (psNodeDBTable->uTxOk[MAX_RATE] > - (psNodeDBTable->uTxFail[MAX_RATE] * 4)) { - psNodeDBTable->wTxDataRate = wIdxUpRate; - } - } else { - /* adhoc, if uTxOk =0 & uTxFail = 0 */ - if (psNodeDBTable->uTxFail[MAX_RATE] == 0) - psNodeDBTable->wTxDataRate = wIdxUpRate; - } - - /* 2008-5-8 <add> by chester */ - TxRate_iwconfig = psNodeDBTable->wTxDataRate; - s_vResetCounter(psNodeDBTable); -} - -/*+ - * - * Description: - * This routine is used to assemble available Rate IE. - * - * Parameters: - * In: - * pDevice - * Out: - * - * Return Value: None - * - -*/ -unsigned char -RATEuSetIE( - PWLAN_IE_SUPP_RATES pSrcRates, - PWLAN_IE_SUPP_RATES pDstRates, - unsigned int uRateLen -) -{ - unsigned int ii, uu, uRateCnt = 0; - - if ((pSrcRates == NULL) || (pDstRates == NULL)) - return 0; - - if (pSrcRates->len == 0) - return 0; - - for (ii = 0; ii < uRateLen; ii++) { - for (uu = 0; uu < pSrcRates->len; uu++) { - if ((pSrcRates->abyRates[uu] & 0x7F) == acbyIERate[ii]) { - pDstRates->abyRates[uRateCnt++] = pSrcRates->abyRates[uu]; - break; - } - } - } - return (unsigned char)uRateCnt; -} diff --git a/drivers/staging/vt6655/datarate.h b/drivers/staging/vt6655/datarate.h deleted file mode 100644 index 0509c4fd2a42..000000000000 --- a/drivers/staging/vt6655/datarate.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: datarate.h - * - * Purpose: Handles the auto fallback & data rates functions - * - * Author: Lyndon Chen - * - * Date: July 16, 2002 - * - */ -#ifndef __DATARATE_H__ -#define __DATARATE_H__ - -#define FALLBACK_PKT_COLLECT_TR_H 50 -#define FALLBACK_PKT_COLLECT_TR_L 10 -#define FALLBACK_POLL_SECOND 5 -#define FALLBACK_RECOVER_SECOND 30 -#define FALLBACK_THRESHOLD 15 -#define UPGRADE_THRESHOLD 5 -#define UPGRADE_CNT_THRD 3 -#define RETRY_TIMES_THRD_H 2 -#define RETRY_TIMES_THRD_L 1 - -void -RATEvParseMaxRate( - void *pDeviceHandler, - PWLAN_IE_SUPP_RATES pItemRates, - PWLAN_IE_SUPP_RATES pItemExtRates, - bool bUpdateBasicRate, - unsigned short *pwMaxBasicRate, - unsigned short *pwMaxSuppRate, - unsigned short *pwSuppRate, - unsigned char *pbyTopCCKRate, - unsigned char *pbyTopOFDMRate -); - -void -RATEvTxRateFallBack( - void *pDeviceHandler, - PKnownNodeDB psNodeDBTable -); - -unsigned char -RATEuSetIE( - PWLAN_IE_SUPP_RATES pSrcRates, - PWLAN_IE_SUPP_RATES pDstRates, - unsigned int uRateLen -); - -unsigned short -wGetRateIdx( - unsigned char byRate -); - -unsigned char -DATARATEbyGetRateIdx( - unsigned char byRate -); - -#endif //__DATARATE_H__ diff --git a/drivers/staging/vt6655/desc.h b/drivers/staging/vt6655/desc.h index 5a2bbd2047d8..758eeb2afd51 100644 --- a/drivers/staging/vt6655/desc.h +++ b/drivers/staging/vt6655/desc.h @@ -34,44 +34,34 @@ #include <linux/types.h> #include <linux/mm.h> #include "linux/ieee80211.h" -#include "ttype.h" -#include "tether.h" #define B_OWNED_BY_CHIP 1 #define B_OWNED_BY_HOST 0 -// -// Bits in the RSR register -// +/* Bits in the RSR register */ #define RSR_ADDRBROAD 0x80 #define RSR_ADDRMULTI 0x40 #define RSR_ADDRUNI 0x00 #define RSR_IVLDTYP 0x20 -#define RSR_IVLDLEN 0x10 // invalid len (> 2312 byte) +#define RSR_IVLDLEN 0x10 /* invalid len (> 2312 byte) */ #define RSR_BSSIDOK 0x08 #define RSR_CRCOK 0x04 #define RSR_BCNSSIDOK 0x02 #define RSR_ADDROK 0x01 -// -// Bits in the new RSR register -// +/* Bits in the new RSR register */ #define NEWRSR_DECRYPTOK 0x10 #define NEWRSR_CFPIND 0x08 #define NEWRSR_HWUTSF 0x04 #define NEWRSR_BCNHITAID 0x02 #define NEWRSR_BCNHITAID0 0x01 -// -// Bits in the TSR0 register -// +/* Bits in the TSR0 register */ #define TSR0_PWRSTS1_2 0xC0 #define TSR0_PWRSTS7 0x20 #define TSR0_NCR 0x1F -// -// Bits in the TSR1 register -// +/* Bits in the TSR1 register */ #define TSR1_TERR 0x80 #define TSR1_PWRSTS4_6 0x70 #define TSR1_RETRYTMO 0x08 @@ -79,16 +69,14 @@ #define TSR1_PWRSTS3 0x02 #define ACK_DATA 0x01 -// -// Bits in the TCR register -// -#define EDMSDU 0x04 // end of sdu -#define TCR_EDP 0x02 // end of packet -#define TCR_STP 0x01 // start of packet +/* Bits in the TCR register */ +#define EDMSDU 0x04 /* end of sdu */ +#define TCR_EDP 0x02 /* end of packet */ +#define TCR_STP 0x01 /* start of packet */ -// max transmit or receive buffer size +/* max transmit or receive buffer size */ #define CB_MAX_BUF_SIZE 2900U - // NOTE: must be multiple of 4 + /* NOTE: must be multiple of 4 */ #define CB_MAX_TX_BUF_SIZE CB_MAX_BUF_SIZE #define CB_MAX_RX_BUF_SIZE_NORMAL CB_MAX_BUF_SIZE @@ -100,18 +88,21 @@ #define CB_MIN_TX_DESC 16 #define CB_MAX_RECEIVED_PACKETS 16 - // limit our receive routine to indicating - // this many at a time for 2 reasons: - // 1. driver flow control to protocol layer - // 2. limit the time used in ISR routine + /* + * limit our receive routine to indicating + * this many at a time for 2 reasons: + * 1. driver flow control to protocol layer + * 2. limit the time used in ISR routine + */ #define CB_EXTRA_RD_NUM 32 #define CB_RD_NUM 32 #define CB_TD_NUM 32 -// max number of physical segments -// in a single NDIS packet. Above this threshold, the packet -// is copied into a single physically contiguous buffer +/* + * max number of physical segments in a single NDIS packet. Above this + * threshold, the packet is copied into a single physically contiguous buffer + */ #define CB_MAX_SEGMENT 4 #define CB_MIN_MAP_REG_NUM 4 @@ -119,42 +110,13 @@ #define CB_PROTOCOL_RESERVED_SECTION 16 -// if retrys excess 15 times , tx will abort, and -// if tx fifo underflow, tx will fail -// we should try to resend it +/* + * if retrys excess 15 times , tx will abort, and if tx fifo underflow, + * tx will fail, we should try to resend it + */ #define CB_MAX_TX_ABORT_RETRY 3 -#ifdef __BIG_ENDIAN - -// WMAC definition FIFO Control -#define FIFOCTL_AUTO_FB_1 0x0010 -#define FIFOCTL_AUTO_FB_0 0x0008 -#define FIFOCTL_GRPACK 0x0004 -#define FIFOCTL_11GA 0x0003 -#define FIFOCTL_11GB 0x0002 -#define FIFOCTL_11B 0x0001 -#define FIFOCTL_11A 0x0000 -#define FIFOCTL_RTS 0x8000 -#define FIFOCTL_ISDMA0 0x4000 -#define FIFOCTL_GENINT 0x2000 -#define FIFOCTL_TMOEN 0x1000 -#define FIFOCTL_LRETRY 0x0800 -#define FIFOCTL_CRCDIS 0x0400 -#define FIFOCTL_NEEDACK 0x0200 -#define FIFOCTL_LHEAD 0x0100 - -//WMAC definition Frag Control -#define FRAGCTL_AES 0x0003 -#define FRAGCTL_TKIP 0x0002 -#define FRAGCTL_LEGACY 0x0001 -#define FRAGCTL_NONENCRYPT 0x0000 -#define FRAGCTL_ENDFRAG 0x0300 -#define FRAGCTL_MIDFRAG 0x0200 -#define FRAGCTL_STAFRAG 0x0100 -#define FRAGCTL_NONFRAG 0x0000 - -#else - +/* WMAC definition FIFO Control */ #define FIFOCTL_AUTO_FB_1 0x1000 #define FIFOCTL_AUTO_FB_0 0x0800 #define FIFOCTL_GRPACK 0x0400 @@ -171,7 +133,7 @@ #define FIFOCTL_NEEDACK 0x0002 #define FIFOCTL_LHEAD 0x0001 -//WMAC definition Frag Control +/* WMAC definition Frag Control */ #define FRAGCTL_AES 0x0300 #define FRAGCTL_TKIP 0x0200 #define FRAGCTL_LEGACY 0x0100 @@ -181,8 +143,6 @@ #define FRAGCTL_STAFRAG 0x0001 #define FRAGCTL_NONFRAG 0x0000 -#endif - #define TYPE_TXDMA0 0 #define TYPE_AC0DMA 1 #define TYPE_ATIMDMA 2 @@ -195,14 +155,17 @@ #define TYPE_RXDMA1 1 #define TYPE_MAXRD 2 -// TD_INFO flags control bit -#define TD_FLAGS_NETIF_SKB 0x01 // check if need release skb -#define TD_FLAGS_PRIV_SKB 0x02 // check if called from private skb(hostap) -#define TD_FLAGS_PS_RETRY 0x04 // check if PS STA frame re-transmit +/* TD_INFO flags control bit */ +#define TD_FLAGS_NETIF_SKB 0x01 /* check if need release skb */ +#define TD_FLAGS_PRIV_SKB 0x02 /* check if called from private skb (hostap) */ +#define TD_FLAGS_PS_RETRY 0x04 /* check if PS STA frame re-transmit */ -// ref_sk_buff is used for mapping the skb structure between pre-built driver-obj & running kernel. -// Since different kernel version (2.4x) may change skb structure, i.e. pre-built driver-obj -// may link to older skb that leads error. +/* + * ref_sk_buff is used for mapping the skb structure between pre-built + * driver-obj & running kernel. Since different kernel version (2.4x) may + * change skb structure, i.e. pre-built driver-obj may link to older skb that + * leads error. + */ typedef struct tagDEVICE_RD_INFO { struct sk_buff *skb; @@ -242,9 +205,7 @@ typedef struct tagRDES1 { } __attribute__ ((__packed__)) SRDES1; -// -// Rx descriptor -// +/* Rx descriptor*/ typedef struct tagSRxDesc { volatile SRDES0 m_rd0RD0; volatile SRDES1 m_rd1RD1; @@ -292,6 +253,7 @@ typedef struct tagTDES1 { STDES1; typedef struct tagDEVICE_TD_INFO { + void *mic_hdr; struct sk_buff *skb; unsigned char *buf; dma_addr_t skb_dma; @@ -302,9 +264,7 @@ typedef struct tagDEVICE_TD_INFO { unsigned char byFlags; } DEVICE_TD_INFO, *PDEVICE_TD_INFO; -// -// transmit descriptor -// +/* transmit descriptor */ typedef struct tagSTxDesc { volatile STDES0 m_td0TD0; volatile STDES1 m_td1TD1; @@ -319,8 +279,8 @@ typedef const STxDesc *PCSTxDesc; typedef struct tagSTxSyncDesc { volatile STDES0 m_td0TD0; volatile STDES1 m_td1TD1; - volatile u32 buff_addr; // pointer to logical buffer - volatile u32 next_desc; // pointer to next logical descriptor + volatile u32 buff_addr; /* pointer to logical buffer */ + volatile u32 next_desc; /* pointer to next logical descriptor */ volatile unsigned short m_wFIFOCtl; volatile unsigned short m_wTimeStamp; struct tagSTxSyncDesc *next __aligned(8); @@ -329,9 +289,7 @@ typedef struct tagSTxSyncDesc { STxSyncDesc, *PSTxSyncDesc; typedef const STxSyncDesc *PCSTxSyncDesc; -// -// RsvTime buffer header -// +/* RsvTime buffer header */ typedef struct tagSRrvTime_atim { unsigned short wCTSTxRrvTime_ba; unsigned short wTxRrvTime_a; @@ -352,9 +310,7 @@ union vnt_phy_field_swap { u32 field_write; }; -// -// Tx FIFO header -// +/* Tx FIFO header */ typedef struct tagSTxBufHead { u32 adwTxKey[4]; unsigned short wFIFOCtl; @@ -392,4 +348,4 @@ typedef struct tagSKeyEntry { } __attribute__ ((__packed__)) SKeyEntry; -#endif // __DESC_H__ +#endif /* __DESC_H__ */ diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index ddd356aa7eaf..83efbfb57c79 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -50,40 +50,47 @@ #include <linux/io.h> #include <linux/if.h> #include <linux/crc32.h> -//#include <linux/config.h> #include <linux/uaccess.h> #include <linux/proc_fs.h> #include <linux/inetdevice.h> #include <linux/reboot.h> #include <linux/ethtool.h> /* Include Wireless Extension definition and check version - Jean II */ +#include <net/mac80211.h> #include <linux/wireless.h> -#include <net/iw_handler.h> // New driver API +#include <net/iw_handler.h> /* New driver API */ -//2008-0409-07, <Add> by Einsn Liu #ifndef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT #define WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT #endif -// -// device specific -// +/* device specific */ #include "device_cfg.h" -#include "ttype.h" -#include "80211hdr.h" -#include "tether.h" -#include "wmgr.h" -#include "wcmd.h" +#include "card.h" #include "mib.h" #include "srom.h" -#include "rc4.h" #include "desc.h" #include "key.h" #include "mac.h" /*--------------------- Export Definitions -------------------------*/ +#define RATE_1M 0 +#define RATE_2M 1 +#define RATE_5M 2 +#define RATE_11M 3 +#define RATE_6M 4 +#define RATE_9M 5 +#define RATE_12M 6 +#define RATE_18M 7 +#define RATE_24M 8 +#define RATE_36M 9 +#define RATE_48M 10 +#define RATE_54M 11 +#define RATE_AUTO 12 +#define MAX_RATE 12 + #define MAC_MAX_CONTEXT_REG (256+128) #define MAX_MULTICAST_ADDRESS_NUM 32 @@ -112,7 +119,7 @@ #define FB_RATE0 0 #define FB_RATE1 1 -// Antenna Mode +/* Antenna Mode */ #define ANT_A 0 #define ANT_B 1 #define ANT_DIVERSITY 2 @@ -129,120 +136,28 @@ #define RUN_AT(x) (jiffies+(x)) #endif -// DMA related +#define MAKE_BEACON_RESERVED 10 /* (us) */ + +/* DMA related */ #define RESERV_AC0DMA 4 -// BUILD OBJ mode +/* BUILD OBJ mode */ #define AVAIL_TD(p, q) ((p)->sOpts.nTxDescs[(q)] - ((p)->iTDUsed[(q)])) #define NUM 64 -#define PRIVATE_Message 0 - -/*--------------------- Export Types ------------------------------*/ - -#define PRINT_K(p, args...) \ -do { \ - if (PRIVATE_Message) \ - printk(p, ##args); \ -} while (0) +/* 0:11A 1:11B 2:11G */ +#define BB_TYPE_11A 0 +#define BB_TYPE_11B 1 +#define BB_TYPE_11G 2 -//0:11A 1:11B 2:11G -typedef enum _VIA_BB_TYPE -{ - BB_TYPE_11A = 0, - BB_TYPE_11B, - BB_TYPE_11G -} VIA_BB_TYPE, *PVIA_BB_TYPE; - -//0:11a,1:11b,2:11gb(only CCK in BasicRate),3:11ga(OFDM in Basic Rate) -typedef enum _VIA_PKT_TYPE -{ - PK_TYPE_11A = 0, - PK_TYPE_11B, - PK_TYPE_11GB, - PK_TYPE_11GA -} VIA_PKT_TYPE, *PVIA_PKT_TYPE; - -typedef enum __device_msg_level { - MSG_LEVEL_ERR = 0, //Errors that will cause abnormal operation. - MSG_LEVEL_NOTICE = 1, //Some errors need users to be notified. - MSG_LEVEL_INFO = 2, //Normal message. - MSG_LEVEL_VERBOSE = 3, //Will report all trival errors. - MSG_LEVEL_DEBUG = 4 //Only for debug purpose. -} DEVICE_MSG_LEVEL, *PDEVICE_MSG_LEVEL; - -//++ NDIS related - -#define MAX_BSSIDINFO_4_PMKID 16 -#define MAX_PMKIDLIST 5 -//Flags for PMKID Candidate list structure -#define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01 - -// PMKID Structures -typedef unsigned char NDIS_802_11_PMKID_VALUE[16]; - -typedef enum _NDIS_802_11_WEP_STATUS { - Ndis802_11WEPEnabled, - Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, - Ndis802_11WEPDisabled, - Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, - Ndis802_11WEPKeyAbsent, - Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, - Ndis802_11WEPNotSupported, - Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, - Ndis802_11Encryption2Enabled, - Ndis802_11Encryption2KeyAbsent, - Ndis802_11Encryption3Enabled, - Ndis802_11Encryption3KeyAbsent -} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS, - NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS; - -typedef enum _NDIS_802_11_STATUS_TYPE { - Ndis802_11StatusType_Authentication, - Ndis802_11StatusType_MediaStreamMode, - Ndis802_11StatusType_PMKID_CandidateList, - Ndis802_11StatusTypeMax // not a real type, defined as an upper bound -} NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE; - -//Added new types for PMKID Candidate lists. -struct pmkid_candidate { - NDIS_802_11_MAC_ADDRESS BSSID; - unsigned long Flags; -}; +/* 0:11a, 1:11b, 2:11gb (only CCK in BasicRate), 3:11ga (OFDM in BasicRate) */ +#define PK_TYPE_11A 0 +#define PK_TYPE_11B 1 +#define PK_TYPE_11GB 2 +#define PK_TYPE_11GA 3 -typedef struct _BSSID_INFO { - NDIS_802_11_MAC_ADDRESS BSSID; - NDIS_802_11_PMKID_VALUE PMKID; -} BSSID_INFO, *PBSSID_INFO; - -typedef struct tagSPMKID { - unsigned long Length; - unsigned long BSSIDInfoCount; - BSSID_INFO BSSIDInfo[MAX_BSSIDINFO_4_PMKID]; -} SPMKID, *PSPMKID; - -typedef struct tagSPMKIDCandidateEvent { - NDIS_802_11_STATUS_TYPE StatusType; - unsigned long Version; // Version of the structure - unsigned long NumCandidates; // No. of pmkid candidates - struct pmkid_candidate CandidateList[MAX_PMKIDLIST]; -} SPMKIDCandidateEvent, *PSPMKIDCandidateEvent; - -//-- - -//++ 802.11h related -#define MAX_QUIET_COUNT 8 - -typedef struct tagSQuietControl { - bool bEnable; - unsigned long dwStartTime; - unsigned char byPeriod; - unsigned short wDuration; -} SQuietControl, *PSQuietControl; - -//-- typedef struct __chip_info_tbl { CHIP_TYPE chip_id; char *name; @@ -256,34 +171,7 @@ typedef enum { OWNED_BY_NIC = 1 } DEVICE_OWNER_TYPE, *PDEVICE_OWNER_TYPE; -// The receive duplicate detection cache entry -typedef struct tagSCacheEntry { - unsigned short wFmSequence; - unsigned char abyAddr2[ETH_ALEN]; -} SCacheEntry, *PSCacheEntry; - -typedef struct tagSCache { -/* The receive cache is updated circularly. The next entry to be written is - * indexed by the "InPtr". - */ - unsigned int uInPtr; // Place to use next - SCacheEntry asCacheEntry[DUPLICATE_RX_CACHE_LENGTH]; -} SCache, *PSCache; - -#define CB_MAX_RX_FRAG 64 -// DeFragment Control Block, used for collecting fragments prior to reassembly -typedef struct tagSDeFragControlBlock { - unsigned short wSequence; - unsigned short wFragNum; - unsigned char abyAddr2[ETH_ALEN]; - unsigned int uLifetime; - struct sk_buff *skb; - unsigned char *pbyRxBuffer; - unsigned int cbFrameLength; - bool bInUse; -} SDeFragControlBlock, *PSDeFragControlBlock; - -//flags for options +/* flags for options */ #define DEVICE_FLAGS_IP_ALIGN 0x00000001UL #define DEVICE_FLAGS_PREAMBLE_TYPE 0x00000002UL #define DEVICE_FLAGS_OP_MODE 0x00000004UL @@ -291,15 +179,15 @@ typedef struct tagSDeFragControlBlock { #define DEVICE_FLAGS_80211h_MODE 0x00000010UL #define DEVICE_FLAGS_DiversityANT 0x00000020UL -//flags for driver status +/* flags for driver status */ #define DEVICE_FLAGS_OPENED 0x00010000UL #define DEVICE_FLAGS_WOL_ENABLED 0x00080000UL -//flags for capabilities +/* flags for capabilities */ #define DEVICE_FLAGS_TX_ALIGN 0x01000000UL #define DEVICE_FLAGS_HAVE_CAM 0x02000000UL #define DEVICE_FLAGS_FLOW_CTRL 0x04000000UL -//flags for MII status +/* flags for MII status */ #define DEVICE_LINK_FAIL 0x00000001UL #define DEVICE_SPEED_10 0x00000002UL #define DEVICE_SPEED_100 0x00000004UL @@ -307,18 +195,14 @@ typedef struct tagSDeFragControlBlock { #define DEVICE_DUPLEX_FULL 0x00000010UL #define DEVICE_AUTONEG_ENABLE 0x00000020UL #define DEVICE_FORCED_BY_EEPROM 0x00000040UL -//for device_set_media_duplex +/* for device_set_media_duplex */ #define DEVICE_LINK_CHANGE 0x00000001UL typedef struct __device_opt { - int nRxDescs0; //Number of RX descriptors0 - int nRxDescs1; //Number of RX descriptors1 - int nTxDescs[2]; //Number of TX descriptors 0, 1 - int int_works; //interrupt limits - int rts_thresh; //rts threshold - int frag_thresh; - int data_rate; - int channel_num; + int nRxDescs0; /* Number of RX descriptors0 */ + int nRxDescs1; /* Number of RX descriptors1 */ + int nTxDescs[2]; /* Number of TX descriptors 0, 1 */ + int int_works; /* interrupt limits */ int short_retry; int long_retry; int bbp_type; @@ -327,11 +211,16 @@ typedef struct __device_opt { struct vnt_private { struct pci_dev *pcid; - -// netdev - struct net_device *dev; - -//dma addr, rx/tx pool + /* mac80211 */ + struct ieee80211_hw *hw; + struct ieee80211_vif *vif; + unsigned long key_entry_inuse; + u32 basic_rates; + u16 current_aid; + int mc_list_count; + u8 mac_hw; + +/* dma addr, rx/tx pool */ dma_addr_t pool_dma; dma_addr_t rd0_pool_dma; dma_addr_t rd1_pool_dma; @@ -356,9 +245,12 @@ struct vnt_private { u32 io_size; unsigned char byRevId; + unsigned char byRxMode; unsigned short SubSystemID; unsigned short SubVendorID; + spinlock_t lock; + int nTxQueues; volatile int iTDUsed[TYPE_MAXTD]; @@ -371,30 +263,18 @@ struct vnt_private { volatile PSRxDesc aRD0Ring; volatile PSRxDesc aRD1Ring; volatile PSRxDesc pCurrRD[TYPE_MAXRD]; - SCache sDupRxCache; - - SDeFragControlBlock sRxDFCB[CB_MAX_RX_FRAG]; - unsigned int cbDFCB; - unsigned int cbFreeDFCB; - unsigned int uCurrentDFCBIdx; OPTIONS sOpts; u32 flags; u32 rx_buf_sz; + u8 rx_rate; int multicast_limit; - unsigned char byRxMode; - - spinlock_t lock; - - pid_t MLMEThr_pid; - struct completion notify; - struct semaphore mlme_semaphore; u32 rx_bytes; - // Version control + /* Version control */ unsigned char byLocalID; unsigned char byRFType; @@ -402,20 +282,15 @@ struct vnt_private { unsigned char byZoneType; bool bZoneRegExist; unsigned char byOriginalZonetype; - unsigned char abyMacContext[MAC_MAX_CONTEXT_REG]; - bool bLinkPass; // link status: OK or fail - unsigned char abyCurrentNetAddr[ETH_ALEN]; - // Adapter statistics + unsigned char abyCurrentNetAddr[ETH_ALEN]; __aligned(2) + bool bLinkPass; /* link status: OK or fail */ + + /* Adapter statistics */ SStatCounter scStatistic; - // 802.11 counter + /* 802.11 counter */ SDot11Counters s802_11Counter; - // 802.11 management - PSMgmtObject pMgmt; - SMgmtObject sMgmtObj; - - // 802.11 MAC specific unsigned int uCurrRSSI; unsigned char byCurrSQ; @@ -427,22 +302,25 @@ struct vnt_private { bool bTxRxAntInv; unsigned char *pbyTmpBuff; - unsigned int uSIFS; //Current SIFS - unsigned int uDIFS; //Current DIFS - unsigned int uEIFS; //Current EIFS - unsigned int uSlot; //Current SlotTime - unsigned int uCwMin; //Current CwMin - unsigned int uCwMax; //CwMax is fixed on 1023. - // PHY parameter + unsigned int uSIFS; /* Current SIFS */ + unsigned int uDIFS; /* Current DIFS */ + unsigned int uEIFS; /* Current EIFS */ + unsigned int uSlot; /* Current SlotTime */ + unsigned int uCwMin; /* Current CwMin */ + unsigned int uCwMax; /* CwMax is fixed on 1023. */ + /* PHY parameter */ unsigned char bySIFS; unsigned char byDIFS; unsigned char byEIFS; unsigned char bySlot; unsigned char byCWMaxMin; - CARD_PHY_TYPE eCurrentPHYType; - VIA_BB_TYPE byBBType; //0: 11A, 1:11B, 2:11G - VIA_PKT_TYPE byPacketType; //0:11a,1:11b,2:11gb(only CCK in BasicRate),3:11ga(OFDM in Basic Rate) + u8 byBBType; /* 0:11A, 1:11B, 2:11G */ + u8 byPacketType; /* + * 0:11a,1:11b,2:11gb (only CCK + * in BasicRate), 3:11ga (OFDM in + * Basic Rate) + */ unsigned short wBasicRate; unsigned char byACKRate; unsigned char byTopOFDMBasicRate; @@ -450,28 +328,16 @@ struct vnt_private { unsigned char byMinChannel; unsigned char byMaxChannel; - unsigned int uConnectionRate; unsigned char byPreambleType; unsigned char byShortPreamble; unsigned short wCurrentRate; - unsigned short wRTSThreshold; - unsigned short wFragmentationThreshold; unsigned char byShortRetryLimit; unsigned char byLongRetryLimit; enum nl80211_iftype op_mode; - unsigned char byOpMode; bool bBSSIDFilter; unsigned short wMaxTransmitMSDULifetime; - unsigned char abyBSSID[ETH_ALEN]; - unsigned char abyDesireBSSID[ETH_ALEN]; - unsigned short wACKDuration; // update while speed change - unsigned short wRTSTransmitLen; // update while speed change - unsigned char byRTSServiceField; // update while speed change - unsigned char byRTSSignalField; // update while speed change - - unsigned long dwMaxReceiveLifetime; // dot11MaxReceiveLifetime bool bEncryptionEnable; bool bLongHeader; @@ -480,24 +346,20 @@ struct vnt_private { bool bNonERPPresent; bool bBarkerPreambleMd; - unsigned char byERPFlag; - unsigned short wUseProtectCntDown; - bool bRadioControlOff; bool bRadioOff; bool bEnablePSMode; unsigned short wListenInterval; bool bPWBitOn; - WMAC_POWER_MODE ePSMode; - // GPIO Radio Control + /* GPIO Radio Control */ unsigned char byRadioCtl; unsigned char byGPIO; bool bHWRadioOff; bool bPrvActive4RadioOFF; bool bGPIOBlockRead; - // Beacon related + /* Beacon related */ unsigned short wSeqCounter; unsigned short wBCNBufLen; bool bBeaconBufReady; @@ -506,71 +368,12 @@ struct vnt_private { unsigned int cbBeaconBufReadySetCnt; bool bFixRate; unsigned char byCurrentCh; - unsigned int uScanTime; - - CMD_STATE eCommandState; - - CMD_CODE eCommand; - bool bBeaconTx; - - bool bStopBeacon; - bool bStopDataPkt; - bool bStopTx0Pkt; - unsigned int uAutoReConnectTime; - - // 802.11 counter - - CMD_ITEM eCmdQueue[CMD_Q_SIZE]; - unsigned int uCmdDequeueIdx; - unsigned int uCmdEnqueueIdx; - unsigned int cbFreeCmdQueue; - bool bCmdRunning; - bool bCmdClear; - - bool bRoaming; - //WOW - unsigned char abyIPAddr[4]; - - unsigned long ulTxPower; - NDIS_802_11_WEP_STATUS eEncryptionStatus; - bool bTransmitKey; -//2007-0925-01<Add>by MikeLiu -//mike add :save old Encryption - NDIS_802_11_WEP_STATUS eOldEncryptionStatus; - - SKeyManagement sKey; - unsigned long dwIVCounter; - - u64 qwPacketNumber; /* For CCMP and TKIP as TSC(6 bytes) */ - unsigned int uCurrentWEPMode; - - RC4Ext SBox; - unsigned char abyPRNG[WLAN_WEPMAX_KEYLEN+3]; - unsigned char byKeyIndex; - unsigned int uKeyLength; - unsigned char abyKey[WLAN_WEP232_KEYLEN]; bool bAES; - unsigned char byCntMeasure; - - // for AP mode - unsigned int uAssocCount; - bool bMoreData; - - // QoS - bool bGrpAckPolicy; - - // for OID_802_11_ASSOCIATION_INFORMATION - bool bAssocInfoSet; unsigned char byAutoFBCtrl; - bool bTxMICFail; - bool bRxMICFail; - - unsigned int uRATEIdx; - - // For Update BaseBand VGA Gain Offset + /* For Update BaseBand VGA Gain Offset */ bool bUpdateBBVGA; unsigned int uBBVGADiffCount; unsigned char byBBVGANew; @@ -581,24 +384,12 @@ struct vnt_private { unsigned char byBBPreEDRSSI; unsigned char byBBPreEDIndex; - bool bRadioCmd; unsigned long dwDiagRefCount; - // For FOE Tuning + /* For FOE Tuning */ unsigned char byFOETuning; - // For Auto Power Tunning - - unsigned char byAutoPwrTunning; - short sPSetPointCCK; - short sPSetPointOFDMG; - short sPSetPointOFDMA; - long lPFormulaOffset; - short sPThreshold; - char cAdjustStep; - char cMinTxAGC; - - // For RF Power table + /* For RF Power table */ unsigned char byCCKPwr; unsigned char byOFDMPwrG; unsigned char byCurPwr; @@ -610,27 +401,12 @@ struct vnt_private { char abyRegPwr[CB_MAX_CHANNEL+1]; char abyLocalPwr[CB_MAX_CHANNEL+1]; - // BaseBand Loopback Use + /* BaseBand Loopback Use */ unsigned char byBBCR4d; unsigned char byBBCRc9; unsigned char byBBCR88; unsigned char byBBCR09; - // command timer - struct timer_list sTimerCommand; - struct timer_list sTimerTxData; - unsigned long nTxDataTimeCout; - bool fTxDataInSleep; - bool IsTxDataTrigger; - -#ifdef WPA_SM_Transtatus - bool fWPA_Authened; //is WPA/WPA-PSK or WPA2/WPA2-PSK authen?? -#endif - unsigned char byReAssocCount; //mike add:re-association retry times! - unsigned char byLinkWaitCount; - - unsigned char abyNodeName[17]; - bool bDiversityRegCtlON; bool bDiversityEnable; unsigned long ulDiversityNValue; @@ -640,13 +416,13 @@ struct vnt_private { unsigned char byTMax3; unsigned long ulSQ3TH; -// ANT diversity + /* ANT diversity */ unsigned long uDiversityCnt; unsigned char byAntennaState; unsigned long ulRatio_State0; unsigned long ulRatio_State1; - //SQ3 functions for antenna diversity + /* SQ3 functions for antenna diversity */ struct timer_list TimerSQ3Tmax1; struct timer_list TimerSQ3Tmax2; struct timer_list TimerSQ3Tmax3; @@ -654,86 +430,11 @@ struct vnt_private { unsigned long uNumSQ3[MAX_RATE]; unsigned short wAntDiversityMaxRate; - SEthernetHeader sTxEthHeader; - SEthernetHeader sRxEthHeader; - unsigned char abyBroadcastAddr[ETH_ALEN]; - unsigned char abySNAP_RFC1042[ETH_ALEN]; - unsigned char abySNAP_Bridgetunnel[ETH_ALEN]; - unsigned char abyEEPROM[EEP_MAX_CONTEXT_SIZE]; //unsigned long alignment - // Pre-Authentication & PMK cache - SPMKID gsPMKID; - SPMKIDCandidateEvent gsPMKIDCandidate; - - // for 802.11h - bool b11hEnable; - unsigned char abyCountryCode[3]; - // for 802.11h DFS - unsigned int uNumOfMeasureEIDs; - PWLAN_IE_MEASURE_REQ pCurrMeasureEID; - bool bMeasureInProgress; - unsigned char byOrgChannel; - unsigned char byOrgRCR; - unsigned long dwOrgMAR0; - unsigned long dwOrgMAR4; - unsigned char byBasicMap; - unsigned char byCCAFraction; - unsigned char abyRPIs[8]; - unsigned long dwRPIs[8]; - bool bChannelSwitch; - unsigned char byNewChannel; - unsigned char byChannelSwitchCount; - bool bQuietEnable; - bool bEnableFirstQuiet; - unsigned char byQuietStartCount; - unsigned int uQuietEnqueue; - unsigned long dwCurrentQuietEndTime; - SQuietControl sQuiet[MAX_QUIET_COUNT]; - // for 802.11h TPC - bool bCountryInfo5G; - bool bCountryInfo24G; + unsigned char abyEEPROM[EEP_MAX_CONTEXT_SIZE]; /* unsigned long alignment */ unsigned short wBeaconInterval; - - //WPA supplicant deamon - struct net_device *wpadev; - bool bWPADEVUp; - struct sk_buff *skb; -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - unsigned int bwextcount; - bool bWPASuppWextEnabled; -#endif - - //-- -#ifdef HOSTAP - // user space daemon: hostapd, is used for HOSTAP - bool bEnableHostapd; - bool bEnable8021x; - bool bEnableHostWEP; - struct net_device *apdev; - int (*tx_80211)(struct sk_buff *skb, struct net_device *dev); -#endif - unsigned int uChannel; - bool bMACSuspend; - - struct iw_statistics wstats; // wireless stats - bool bCommit; }; -static inline bool device_get_ip(struct vnt_private *pInfo) -{ - struct in_device *in_dev = (struct in_device *)pInfo->dev->ip_ptr; - struct in_ifaddr *ifa; - - if (in_dev != NULL) { - ifa = (struct in_ifaddr *)in_dev->ifa_list; - if (ifa != NULL) { - memcpy(pInfo->abyIPAddr, &ifa->ifa_address, 4); - return true; - } - } - return false; -} - static inline PDEVICE_RD_INFO alloc_rd_info(void) { return kzalloc(sizeof(DEVICE_RD_INFO), GFP_ATOMIC); @@ -743,13 +444,4 @@ static inline PDEVICE_TD_INFO alloc_td_info(void) { return kzalloc(sizeof(DEVICE_TD_INFO), GFP_ATOMIC); } - -/*--------------------- Export Functions --------------------------*/ - -bool device_dma0_xmit(struct vnt_private *pDevice, - struct sk_buff *skb, unsigned int uNodeIndex); -bool device_alloc_frag_buf(struct vnt_private *pDevice, - PSDeFragControlBlock pDeF); -int Config_FileOperation(struct vnt_private *pDevice, - bool fwrite, unsigned char *Parameter); #endif diff --git a/drivers/staging/vt6655/device_cfg.h b/drivers/staging/vt6655/device_cfg.h index 7221824e4f23..a4a8a8489e0b 100644 --- a/drivers/staging/vt6655/device_cfg.h +++ b/drivers/staging/vt6655/device_cfg.h @@ -29,8 +29,6 @@ #include <linux/types.h> -#include "ttype.h" - typedef struct _version { unsigned char major; diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 54e16f40d8ed..cd1a277d853b 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -32,27 +32,16 @@ * device_free_info - device structure resource free function * device_get_pci_info - get allocated pci io/mem resource * device_print_info - print out resource - * device_open - allocate dma/descripter resource & initial mac/bbp function - * device_xmit - asynchrous data tx function * device_intr - interrupt handle function - * device_set_multi - set mac filter - * device_ioctl - ioctl entry - * device_close - shutdown mac/bbp & free dma/descripter resource * device_rx_srv - rx service function - * device_receive_frame - rx data function * device_alloc_rx_buf - rx buffer pre-allocated function - * device_alloc_frag_buf - rx fragement pre-allocated function * device_free_tx_buf - free tx buffer function - * device_free_frag_buf- free de-fragement buffer - * device_dma0_tx_80211- tx 802.11 frame via dma0 - * device_dma0_xmit- tx PS bufferred frame via dma0 * device_init_rd0_ring- initial rd dma0 ring * device_init_rd1_ring- initial rd dma1 ring * device_init_td0_ring- initial tx dma0 ring buffer * device_init_td1_ring- initial tx dma1 ring buffer * device_init_registers- initial MAC & BBP & RF internal registers. * device_init_rings- initial tx/rx ring buffer - * device_init_defrag_cb- initial & allocate de-fragement buffer. * device_free_rings- free all allocated ring buffer * device_tx_srv- tx interrupt service function * @@ -66,24 +55,10 @@ #include "channel.h" #include "baseband.h" #include "mac.h" -#include "tether.h" -#include "wmgr.h" -#include "wctl.h" #include "power.h" -#include "wcmd.h" -#include "iocmd.h" -#include "tcrc.h" #include "rxtx.h" -#include "wroute.h" -#include "bssdb.h" -#include "hostap.h" -#include "wpactl.h" -#include "ioctl.h" -#include "iwctl.h" #include "dpc.h" -#include "datarate.h" #include "rf.h" -#include "iowpa.h" #include <linux/delay.h> #include <linux/kthread.h> #include <linux/slab.h> @@ -118,89 +93,16 @@ DEVICE_PARAM(TxDescriptors0, "Number of transmit descriptors0"); #define TX_DESC_DEF1 64 DEVICE_PARAM(TxDescriptors1, "Number of transmit descriptors1"); -#define IP_ALIG_DEF 0 -/* IP_byte_align[] is used for IP header unsigned long byte aligned - 0: indicate the IP header won't be unsigned long byte aligned.(Default) . - 1: indicate the IP header will be unsigned long byte aligned. - In some environment, the IP header should be unsigned long byte aligned, - or the packet will be droped when we receive it. (eg: IPVS) -*/ -DEVICE_PARAM(IP_byte_align, "Enable IP header dword aligned"); - #define INT_WORKS_DEF 20 #define INT_WORKS_MIN 10 #define INT_WORKS_MAX 64 DEVICE_PARAM(int_works, "Number of packets per interrupt services"); -#define CHANNEL_MIN 1 -#define CHANNEL_MAX 14 -#define CHANNEL_DEF 6 - -DEVICE_PARAM(Channel, "Channel number"); - -/* PreambleType[] is the preamble length used for transmit. - 0: indicate allows long preamble type - 1: indicate allows short preamble type -*/ - -#define PREAMBLE_TYPE_DEF 1 - -DEVICE_PARAM(PreambleType, "Preamble Type"); - -#define RTS_THRESH_MIN 512 -#define RTS_THRESH_MAX 2347 #define RTS_THRESH_DEF 2347 -DEVICE_PARAM(RTSThreshold, "RTS threshold"); - -#define FRAG_THRESH_MIN 256 -#define FRAG_THRESH_MAX 2346 #define FRAG_THRESH_DEF 2346 -DEVICE_PARAM(FragThreshold, "Fragmentation threshold"); - -#define DATA_RATE_MIN 0 -#define DATA_RATE_MAX 13 -#define DATA_RATE_DEF 13 -/* datarate[] index - 0: indicate 1 Mbps 0x02 - 1: indicate 2 Mbps 0x04 - 2: indicate 5.5 Mbps 0x0B - 3: indicate 11 Mbps 0x16 - 4: indicate 6 Mbps 0x0c - 5: indicate 9 Mbps 0x12 - 6: indicate 12 Mbps 0x18 - 7: indicate 18 Mbps 0x24 - 8: indicate 24 Mbps 0x30 - 9: indicate 36 Mbps 0x48 - 10: indicate 48 Mbps 0x60 - 11: indicate 54 Mbps 0x6c - 12: indicate 72 Mbps 0x90 - 13: indicate auto rate -*/ - -DEVICE_PARAM(ConnectionRate, "Connection data rate"); - -#define OP_MODE_DEF 0 - -DEVICE_PARAM(OPMode, "Infrastruct, adhoc, AP mode "); - -/* OpMode[] is used for transmit. - 0: indicate infrastruct mode used - 1: indicate adhoc mode used - 2: indicate AP mode used -*/ - -/* PSMode[] - 0: indicate disable power saving mode - 1: indicate enable power saving mode -*/ - -#define PS_MODE_DEF 0 - -DEVICE_PARAM(PSMode, "Power saving mode"); - #define SHORT_RETRY_MIN 0 #define SHORT_RETRY_MAX 31 #define SHORT_RETRY_DEF 8 @@ -224,20 +126,6 @@ DEVICE_PARAM(LongRetryLimit, "long frame retry limits"); DEVICE_PARAM(BasebandType, "baseband type"); -/* 80211hEnable[] - 0: indicate disable 802.11h - 1: indicate enable 802.11h -*/ - -#define X80211h_MODE_DEF 0 - -DEVICE_PARAM(b80211hEnable, "802.11h mode"); - -/* 80211hEnable[] - 0: indicate disable 802.11h - 1: indicate enable 802.11h -*/ - #define DIVERSITY_ANT_DEF 0 DEVICE_PARAM(bDiversityANTEnable, "ANT diversity mode"); @@ -265,17 +153,10 @@ static void device_free_info(struct vnt_private *pDevice); static bool device_get_pci_info(struct vnt_private *, struct pci_dev *pcid); static void device_print_info(struct vnt_private *pDevice); static void device_init_diversity_timer(struct vnt_private *pDevice); -static int device_open(struct net_device *dev); -static int device_xmit(struct sk_buff *skb, struct net_device *dev); static irqreturn_t device_intr(int irq, void *dev_instance); -static void device_set_multi(struct net_device *dev); -static int device_close(struct net_device *dev); -static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); #ifdef CONFIG_PM static int device_notify_reboot(struct notifier_block *, unsigned long event, void *ptr); -static int viawget_suspend(struct pci_dev *pcid, pm_message_t state); -static int viawget_resume(struct pci_dev *pcid); static struct notifier_block device_notifier = { .notifier_call = device_notify_reboot, .next = NULL, @@ -285,15 +166,9 @@ static struct notifier_block device_notifier = { static void device_init_rd0_ring(struct vnt_private *pDevice); static void device_init_rd1_ring(struct vnt_private *pDevice); -static void device_init_defrag_cb(struct vnt_private *pDevice); static void device_init_td0_ring(struct vnt_private *pDevice); static void device_init_td1_ring(struct vnt_private *pDevice); -static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev); -//2008-0714<Add>by Mike Liu -static bool device_release_WPADEV(struct vnt_private *pDevice); - -static int ethtool_ioctl(struct net_device *dev, void __user *useraddr); static int device_rx_srv(struct vnt_private *pDevice, unsigned int uIdx); static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx); static bool device_alloc_rx_buf(struct vnt_private *pDevice, PSRxDesc pDesc); @@ -304,9 +179,6 @@ static void device_free_td1_ring(struct vnt_private *pDevice); static void device_free_rd0_ring(struct vnt_private *pDevice); static void device_free_rd1_ring(struct vnt_private *pDevice); static void device_free_rings(struct vnt_private *pDevice); -static void device_free_frag_buf(struct vnt_private *pDevice); -static int Config_FileGetParameter(unsigned char *string, - unsigned char *dest, unsigned char *source); /*--------------------- Export Variables --------------------------*/ @@ -339,124 +211,50 @@ static void device_get_options(struct vnt_private *pDevice) pOpts->nRxDescs1 = RX_DESC_DEF1; pOpts->nTxDescs[0] = TX_DESC_DEF0; pOpts->nTxDescs[1] = TX_DESC_DEF1; - pOpts->flags |= DEVICE_FLAGS_IP_ALIGN; pOpts->int_works = INT_WORKS_DEF; - pOpts->rts_thresh = RTS_THRESH_DEF; - pOpts->frag_thresh = FRAG_THRESH_DEF; - pOpts->data_rate = DATA_RATE_DEF; - pOpts->channel_num = CHANNEL_DEF; - pOpts->flags |= DEVICE_FLAGS_PREAMBLE_TYPE; - pOpts->flags |= DEVICE_FLAGS_OP_MODE; pOpts->short_retry = SHORT_RETRY_DEF; pOpts->long_retry = LONG_RETRY_DEF; pOpts->bbp_type = BBP_TYPE_DEF; - pOpts->flags |= DEVICE_FLAGS_80211h_MODE; pOpts->flags |= DEVICE_FLAGS_DiversityANT; } static void device_set_options(struct vnt_private *pDevice) { - unsigned char abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - unsigned char abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}; - unsigned char abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8}; - - memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN); - memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN); - memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, ETH_ALEN); - - pDevice->uChannel = pDevice->sOpts.channel_num; - pDevice->wRTSThreshold = pDevice->sOpts.rts_thresh; - pDevice->wFragmentationThreshold = pDevice->sOpts.frag_thresh; pDevice->byShortRetryLimit = pDevice->sOpts.short_retry; pDevice->byLongRetryLimit = pDevice->sOpts.long_retry; - pDevice->wMaxTransmitMSDULifetime = DEFAULT_MSDU_LIFETIME; - pDevice->byShortPreamble = (pDevice->sOpts.flags & DEVICE_FLAGS_PREAMBLE_TYPE) ? 1 : 0; - pDevice->byOpMode = (pDevice->sOpts.flags & DEVICE_FLAGS_OP_MODE) ? 1 : 0; - pDevice->ePSMode = (pDevice->sOpts.flags & DEVICE_FLAGS_PS_MODE) ? 1 : 0; - pDevice->b11hEnable = (pDevice->sOpts.flags & DEVICE_FLAGS_80211h_MODE) ? 1 : 0; pDevice->bDiversityRegCtlON = (pDevice->sOpts.flags & DEVICE_FLAGS_DiversityANT) ? 1 : 0; - pDevice->uConnectionRate = pDevice->sOpts.data_rate; - if (pDevice->uConnectionRate < RATE_AUTO) - pDevice->bFixRate = true; pDevice->byBBType = pDevice->sOpts.bbp_type; - pDevice->byPacketType = (VIA_PKT_TYPE)pDevice->byBBType; + pDevice->byPacketType = pDevice->byBBType; pDevice->byAutoFBCtrl = AUTO_FB_0; pDevice->bUpdateBBVGA = true; - pDevice->byFOETuning = 0; pDevice->byPreambleType = 0; - pr_debug(" uChannel= %d\n", (int)pDevice->uChannel); - pr_debug(" byOpMode= %d\n", (int)pDevice->byOpMode); - pr_debug(" ePSMode= %d\n", (int)pDevice->ePSMode); - pr_debug(" wRTSThreshold= %d\n", (int)pDevice->wRTSThreshold); pr_debug(" byShortRetryLimit= %d\n", (int)pDevice->byShortRetryLimit); pr_debug(" byLongRetryLimit= %d\n", (int)pDevice->byLongRetryLimit); pr_debug(" byPreambleType= %d\n", (int)pDevice->byPreambleType); pr_debug(" byShortPreamble= %d\n", (int)pDevice->byShortPreamble); - pr_debug(" uConnectionRate= %d\n", (int)pDevice->uConnectionRate); pr_debug(" byBBType= %d\n", (int)pDevice->byBBType); - pr_debug(" pDevice->b11hEnable= %d\n", (int)pDevice->b11hEnable); pr_debug(" pDevice->bDiversityRegCtlON= %d\n", (int)pDevice->bDiversityRegCtlON); } -static void s_vCompleteCurrentMeasure(struct vnt_private *pDevice, - unsigned char byResult) -{ - unsigned int ii; - unsigned long dwDuration = 0; - unsigned char byRPI0 = 0; - - for (ii = 1; ii < 8; ii++) { - pDevice->dwRPIs[ii] *= 255; - dwDuration |= *((unsigned short *)(pDevice->pCurrMeasureEID->sReq.abyDuration)); - dwDuration <<= 10; - pDevice->dwRPIs[ii] /= dwDuration; - pDevice->abyRPIs[ii] = (unsigned char)pDevice->dwRPIs[ii]; - byRPI0 += pDevice->abyRPIs[ii]; - } - pDevice->abyRPIs[0] = (0xFF - byRPI0); - - if (pDevice->uNumOfMeasureEIDs == 0) { - VNTWIFIbMeasureReport(pDevice->pMgmt, - true, - pDevice->pCurrMeasureEID, - byResult, - pDevice->byBasicMap, - pDevice->byCCAFraction, - pDevice->abyRPIs - ); - } else { - VNTWIFIbMeasureReport(pDevice->pMgmt, - false, - pDevice->pCurrMeasureEID, - byResult, - pDevice->byBasicMap, - pDevice->byCCAFraction, - pDevice->abyRPIs - ); - CARDbStartMeasure(pDevice, pDevice->pCurrMeasureEID++, pDevice->uNumOfMeasureEIDs); - } -} - // // Initialisation of MAC & BBP registers // static void device_init_registers(struct vnt_private *pDevice) { + unsigned long flags; unsigned int ii; unsigned char byValue; unsigned char byValue1; unsigned char byCCKPwrdBm = 0; unsigned char byOFDMPwrdBm = 0; - int zonetype = 0; - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); MACbShutdown(pDevice->PortOffset); - BBvSoftwareReset(pDevice->PortOffset); + BBvSoftwareReset(pDevice); /* Do MACbSoftwareReset in MACvInitialize */ MACbSoftwareReset(pDevice->PortOffset); @@ -481,11 +279,11 @@ static void device_init_registers(struct vnt_private *pDevice) /* Get Local ID */ VNSvInPortB(pDevice->PortOffset + MAC_REG_LOCALID, &pDevice->byLocalID); - spin_lock_irq(&pDevice->lock); + spin_lock_irqsave(&pDevice->lock, flags); SROMvReadAllContents(pDevice->PortOffset, pDevice->abyEEPROM); - spin_unlock_irq(&pDevice->lock); + spin_unlock_irqrestore(&pDevice->lock, flags); /* Get Channel range */ pDevice->byMinChannel = 1; @@ -558,41 +356,6 @@ static void device_init_registers(struct vnt_private *pDevice) /* zonetype initial */ pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE]; - zonetype = Config_FileOperation(pDevice, false, NULL); - - if (zonetype >= 0) { - if ((zonetype == 0) && - (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x00)) { - /* for USA */ - pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0; - pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0B; - - pr_debug("Init Zone Type :USA\n"); - } else if ((zonetype == 1) && - (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x01)) { - /* for Japan */ - pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x01; - pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D; - } else if ((zonetype == 2) && - (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x02)) { - /* for Europe */ - pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x02; - pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D; - - pr_debug("Init Zone Type :Europe\n"); - } else { - if (zonetype != pDevice->abyEEPROM[EEP_OFS_ZONETYPE]) - pr_debug("zonetype in file[%02x] mismatch with in EEPROM[%02x]\n", - zonetype, - pDevice->abyEEPROM[EEP_OFS_ZONETYPE]); - else - pr_debug("Read Zonetype file success,use default zonetype setting[%02x]\n", - zonetype); - } - } else { - pr_debug("Read Zonetype file fail,use default zonetype setting[%02x]\n", - SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ZONETYPE)); - } /* Get RFType */ pDevice->byRFType = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RFTYPE); @@ -636,14 +399,9 @@ static void device_init_registers(struct vnt_private *pDevice) } /* recover 12,13 ,14channel for EUROPE by 11 channel */ - if (((pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Japan) || - (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Europe)) && - (pDevice->byOriginalZonetype == ZoneType_USA)) { - for (ii = 11; ii < 14; ii++) { - pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10]; - pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10]; - - } + for (ii = 11; ii < 14; ii++) { + pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10]; + pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10]; } /* Load OFDM A Power Table */ @@ -657,8 +415,6 @@ static void device_init_registers(struct vnt_private *pDevice) (unsigned char)(ii + EEP_OFS_OFDMA_PWR_dBm)); } - init_channel_table((void *)pDevice); - if (pDevice->byLocalID > REV_ID_VT3253_B1) { MACvSelectPage1(pDevice->PortOffset); @@ -690,21 +446,12 @@ static void device_init_registers(struct vnt_private *pDevice) BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]); } - BBvSetRxAntennaMode(pDevice->PortOffset, pDevice->byRxAntennaMode); - BBvSetTxAntennaMode(pDevice->PortOffset, pDevice->byTxAntennaMode); - - pDevice->byCurrentCh = 0; + BBvSetRxAntennaMode(pDevice, pDevice->byRxAntennaMode); + BBvSetTxAntennaMode(pDevice, pDevice->byTxAntennaMode); /* Set BB and packet type at the same time. */ /* Set Short Slot Time, xIFS, and RSPINF. */ - if (pDevice->uConnectionRate == RATE_AUTO) - pDevice->wCurrentRate = RATE_54M; - else - pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; - - /* default G Mode */ - VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_11G); - VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_AUTO); + pDevice->wCurrentRate = RATE_54M; pDevice->bRadioOff = false; @@ -726,8 +473,6 @@ static void device_init_registers(struct vnt_private *pDevice) if (pDevice->bHWRadioOff || pDevice->bRadioControlOff) CARDbRadioPowerOff(pDevice); - pMgmt->eScanType = WMAC_SCAN_PASSIVE; - /* get Permanent network address */ SROMvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr); pr_debug("Network address = %pM\n", pDevice->abyCurrentNetAddr); @@ -740,223 +485,39 @@ static void device_init_registers(struct vnt_private *pDevice) if (pDevice->byLocalID <= REV_ID_VT3253_A1) MACvRegBitsOn(pDevice->PortOffset, MAC_REG_RCR, RCR_WPAERR); - pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - /* Turn On Rx DMA */ MACvReceive0(pDevice->PortOffset); MACvReceive1(pDevice->PortOffset); /* start the adapter */ MACvStart(pDevice->PortOffset); - - netif_stop_queue(pDevice->dev); } static void device_init_diversity_timer(struct vnt_private *pDevice) { init_timer(&pDevice->TimerSQ3Tmax1); pDevice->TimerSQ3Tmax1.data = (unsigned long) pDevice; - pDevice->TimerSQ3Tmax1.function = (TimerFunction)TimerSQ3CallBack; + pDevice->TimerSQ3Tmax1.function = TimerSQ3CallBack; pDevice->TimerSQ3Tmax1.expires = RUN_AT(HZ); init_timer(&pDevice->TimerSQ3Tmax2); pDevice->TimerSQ3Tmax2.data = (unsigned long) pDevice; - pDevice->TimerSQ3Tmax2.function = (TimerFunction)TimerSQ3CallBack; + pDevice->TimerSQ3Tmax2.function = TimerSQ3CallBack; pDevice->TimerSQ3Tmax2.expires = RUN_AT(HZ); init_timer(&pDevice->TimerSQ3Tmax3); pDevice->TimerSQ3Tmax3.data = (unsigned long) pDevice; - pDevice->TimerSQ3Tmax3.function = (TimerFunction)TimerState1CallBack; + pDevice->TimerSQ3Tmax3.function = TimerState1CallBack; pDevice->TimerSQ3Tmax3.expires = RUN_AT(HZ); } -static bool device_release_WPADEV(struct vnt_private *pDevice) -{ - viawget_wpa_header *wpahdr; - int ii = 0; - - //send device close to wpa_supplicnat layer - if (pDevice->bWPADEVUp) { - wpahdr = (viawget_wpa_header *)pDevice->skb->data; - wpahdr->type = VIAWGET_DEVICECLOSE_MSG; - wpahdr->resp_ie_len = 0; - wpahdr->req_ie_len = 0; - skb_put(pDevice->skb, sizeof(viawget_wpa_header)); - pDevice->skb->dev = pDevice->wpadev; - skb_reset_mac_header(pDevice->skb); - pDevice->skb->pkt_type = PACKET_HOST; - pDevice->skb->protocol = htons(ETH_P_802_2); - memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); - netif_rx(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - - while (pDevice->bWPADEVUp) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ / 20); //wait 50ms - ii++; - if (ii > 20) - break; - } - } - return true; -} - -static const struct net_device_ops device_netdev_ops = { - .ndo_open = device_open, - .ndo_stop = device_close, - .ndo_do_ioctl = device_ioctl, - .ndo_start_xmit = device_xmit, - .ndo_set_rx_mode = device_set_multi, -}; - -static int -vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) -{ - static bool bFirst = true; - struct net_device *dev = NULL; - PCHIP_INFO pChip_info = (PCHIP_INFO)ent->driver_data; - struct vnt_private *pDevice; - int rc; - - dev = alloc_etherdev(sizeof(*pDevice)); - - pDevice = netdev_priv(dev); - - if (dev == NULL) { - pr_err(DEVICE_NAME ": allocate net device failed\n"); - return -ENOMEM; - } - - // Chain it all together - SET_NETDEV_DEV(dev, &pcid->dev); - - if (bFirst) { - pr_notice("%s Ver. %s\n", DEVICE_FULL_DRV_NAM, DEVICE_VERSION); - pr_notice("Copyright (c) 2003 VIA Networking Technologies, Inc.\n"); - bFirst = false; - } - - vt6655_init_info(pcid, &pDevice, pChip_info); - pDevice->dev = dev; - - if (pci_enable_device(pcid)) { - device_free_info(pDevice); - return -ENODEV; - } - dev->irq = pcid->irq; - -#ifdef DEBUG - pr_debug("Before get pci_info memaddr is %x\n", pDevice->memaddr); -#endif - if (!device_get_pci_info(pDevice, pcid)) { - pr_err(DEVICE_NAME ": Failed to find PCI device.\n"); - device_free_info(pDevice); - return -ENODEV; - } - -#if 1 - -#ifdef DEBUG - - pr_debug("after get pci_info memaddr is %x, io addr is %x,io_size is %d\n", pDevice->memaddr, pDevice->ioaddr, pDevice->io_size); - { - int i; - u32 bar, len; - u32 address[] = { - PCI_BASE_ADDRESS_0, - PCI_BASE_ADDRESS_1, - PCI_BASE_ADDRESS_2, - PCI_BASE_ADDRESS_3, - PCI_BASE_ADDRESS_4, - PCI_BASE_ADDRESS_5, - 0}; - for (i = 0; address[i]; i++) { - pci_read_config_dword(pcid, address[i], &bar); - pr_debug("bar %d is %x\n", i, bar); - if (!bar) { - pr_debug("bar %d not implemented\n", i); - continue; - } - if (bar & PCI_BASE_ADDRESS_SPACE_IO) { - /* This is IO */ - - len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF); - len = len & ~(len - 1); - - pr_debug("IO space: len in IO %x, BAR %d\n", len, i); - } else { - len = bar & 0xFFFFFFF0; - len = ~len + 1; - - pr_debug("len in MEM %x, BAR %d\n", len, i); - } - } - } -#endif - -#endif - - pDevice->PortOffset = ioremap(pDevice->memaddr & PCI_BASE_ADDRESS_MEM_MASK, pDevice->io_size); - - if (pDevice->PortOffset == NULL) { - pr_err(DEVICE_NAME ": Failed to IO remapping ..\n"); - device_free_info(pDevice); - return -ENODEV; - } - - rc = pci_request_regions(pcid, DEVICE_NAME); - if (rc) { - pr_err(DEVICE_NAME ": Failed to find PCI device\n"); - device_free_info(pDevice); - return -ENODEV; - } - - dev->base_addr = pDevice->ioaddr; - // do reset - if (!MACbSoftwareReset(pDevice->PortOffset)) { - pr_err(DEVICE_NAME ": Failed to access MAC hardware..\n"); - device_free_info(pDevice); - return -ENODEV; - } - // initial to reload eeprom - MACvInitialize(pDevice->PortOffset); - MACvReadEtherAddress(pDevice->PortOffset, dev->dev_addr); - - device_get_options(pDevice); - device_set_options(pDevice); - //Mask out the options cannot be set to the chip - pDevice->sOpts.flags &= pChip_info->flags; - - //Enable the chip specified capabilities - pDevice->flags = pDevice->sOpts.flags | (pChip_info->flags & 0xFF000000UL); - pDevice->tx_80211 = device_dma0_tx_80211; - pDevice->sMgmtObj.pAdapter = (void *)pDevice; - pDevice->pMgmt = &(pDevice->sMgmtObj); - - dev->irq = pcid->irq; - dev->netdev_ops = &device_netdev_ops; - - dev->wireless_handlers = (struct iw_handler_def *)&iwctl_handler_def; - - rc = register_netdev(dev); - if (rc) { - pr_err(DEVICE_NAME " Failed to register netdev\n"); - device_free_info(pDevice); - return -ENODEV; - } - device_print_info(pDevice); - pci_set_drvdata(pcid, pDevice); - return 0; -} - static void device_print_info(struct vnt_private *pDevice) { - struct net_device *dev = pDevice->dev; + dev_info(&pDevice->pcid->dev, "%s\n", get_chip_name(pDevice->chip_id)); - pr_info("%s: %s\n", dev->name, get_chip_name(pDevice->chip_id)); - pr_info("%s: MAC=%pM IO=0x%lx Mem=0x%lx IRQ=%d\n", - dev->name, dev->dev_addr, (unsigned long)pDevice->ioaddr, - (unsigned long)pDevice->PortOffset, pDevice->dev->irq); + dev_info(&pDevice->pcid->dev, "MAC=%pM IO=0x%lx Mem=0x%lx IRQ=%d\n", + pDevice->abyCurrentNetAddr, (unsigned long)pDevice->ioaddr, + (unsigned long)pDevice->PortOffset, pDevice->pcid->irq); } static void vt6655_init_info(struct pci_dev *pcid, @@ -1003,31 +564,20 @@ static bool device_get_pci_info(struct vnt_private *pDevice, static void device_free_info(struct vnt_private *pDevice) { - struct net_device *dev = pDevice->dev; - - ASSERT(pDevice); -//2008-0714-01<Add>by chester - device_release_WPADEV(pDevice); - -//2008-07-21-01<Add>by MikeLiu -//unregister wpadev - if (wpa_set_wpadev(pDevice, 0) != 0) - pr_err("unregister wpadev fail?\n"); + if (!pDevice) + return; -#ifdef HOSTAP - if (dev) - vt6655_hostap_set_hostapd(pDevice, 0, 0); -#endif - if (dev) - unregister_netdev(dev); + if (pDevice->mac_hw) + ieee80211_unregister_hw(pDevice->hw); if (pDevice->PortOffset) iounmap(pDevice->PortOffset); if (pDevice->pcid) pci_release_regions(pDevice->pcid); - if (dev) - free_netdev(dev); + + if (pDevice->hw) + ieee80211_free_hw(pDevice->hw); } static bool device_init_rings(struct vnt_private *pDevice) @@ -1176,21 +726,6 @@ static void device_init_rd1_ring(struct vnt_private *pDevice) pDevice->pCurrRD[1] = &(pDevice->aRD1Ring[0]); } -static void device_init_defrag_cb(struct vnt_private *pDevice) -{ - int i; - PSDeFragControlBlock pDeF; - - /* Init the fragment ctl entries */ - for (i = 0; i < CB_MAX_RX_FRAG; i++) { - pDeF = &(pDevice->sRxDFCB[i]); - if (!device_alloc_frag_buf(pDevice, pDeF)) - dev_err(&pDevice->pcid->dev, "can not alloc frag bufs\n"); - } - pDevice->cbDFCB = CB_MAX_RX_FRAG; - pDevice->cbFreeDFCB = pDevice->cbDFCB; -} - static void device_free_rd0_ring(struct vnt_private *pDevice) { int i; @@ -1204,7 +739,7 @@ static void device_free_rd0_ring(struct vnt_private *pDevice) dev_kfree_skb(pRDInfo->skb); - kfree((void *)pDesc->pRDInfo); + kfree(pDesc->pRDInfo); } } @@ -1221,21 +756,7 @@ static void device_free_rd1_ring(struct vnt_private *pDevice) dev_kfree_skb(pRDInfo->skb); - kfree((void *)pDesc->pRDInfo); - } -} - -static void device_free_frag_buf(struct vnt_private *pDevice) -{ - PSDeFragControlBlock pDeF; - int i; - - for (i = 0; i < CB_MAX_RX_FRAG; i++) { - pDeF = &(pDevice->sRxDFCB[i]); - - if (pDeF->skb) - dev_kfree_skb(pDeF->skb); - + kfree(pDesc->pRDInfo); } } @@ -1305,7 +826,7 @@ static void device_free_td0_ring(struct vnt_private *pDevice) if (pTDInfo->skb) dev_kfree_skb(pTDInfo->skb); - kfree((void *)pDesc->pTDInfo); + kfree(pDesc->pTDInfo); } } @@ -1324,7 +845,7 @@ static void device_free_td1_ring(struct vnt_private *pDevice) if (pTDInfo->skb) dev_kfree_skb(pTDInfo->skb); - kfree((void *)pDesc->pTDInfo); + kfree(pDesc->pTDInfo); } } @@ -1340,7 +861,7 @@ static int device_rx_srv(struct vnt_private *pDevice, unsigned int uIdx) pRD = pRD->next) { if (works++ > 15) break; - if (device_receive_frame(pDevice, pRD)) { + if (vnt_receive_frame(pDevice, pRD)) { if (!device_alloc_rx_buf(pDevice, pRD)) { dev_err(&pDevice->pcid->dev, "can not allocate rx buf\n"); @@ -1348,7 +869,6 @@ static int device_rx_srv(struct vnt_private *pDevice, unsigned int uIdx) } } pRD->m_rd0RD0.f1Owner = OWNED_BY_NIC; - pDevice->dev->last_rx = jiffies; } pDevice->pCurrRD[uIdx] = pRD; @@ -1364,9 +884,12 @@ static bool device_alloc_rx_buf(struct vnt_private *pDevice, PSRxDesc pRD) if (pRDInfo->skb == NULL) return false; ASSERT(pRDInfo->skb); - pRDInfo->skb->dev = pDevice->dev; - pRDInfo->skb_dma = pci_map_single(pDevice->pcid, skb_tail_pointer(pRDInfo->skb), - pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE); + + pRDInfo->skb_dma = + pci_map_single(pDevice->pcid, + skb_put(pRDInfo->skb, skb_tailroom(pRDInfo->skb)), + pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE); + *((unsigned int *)&(pRD->m_rd0RD0)) = 0; /* FIX cast */ pRD->m_rd0RD0.wResCount = cpu_to_le16(pDevice->rx_buf_sz); @@ -1377,31 +900,84 @@ static bool device_alloc_rx_buf(struct vnt_private *pDevice, PSRxDesc pRD) return true; } -bool device_alloc_frag_buf(struct vnt_private *pDevice, - PSDeFragControlBlock pDeF) +static const u8 fallback_rate0[5][5] = { + {RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M}, + {RATE_24M, RATE_24M, RATE_18M, RATE_12M, RATE_12M}, + {RATE_36M, RATE_36M, RATE_24M, RATE_18M, RATE_18M}, + {RATE_48M, RATE_48M, RATE_36M, RATE_24M, RATE_24M}, + {RATE_54M, RATE_54M, RATE_48M, RATE_36M, RATE_36M} +}; + +static const u8 fallback_rate1[5][5] = { + {RATE_18M, RATE_18M, RATE_12M, RATE_6M, RATE_6M}, + {RATE_24M, RATE_24M, RATE_18M, RATE_6M, RATE_6M}, + {RATE_36M, RATE_36M, RATE_24M, RATE_12M, RATE_12M}, + {RATE_48M, RATE_48M, RATE_24M, RATE_12M, RATE_12M}, + {RATE_54M, RATE_54M, RATE_36M, RATE_18M, RATE_18M} +}; + +static int vnt_int_report_rate(struct vnt_private *priv, + PDEVICE_TD_INFO context, u8 tsr0, u8 tsr1) { - pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - if (pDeF->skb == NULL) - return false; - ASSERT(pDeF->skb); - pDeF->skb->dev = pDevice->dev; + struct vnt_tx_fifo_head *fifo_head; + struct ieee80211_tx_info *info; + struct ieee80211_rate *rate; + u16 fb_option; + u8 tx_retry = (tsr0 & TSR0_NCR); + s8 idx; + + if (!context) + return -ENOMEM; - return true; + if (!context->skb) + return -EINVAL; + + fifo_head = (struct vnt_tx_fifo_head *)context->buf; + fb_option = (le16_to_cpu(fifo_head->fifo_ctl) & + (FIFOCTL_AUTO_FB_0 | FIFOCTL_AUTO_FB_1)); + + info = IEEE80211_SKB_CB(context->skb); + idx = info->control.rates[0].idx; + + if (fb_option && !(tsr1 & TSR1_TERR)) { + u8 tx_rate; + u8 retry = tx_retry; + + rate = ieee80211_get_tx_rate(priv->hw, info); + tx_rate = rate->hw_value - RATE_18M; + + if (retry > 4) + retry = 4; + + if (fb_option & FIFOCTL_AUTO_FB_0) + tx_rate = fallback_rate0[tx_rate][retry]; + else if (fb_option & FIFOCTL_AUTO_FB_1) + tx_rate = fallback_rate1[tx_rate][retry]; + + if (info->band == IEEE80211_BAND_5GHZ) + idx = tx_rate - RATE_6M; + else + idx = tx_rate; + } + + ieee80211_tx_info_clear_status(info); + + info->status.rates[0].count = tx_retry; + + if (!(tsr1 & TSR1_TERR)) { + info->status.rates[0].idx = idx; + info->flags |= IEEE80211_TX_STAT_ACK; + } + + return 0; } static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx) { PSTxDesc pTD; - bool bFull = false; int works = 0; unsigned char byTsr0; unsigned char byTsr1; - unsigned int uFrameSize, uFIFOHeaderSize; - PSTxBufHead pTxBufHead; - struct net_device_stats *pStats = &pDevice->dev->stats; - struct sk_buff *skb; - unsigned int uNodeIndex; - PSMgmtObject pMgmt = pDevice->pMgmt; for (pTD = pDevice->apTailTD[uIdx]; pDevice->iTDUsed[uIdx] > 0; pTD = pTD->next) { if (pTD->m_td0TD0.f1Owner == OWNED_BY_NIC) @@ -1415,22 +991,8 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx) //Only the status of first TD in the chain is correct if (pTD->m_td1TD1.byTCR & TCR_STP) { if ((pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0) { - uFIFOHeaderSize = pTD->pTDInfo->dwHeaderLength; - uFrameSize = pTD->pTDInfo->dwReqCount - uFIFOHeaderSize; - pTxBufHead = (PSTxBufHead) (pTD->pTDInfo->buf); - // Update the statistics based on the Transmit status - // now, we DONT check TSR0_CDH - - STAvUpdateTDStatCounter(&pDevice->scStatistic, - byTsr0, byTsr1, - (unsigned char *)(pTD->pTDInfo->buf + uFIFOHeaderSize), - uFrameSize, uIdx); - - BSSvUpdateNodeTxCounter(pDevice, - byTsr0, byTsr1, - (unsigned char *)(pTD->pTDInfo->buf), - uFIFOHeaderSize - ); + + vnt_int_report_rate(pDevice, pTD->pTDInfo, byTsr0, byTsr1); if (!(byTsr1 & TSR1_TERR)) { if (byTsr0 != 0) { @@ -1438,28 +1000,9 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx) (int)uIdx, byTsr1, byTsr0); } - if ((pTxBufHead->wFragCtl & FRAGCTL_ENDFRAG) != FRAGCTL_NONFRAG) - pDevice->s802_11Counter.TransmittedFragmentCount++; - - pStats->tx_packets++; - pStats->tx_bytes += pTD->pTDInfo->skb->len; } else { pr_debug(" Tx[%d] dropped & tsr1[%02X] tsr0[%02X]\n", (int)uIdx, byTsr1, byTsr0); - pStats->tx_errors++; - pStats->tx_dropped++; - } - } - - if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) { - if (pDevice->bEnableHostapd) { - pr_debug("tx call back netif..\n"); - skb = pTD->pTDInfo->skb; - skb->dev = pDevice->apdev; - skb_reset_mac_header(skb); - skb->pkt_type = PACKET_OTHERHOST; - memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx(skb); } } @@ -1468,49 +1011,12 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx) pr_debug(" Tx[%d] fail has error. tsr1[%02X] tsr0[%02X]\n", (int)uIdx, byTsr1, byTsr0); } - - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && - (pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB)) { - unsigned short wAID; - unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; - - skb = pTD->pTDInfo->skb; - if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data), &uNodeIndex)) { - if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) { - skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb); - pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++; - // set tx map - wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID; - pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7]; - pTD->pTDInfo->byFlags &= ~(TD_FLAGS_NETIF_SKB); - pr_debug("tx_srv:tx fail re-queue sta index= %d, QueCnt= %d\n", - (int)uNodeIndex, - pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt); - pStats->tx_errors--; - pStats->tx_dropped--; - } - } - } } device_free_tx_buf(pDevice, pTD); pDevice->iTDUsed[uIdx]--; } } - if (uIdx == TYPE_AC0DMA) { - // RESERV_AC0DMA reserved for relay - - if (AVAIL_TD(pDevice, uIdx) < RESERV_AC0DMA) { - bFull = true; - pr_debug(" AC0DMA is Full = %d\n", - pDevice->iTDUsed[uIdx]); - } - if (netif_queue_stopped(pDevice->dev) && !bFull) - netif_wake_queue(pDevice->dev); - - } - pDevice->apTailTD[uIdx] = pTD; return works; @@ -1521,10 +1027,6 @@ static void device_error(struct vnt_private *pDevice, unsigned short status) if (status & ISR_FETALERR) { dev_err(&pDevice->pcid->dev, "Hardware fatal error\n"); - netif_stop_queue(pDevice->dev); - del_timer(&pDevice->sTimerCommand); - del_timer(&(pDevice->pMgmt->sTimerSecondCallback)); - pDevice->bCmdRunning = false; MACbShutdown(pDevice->PortOffset); return; } @@ -1541,7 +1043,9 @@ static void device_free_tx_buf(struct vnt_private *pDevice, PSTxDesc pDesc) PCI_DMA_TODEVICE); } - if ((pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0) + if (pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) + ieee80211_tx_status_irqsafe(pDevice->hw, skb); + else dev_kfree_skb_irq(skb); pTDInfo->skb_dma = 0; @@ -1549,671 +1053,13 @@ static void device_free_tx_buf(struct vnt_private *pDevice, PSTxDesc pDesc) pTDInfo->byFlags = 0; } -static int device_open(struct net_device *dev) -{ - struct vnt_private *pDevice = netdev_priv(dev); - int i; -#ifdef WPA_SM_Transtatus - extern SWPAResult wpa_Result; -#endif - - pDevice->rx_buf_sz = PKT_BUF_SZ; - if (!device_init_rings(pDevice)) - return -ENOMEM; - -//2008-5-13 <add> by chester - i = request_irq(pDevice->pcid->irq, &device_intr, IRQF_SHARED, dev->name, dev); - if (i) - return i; - -#ifdef WPA_SM_Transtatus - memset(wpa_Result.ifname, 0, sizeof(wpa_Result.ifname)); - wpa_Result.proto = 0; - wpa_Result.key_mgmt = 0; - wpa_Result.eap_type = 0; - wpa_Result.authenticated = false; - pDevice->fWPA_Authened = false; -#endif - pr_debug("call device init rd0 ring\n"); - device_init_rd0_ring(pDevice); - device_init_rd1_ring(pDevice); - device_init_defrag_cb(pDevice); - device_init_td0_ring(pDevice); - device_init_td1_ring(pDevice); - - if (pDevice->bDiversityRegCtlON) - device_init_diversity_timer(pDevice); - - vMgrObjectInit(pDevice); - vMgrTimerInit(pDevice); - - pr_debug("call device_init_registers\n"); - device_init_registers(pDevice); - - MACvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr); - memcpy(pDevice->pMgmt->abyMACAddr, pDevice->abyCurrentNetAddr, ETH_ALEN); - device_set_multi(pDevice->dev); - - // Init for Key Management - KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); - add_timer(&(pDevice->pMgmt->sTimerSecondCallback)); - -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - pDevice->bwextcount = 0; - pDevice->bWPASuppWextEnabled = false; -#endif - pDevice->byReAssocCount = 0; - pDevice->bWPADEVUp = false; - // Patch: if WEP key already set by iwconfig but device not yet open - if (pDevice->bEncryptionEnable && pDevice->bTransmitKey) { - KeybSetDefaultKey(&(pDevice->sKey), - (unsigned long)(pDevice->byKeyIndex | (1 << 31)), - pDevice->uKeyLength, - NULL, - pDevice->abyKey, - KEY_CTL_WEP, - pDevice->PortOffset, - pDevice->byLocalID - ); - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - } - - pr_debug("call MACvIntEnable\n"); - MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); - - if (pDevice->pMgmt->eConfigMode == WMAC_CONFIG_AP) { - bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL); - } else { - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); - bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); - } - pDevice->flags |= DEVICE_FLAGS_OPENED; - - pr_debug("device_open success..\n"); - return 0; -} - -static int device_close(struct net_device *dev) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = pDevice->pMgmt; -//2007-1121-02<Add>by EinsnLiu - if (pDevice->bLinkPass) { - bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL); - mdelay(30); - } - - del_timer(&pDevice->sTimerTxData); - del_timer(&pDevice->sTimerCommand); - del_timer(&pMgmt->sTimerSecondCallback); - if (pDevice->bDiversityRegCtlON) { - del_timer(&pDevice->TimerSQ3Tmax1); - del_timer(&pDevice->TimerSQ3Tmax2); - del_timer(&pDevice->TimerSQ3Tmax3); - } - - netif_stop_queue(dev); - pDevice->bCmdRunning = false; - MACbShutdown(pDevice->PortOffset); - MACbSoftwareReset(pDevice->PortOffset); - CARDbRadioPowerOff(pDevice); - - pDevice->bLinkPass = false; - memset(pMgmt->abyCurrBSSID, 0, 6); - pMgmt->eCurrState = WMAC_STATE_IDLE; - device_free_td0_ring(pDevice); - device_free_td1_ring(pDevice); - device_free_rd0_ring(pDevice); - device_free_rd1_ring(pDevice); - device_free_frag_buf(pDevice); - device_free_rings(pDevice); - BSSvClearNodeDBTable(pDevice, 0); - free_irq(dev->irq, dev); - pDevice->flags &= (~DEVICE_FLAGS_OPENED); - //2008-0714-01<Add>by chester - device_release_WPADEV(pDevice); - - pr_debug("device_close..\n"); - return 0; -} - -static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) -{ - struct vnt_private *pDevice = netdev_priv(dev); - unsigned char *pbMPDU; - unsigned int cbMPDULen = 0; - - pr_debug("device_dma0_tx_80211\n"); - spin_lock_irq(&pDevice->lock); - - if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) { - pr_debug("device_dma0_tx_80211, td0 <=0\n"); - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - - if (pDevice->bStopTx0Pkt) { - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - - cbMPDULen = skb->len; - pbMPDU = skb->data; - - vDMA0_tx_80211(pDevice, skb, pbMPDU, cbMPDULen); - - spin_unlock_irq(&pDevice->lock); - - return 0; -} - -bool device_dma0_xmit(struct vnt_private *pDevice, - struct sk_buff *skb, unsigned int uNodeIndex) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - PSTxDesc pHeadTD, pLastTD; - unsigned int cbFrameBodySize; - unsigned int uMACfragNum; - unsigned char byPktType; - bool bNeedEncryption = false; - PSKeyItem pTransmitKey = NULL; - unsigned int cbHeaderSize; - unsigned int ii; - SKeyItem STempKey; - - if (pDevice->bStopTx0Pkt) { - dev_kfree_skb_irq(skb); - return false; - } - - if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) { - dev_kfree_skb_irq(skb); - pr_debug("device_dma0_xmit, td0 <=0\n"); - return false; - } - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (pDevice->uAssocCount == 0) { - dev_kfree_skb_irq(skb); - pr_debug("device_dma0_xmit, assocCount = 0\n"); - return false; - } - } - - pHeadTD = pDevice->apCurrTD[TYPE_TXDMA0]; - - pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP); - - memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)(skb->data), ETH_HLEN); - cbFrameBodySize = skb->len - ETH_HLEN; - - // 802.1H - if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN) - cbFrameBodySize += 8; - - uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader); - - if (uMACfragNum > AVAIL_TD(pDevice, TYPE_TXDMA0)) { - dev_kfree_skb_irq(skb); - return false; - } - byPktType = (unsigned char)pDevice->byPacketType; - - if (pDevice->bFixRate) { - if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { - if (pDevice->uConnectionRate >= RATE_11M) - pDevice->wCurrentRate = RATE_11M; - else - pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; - } else { - if (pDevice->uConnectionRate >= RATE_54M) - pDevice->wCurrentRate = RATE_54M; - else - pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; - } - } else { - pDevice->wCurrentRate = pDevice->pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate; - } - - //preamble type - if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) - pDevice->byPreambleType = pDevice->byShortPreamble; - else - pDevice->byPreambleType = PREAMBLE_LONG; - - pr_debug("dma0: pDevice->wCurrentRate = %d\n", pDevice->wCurrentRate); - - if (pDevice->wCurrentRate <= RATE_11M) { - byPktType = PK_TYPE_11B; - } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { - byPktType = PK_TYPE_11A; - } else { - if (pDevice->bProtectMode) - byPktType = PK_TYPE_11GB; - else - byPktType = PK_TYPE_11GA; - } - - if (pDevice->bEncryptionEnable) - bNeedEncryption = true; - - if (pDevice->bEnableHostWEP) { - pTransmitKey = &STempKey; - pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite; - pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex; - pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength; - pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16; - pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0; - memcpy(pTransmitKey->abyKey, - &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0], - pTransmitKey->uKeyLength - ); - } - vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption, - cbFrameBodySize, TYPE_TXDMA0, pHeadTD, - &pDevice->sTxEthHeader, (unsigned char *)skb->data, pTransmitKey, uNodeIndex, - &uMACfragNum, - &cbHeaderSize - ); - - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { - // Disable PS - MACbPSWakeup(pDevice->PortOffset); - } - - pDevice->bPWBitOn = false; - - pLastTD = pHeadTD; - for (ii = 0; ii < uMACfragNum; ii++) { - // Poll Transmit the adapter - wmb(); - pHeadTD->m_td0TD0.f1Owner = OWNED_BY_NIC; - wmb(); - if (ii == (uMACfragNum - 1)) - pLastTD = pHeadTD; - pHeadTD = pHeadTD->next; - } - - // Save the information needed by the tx interrupt handler - // to complete the Send request - pLastTD->pTDInfo->skb = skb; - pLastTD->pTDInfo->byFlags = 0; - pLastTD->pTDInfo->byFlags |= TD_FLAGS_NETIF_SKB; - - pDevice->apCurrTD[TYPE_TXDMA0] = pHeadTD; - - MACvTransmit0(pDevice->PortOffset); - - return true; -} - -//TYPE_AC0DMA data tx -static int device_xmit(struct sk_buff *skb, struct net_device *dev) { - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = pDevice->pMgmt; - PSTxDesc pHeadTD, pLastTD; - unsigned int uNodeIndex = 0; - unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; - unsigned short wAID; - unsigned int uMACfragNum = 1; - unsigned int cbFrameBodySize; - unsigned char byPktType; - unsigned int cbHeaderSize; - bool bNeedEncryption = false; - PSKeyItem pTransmitKey = NULL; - SKeyItem STempKey; - unsigned int ii; - bool bTKIP_UseGTK = false; - bool bNeedDeAuth = false; - unsigned char *pbyBSSID; - bool bNodeExist = false; - - spin_lock_irq(&pDevice->lock); - if (!pDevice->bLinkPass) { - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - - if (pDevice->bStopDataPkt) { - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (pDevice->uAssocCount == 0) { - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - if (is_multicast_ether_addr((unsigned char *)(skb->data))) { - uNodeIndex = 0; - bNodeExist = true; - if (pMgmt->sNodeDBTable[0].bPSEnable) { - skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skb); - pMgmt->sNodeDBTable[0].wEnQueueCnt++; - // set tx map - pMgmt->abyPSTxMap[0] |= byMask[0]; - spin_unlock_irq(&pDevice->lock); - return 0; - } - } else { - if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data), &uNodeIndex)) { - if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) { - skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb); - pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++; - // set tx map - wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID; - pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7]; - pr_debug("Set:pMgmt->abyPSTxMap[%d]= %d\n", - (wAID >> 3), - pMgmt->abyPSTxMap[wAID >> 3]); - spin_unlock_irq(&pDevice->lock); - return 0; - } - - if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) - pDevice->byPreambleType = pDevice->byShortPreamble; - else - pDevice->byPreambleType = PREAMBLE_LONG; - - bNodeExist = true; - - } - } - - if (!bNodeExist) { - pr_debug("Unknown STA not found in node DB\n"); - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - } - - pHeadTD = pDevice->apCurrTD[TYPE_AC0DMA]; - - pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP); - - memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)(skb->data), ETH_HLEN); - cbFrameBodySize = skb->len - ETH_HLEN; - // 802.1H - if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN) - cbFrameBodySize += 8; - - if (pDevice->bEncryptionEnable) { - bNeedEncryption = true; - // get Transmit key - do { - if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - pbyBSSID = pDevice->abyBSSID; - // get pairwise key - if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) { - // get group key - if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) { - bTKIP_UseGTK = true; - pr_debug("Get GTK\n"); - break; - } - } else { - pr_debug("Get PTK\n"); - break; - } - } else if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - pbyBSSID = pDevice->sTxEthHeader.abyDstAddr; //TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1 - pr_debug("IBSS Serach Key:\n"); - for (ii = 0; ii < 6; ii++) - pr_debug("%x\n", *(pbyBSSID+ii)); - pr_debug("\n"); - - // get pairwise key - if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == true) - break; - } - // get group key - pbyBSSID = pDevice->abyBroadcastAddr; - if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) { - pTransmitKey = NULL; - if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) - pr_debug("IBSS and KEY is NULL. [%d]\n", - pDevice->pMgmt->eCurrMode); - else - pr_debug("NOT IBSS and KEY is NULL. [%d]\n", - pDevice->pMgmt->eCurrMode); - } else { - bTKIP_UseGTK = true; - pr_debug("Get GTK\n"); - } - } while (false); - } - - if (pDevice->bEnableHostWEP) { - pr_debug("acdma0: STA index %d\n", uNodeIndex); - if (pDevice->bEncryptionEnable) { - pTransmitKey = &STempKey; - pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite; - pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex; - pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength; - pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16; - pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0; - memcpy(pTransmitKey->abyKey, - &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0], - pTransmitKey->uKeyLength - ); - } - } - - uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader); - - if (uMACfragNum > AVAIL_TD(pDevice, TYPE_AC0DMA)) { - pr_debug("uMACfragNum > AVAIL_TD(TYPE_AC0DMA) = %d\n", - uMACfragNum); - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - - if (pTransmitKey != NULL) { - if ((pTransmitKey->byCipherSuite == KEY_CTL_WEP) && - (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN)) { - uMACfragNum = 1; //WEP256 doesn't support fragment - } - } - - byPktType = (unsigned char)pDevice->byPacketType; - - if (pDevice->bFixRate) { - if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { - if (pDevice->uConnectionRate >= RATE_11M) - pDevice->wCurrentRate = RATE_11M; - else - pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; - } else { - if ((pDevice->eCurrentPHYType == PHY_TYPE_11A) && - (pDevice->uConnectionRate <= RATE_6M)) { - pDevice->wCurrentRate = RATE_6M; - } else { - if (pDevice->uConnectionRate >= RATE_54M) - pDevice->wCurrentRate = RATE_54M; - else - pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; - - } - } - pDevice->byACKRate = (unsigned char) pDevice->wCurrentRate; - pDevice->byTopCCKBasicRate = RATE_1M; - pDevice->byTopOFDMBasicRate = RATE_6M; - } else { - //auto rate - if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) { - if (pDevice->eCurrentPHYType != PHY_TYPE_11A) { - pDevice->wCurrentRate = RATE_1M; - pDevice->byACKRate = RATE_1M; - pDevice->byTopCCKBasicRate = RATE_1M; - pDevice->byTopOFDMBasicRate = RATE_6M; - } else { - pDevice->wCurrentRate = RATE_6M; - pDevice->byACKRate = RATE_6M; - pDevice->byTopCCKBasicRate = RATE_1M; - pDevice->byTopOFDMBasicRate = RATE_6M; - } - } else { - VNTWIFIvGetTxRate(pDevice->pMgmt, - pDevice->sTxEthHeader.abyDstAddr, - &(pDevice->wCurrentRate), - &(pDevice->byACKRate), - &(pDevice->byTopCCKBasicRate), - &(pDevice->byTopOFDMBasicRate)); - - } - } - - - if (pDevice->wCurrentRate <= RATE_11M) { - byPktType = PK_TYPE_11B; - } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { - byPktType = PK_TYPE_11A; - } else { - if (pDevice->bProtectMode) - byPktType = PK_TYPE_11GB; - else - byPktType = PK_TYPE_11GA; - } - - if (bNeedEncryption) { - pr_debug("ntohs Pkt Type=%04x\n", - ntohs(pDevice->sTxEthHeader.wType)); - if ((pDevice->sTxEthHeader.wType) == TYPE_PKT_802_1x) { - bNeedEncryption = false; - pr_debug("Pkt Type=%04x\n", - (pDevice->sTxEthHeader.wType)); - if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - if (pTransmitKey == NULL) { - pr_debug("Don't Find TX KEY\n"); - } else { - if (bTKIP_UseGTK) { - pr_debug("error: KEY is GTK!!~~\n"); - } else { - pr_debug("Find PTK [%lX]\n", - pTransmitKey->dwKeyIndex); - bNeedEncryption = true; - } - } - } - - if (pDevice->byCntMeasure == 2) { - bNeedDeAuth = true; - pDevice->s802_11Counter.TKIPCounterMeasuresInvoked++; - } - - if (pDevice->bEnableHostWEP) { - if ((uNodeIndex != 0) && - (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) { - pr_debug("Find PTK [%lX]\n", - pTransmitKey->dwKeyIndex); - bNeedEncryption = true; - } - } - } else { - if (pTransmitKey == NULL) { - pr_debug("return no tx key\n"); - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - } - } - - vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption, - cbFrameBodySize, TYPE_AC0DMA, pHeadTD, - &pDevice->sTxEthHeader, (unsigned char *)skb->data, pTransmitKey, uNodeIndex, - &uMACfragNum, - &cbHeaderSize - ); - - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { - // Disable PS - MACbPSWakeup(pDevice->PortOffset); - } - pDevice->bPWBitOn = false; - - pLastTD = pHeadTD; - for (ii = 0; ii < uMACfragNum; ii++) { - // Poll Transmit the adapter - wmb(); - pHeadTD->m_td0TD0.f1Owner = OWNED_BY_NIC; - wmb(); - if (ii == uMACfragNum - 1) - pLastTD = pHeadTD; - pHeadTD = pHeadTD->next; - } - - // Save the information needed by the tx interrupt handler - // to complete the Send request - pLastTD->pTDInfo->skb = skb; - pLastTD->pTDInfo->byFlags = 0; - pLastTD->pTDInfo->byFlags |= TD_FLAGS_NETIF_SKB; - pDevice->nTxDataTimeCout = 0; //2008-8-21 chester <add> for send null packet - - if (AVAIL_TD(pDevice, TYPE_AC0DMA) <= 1) - netif_stop_queue(dev); - - pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD; - - if (pDevice->bFixRate) - pr_debug("FixRate:Rate is %d,TxPower is %d\n", pDevice->wCurrentRate, pDevice->byCurPwr); - - { - unsigned char Protocol_Version; //802.1x Authentication - unsigned char Packet_Type; //802.1x Authentication - unsigned char Descriptor_type; - unsigned short Key_info; - bool bTxeapol_key = false; - - Protocol_Version = skb->data[ETH_HLEN]; - Packet_Type = skb->data[ETH_HLEN+1]; - Descriptor_type = skb->data[ETH_HLEN+1+1+2]; - Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]); - if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) { - if (((Protocol_Version == 1) || (Protocol_Version == 2)) && - (Packet_Type == 3)) { //802.1x OR eapol-key challenge frame transfer - bTxeapol_key = true; - if ((Descriptor_type == 254) || (Descriptor_type == 2)) { //WPA or RSN - if (!(Key_info & BIT3) && //group-key challenge - (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key - pDevice->fWPA_Authened = true; - if (Descriptor_type == 254) - pr_debug("WPA "); - else - pr_debug("WPA2 "); - pr_debug("Authentication completed!!\n"); - } - } - } - } - } - - MACvTransmitAC0(pDevice->PortOffset); - - dev->trans_start = jiffies; - - spin_unlock_irq(&pDevice->lock); - return 0; -} - static irqreturn_t device_intr(int irq, void *dev_instance) { - struct net_device *dev = dev_instance; - struct vnt_private *pDevice = netdev_priv(dev); + struct vnt_private *pDevice = dev_instance; int max_count = 0; unsigned long dwMIBCounter = 0; - PSMgmtObject pMgmt = pDevice->pMgmt; unsigned char byOrgPageSel = 0; int handled = 0; - unsigned char byData = 0; int ii = 0; unsigned long flags; @@ -2256,96 +1102,13 @@ static irqreturn_t device_intr(int irq, void *dev_instance) device_error(pDevice, pDevice->dwIsr); } - if (pDevice->byLocalID > REV_ID_VT3253_B1) { - if (pDevice->dwIsr & ISR_MEASURESTART) { - // 802.11h measure start - pDevice->byOrgChannel = pDevice->byCurrentCh; - VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byOrgRCR)); - VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, (RCR_RXALLTYPE | RCR_UNICAST | RCR_BROADCAST | RCR_MULTICAST | RCR_WPAERR)); - MACvSelectPage1(pDevice->PortOffset); - VNSvInPortD(pDevice->PortOffset + MAC_REG_MAR0, &(pDevice->dwOrgMAR0)); - VNSvInPortD(pDevice->PortOffset + MAC_REG_MAR4, &(pDevice->dwOrgMAR4)); - MACvSelectPage0(pDevice->PortOffset); - //xxxx - if (set_channel(pDevice, pDevice->pCurrMeasureEID->sReq.byChannel)) { - pDevice->bMeasureInProgress = true; - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_READY); - MACvSelectPage0(pDevice->PortOffset); - pDevice->byBasicMap = 0; - pDevice->byCCAFraction = 0; - for (ii = 0; ii < 8; ii++) - pDevice->dwRPIs[ii] = 0; - - } else { - // can not measure because set channel fail - // clear measure control - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN); - s_vCompleteCurrentMeasure(pDevice, MEASURE_MODE_INCAPABLE); - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); - MACvSelectPage0(pDevice->PortOffset); - } - } - if (pDevice->dwIsr & ISR_MEASUREEND) { - // 802.11h measure end - pDevice->bMeasureInProgress = false; - VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byOrgRCR); - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, pDevice->dwOrgMAR0); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR4, pDevice->dwOrgMAR4); - VNSvInPortB(pDevice->PortOffset + MAC_REG_MSRBBSTS, &byData); - pDevice->byBasicMap |= (byData >> 4); - VNSvInPortB(pDevice->PortOffset + MAC_REG_CCAFRACTION, &pDevice->byCCAFraction); - VNSvInPortB(pDevice->PortOffset + MAC_REG_MSRCTL, &byData); - // clear measure control - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN); - MACvSelectPage0(pDevice->PortOffset); - set_channel(pDevice, pDevice->byOrgChannel); - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); - MACvSelectPage0(pDevice->PortOffset); - if (byData & MSRCTL_FINISH) { - // measure success - s_vCompleteCurrentMeasure(pDevice, 0); - } else { - // can not measure because not ready before end of measure time - s_vCompleteCurrentMeasure(pDevice, MEASURE_MODE_LATE); - } - } - if (pDevice->dwIsr & ISR_QUIETSTART) { - do { - ; - } while (!CARDbStartQuiet(pDevice)); - } - } - if (pDevice->dwIsr & ISR_TBTT) { - if (pDevice->bEnableFirstQuiet) { - pDevice->byQuietStartCount--; - if (pDevice->byQuietStartCount == 0) { - pDevice->bEnableFirstQuiet = false; - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN)); - MACvSelectPage0(pDevice->PortOffset); - } - } - if (pDevice->bChannelSwitch && - (pDevice->op_mode == NL80211_IFTYPE_STATION)) { - pDevice->byChannelSwitchCount--; - if (pDevice->byChannelSwitchCount == 0) { - pDevice->bChannelSwitch = false; - set_channel(pDevice, pDevice->byNewChannel); - VNTWIFIbChannelSwitch(pDevice->pMgmt, pDevice->byNewChannel); - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); - MACvSelectPage0(pDevice->PortOffset); - CARDbStartTxPacket(pDevice, PKT_TYPE_802_11_ALL); - - } - } - if (pDevice->op_mode != NL80211_IFTYPE_ADHOC) { - if ((pDevice->bUpdateBBVGA) && pDevice->bLinkPass && (pDevice->uCurrRSSI != 0)) { + if (pDevice->vif && + pDevice->op_mode != NL80211_IFTYPE_ADHOC) { + if (pDevice->bUpdateBBVGA && + !(pDevice->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) && + pDevice->vif->bss_conf.assoc && + pDevice->uCurrRSSI) { long ldBm; RFvRSSITodBm(pDevice, (unsigned char) pDevice->uCurrRSSI, &ldBm); @@ -2384,10 +1147,11 @@ static irqreturn_t device_intr(int irq, void *dev_instance) if (pDevice->bEnablePSMode) PSbIsNextTBTTWakeUp((void *)pDevice); - if ((pDevice->op_mode == NL80211_IFTYPE_AP) || - (pDevice->op_mode == NL80211_IFTYPE_ADHOC)) { + if ((pDevice->op_mode == NL80211_IFTYPE_AP || + pDevice->op_mode == NL80211_IFTYPE_ADHOC) && + pDevice->vif->bss_conf.enable_beacon) { MACvOneShotTimer1MicroSec(pDevice->PortOffset, - (pMgmt->wIBSSBeaconPeriod - MAKE_BEACON_RESERVED) << 10); + (pDevice->vif->bss_conf.beacon_int - MAKE_BEACON_RESERVED) << 10); } /* TODO: adhoc PS mode */ @@ -2400,34 +1164,7 @@ static irqreturn_t device_intr(int irq, void *dev_instance) pDevice->cbBeaconBufReadySetCnt = 0; } - if (pDevice->op_mode == NL80211_IFTYPE_AP) { - if (pMgmt->byDTIMCount > 0) { - pMgmt->byDTIMCount--; - pMgmt->sNodeDBTable[0].bRxPSPoll = false; - } else { - if (pMgmt->byDTIMCount == 0) { - // check if mutltcast tx bufferring - pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1; - pMgmt->sNodeDBTable[0].bRxPSPoll = true; - bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); - } - } - } pDevice->bBeaconSent = true; - - if (pDevice->bChannelSwitch) { - pDevice->byChannelSwitchCount--; - if (pDevice->byChannelSwitchCount == 0) { - pDevice->bChannelSwitch = false; - set_channel(pDevice, pDevice->byNewChannel); - VNTWIFIbChannelSwitch(pDevice->pMgmt, pDevice->byNewChannel); - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); - MACvSelectPage0(pDevice->PortOffset); - CARDbStartTxPacket(pDevice, PKT_TYPE_802_11_ALL); - } - } - } if (pDevice->dwIsr & ISR_RXDMA0) @@ -2443,14 +1180,18 @@ static irqreturn_t device_intr(int irq, void *dev_instance) max_count += device_tx_srv(pDevice, TYPE_AC0DMA); if (pDevice->dwIsr & ISR_SOFTTIMER1) { - if (pDevice->op_mode == NL80211_IFTYPE_AP) { - if (pDevice->bShortSlotTime) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1); - else - pMgmt->wCurrCapInfo &= ~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1)); + if (pDevice->vif) { + if (pDevice->vif->bss_conf.enable_beacon) + vnt_beacon_make(pDevice, pDevice->vif); } - bMgrPrepareBeaconToSend(pDevice, pMgmt); - pDevice->byCntMeasure = 0; + } + + /* If both buffers available wake the queue */ + if (pDevice->vif) { + if (AVAIL_TD(pDevice, TYPE_TXDMA0) && + AVAIL_TD(pDevice, TYPE_AC0DMA) && + ieee80211_queue_stopped(pDevice->hw, 0)) + ieee80211_wake_queues(pDevice->hw); } MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr); @@ -2472,550 +1213,662 @@ static irqreturn_t device_intr(int irq, void *dev_instance) return IRQ_RETVAL(handled); } -//2008-8-4 <add> by chester -static int Config_FileGetParameter(unsigned char *string, - unsigned char *dest, unsigned char *source) +static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) { - unsigned char buf1[100]; - int source_len = strlen(source); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + PSTxDesc head_td; + u32 dma_idx = TYPE_AC0DMA; + unsigned long flags; - memset(buf1, 0, 100); - strcat(buf1, string); - strcat(buf1, "="); - source += strlen(buf1); + spin_lock_irqsave(&priv->lock, flags); - memcpy(dest, source, source_len - strlen(buf1)); - return true; -} + if (!ieee80211_is_data(hdr->frame_control)) + dma_idx = TYPE_TXDMA0; -int Config_FileOperation(struct vnt_private *pDevice, - bool fwrite, unsigned char *Parameter) -{ - unsigned char *buffer = kmalloc(1024, GFP_KERNEL); - unsigned char tmpbuffer[20]; - struct file *file; - int result = 0; - - if (!buffer) { - pr_err("allocate mem for file fail?\n"); - return -1; - } - file = filp_open(CONFIG_PATH, O_RDONLY, 0); - if (IS_ERR(file)) { - kfree(buffer); - pr_err("Config_FileOperation:open file fail?\n"); - return -1; + if (AVAIL_TD(priv, dma_idx) < 1) { + spin_unlock_irqrestore(&priv->lock, flags); + return -ENOMEM; } - if (kernel_read(file, 0, buffer, 1024) < 0) { - pr_err("read file error?\n"); - result = -1; - goto error1; - } + head_td = priv->apCurrTD[dma_idx]; - if (Config_FileGetParameter("ZONETYPE", tmpbuffer, buffer) != true) { - pr_err("get parameter error?\n"); - result = -1; - goto error1; - } + head_td->m_td1TD1.byTCR = 0; - if (memcmp(tmpbuffer, "USA", 3) == 0) { - result = ZoneType_USA; - } else if (memcmp(tmpbuffer, "JAPAN", 5) == 0) { - result = ZoneType_Japan; - } else if (memcmp(tmpbuffer, "EUROPE", 5) == 0) { - result = ZoneType_Europe; - } else { - result = -1; - pr_err("Unknown Zonetype[%s]?\n", tmpbuffer); - } + head_td->pTDInfo->skb = skb; + + priv->iTDUsed[dma_idx]++; + + /* Take ownership */ + wmb(); + head_td->m_td0TD0.f1Owner = OWNED_BY_NIC; + + /* get Next */ + wmb(); + priv->apCurrTD[dma_idx] = head_td->next; + + spin_unlock_irqrestore(&priv->lock, flags); + + vnt_generate_fifo_header(priv, dma_idx, head_td, skb); + + if (MACbIsRegBitsOn(priv->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) + MACbPSWakeup(priv->PortOffset); + + spin_lock_irqsave(&priv->lock, flags); -error1: - kfree(buffer); - fput(file); - return result; + priv->bPWBitOn = false; + + /* Set TSR1 & ReqCount in TxDescHead */ + head_td->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); + head_td->m_td1TD1.wReqCount = + cpu_to_le16((u16)head_td->pTDInfo->dwReqCount); + + head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB; + + if (dma_idx == TYPE_AC0DMA) + MACvTransmitAC0(priv->PortOffset); + else + MACvTransmit0(priv->PortOffset); + + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; } -static void device_set_multi(struct net_device *dev) { - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = pDevice->pMgmt; - u32 mc_filter[2]; - struct netdev_hw_addr *ha; +static void vnt_tx_80211(struct ieee80211_hw *hw, + struct ieee80211_tx_control *control, + struct sk_buff *skb) +{ + struct vnt_private *priv = hw->priv; - VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode)); + ieee80211_stop_queues(hw); - if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ - pr_notice("%s: Promiscuous mode enabled\n", dev->name); - /* Unconditionally log net taps. */ - pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST); - } else if ((netdev_mc_count(dev) > pDevice->multicast_limit) - || (dev->flags & IFF_ALLMULTI)) { - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, 0xffffffff); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0 + 4, 0xffffffff); - MACvSelectPage0(pDevice->PortOffset); - pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST); - } else { - memset(mc_filter, 0, sizeof(mc_filter)); - netdev_for_each_mc_addr(ha, dev) { - int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26; + if (vnt_tx_packet(priv, skb)) { + ieee80211_free_txskb(hw, skb); - mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31)); - } - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, mc_filter[0]); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0 + 4, mc_filter[1]); - MACvSelectPage0(pDevice->PortOffset); - pDevice->byRxMode &= ~(RCR_UNICAST); - pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST); + ieee80211_wake_queues(hw); } +} + +static int vnt_start(struct ieee80211_hw *hw) +{ + struct vnt_private *priv = hw->priv; + int ret; + + priv->rx_buf_sz = PKT_BUF_SZ; + if (!device_init_rings(priv)) + return -ENOMEM; - if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { - // If AP mode, don't enable RCR_UNICAST. Since hw only compare addr1 with local mac. - pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST); - pDevice->byRxMode &= ~(RCR_UNICAST); + ret = request_irq(priv->pcid->irq, &device_intr, + IRQF_SHARED, "vt6655", priv); + if (ret) { + dev_dbg(&priv->pcid->dev, "failed to start irq\n"); + return ret; } - VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byRxMode); - pr_debug("pDevice->byRxMode = %x\n", pDevice->byRxMode); + dev_dbg(&priv->pcid->dev, "call device init rd0 ring\n"); + device_init_rd0_ring(priv); + device_init_rd1_ring(priv); + device_init_td0_ring(priv); + device_init_td1_ring(priv); + + device_init_registers(priv); + + dev_dbg(&priv->pcid->dev, "call MACvIntEnable\n"); + MACvIntEnable(priv->PortOffset, IMR_MASK_VALUE); + + ieee80211_wake_queues(hw); + + return 0; } -static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +static void vnt_stop(struct ieee80211_hw *hw) { - struct vnt_private *pDevice = netdev_priv(dev); - struct iwreq *wrq = (struct iwreq *)rq; - int rc = 0; - PSMgmtObject pMgmt = pDevice->pMgmt; - PSCmdRequest pReq; - - if (pMgmt == NULL) { - rc = -EFAULT; - return rc; - } + struct vnt_private *priv = hw->priv; - switch (cmd) { - case SIOCGIWNAME: - rc = iwctl_giwname(dev, NULL, (char *)&(wrq->u.name), NULL); - break; + ieee80211_stop_queues(hw); + + MACbShutdown(priv->PortOffset); + MACbSoftwareReset(priv->PortOffset); + CARDbRadioPowerOff(priv); + + device_free_td0_ring(priv); + device_free_td1_ring(priv); + device_free_rd0_ring(priv); + device_free_rd1_ring(priv); + device_free_rings(priv); + + free_irq(priv->pcid->irq, priv); +} + +static int vnt_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct vnt_private *priv = hw->priv; - case SIOCGIWNWID: //0x8b03 support - rc = -EOPNOTSUPP; + priv->vif = vif; + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + if (priv->bDiversityRegCtlON) + device_init_diversity_timer(priv); break; + case NL80211_IFTYPE_ADHOC: + MACvRegBitsOff(priv->PortOffset, MAC_REG_RCR, RCR_UNICAST); + + MACvRegBitsOn(priv->PortOffset, MAC_REG_HOSTCR, HOSTCR_ADHOC); - // Set frequency/channel - case SIOCSIWFREQ: - rc = iwctl_siwfreq(dev, NULL, &(wrq->u.freq), NULL); break; + case NL80211_IFTYPE_AP: + MACvRegBitsOff(priv->PortOffset, MAC_REG_RCR, RCR_UNICAST); + + MACvRegBitsOn(priv->PortOffset, MAC_REG_HOSTCR, HOSTCR_AP); - // Get frequency/channel - case SIOCGIWFREQ: - rc = iwctl_giwfreq(dev, NULL, &(wrq->u.freq), NULL); break; + default: + return -EOPNOTSUPP; + } - // Set desired network name (ESSID) - case SIOCSIWESSID: + priv->op_mode = vif->type; - { - char essid[IW_ESSID_MAX_SIZE+1]; + return 0; +} - if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) { - rc = -E2BIG; - break; - } - if (copy_from_user(essid, wrq->u.essid.pointer, - wrq->u.essid.length)) { - rc = -EFAULT; - break; +static void vnt_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct vnt_private *priv = hw->priv; + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + if (priv->bDiversityRegCtlON) { + del_timer(&priv->TimerSQ3Tmax1); + del_timer(&priv->TimerSQ3Tmax2); + del_timer(&priv->TimerSQ3Tmax3); } - rc = iwctl_siwessid(dev, NULL, - &(wrq->u.essid), essid); + break; + case NL80211_IFTYPE_ADHOC: + MACvRegBitsOff(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); + MACvRegBitsOff(priv->PortOffset, + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); + MACvRegBitsOff(priv->PortOffset, MAC_REG_HOSTCR, HOSTCR_ADHOC); + break; + case NL80211_IFTYPE_AP: + MACvRegBitsOff(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); + MACvRegBitsOff(priv->PortOffset, + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); + MACvRegBitsOff(priv->PortOffset, MAC_REG_HOSTCR, HOSTCR_AP); + break; + default: + break; } - break; - // Get current network name (ESSID) - case SIOCGIWESSID: + priv->op_mode = NL80211_IFTYPE_UNSPECIFIED; +} - { - char essid[IW_ESSID_MAX_SIZE+1]; - - if (wrq->u.essid.pointer) - rc = iwctl_giwessid(dev, NULL, - &(wrq->u.essid), essid); - if (copy_to_user(wrq->u.essid.pointer, - essid, - wrq->u.essid.length)) - rc = -EFAULT; + +static int vnt_config(struct ieee80211_hw *hw, u32 changed) +{ + struct vnt_private *priv = hw->priv; + struct ieee80211_conf *conf = &hw->conf; + u8 bb_type; + + if (changed & IEEE80211_CONF_CHANGE_PS) { + if (conf->flags & IEEE80211_CONF_PS) + PSvEnablePowerSaving(priv, conf->listen_interval); + else + PSvDisablePowerSaving(priv); } - break; - case SIOCSIWAP: + if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || + (conf->flags & IEEE80211_CONF_OFFCHANNEL)) { + set_channel(priv, conf->chandef.chan->hw_value); - rc = iwctl_siwap(dev, NULL, &(wrq->u.ap_addr), NULL); - break; + if (conf->chandef.chan->band == IEEE80211_BAND_5GHZ) + bb_type = BB_TYPE_11A; + else + bb_type = BB_TYPE_11G; - // Get current Access Point (BSSID) - case SIOCGIWAP: - rc = iwctl_giwap(dev, NULL, &(wrq->u.ap_addr), NULL); - break; + if (priv->byBBType != bb_type) { + priv->byBBType = bb_type; - // Set desired station name - case SIOCSIWNICKN: - pr_debug(" SIOCSIWNICKN\n"); - rc = -EOPNOTSUPP; - break; + CARDbSetPhyParameter(priv, priv->byBBType); + } + } - // Get current station name - case SIOCGIWNICKN: - pr_debug(" SIOCGIWNICKN\n"); - rc = -EOPNOTSUPP; - break; + if (changed & IEEE80211_CONF_CHANGE_POWER) { + if (priv->byBBType == BB_TYPE_11B) + priv->wCurrentRate = RATE_1M; + else + priv->wCurrentRate = RATE_54M; - // Set the desired bit-rate - case SIOCSIWRATE: - rc = iwctl_siwrate(dev, NULL, &(wrq->u.bitrate), NULL); - break; + RFbSetPower(priv, priv->wCurrentRate, + conf->chandef.chan->hw_value); + } - // Get the current bit-rate - case SIOCGIWRATE: + return 0; +} - rc = iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL); - break; +static void vnt_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, struct ieee80211_bss_conf *conf, + u32 changed) +{ + struct vnt_private *priv = hw->priv; - // Set the desired RTS threshold - case SIOCSIWRTS: + priv->current_aid = conf->aid; - rc = iwctl_siwrts(dev, NULL, &(wrq->u.rts), NULL); - break; + if (changed & BSS_CHANGED_BSSID) + MACvWriteBSSIDAddress(priv->PortOffset, (u8 *)conf->bssid); - // Get the current RTS threshold - case SIOCGIWRTS: + if (changed & BSS_CHANGED_BASIC_RATES) { + priv->basic_rates = conf->basic_rates; - rc = iwctl_giwrts(dev, NULL, &(wrq->u.rts), NULL); - break; + CARDvUpdateBasicTopRate(priv); - // Set the desired fragmentation threshold - case SIOCSIWFRAG: + dev_dbg(&priv->pcid->dev, + "basic rates %x\n", conf->basic_rates); + } - rc = iwctl_siwfrag(dev, NULL, &(wrq->u.frag), NULL); - break; + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + if (conf->use_short_preamble) { + MACvEnableBarkerPreambleMd(priv->PortOffset); + priv->byPreambleType = true; + } else { + MACvDisableBarkerPreambleMd(priv->PortOffset); + priv->byPreambleType = false; + } + } - // Get the current fragmentation threshold - case SIOCGIWFRAG: + if (changed & BSS_CHANGED_ERP_CTS_PROT) { + if (conf->use_cts_prot) + MACvEnableProtectMD(priv->PortOffset); + else + MACvDisableProtectMD(priv->PortOffset); + } - rc = iwctl_giwfrag(dev, NULL, &(wrq->u.frag), NULL); - break; + if (changed & BSS_CHANGED_ERP_SLOT) { + if (conf->use_short_slot) + priv->bShortSlotTime = true; + else + priv->bShortSlotTime = false; - // Set mode of operation - case SIOCSIWMODE: - rc = iwctl_siwmode(dev, NULL, &(wrq->u.mode), NULL); - break; + CARDbSetPhyParameter(priv, priv->byBBType); + BBvSetVGAGainOffset(priv, priv->abyBBVGA[0]); + } - // Get mode of operation - case SIOCGIWMODE: - rc = iwctl_giwmode(dev, NULL, &(wrq->u.mode), NULL); - break; + if (changed & BSS_CHANGED_TXPOWER) + RFbSetPower(priv, priv->wCurrentRate, + conf->chandef.chan->hw_value); - // Set WEP keys and mode - case SIOCSIWENCODE: { - char abyKey[WLAN_WEP232_KEYLEN]; + if (changed & BSS_CHANGED_BEACON_ENABLED) { + dev_dbg(&priv->pcid->dev, + "Beacon enable %d\n", conf->enable_beacon); - if (wrq->u.encoding.pointer) { - if (wrq->u.encoding.length > WLAN_WEP232_KEYLEN) { - rc = -E2BIG; - break; - } - memset(abyKey, 0, WLAN_WEP232_KEYLEN); - if (copy_from_user(abyKey, - wrq->u.encoding.pointer, - wrq->u.encoding.length)) { - rc = -EFAULT; - break; - } - } else if (wrq->u.encoding.length != 0) { - rc = -EINVAL; - break; + if (conf->enable_beacon) { + vnt_beacon_enable(priv, vif, conf); + + MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, + TCR_AUTOBCNTX); + } else { + MACvRegBitsOff(priv->PortOffset, MAC_REG_TCR, + TCR_AUTOBCNTX); } - rc = iwctl_siwencode(dev, NULL, &(wrq->u.encoding), abyKey); } - break; - // Get the WEP keys and mode - case SIOCGIWENCODE: + if (changed & BSS_CHANGED_ASSOC && priv->op_mode != NL80211_IFTYPE_AP) { + if (conf->assoc) { + CARDbUpdateTSF(priv, conf->beacon_rate->hw_value, + conf->sync_device_ts, conf->sync_tsf); - if (!capable(CAP_NET_ADMIN)) { - rc = -EPERM; - break; + CARDbSetBeaconPeriod(priv, conf->beacon_int); + + CARDvSetFirstNextTBTT(priv, conf->beacon_int); + } else { + VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, + TFTCTL_TSFCNTRST); + VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, + TFTCTL_TSFCNTREN); } - { - char abyKey[WLAN_WEP232_KEYLEN]; + } +} - rc = iwctl_giwencode(dev, NULL, &(wrq->u.encoding), abyKey); - if (rc != 0) - break; - if (wrq->u.encoding.pointer) { - if (copy_to_user(wrq->u.encoding.pointer, - abyKey, - wrq->u.encoding.length)) - rc = -EFAULT; +static u64 vnt_prepare_multicast(struct ieee80211_hw *hw, + struct netdev_hw_addr_list *mc_list) +{ + struct vnt_private *priv = hw->priv; + struct netdev_hw_addr *ha; + u64 mc_filter = 0; + u32 bit_nr = 0; + + netdev_hw_addr_list_for_each(ha, mc_list) { + bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26; + + mc_filter |= 1ULL << (bit_nr & 0x3f); + } + + priv->mc_list_count = mc_list->count; + + return mc_filter; +} + +static void vnt_configure(struct ieee80211_hw *hw, + unsigned int changed_flags, unsigned int *total_flags, u64 multicast) +{ + struct vnt_private *priv = hw->priv; + u8 rx_mode = 0; + + *total_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_PROMISC_IN_BSS | + FIF_BCN_PRBRESP_PROMISC; + + VNSvInPortB(priv->PortOffset + MAC_REG_RCR, &rx_mode); + + dev_dbg(&priv->pcid->dev, "rx mode in = %x\n", rx_mode); + + if (changed_flags & FIF_PROMISC_IN_BSS) { + /* unconditionally log net taps */ + if (*total_flags & FIF_PROMISC_IN_BSS) + rx_mode |= RCR_UNICAST; + else + rx_mode &= ~RCR_UNICAST; + } + + if (changed_flags & FIF_ALLMULTI) { + if (*total_flags & FIF_ALLMULTI) { + if (priv->mc_list_count > 2) { + MACvSelectPage1(priv->PortOffset); + + VNSvOutPortD(priv->PortOffset + + MAC_REG_MAR0, 0xffffffff); + VNSvOutPortD(priv->PortOffset + + MAC_REG_MAR0 + 4, 0xffffffff); + + MACvSelectPage0(priv->PortOffset); + } else { + MACvSelectPage1(priv->PortOffset); + + VNSvOutPortD(priv->PortOffset + + MAC_REG_MAR0, (u32)multicast); + VNSvOutPortD(priv->PortOffset + + MAC_REG_MAR0 + 4, + (u32)(multicast >> 32)); + + MACvSelectPage0(priv->PortOffset); } + + rx_mode |= RCR_MULTICAST | RCR_BROADCAST; + } else { + rx_mode &= ~(RCR_MULTICAST | RCR_BROADCAST); } - break; + } - // Get the current Tx-Power - case SIOCGIWTXPOW: - pr_debug(" SIOCGIWTXPOW\n"); - rc = -EOPNOTSUPP; - break; + if (changed_flags & (FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC)) { + rx_mode |= RCR_MULTICAST | RCR_BROADCAST; - case SIOCSIWTXPOW: - pr_debug(" SIOCSIWTXPOW\n"); - rc = -EOPNOTSUPP; - break; + if (*total_flags & (FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC)) + rx_mode &= ~RCR_BSSID; + else + rx_mode |= RCR_BSSID; + } - case SIOCSIWRETRY: + VNSvOutPortB(priv->PortOffset + MAC_REG_RCR, rx_mode); - rc = iwctl_siwretry(dev, NULL, &(wrq->u.retry), NULL); - break; + dev_dbg(&priv->pcid->dev, "rx mode out= %x\n", rx_mode); +} - case SIOCGIWRETRY: +static int vnt_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + struct vnt_private *priv = hw->priv; - rc = iwctl_giwretry(dev, NULL, &(wrq->u.retry), NULL); + switch (cmd) { + case SET_KEY: + if (vnt_set_keys(hw, sta, vif, key)) + return -EOPNOTSUPP; + break; + case DISABLE_KEY: + if (test_bit(key->hw_key_idx, &priv->key_entry_inuse)) + clear_bit(key->hw_key_idx, &priv->key_entry_inuse); + default: break; + } - // Get range of parameters - case SIOCGIWRANGE: + return 0; +} - { - struct iw_range range; +static u64 vnt_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct vnt_private *priv = hw->priv; + u64 tsf; - rc = iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *)&range); - if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range))) - rc = -EFAULT; - } + CARDbGetCurrentTSF(priv, &tsf); - break; + return tsf; +} - case SIOCGIWPOWER: +static void vnt_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u64 tsf) +{ + struct vnt_private *priv = hw->priv; - rc = iwctl_giwpower(dev, NULL, &(wrq->u.power), NULL); - break; + CARDvUpdateNextTBTT(priv, tsf, vif->bss_conf.beacon_int); +} - case SIOCSIWPOWER: +static void vnt_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct vnt_private *priv = hw->priv; - rc = iwctl_siwpower(dev, NULL, &(wrq->u.power), NULL); - break; + /* reset TSF counter */ + VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); +} - case SIOCGIWSENS: +static const struct ieee80211_ops vnt_mac_ops = { + .tx = vnt_tx_80211, + .start = vnt_start, + .stop = vnt_stop, + .add_interface = vnt_add_interface, + .remove_interface = vnt_remove_interface, + .config = vnt_config, + .bss_info_changed = vnt_bss_info_changed, + .prepare_multicast = vnt_prepare_multicast, + .configure_filter = vnt_configure, + .set_key = vnt_set_key, + .get_tsf = vnt_get_tsf, + .set_tsf = vnt_set_tsf, + .reset_tsf = vnt_reset_tsf, +}; - rc = iwctl_giwsens(dev, NULL, &(wrq->u.sens), NULL); - break; +int vnt_init(struct vnt_private *priv) +{ + SET_IEEE80211_PERM_ADDR(priv->hw, priv->abyCurrentNetAddr); - case SIOCSIWSENS: - pr_debug(" SIOCSIWSENS\n"); - rc = -EOPNOTSUPP; - break; + vnt_init_bands(priv); - case SIOCGIWAPLIST: { - char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))]; - - if (wrq->u.data.pointer) { - rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer); - if (rc == 0) { - if (copy_to_user(wrq->u.data.pointer, - buffer, - (wrq->u.data.length * (sizeof(struct sockaddr) + sizeof(struct iw_quality))) - )) - rc = -EFAULT; - } - } - } - break; + if (ieee80211_register_hw(priv->hw)) + return -ENODEV; -#ifdef WIRELESS_SPY - // Set the spy list - case SIOCSIWSPY: + priv->mac_hw = true; - pr_debug(" SIOCSIWSPY\n"); - rc = -EOPNOTSUPP; - break; + CARDbRadioPowerOff(priv); - // Get the spy list - case SIOCGIWSPY: + return 0; +} - pr_debug(" SIOCGIWSPY\n"); - rc = -EOPNOTSUPP; - break; +static int +vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) +{ + PCHIP_INFO pChip_info = (PCHIP_INFO)ent->driver_data; + struct vnt_private *priv; + struct ieee80211_hw *hw; + struct wiphy *wiphy; + int rc; -#endif // WIRELESS_SPY + dev_notice(&pcid->dev, + "%s Ver. %s\n", DEVICE_FULL_DRV_NAM, DEVICE_VERSION); - case SIOCGIWPRIV: - pr_debug(" SIOCGIWPRIV\n"); - rc = -EOPNOTSUPP; - break; + dev_notice(&pcid->dev, + "Copyright (c) 2003 VIA Networking Technologies, Inc.\n"); -//2008-0409-07, <Add> by Einsn Liu -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - case SIOCSIWAUTH: - pr_debug(" SIOCSIWAUTH\n"); - rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL); - break; + hw = ieee80211_alloc_hw(sizeof(*priv), &vnt_mac_ops); + if (!hw) { + dev_err(&pcid->dev, "could not register ieee80211_hw\n"); + return -ENOMEM; + } - case SIOCGIWAUTH: - pr_debug(" SIOCGIWAUTH\n"); - rc = iwctl_giwauth(dev, NULL, &(wrq->u.param), NULL); - break; + priv = hw->priv; - case SIOCSIWGENIE: - pr_debug(" SIOCSIWGENIE\n"); - rc = iwctl_siwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer); - break; + vt6655_init_info(pcid, &priv, pChip_info); - case SIOCGIWGENIE: - pr_debug(" SIOCGIWGENIE\n"); - rc = iwctl_giwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer); - break; + priv->hw = hw; - case SIOCSIWENCODEEXT: { - char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1]; + SET_IEEE80211_DEV(priv->hw, &pcid->dev); - pr_debug(" SIOCSIWENCODEEXT\n"); - if (wrq->u.encoding.pointer) { - memset(extra, 0, sizeof(struct iw_encode_ext)+MAX_KEY_LEN + 1); - if (wrq->u.encoding.length > (sizeof(struct iw_encode_ext) + MAX_KEY_LEN)) { - rc = -E2BIG; - break; - } - if (copy_from_user(extra, wrq->u.encoding.pointer, wrq->u.encoding.length)) { - rc = -EFAULT; - break; - } - } else if (wrq->u.encoding.length != 0) { - rc = -EINVAL; - break; - } - rc = iwctl_siwencodeext(dev, NULL, &(wrq->u.encoding), extra); + if (pci_enable_device(pcid)) { + device_free_info(priv); + return -ENODEV; } - break; - case SIOCGIWENCODEEXT: - pr_debug(" SIOCGIWENCODEEXT\n"); - rc = iwctl_giwencodeext(dev, NULL, &(wrq->u.encoding), NULL); - break; + dev_dbg(&pcid->dev, + "Before get pci_info memaddr is %x\n", priv->memaddr); - case SIOCSIWMLME: - pr_debug(" SIOCSIWMLME\n"); - rc = iwctl_siwmlme(dev, NULL, &(wrq->u.data), wrq->u.data.pointer); - break; + if (!device_get_pci_info(priv, pcid)) { + dev_err(&pcid->dev, ": Failed to find PCI device.\n"); + device_free_info(priv); + return -ENODEV; + } + +#ifdef DEBUG + dev_dbg(&pcid->dev, + "after get pci_info memaddr is %x, io addr is %x,io_size is %d\n", + priv->memaddr, priv->ioaddr, priv->io_size); + { + int i; + u32 bar, len; + u32 address[] = { + PCI_BASE_ADDRESS_0, + PCI_BASE_ADDRESS_1, + PCI_BASE_ADDRESS_2, + PCI_BASE_ADDRESS_3, + PCI_BASE_ADDRESS_4, + PCI_BASE_ADDRESS_5, + 0}; + for (i = 0; address[i]; i++) { + pci_read_config_dword(pcid, address[i], &bar); -#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -//End Add -- //2008-0409-07, <Add> by Einsn Liu + dev_dbg(&pcid->dev, "bar %d is %x\n", i, bar); - case IOCTL_CMD_TEST: + if (!bar) { + dev_dbg(&pcid->dev, + "bar %d not implemented\n", i); + continue; + } - if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) { - rc = -EFAULT; - break; - } else { - rc = 0; - } - pReq = (PSCmdRequest)rq; - pReq->wResult = MAGIC_CODE; - break; + if (bar & PCI_BASE_ADDRESS_SPACE_IO) { + /* This is IO */ - case IOCTL_CMD_SET: + len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xffff); + len = len & ~(len - 1); -#ifdef SndEvt_ToAPI - if ((((PSCmdRequest)rq)->wCmdCode != WLAN_CMD_SET_EVT) && - !(pDevice->flags & DEVICE_FLAGS_OPENED)) -#else - if (!(pDevice->flags & DEVICE_FLAGS_OPENED) && - (((PSCmdRequest)rq)->wCmdCode != WLAN_CMD_SET_WPA)) -#endif - { - rc = -EFAULT; - break; + dev_dbg(&pcid->dev, + "IO space: len in IO %x, BAR %d\n", + len, i); } else { - rc = 0; + len = bar & 0xfffffff0; + len = ~len + 1; + + dev_dbg(&pcid->dev, + "len in MEM %x, BAR %d\n", len, i); } + } + } +#endif - if (test_and_set_bit(0, (void *)&(pMgmt->uCmdBusy))) - return -EBUSY; + priv->PortOffset = ioremap(priv->memaddr & PCI_BASE_ADDRESS_MEM_MASK, + priv->io_size); + if (!priv->PortOffset) { + dev_err(&pcid->dev, ": Failed to IO remapping ..\n"); + device_free_info(priv); + return -ENODEV; + } - rc = private_ioctl(pDevice, rq); - clear_bit(0, (void *)&(pMgmt->uCmdBusy)); - break; + rc = pci_request_regions(pcid, DEVICE_NAME); + if (rc) { + dev_err(&pcid->dev, ": Failed to find PCI device\n"); + device_free_info(priv); + return -ENODEV; + } - case IOCTL_CMD_HOSTAPD: + /* do reset */ + if (!MACbSoftwareReset(priv->PortOffset)) { + dev_err(&pcid->dev, ": Failed to access MAC hardware..\n"); + device_free_info(priv); + return -ENODEV; + } + /* initial to reload eeprom */ + MACvInitialize(priv->PortOffset); + MACvReadEtherAddress(priv->PortOffset, priv->abyCurrentNetAddr); - rc = vt6655_hostap_ioctl(pDevice, &wrq->u.data); - break; + device_get_options(priv); + device_set_options(priv); + /* Mask out the options cannot be set to the chip */ + priv->sOpts.flags &= pChip_info->flags; - case IOCTL_CMD_WPA: + /* Enable the chip specified capabilities */ + priv->flags = priv->sOpts.flags | (pChip_info->flags & 0xff000000UL); - rc = wpa_ioctl(pDevice, &wrq->u.data); - break; + wiphy = priv->hw->wiphy; - case SIOCETHTOOL: - return ethtool_ioctl(dev, rq->ifr_data); - // All other calls are currently unsupported + wiphy->frag_threshold = FRAG_THRESH_DEF; + wiphy->rts_threshold = RTS_THRESH_DEF; + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP); - default: - rc = -EOPNOTSUPP; - pr_debug("Ioctl command not support..%x\n", cmd); + priv->hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_REPORTS_TX_ACK_STATUS | + IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_TIMING_BEACON_ONLY; - } + priv->hw->max_signal = 100; - if (pDevice->bCommit) { - if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { - netif_stop_queue(pDevice->dev); - spin_lock_irq(&pDevice->lock); - bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL); - spin_unlock_irq(&pDevice->lock); - } else { - pr_debug("Commit the settings\n"); - spin_lock_irq(&pDevice->lock); - pDevice->bLinkPass = false; - memset(pMgmt->abyCurrBSSID, 0, 6); - pMgmt->eCurrState = WMAC_STATE_IDLE; - netif_stop_queue(pDevice->dev); -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - pMgmt->eScanType = WMAC_SCAN_ACTIVE; - if (!pDevice->bWPASuppWextEnabled) -#endif - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); - spin_unlock_irq(&pDevice->lock); - } - pDevice->bCommit = false; - } + if (vnt_init(priv)) + return -ENODEV; - return rc; + device_print_info(priv); + pci_set_drvdata(pcid, priv); + + return 0; } -static int ethtool_ioctl(struct net_device *dev, void __user *useraddr) +/*------------------------------------------------------------------*/ + +#ifdef CONFIG_PM +static int vt6655_suspend(struct pci_dev *pcid, pm_message_t state) { - u32 ethcmd; + struct vnt_private *priv = pci_get_drvdata(pcid); + unsigned long flags; - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; + spin_lock_irqsave(&priv->lock, flags); - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; + pci_save_state(pcid); - strncpy(info.driver, DEVICE_NAME, sizeof(info.driver)-1); - strncpy(info.version, DEVICE_VERSION, sizeof(info.version)-1); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } + MACbShutdown(priv->PortOffset); - } + pci_disable_device(pcid); + pci_set_power_state(pcid, pci_choose_state(pcid, state)); + + spin_unlock_irqrestore(&priv->lock, flags); - return -EOPNOTSUPP; + return 0; } -/*------------------------------------------------------------------*/ +static int vt6655_resume(struct pci_dev *pcid) +{ + + pci_set_power_state(pcid, PCI_D0); + pci_enable_wake(pcid, PCI_D0, 0); + pci_restore_state(pcid); + + return 0; +} +#endif MODULE_DEVICE_TABLE(pci, vt6655_pci_id_table); @@ -3025,8 +1878,8 @@ static struct pci_driver device_driver = { .probe = vt6655_probe, .remove = vt6655_remove, #ifdef CONFIG_PM - .suspend = viawget_suspend, - .resume = viawget_resume, + .suspend = vt6655_suspend, + .resume = vt6655_resume, #endif }; @@ -3067,75 +1920,10 @@ device_notify_reboot(struct notifier_block *nb, unsigned long event, void *p) for_each_pci_dev(pdev) { if (pci_dev_driver(pdev) == &device_driver) { if (pci_get_drvdata(pdev)) - viawget_suspend(pdev, PMSG_HIBERNATE); + vt6655_suspend(pdev, PMSG_HIBERNATE); } } } return NOTIFY_DONE; } - -static int -viawget_suspend(struct pci_dev *pcid, pm_message_t state) -{ - int power_status; // to silence the compiler - - struct vnt_private *pDevice = pci_get_drvdata(pcid); - PSMgmtObject pMgmt = pDevice->pMgmt; - - netif_stop_queue(pDevice->dev); - spin_lock_irq(&pDevice->lock); - pci_save_state(pcid); - del_timer(&pDevice->sTimerCommand); - del_timer(&pMgmt->sTimerSecondCallback); - pDevice->cbFreeCmdQueue = CMD_Q_SIZE; - pDevice->uCmdDequeueIdx = 0; - pDevice->uCmdEnqueueIdx = 0; - pDevice->bCmdRunning = false; - MACbShutdown(pDevice->PortOffset); - MACvSaveContext(pDevice->PortOffset, pDevice->abyMacContext); - pDevice->bLinkPass = false; - memset(pMgmt->abyCurrBSSID, 0, 6); - pMgmt->eCurrState = WMAC_STATE_IDLE; - pci_disable_device(pcid); - power_status = pci_set_power_state(pcid, pci_choose_state(pcid, state)); - spin_unlock_irq(&pDevice->lock); - return 0; -} - -static int -viawget_resume(struct pci_dev *pcid) -{ - struct vnt_private *pDevice = pci_get_drvdata(pcid); - PSMgmtObject pMgmt = pDevice->pMgmt; - int power_status; // to silence the compiler - - power_status = pci_set_power_state(pcid, PCI_D0); - power_status = pci_enable_wake(pcid, PCI_D0, 0); - pci_restore_state(pcid); - if (netif_running(pDevice->dev)) { - spin_lock_irq(&pDevice->lock); - MACvRestoreContext(pDevice->PortOffset, pDevice->abyMacContext); - device_init_registers(pDevice); - if (pMgmt->sNodeDBTable[0].bActive) { // Assoc with BSS - pMgmt->sNodeDBTable[0].bActive = false; - pDevice->bLinkPass = false; - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - // In Adhoc, BSS state set back to started. - pMgmt->eCurrState = WMAC_STATE_STARTED; - } else { - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - pMgmt->eCurrState = WMAC_STATE_IDLE; - } - } - init_timer(&pMgmt->sTimerSecondCallback); - init_timer(&pDevice->sTimerCommand); - MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); - BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); - bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); - spin_unlock_irq(&pDevice->lock); - } - return 0; -} - #endif diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index 8515b8c80801..977683cb7391 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -25,1289 +25,135 @@ * Date: May 20, 2003 * * Functions: - * device_receive_frame - Rcv 802.11 frame function - * s_bAPModeRxCtl- AP Rcv frame filer Ctl. - * s_bAPModeRxData- AP Rcv data frame handle - * s_bHandleRxEncryption- Rcv decrypted data via on-fly - * s_bHostWepRxEncryption- Rcv encrypted data via host - * s_byGetRateIdx- get rate index - * s_vGetDASA- get data offset - * s_vProcessRxMACHeader- Rcv 802.11 and translate to 802.3 * * Revision History: * */ #include "device.h" -#include "rxtx.h" -#include "tether.h" -#include "card.h" -#include "bssdb.h" -#include "mac.h" #include "baseband.h" -#include "michael.h" -#include "tkip.h" -#include "tcrc.h" -#include "wctl.h" -#include "wroute.h" -#include "hostap.h" #include "rf.h" -#include "iowpa.h" -#include "aes_ccmp.h" #include "dpc.h" -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ -static const unsigned char acbyRxRate[MAX_RATE] = -{2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108}; - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -static unsigned char s_byGetRateIdx(unsigned char byRate); - -static void -s_vGetDASA(unsigned char *pbyRxBufferAddr, unsigned int *pcbHeaderSize, - PSEthernetHeader psEthHeader); - -static void -s_vProcessRxMACHeader(struct vnt_private *pDevice, unsigned char *pbyRxBufferAddr, - unsigned int cbPacketSize, bool bIsWEP, bool bExtIV, - unsigned int *pcbHeadSize); - -static bool s_bAPModeRxCtl( - struct vnt_private *pDevice, - unsigned char *pbyFrame, - int iSANodeIndex -); - -static bool s_bAPModeRxData( - struct vnt_private *pDevice, - struct sk_buff *skb, - unsigned int FrameSize, - unsigned int cbHeaderOffset, - int iSANodeIndex, - int iDANodeIndex -); - -static bool s_bHandleRxEncryption( - struct vnt_private *pDevice, - unsigned char *pbyFrame, - unsigned int FrameSize, - unsigned char *pbyRsr, - unsigned char *pbyNewRsr, - PSKeyItem *pKeyOut, - bool *pbExtIV, - unsigned short *pwRxTSC15_0, - unsigned long *pdwRxTSC47_16 -); - -static bool s_bHostWepRxEncryption( - - struct vnt_private *pDevice, - unsigned char *pbyFrame, - unsigned int FrameSize, - unsigned char *pbyRsr, - bool bOnFly, - PSKeyItem pKey, - unsigned char *pbyNewRsr, - bool *pbExtIV, - unsigned short *pwRxTSC15_0, - unsigned long *pdwRxTSC47_16 - -); - -/*--------------------- Export Variables --------------------------*/ - -/*+ - * - * Description: - * Translate Rcv 802.11 header to 802.3 header with Rx buffer - * - * Parameters: - * In: - * pDevice - * dwRxBufferAddr - Address of Rcv Buffer - * cbPacketSize - Rcv Packet size - * bIsWEP - If Rcv with WEP - * Out: - * pcbHeaderSize - 802.11 header size - * - * Return Value: None - * - -*/ -static void -s_vProcessRxMACHeader(struct vnt_private *pDevice, - unsigned char *pbyRxBufferAddr, - unsigned int cbPacketSize, bool bIsWEP, bool bExtIV, - unsigned int *pcbHeadSize) +static bool vnt_rx_data(struct vnt_private *priv, struct sk_buff *skb, + u16 bytes_received) { - unsigned char *pbyRxBuffer; - unsigned int cbHeaderSize = 0; - unsigned short *pwType; - PS802_11Header pMACHeader; - int ii; - - pMACHeader = (PS802_11Header) (pbyRxBufferAddr + cbHeaderSize); - - s_vGetDASA((unsigned char *)pMACHeader, &cbHeaderSize, &pDevice->sRxEthHeader); - - if (bIsWEP) { - if (bExtIV) { - // strip IV&ExtIV , add 8 byte - cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 8); - } else { - // strip IV , add 4 byte - cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 4); - } - } else { - cbHeaderSize += WLAN_HDR_ADDR3_LEN; - } - - pbyRxBuffer = (unsigned char *)(pbyRxBufferAddr + cbHeaderSize); - if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_Bridgetunnel)) { - cbHeaderSize += 6; - } else if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_RFC1042)) { - cbHeaderSize += 6; - pwType = (unsigned short *)(pbyRxBufferAddr + cbHeaderSize); - if ((*pwType != TYPE_PKT_IPX) && (*pwType != cpu_to_le16(0xF380))) { - } else { - cbHeaderSize -= 8; - pwType = (unsigned short *)(pbyRxBufferAddr + cbHeaderSize); - if (bIsWEP) { - if (bExtIV) - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8); // 8 is IV&ExtIV - else - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4); // 4 is IV - - } else { - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN); - } - } - } else { - cbHeaderSize -= 2; - pwType = (unsigned short *)(pbyRxBufferAddr + cbHeaderSize); - if (bIsWEP) { - if (bExtIV) - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8); // 8 is IV&ExtIV - else - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4); // 4 is IV - - } else { - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN); - } - } - - cbHeaderSize -= (ETH_ALEN * 2); - pbyRxBuffer = (unsigned char *)(pbyRxBufferAddr + cbHeaderSize); - for (ii = 0; ii < ETH_ALEN; ii++) - *pbyRxBuffer++ = pDevice->sRxEthHeader.abyDstAddr[ii]; - for (ii = 0; ii < ETH_ALEN; ii++) - *pbyRxBuffer++ = pDevice->sRxEthHeader.abySrcAddr[ii]; - - *pcbHeadSize = cbHeaderSize; -} - -static unsigned char s_byGetRateIdx(unsigned char byRate) -{ - unsigned char byRateIdx; - - for (byRateIdx = 0; byRateIdx < MAX_RATE; byRateIdx++) { - if (acbyRxRate[byRateIdx % MAX_RATE] == byRate) - return byRateIdx; - } - - return 0; -} - -static void -s_vGetDASA(unsigned char *pbyRxBufferAddr, unsigned int *pcbHeaderSize, - PSEthernetHeader psEthHeader) -{ - unsigned int cbHeaderSize = 0; - PS802_11Header pMACHeader; - int ii; - - pMACHeader = (PS802_11Header) (pbyRxBufferAddr + cbHeaderSize); - - if ((pMACHeader->wFrameCtl & FC_TODS) == 0) { - if (pMACHeader->wFrameCtl & FC_FROMDS) { - for (ii = 0; ii < ETH_ALEN; ii++) { - psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr1[ii]; - psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr3[ii]; - } - } else { - // IBSS mode - for (ii = 0; ii < ETH_ALEN; ii++) { - psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr1[ii]; - psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii]; - } - } - } else { - // Is AP mode.. - if (pMACHeader->wFrameCtl & FC_FROMDS) { - for (ii = 0; ii < ETH_ALEN; ii++) { - psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr3[ii]; - psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr4[ii]; - cbHeaderSize += 6; - } - } else { - for (ii = 0; ii < ETH_ALEN; ii++) { - psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr3[ii]; - psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii]; - } - } - } - *pcbHeaderSize = cbHeaderSize; -} - -bool -device_receive_frame( - struct vnt_private *pDevice, - PSRxDesc pCurrRD -) -{ - PDEVICE_RD_INFO pRDInfo = pCurrRD->pRDInfo; - struct net_device_stats *pStats = &pDevice->dev->stats; - struct sk_buff *skb; - PSMgmtObject pMgmt = pDevice->pMgmt; - PSRxMgmtPacket pRxPacket = &(pDevice->pMgmt->sRxPacket); - PS802_11Header p802_11Header; - unsigned char *pbyRsr; - unsigned char *pbyNewRsr; - unsigned char *pbyRSSI; - __le64 *pqwTSFTime; - unsigned short *pwFrameSize; - unsigned char *pbyFrame; - bool bDeFragRx = false; - bool bIsWEP = false; - unsigned int cbHeaderOffset; - unsigned int FrameSize; - unsigned short wEtherType = 0; - int iSANodeIndex = -1; - int iDANodeIndex = -1; - unsigned int ii; - unsigned int cbIVOffset; - bool bExtIV = false; - unsigned char *pbyRxSts; - unsigned char *pbyRxRate; - unsigned char *pbySQ; - unsigned int cbHeaderSize; - PSKeyItem pKey = NULL; - unsigned short wRxTSC15_0 = 0; - unsigned long dwRxTSC47_16 = 0; - SKeyItem STempKey; - // 802.11h RPI - unsigned long dwDuration = 0; - long ldBm = 0; - long ldBmThreshold = 0; - PS802_11Header pMACHeader; - bool bRxeapol_key = false; - - skb = pRDInfo->skb; - - pci_unmap_single(pDevice->pcid, pRDInfo->skb_dma, - pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE); - - pwFrameSize = (unsigned short *)(skb->data + 2); - FrameSize = cpu_to_le16(pCurrRD->m_rd1RD1.wReqCount) - cpu_to_le16(pCurrRD->m_rd0RD0.wResCount); - - // Max: 2312Payload + 30HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR - // Min (ACK): 10HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR - if ((FrameSize > 2364) || (FrameSize <= 32)) { - // Frame Size error drop this packet. - pr_debug("---------- WRONG Length 1\n"); - return false; - } - - pbyRxSts = (unsigned char *)(skb->data); - pbyRxRate = (unsigned char *)(skb->data + 1); - pbyRsr = (unsigned char *)(skb->data + FrameSize - 1); - pbyRSSI = (unsigned char *)(skb->data + FrameSize - 2); - pbyNewRsr = (unsigned char *)(skb->data + FrameSize - 3); - pbySQ = (unsigned char *)(skb->data + FrameSize - 4); - pqwTSFTime = (__le64 *)(skb->data + FrameSize - 12); - pbyFrame = (unsigned char *)(skb->data + 4); - - // get packet size - FrameSize = cpu_to_le16(*pwFrameSize); - - if ((FrameSize > 2346)|(FrameSize < 14)) { // Max: 2312Payload + 30HD +4CRC - // Min: 14 bytes ACK - pr_debug("---------- WRONG Length 2\n"); - return false; - } - - // update receive statistic counter - STAvUpdateRDStatCounter(&pDevice->scStatistic, - *pbyRsr, - *pbyNewRsr, - *pbyRxRate, - pbyFrame, - FrameSize); - - pMACHeader = (PS802_11Header)((unsigned char *)(skb->data) + 8); - - if (pDevice->bMeasureInProgress) { - if ((*pbyRsr & RSR_CRCOK) != 0) - pDevice->byBasicMap |= 0x01; - - dwDuration = (FrameSize << 4); - dwDuration /= acbyRxRate[*pbyRxRate%MAX_RATE]; - if (*pbyRxRate <= RATE_11M) { - if (*pbyRxSts & 0x01) { - // long preamble - dwDuration += 192; - } else { - // short preamble - dwDuration += 96; - } - } else { - dwDuration += 16; - } - RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm); - ldBmThreshold = -57; - for (ii = 7; ii > 0;) { - if (ldBm > ldBmThreshold) - break; - - ldBmThreshold -= 5; - ii--; - } - pDevice->dwRPIs[ii] += dwDuration; - return false; - } - - if (!is_multicast_ether_addr(pbyFrame)) { - if (WCTLbIsDuplicate(&(pDevice->sDupRxCache), (PS802_11Header)(skb->data + 4))) { - pDevice->s802_11Counter.FrameDuplicateCount++; - return false; - } - } - - // Use for TKIP MIC - s_vGetDASA(skb->data+4, &cbHeaderSize, &pDevice->sRxEthHeader); - - // filter packet send from myself - if (ether_addr_equal(pDevice->sRxEthHeader.abySrcAddr, - pDevice->abyCurrentNetAddr)) - return false; - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { - if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) { - p802_11Header = (PS802_11Header)(pbyFrame); - // get SA NodeIndex - if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(p802_11Header->abyAddr2), &iSANodeIndex)) { - pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies; - pMgmt->sNodeDBTable[iSANodeIndex].uInActiveCount = 0; - } - } - } - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (s_bAPModeRxCtl(pDevice, pbyFrame, iSANodeIndex)) - return false; - } - - if (IS_FC_WEP(pbyFrame)) { - bool bRxDecryOK = false; - - pr_debug("rx WEP pkt\n"); - bIsWEP = true; - if ((pDevice->bEnableHostWEP) && (iSANodeIndex >= 0)) { - pKey = &STempKey; - pKey->byCipherSuite = pMgmt->sNodeDBTable[iSANodeIndex].byCipherSuite; - pKey->dwKeyIndex = pMgmt->sNodeDBTable[iSANodeIndex].dwKeyIndex; - pKey->uKeyLength = pMgmt->sNodeDBTable[iSANodeIndex].uWepKeyLength; - pKey->dwTSC47_16 = pMgmt->sNodeDBTable[iSANodeIndex].dwTSC47_16; - pKey->wTSC15_0 = pMgmt->sNodeDBTable[iSANodeIndex].wTSC15_0; - memcpy(pKey->abyKey, - &pMgmt->sNodeDBTable[iSANodeIndex].abyWepKey[0], - pKey->uKeyLength -); - - bRxDecryOK = s_bHostWepRxEncryption(pDevice, - pbyFrame, - FrameSize, - pbyRsr, - pMgmt->sNodeDBTable[iSANodeIndex].bOnFly, - pKey, - pbyNewRsr, - &bExtIV, - &wRxTSC15_0, - &dwRxTSC47_16); - } else { - bRxDecryOK = s_bHandleRxEncryption(pDevice, - pbyFrame, - FrameSize, - pbyRsr, - pbyNewRsr, - &pKey, - &bExtIV, - &wRxTSC15_0, - &dwRxTSC47_16); - } - - if (bRxDecryOK) { - if ((*pbyNewRsr & NEWRSR_DECRYPTOK) == 0) { - pr_debug("ICV Fail\n"); - if ((pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA) || - (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || - (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) || - (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || - (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { - if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) - pDevice->s802_11Counter.TKIPICVErrors++; - else if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP)) - pDevice->s802_11Counter.CCMPDecryptErrors++; - } - return false; - } - } else { - pr_debug("WEP Func Fail\n"); - return false; - } - if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP)) - FrameSize -= 8; // Message Integrity Code - else - FrameSize -= 4; // 4 is ICV - } - - // - // RX OK - // - //remove the CRC length - FrameSize -= ETH_FCS_LEN; - - if ((!(*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI))) && // unicast address - (IS_FRAGMENT_PKT((skb->data+4))) -) { - // defragment - bDeFragRx = WCTLbHandleFragment(pDevice, (PS802_11Header)(skb->data+4), FrameSize, bIsWEP, bExtIV); - pDevice->s802_11Counter.ReceivedFragmentCount++; - if (bDeFragRx) { - // defrag complete - skb = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb; - FrameSize = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength; - - } else { - return false; - } - } - -// Management & Control frame Handle - if ((IS_TYPE_DATA((skb->data+4))) == false) { - // Handle Control & Manage Frame - - if (IS_TYPE_MGMT((skb->data+4))) { - unsigned char *pbyData1; - unsigned char *pbyData2; - - pRxPacket->p80211Header = (PUWLAN_80211HDR)(skb->data+4); - pRxPacket->cbMPDULen = FrameSize; - pRxPacket->uRSSI = *pbyRSSI; - pRxPacket->bySQ = *pbySQ; - pRxPacket->qwLocalTSF = le64_to_cpu(*pqwTSFTime); - if (bIsWEP) { - // strip IV - pbyData1 = WLAN_HDR_A3_DATA_PTR(skb->data+4); - pbyData2 = WLAN_HDR_A3_DATA_PTR(skb->data+4) + 4; - for (ii = 0; ii < (FrameSize - 4); ii++) { - *pbyData1 = *pbyData2; - pbyData1++; - pbyData2++; - } - } - pRxPacket->byRxRate = s_byGetRateIdx(*pbyRxRate); - pRxPacket->byRxChannel = (*pbyRxSts) >> 2; - - vMgrRxManagePacket((void *)pDevice, pDevice->pMgmt, pRxPacket); - - // hostap Deamon handle 802.11 management - if (pDevice->bEnableHostapd) { - skb->dev = pDevice->apdev; - skb->data += 4; - skb->tail += 4; - skb_put(skb, FrameSize); - skb_reset_mac_header(skb); - skb->pkt_type = PACKET_OTHERHOST; - skb->protocol = htons(ETH_P_802_2); - memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx(skb); - return true; - } - } - + struct ieee80211_hw *hw = priv->hw; + struct ieee80211_supported_band *sband; + struct ieee80211_rx_status rx_status = { 0 }; + struct ieee80211_hdr *hdr; + __le16 fc; + u8 *rsr, *new_rsr, *rssi; + __le64 *tsf_time; + u16 frame_size; + int ii, r; + u8 *rx_sts, *rx_rate, *sq; + u8 *skb_data; + u8 rate_idx = 0; + u8 rate[MAX_RATE] = {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108}; + long rx_dbm; + + /* [31:16]RcvByteCount ( not include 4-byte Status ) */ + frame_size = le16_to_cpu(*((__le16 *)(skb->data + 2))); + if (frame_size > 2346 || frame_size < 14) { + dev_dbg(&priv->pcid->dev, "------- WRONG Length 1\n"); return false; - } else { - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - //In AP mode, hw only check addr1(BSSID or RA) if equal to local MAC. - if (!(*pbyRsr & RSR_BSSIDOK)) { - if (bDeFragRx) { - if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - pr_err("%s: can not alloc more frag bufs\n", - pDevice->dev->name); - } - } - return false; - } - } else { - // discard DATA packet while not associate || BSSID error - if (!pDevice->bLinkPass || !(*pbyRsr & RSR_BSSIDOK)) { - if (bDeFragRx) { - if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - pr_err("%s: can not alloc more frag bufs\n", - pDevice->dev->name); - } - } - return false; - } - //mike add:station mode check eapol-key challenge---> - { - unsigned char Protocol_Version; //802.1x Authentication - unsigned char Packet_Type; //802.1x Authentication - - if (bIsWEP) - cbIVOffset = 8; - else - cbIVOffset = 0; - wEtherType = (skb->data[cbIVOffset + 8 + 24 + 6] << 8) | - skb->data[cbIVOffset + 8 + 24 + 6 + 1]; - Protocol_Version = skb->data[cbIVOffset + 8 + 24 + 6 + 1 + 1]; - Packet_Type = skb->data[cbIVOffset + 8 + 24 + 6 + 1 + 1 + 1]; - if (wEtherType == ETH_P_PAE) { //Protocol Type in LLC-Header - if (((Protocol_Version == 1) || (Protocol_Version == 2)) && - (Packet_Type == 3)) { //802.1x OR eapol-key challenge frame receive - bRxeapol_key = true; - } - } - } - //mike add:station mode check eapol-key challenge<--- - } - } - -// Data frame Handle - - if (pDevice->bEnablePSMode) { - if (!IS_FC_MOREDATA((skb->data+4))) { - if (pDevice->pMgmt->bInTIMWake == true) - pDevice->pMgmt->bInTIMWake = false; - } - } - - // Now it only supports 802.11g Infrastructure Mode, and support rate must up to 54 Mbps - if (pDevice->bDiversityEnable && (FrameSize > 50) && - (pDevice->op_mode == NL80211_IFTYPE_STATION) && - pDevice->bLinkPass) { - BBvAntennaDiversity(pDevice, s_byGetRateIdx(*pbyRxRate), 0); - } - - if (pDevice->byLocalID != REV_ID_VT3253_B1) - pDevice->uCurrRSSI = *pbyRSSI; - - pDevice->byCurrSQ = *pbySQ; - - if ((*pbyRSSI != 0) && - (pMgmt->pCurrBSS != NULL)) { - RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm); - // Monitor if RSSI is too strong. - pMgmt->pCurrBSS->byRSSIStatCnt++; - pMgmt->pCurrBSS->byRSSIStatCnt %= RSSI_STAT_COUNT; - pMgmt->pCurrBSS->ldBmAverage[pMgmt->pCurrBSS->byRSSIStatCnt] = ldBm; - for (ii = 0; ii < RSSI_STAT_COUNT; ii++) - if (pMgmt->pCurrBSS->ldBmAverage[ii] != 0) - pMgmt->pCurrBSS->ldBmMAX = max(pMgmt->pCurrBSS->ldBmAverage[ii], ldBm); - } - // ----------------------------------------------- + skb_data = (u8 *)skb->data; - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && pDevice->bEnable8021x) { - unsigned char abyMacHdr[24]; + rx_sts = skb_data; + rx_rate = skb_data + 1; - // Only 802.1x packet incoming allowed - if (bIsWEP) - cbIVOffset = 8; - else - cbIVOffset = 0; - wEtherType = (skb->data[cbIVOffset + 4 + 24 + 6] << 8) | - skb->data[cbIVOffset + 4 + 24 + 6 + 1]; + sband = hw->wiphy->bands[hw->conf.chandef.chan->band]; - pr_debug("wEtherType = %04x\n", wEtherType); - if (wEtherType == ETH_P_PAE) { - skb->dev = pDevice->apdev; - - if (bIsWEP) { - // strip IV header(8) - memcpy(&abyMacHdr[0], (skb->data + 4), 24); - memcpy((skb->data + 4 + cbIVOffset), &abyMacHdr[0], 24); - } - skb->data += (cbIVOffset + 4); - skb->tail += (cbIVOffset + 4); - skb_put(skb, FrameSize); - skb_reset_mac_header(skb); - - skb->pkt_type = PACKET_OTHERHOST; - skb->protocol = htons(ETH_P_802_2); - memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx(skb); - return true; - - } - // check if 802.1x authorized - if (!(pMgmt->sNodeDBTable[iSANodeIndex].dwFlags & WLAN_STA_AUTHORIZED)) - return false; + for (r = RATE_1M; r < MAX_RATE; r++) { + if (*rx_rate == rate[r]) + break; } - if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) { - if (bIsWEP) - FrameSize -= 8; //MIC - } - - //-------------------------------------------------------------------------------- - // Soft MIC - if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) { - if (bIsWEP) { - __le32 *pdwMIC_L; - __le32 *pdwMIC_R; - __le32 dwMIC_Priority; - __le32 dwMICKey0 = 0, dwMICKey1 = 0; - u32 dwLocalMIC_L = 0; - u32 dwLocalMIC_R = 0; - viawget_wpa_header *wpahdr; - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[24])); - dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[28])); - } else { - if (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[16])); - dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[20])); - } else if ((pKey->dwKeyIndex & BIT28) == 0) { - dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[16])); - dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[20])); - } else { - dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[24])); - dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[28])); - } - } - - MIC_vInit(dwMICKey0, dwMICKey1); - MIC_vAppend((unsigned char *)&(pDevice->sRxEthHeader.abyDstAddr[0]), 12); - dwMIC_Priority = 0; - MIC_vAppend((unsigned char *)&dwMIC_Priority, 4); - // 4 is Rcv buffer header, 24 is MAC Header, and 8 is IV and Ext IV. - MIC_vAppend((unsigned char *)(skb->data + 4 + WLAN_HDR_ADDR3_LEN + 8), - FrameSize - WLAN_HDR_ADDR3_LEN - 8); - MIC_vGetMIC(&dwLocalMIC_L, &dwLocalMIC_R); - MIC_vUnInit(); - - pdwMIC_L = (__le32 *)(skb->data + 4 + FrameSize); - pdwMIC_R = (__le32 *)(skb->data + 4 + FrameSize + 4); - - if ((le32_to_cpu(*pdwMIC_L) != dwLocalMIC_L) || - (le32_to_cpu(*pdwMIC_R) != dwLocalMIC_R) || - pDevice->bRxMICFail) { - pr_debug("MIC comparison is fail!\n"); - pDevice->bRxMICFail = false; - pDevice->s802_11Counter.TKIPLocalMICFailures++; - if (bDeFragRx) { - if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - pr_err("%s: can not alloc more frag bufs\n", - pDevice->dev->name); - } - } - //2008-0409-07, <Add> by Einsn Liu -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - //send event to wpa_supplicant - { - union iwreq_data wrqu; - struct iw_michaelmicfailure ev; - int keyidx = pbyFrame[cbHeaderSize+3] >> 6; //top two-bits - - memset(&ev, 0, sizeof(ev)); - ev.flags = keyidx & IW_MICFAILURE_KEY_ID; - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pMgmt->eCurrState == WMAC_STATE_ASSOC) && - (*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) { - ev.flags |= IW_MICFAILURE_PAIRWISE; - } else { - ev.flags |= IW_MICFAILURE_GROUP; - } - - ev.src_addr.sa_family = ARPHRD_ETHER; - memcpy(ev.src_addr.sa_data, pMACHeader->abyAddr2, ETH_ALEN); - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = sizeof(ev); - wireless_send_event(pDevice->dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev); - - } -#endif + priv->rx_rate = r; - if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { - wpahdr = (viawget_wpa_header *)pDevice->skb->data; - if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC) && - (*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) { - wpahdr->type = VIAWGET_PTK_MIC_MSG; - } else { - wpahdr->type = VIAWGET_GTK_MIC_MSG; - } - wpahdr->resp_ie_len = 0; - wpahdr->req_ie_len = 0; - skb_put(pDevice->skb, sizeof(viawget_wpa_header)); - pDevice->skb->dev = pDevice->wpadev; - skb_reset_mac_header(pDevice->skb); - pDevice->skb->pkt_type = PACKET_HOST; - pDevice->skb->protocol = htons(ETH_P_802_2); - memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); - netif_rx(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - } - - return false; - - } - } - } //---end of SOFT MIC----------------------------------------------------------------------- - - // ++++++++++ Reply Counter Check +++++++++++++ - - if ((pKey != NULL) && ((pKey->byCipherSuite == KEY_CTL_TKIP) || - (pKey->byCipherSuite == KEY_CTL_CCMP))) { - if (bIsWEP) { - unsigned short wLocalTSC15_0 = 0; - unsigned long dwLocalTSC47_16 = 0; - unsigned long long RSC = 0; - // endian issues - RSC = *((unsigned long long *)&(pKey->KeyRSC)); - wLocalTSC15_0 = (unsigned short)RSC; - dwLocalTSC47_16 = (unsigned long)(RSC>>16); - - RSC = dwRxTSC47_16; - RSC <<= 16; - RSC += wRxTSC15_0; - pKey->KeyRSC = RSC; - - if ((pDevice->sMgmtObj.eCurrMode == WMAC_MODE_ESS_STA) && - (pDevice->sMgmtObj.eCurrState == WMAC_STATE_ASSOC)) { - // check RSC - if ((wRxTSC15_0 < wLocalTSC15_0) && - (dwRxTSC47_16 <= dwLocalTSC47_16) && - !((dwRxTSC47_16 == 0) && (dwLocalTSC47_16 == 0xFFFFFFFF))) { - pr_debug("TSC is illegal~~!\n "); - if (pKey->byCipherSuite == KEY_CTL_TKIP) - pDevice->s802_11Counter.TKIPReplays++; - else - pDevice->s802_11Counter.CCMPReplays++; - - if (bDeFragRx) { - if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - pr_err("%s: can not alloc more frag bufs\n", - pDevice->dev->name); - } - } - return false; - } - } - } - } // ----- End of Reply Counter Check -------------------------- - - s_vProcessRxMACHeader(pDevice, (unsigned char *)(skb->data+4), FrameSize, bIsWEP, bExtIV, &cbHeaderOffset); - FrameSize -= cbHeaderOffset; - cbHeaderOffset += 4; // 4 is Rcv buffer header - - // Null data, framesize = 14 - if (FrameSize < 15) - return false; - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (!s_bAPModeRxData(pDevice, - skb, - FrameSize, - cbHeaderOffset, - iSANodeIndex, - iDANodeIndex -)) { - if (bDeFragRx) { - if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - pr_err("%s: can not alloc more frag bufs\n", - pDevice->dev->name); - } - } - return false; + for (ii = 0; ii < sband->n_bitrates; ii++) { + if (sband->bitrates[ii].hw_value == r) { + rate_idx = ii; + break; } } - skb->data += cbHeaderOffset; - skb->tail += cbHeaderOffset; - skb_put(skb, FrameSize); - skb->protocol = eth_type_trans(skb, skb->dev); - - //drop frame not met IEEE 802.3 - - skb->ip_summed = CHECKSUM_NONE; - pStats->rx_bytes += skb->len; - pStats->rx_packets++; - netif_rx(skb); - - if (bDeFragRx) { - if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - pr_err("%s: can not alloc more frag bufs\n", - pDevice->dev->name); - } + if (ii == sband->n_bitrates) { + dev_dbg(&priv->pcid->dev, "Wrong RxRate %x\n", *rx_rate); return false; } - return true; -} - -static bool s_bAPModeRxCtl( - struct vnt_private *pDevice, - unsigned char *pbyFrame, - int iSANodeIndex -) -{ - PS802_11Header p802_11Header; - CMD_STATUS Status; - PSMgmtObject pMgmt = pDevice->pMgmt; - - if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) { - p802_11Header = (PS802_11Header)(pbyFrame); - if (!IS_TYPE_MGMT(pbyFrame)) { - // Data & PS-Poll packet - // check frame class - if (iSANodeIndex > 0) { - // frame class 3 fliter & checking - if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_AUTH) { - // send deauth notification - // reason = (6) class 2 received from nonauth sta - vMgrDeAuthenBeginSta(pDevice, - pMgmt, - (unsigned char *)(p802_11Header->abyAddr2), - (WLAN_MGMT_REASON_CLASS2_NONAUTH), - &Status -); - pr_debug("dpc: send vMgrDeAuthenBeginSta 1\n"); - return true; - } - if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_ASSOC) { - // send deassoc notification - // reason = (7) class 3 received from nonassoc sta - vMgrDisassocBeginSta(pDevice, - pMgmt, - (unsigned char *)(p802_11Header->abyAddr2), - (WLAN_MGMT_REASON_CLASS3_NONASSOC), - &Status -); - pr_debug("dpc: send vMgrDisassocBeginSta 2\n"); - return true; - } - - if (pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable) { - // delcare received ps-poll event - if (IS_CTL_PSPOLL(pbyFrame)) { - pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true; - bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); - pr_debug("dpc: WLAN_CMD_RX_PSPOLL 1\n"); - } else { - // check Data PS state - // if PW bit off, send out all PS bufferring packets. - if (!IS_FC_POWERMGT(pbyFrame)) { - pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false; - pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true; - bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); - pr_debug("dpc: WLAN_CMD_RX_PSPOLL 2\n"); - } - } - } else { - if (IS_FC_POWERMGT(pbyFrame)) { - pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = true; - // Once if STA in PS state, enable multicast bufferring - pMgmt->sNodeDBTable[0].bPSEnable = true; - } else { - // clear all pending PS frame. - if (pMgmt->sNodeDBTable[iSANodeIndex].wEnQueueCnt > 0) { - pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false; - pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true; - bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); - pr_debug("dpc: WLAN_CMD_RX_PSPOLL 3\n"); - - } - } - } - } else { - vMgrDeAuthenBeginSta(pDevice, - pMgmt, - (unsigned char *)(p802_11Header->abyAddr2), - (WLAN_MGMT_REASON_CLASS2_NONAUTH), - &Status -); - pr_debug("dpc: send vMgrDeAuthenBeginSta 3\n"); - pr_debug("BSSID:%pM\n", - p802_11Header->abyAddr3); - pr_debug("ADDR2:%pM\n", - p802_11Header->abyAddr2); - pr_debug("ADDR1:%pM\n", - p802_11Header->abyAddr1); - pr_debug("dpc: wFrameCtl= %x\n", - p802_11Header->wFrameCtl); - VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode)); - pr_debug("dpc:pDevice->byRxMode = %x\n", - pDevice->byRxMode); - return true; - } - } - } - return false; -} - -static bool s_bHandleRxEncryption( - struct vnt_private *pDevice, - unsigned char *pbyFrame, - unsigned int FrameSize, - unsigned char *pbyRsr, - unsigned char *pbyNewRsr, - PSKeyItem *pKeyOut, - bool *pbExtIV, - unsigned short *pwRxTSC15_0, - unsigned long *pdwRxTSC47_16 -) -{ - unsigned int PayloadLen = FrameSize; - unsigned char *pbyIV; - unsigned char byKeyIdx; - PSKeyItem pKey = NULL; - unsigned char byDecMode = KEY_CTL_WEP; - PSMgmtObject pMgmt = pDevice->pMgmt; + tsf_time = (__le64 *)(skb_data + bytes_received - 12); + sq = skb_data + bytes_received - 4; + new_rsr = skb_data + bytes_received - 3; + rssi = skb_data + bytes_received - 2; + rsr = skb_data + bytes_received - 1; - *pwRxTSC15_0 = 0; - *pdwRxTSC47_16 = 0; + RFvRSSITodBm(priv, *rssi, &rx_dbm); - pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; - if (WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) && - WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame)) { - pbyIV += 6; // 6 is 802.11 address4 - PayloadLen -= 6; - } - byKeyIdx = (*(pbyIV+3) & 0xc0); - byKeyIdx >>= 6; - pr_debug("\nKeyIdx: %d\n", byKeyIdx); + priv->byBBPreEDRSSI = (u8)rx_dbm + 1; + priv->uCurrRSSI = *rssi; - if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { - if (((*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) && - (pDevice->pMgmt->byCSSPK != KEY_CTL_NONE)) { - // unicast pkt use pairwise key - pr_debug("unicast pkt\n"); - if (KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, 0xFFFFFFFF, &pKey) == true) { - if (pDevice->pMgmt->byCSSPK == KEY_CTL_TKIP) - byDecMode = KEY_CTL_TKIP; - else if (pDevice->pMgmt->byCSSPK == KEY_CTL_CCMP) - byDecMode = KEY_CTL_CCMP; - } - pr_debug("unicast pkt: %d, %p\n", byDecMode, pKey); - } else { - // use group key - KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, byKeyIdx, &pKey); - if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP) - byDecMode = KEY_CTL_TKIP; - else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP) - byDecMode = KEY_CTL_CCMP; - pr_debug("group pkt: %d, %d, %p\n", - byKeyIdx, byDecMode, pKey); - } - } - // our WEP only support Default Key - if (pKey == NULL) { - // use default group key - KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, byKeyIdx, &pKey); - if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP) - byDecMode = KEY_CTL_TKIP; - else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP) - byDecMode = KEY_CTL_CCMP; - } - *pKeyOut = pKey; + skb_pull(skb, 4); + skb_trim(skb, frame_size); - pr_debug("AES:%d %d %d\n", - pDevice->pMgmt->byCSSPK, pDevice->pMgmt->byCSSGK, byDecMode); + rx_status.mactime = le64_to_cpu(*tsf_time); + rx_status.band = hw->conf.chandef.chan->band; + rx_status.signal = rx_dbm; + rx_status.flag = 0; + rx_status.freq = hw->conf.chandef.chan->center_freq; - if (pKey == NULL) { - pr_debug("pKey == NULL\n"); + hdr = (struct ieee80211_hdr *)(skb->data); + fc = hdr->frame_control; - return false; - } - if (byDecMode != pKey->byCipherSuite) { + rx_status.rate_idx = rate_idx; - *pKeyOut = NULL; - return false; + if (ieee80211_has_protected(fc)) { + if (priv->byLocalID > REV_ID_VT3253_A1) + rx_status.flag = RX_FLAG_DECRYPTED; } - if (byDecMode == KEY_CTL_WEP) { - // handle WEP - if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || - (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true)) { - // Software WEP - // 1. 3253A - // 2. WEP 256 - - PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc - memcpy(pDevice->abyPRNG, pbyIV, 3); - memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength); - rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3); - rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen); - - if (ETHbIsBufferCrc32Ok(pbyIV+4, PayloadLen)) - *pbyNewRsr |= NEWRSR_DECRYPTOK; - - } - } else if ((byDecMode == KEY_CTL_TKIP) || - (byDecMode == KEY_CTL_CCMP)) { - // TKIP/AES - - PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc - *pdwRxTSC47_16 = cpu_to_le32(*(unsigned long *)(pbyIV + 4)); - pr_debug("ExtIV: %lx\n", *pdwRxTSC47_16); - if (byDecMode == KEY_CTL_TKIP) - *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV + 2), *pbyIV)); - else - *pwRxTSC15_0 = cpu_to_le16(*(unsigned short *)pbyIV); - - pr_debug("TSC0_15: %x\n", *pwRxTSC15_0); - - if ((byDecMode == KEY_CTL_TKIP) && - (pDevice->byLocalID <= REV_ID_VT3253_A1)) { - // Software TKIP - // 1. 3253 A - PS802_11Header pMACHeader = (PS802_11Header)(pbyFrame); - - TKIPvMixKey(pKey->abyKey, pMACHeader->abyAddr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG); - rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN); - rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen); - if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) { - *pbyNewRsr |= NEWRSR_DECRYPTOK; - pr_debug("ICV OK!\n"); - } else { - pr_debug("ICV FAIL!!!\n"); - pr_debug("PayloadLen = %d\n", PayloadLen); - } - } - }// end of TKIP/AES - - if ((*(pbyIV+3) & 0x20) != 0) - *pbExtIV = true; - return true; -} - -static bool s_bHostWepRxEncryption( - struct vnt_private *pDevice, - unsigned char *pbyFrame, - unsigned int FrameSize, - unsigned char *pbyRsr, - bool bOnFly, - PSKeyItem pKey, - unsigned char *pbyNewRsr, - bool *pbExtIV, - unsigned short *pwRxTSC15_0, - unsigned long *pdwRxTSC47_16 -) -{ - unsigned int PayloadLen = FrameSize; - unsigned char *pbyIV; - unsigned char byKeyIdx; - unsigned char byDecMode = KEY_CTL_WEP; - PS802_11Header pMACHeader; - *pwRxTSC15_0 = 0; - *pdwRxTSC47_16 = 0; - - pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; - if (WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) && - WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame)) { - pbyIV += 6; // 6 is 802.11 address4 - PayloadLen -= 6; + if (priv->vif && priv->bDiversityEnable) { + if (ieee80211_is_data(fc) && + (frame_size > 50) && priv->vif->bss_conf.assoc) + BBvAntennaDiversity(priv, priv->rx_rate, 0); } - byKeyIdx = (*(pbyIV+3) & 0xc0); - byKeyIdx >>= 6; - pr_debug("\nKeyIdx: %d\n", byKeyIdx); - - if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP) - byDecMode = KEY_CTL_TKIP; - else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP) - byDecMode = KEY_CTL_CCMP; - - pr_debug("AES:%d %d %d\n", - pDevice->pMgmt->byCSSPK, pDevice->pMgmt->byCSSGK, byDecMode); - - if (byDecMode != pKey->byCipherSuite) - return false; - - if (byDecMode == KEY_CTL_WEP) { - // handle WEP - pr_debug("byDecMode == KEY_CTL_WEP\n"); - - if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || - (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true) || - !bOnFly) { - // Software WEP - // 1. 3253A - // 2. WEP 256 - // 3. NotOnFly - PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc - memcpy(pDevice->abyPRNG, pbyIV, 3); - memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength); - rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3); - rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen); + memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); - if (ETHbIsBufferCrc32Ok(pbyIV+4, PayloadLen)) - *pbyNewRsr |= NEWRSR_DECRYPTOK; + ieee80211_rx_irqsafe(priv->hw, skb); - } - } else if ((byDecMode == KEY_CTL_TKIP) || - (byDecMode == KEY_CTL_CCMP)) { - // TKIP/AES - - PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc - *pdwRxTSC47_16 = cpu_to_le32(*(unsigned long *)(pbyIV + 4)); - pr_debug("ExtIV: %lx\n", *pdwRxTSC47_16); - - if (byDecMode == KEY_CTL_TKIP) - *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV)); - else - *pwRxTSC15_0 = cpu_to_le16(*(unsigned short *)pbyIV); - - pr_debug("TSC0_15: %x\n", *pwRxTSC15_0); - - if (byDecMode == KEY_CTL_TKIP) { - if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || !bOnFly) { - // Software TKIP - // 1. 3253 A - // 2. NotOnFly - pr_debug("soft KEY_CTL_TKIP\n"); - pMACHeader = (PS802_11Header)(pbyFrame); - TKIPvMixKey(pKey->abyKey, pMACHeader->abyAddr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG); - rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN); - rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen); - if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) { - *pbyNewRsr |= NEWRSR_DECRYPTOK; - pr_debug("ICV OK!\n"); - } else { - pr_debug("ICV FAIL!!!\n"); - pr_debug("PayloadLen = %d\n", - PayloadLen); - } - } - } - - if (byDecMode == KEY_CTL_CCMP) { - if (!bOnFly) { - // Software CCMP - // NotOnFly - pr_debug("soft KEY_CTL_CCMP\n"); - if (AESbGenCCMP(pKey->abyKey, pbyFrame, FrameSize)) { - *pbyNewRsr |= NEWRSR_DECRYPTOK; - pr_debug("CCMP MIC compare OK!\n"); - } else { - pr_debug("CCMP MIC fail!\n"); - } - } - } - - }// end of TKIP/AES - - if ((*(pbyIV+3) & 0x20) != 0) - *pbExtIV = true; return true; } -static bool s_bAPModeRxData( - struct vnt_private *pDevice, - struct sk_buff *skb, - unsigned int FrameSize, - unsigned int cbHeaderOffset, - int iSANodeIndex, - int iDANodeIndex -) +bool vnt_receive_frame(struct vnt_private *priv, PSRxDesc curr_rd) { - PSMgmtObject pMgmt = pDevice->pMgmt; - bool bRelayAndForward = false; - bool bRelayOnly = false; - unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; - unsigned short wAID; - - struct sk_buff *skbcpy = NULL; + PDEVICE_RD_INFO rd_info = curr_rd->pRDInfo; + struct sk_buff *skb; + u16 frame_size; - if (FrameSize > CB_MAX_BUF_SIZE) - return false; - // check DA - if (is_multicast_ether_addr((unsigned char *)(skb->data+cbHeaderOffset))) { - if (pMgmt->sNodeDBTable[0].bPSEnable) { - skbcpy = dev_alloc_skb((int)pDevice->rx_buf_sz); + skb = rd_info->skb; - // if any node in PS mode, buffer packet until DTIM. - if (skbcpy == NULL) { - pr_info("relay multicast no skb available\n"); - } else { - skbcpy->dev = pDevice->dev; - skbcpy->len = FrameSize; - memcpy(skbcpy->data, skb->data+cbHeaderOffset, FrameSize); - skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skbcpy); + pci_unmap_single(priv->pcid, rd_info->skb_dma, + priv->rx_buf_sz, PCI_DMA_FROMDEVICE); - pMgmt->sNodeDBTable[0].wEnQueueCnt++; - // set tx map - pMgmt->abyPSTxMap[0] |= byMask[0]; - } - } else { - bRelayAndForward = true; - } - } else { - // check if relay - if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data+cbHeaderOffset), &iDANodeIndex)) { - if (pMgmt->sNodeDBTable[iDANodeIndex].eNodeState >= NODE_ASSOC) { - if (pMgmt->sNodeDBTable[iDANodeIndex].bPSEnable) { - // queue this skb until next PS tx, and then release. + frame_size = le16_to_cpu(curr_rd->m_rd1RD1.wReqCount) + - cpu_to_le16(curr_rd->m_rd0RD0.wResCount); - skb->data += cbHeaderOffset; - skb->tail += cbHeaderOffset; - skb_put(skb, FrameSize); - skb_queue_tail(&pMgmt->sNodeDBTable[iDANodeIndex].sTxPSQueue, skb); - pMgmt->sNodeDBTable[iDANodeIndex].wEnQueueCnt++; - wAID = pMgmt->sNodeDBTable[iDANodeIndex].wAID; - pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7]; - pr_debug("relay: index= %d, pMgmt->abyPSTxMap[%d]= %d\n", - iDANodeIndex, (wAID >> 3), - pMgmt->abyPSTxMap[wAID >> 3]); - return true; - } else { - bRelayOnly = true; - } - } - } + if ((frame_size > 2364) || (frame_size < 33)) { + /* Frame Size error drop this packet.*/ + dev_dbg(&priv->pcid->dev, "Wrong frame size %d\n", frame_size); + dev_kfree_skb_irq(skb); + return true; } - if (bRelayOnly || bRelayAndForward) { - // relay this packet right now - if (bRelayAndForward) - iDANodeIndex = 0; + if (vnt_rx_data(priv, skb, frame_size)) + return true; - if ((pDevice->uAssocCount > 1) && (iDANodeIndex >= 0)) - ROUTEbRelay(pDevice, (unsigned char *)(skb->data + cbHeaderOffset), FrameSize, (unsigned int)iDANodeIndex); - - if (bRelayOnly) - return false; - } - // none associate, don't forward - if (pDevice->uAssocCount == 0) - return false; + dev_kfree_skb_irq(skb); return true; } diff --git a/drivers/staging/vt6655/dpc.h b/drivers/staging/vt6655/dpc.h index a068b846b1be..ad495719a251 100644 --- a/drivers/staging/vt6655/dpc.h +++ b/drivers/staging/vt6655/dpc.h @@ -29,14 +29,8 @@ #ifndef __DPC_H__ #define __DPC_H__ -#include "ttype.h" #include "device.h" -#include "wcmd.h" -bool -device_receive_frame( - struct vnt_private *, - PSRxDesc pCurrRD -); +bool vnt_receive_frame(struct vnt_private *priv, PSRxDesc curr_rd); -#endif // __RXTX_H__ +#endif /* __RXTX_H__ */ diff --git a/drivers/staging/vt6655/hostap.c b/drivers/staging/vt6655/hostap.c deleted file mode 100644 index ae0dade229d8..000000000000 --- a/drivers/staging/vt6655/hostap.c +++ /dev/null @@ -1,765 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: hostap.c - * - * Purpose: handle hostap deamon ioctl input/out functions - * - * Author: Lyndon Chen - * - * Date: Oct. 20, 2003 - * - * Functions: - * - * Revision History: - * - */ - -#include "hostap.h" -#include "iocmd.h" -#include "mac.h" -#include "card.h" -#include "baseband.h" -#include "wpactl.h" -#include "key.h" - -#define VIAWGET_HOSTAPD_MAX_BUF_SIZE 1024 -#define HOSTAP_CRYPT_FLAG_SET_TX_KEY BIT0 -#define HOSTAP_CRYPT_ERR_UNKNOWN_ADDR 3 -#define HOSTAP_CRYPT_ERR_KEY_SET_FAILED 5 - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/* - * Description: - * register net_device (AP) for hostap deamon - * - * Parameters: - * In: - * pDevice - - * rtnl_locked - - * Out: - * - * Return Value: - * - */ - -static int hostap_enable_hostapd(struct vnt_private *pDevice, int rtnl_locked) -{ - struct vnt_private *apdev_priv; - struct net_device *dev = pDevice->dev; - int ret; - const struct net_device_ops apdev_netdev_ops = { - .ndo_start_xmit = pDevice->tx_80211, - }; - - pr_debug("%s: Enabling hostapd mode\n", dev->name); - - pDevice->apdev = alloc_etherdev(sizeof(*apdev_priv)); - if (pDevice->apdev == NULL) - return -ENOMEM; - - apdev_priv = netdev_priv(pDevice->apdev); - *apdev_priv = *pDevice; - eth_hw_addr_inherit(pDevice->apdev, dev); - - pDevice->apdev->netdev_ops = &apdev_netdev_ops; - - pDevice->apdev->type = ARPHRD_IEEE80211; - - pDevice->apdev->base_addr = dev->base_addr; - pDevice->apdev->irq = dev->irq; - pDevice->apdev->mem_start = dev->mem_start; - pDevice->apdev->mem_end = dev->mem_end; - sprintf(pDevice->apdev->name, "%sap", dev->name); - if (rtnl_locked) - ret = register_netdevice(pDevice->apdev); - else - ret = register_netdev(pDevice->apdev); - if (ret) { - pr_debug("%s: register_netdevice(AP) failed!\n", - dev->name); - free_netdev(pDevice->apdev); - pDevice->apdev = NULL; - return -1; - } - - pr_debug("%s: Registered netdevice %s for AP management\n", - dev->name, pDevice->apdev->name); - - KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); - - return 0; -} - -/* - * Description: - * unregister net_device(AP) - * - * Parameters: - * In: - * pDevice - - * rtnl_locked - - * Out: - * - * Return Value: - * - */ - -static int hostap_disable_hostapd(struct vnt_private *pDevice, int rtnl_locked) -{ - pr_debug("%s: disabling hostapd mode\n", pDevice->dev->name); - - if (pDevice->apdev && pDevice->apdev->name && pDevice->apdev->name[0]) { - if (rtnl_locked) - unregister_netdevice(pDevice->apdev); - else - unregister_netdev(pDevice->apdev); - pr_debug("%s: Netdevice %s unregistered\n", - pDevice->dev->name, pDevice->apdev->name); - } - if (pDevice->apdev) - free_netdev(pDevice->apdev); - pDevice->apdev = NULL; - pDevice->bEnable8021x = false; - pDevice->bEnableHostWEP = false; - pDevice->bEncryptionEnable = false; - -/* 4.2007-0118-03,<Add> by EinsnLiu */ -/* execute some clear work */ - pDevice->pMgmt->byCSSPK = KEY_CTL_NONE; - pDevice->pMgmt->byCSSGK = KEY_CTL_NONE; - KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); - - return 0; -} - -/* - * Description: - * Set enable/disable hostapd mode - * - * Parameters: - * In: - * pDevice - - * rtnl_locked - - * Out: - * - * Return Value: - * - */ - -int vt6655_hostap_set_hostapd(struct vnt_private *pDevice, - int val, int rtnl_locked) -{ - if (val < 0 || val > 1) - return -EINVAL; - - if (pDevice->bEnableHostapd == val) - return 0; - - pDevice->bEnableHostapd = val; - - if (val) - return hostap_enable_hostapd(pDevice, rtnl_locked); - else - return hostap_disable_hostapd(pDevice, rtnl_locked); -} - -/* - * Description: - * remove station function supported for hostap deamon - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ -static int hostap_remove_sta(struct vnt_private *pDevice, - struct viawget_hostapd_param *param) -{ - unsigned int uNodeIndex; - - if (BSSDBbIsSTAInNodeDB(pDevice->pMgmt, param->sta_addr, &uNodeIndex)) - BSSvRemoveOneNode(pDevice, uNodeIndex); - else - return -ENOENT; - - return 0; -} - -/* - * Description: - * add a station from hostap deamon - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ -static int hostap_add_sta(struct vnt_private *pDevice, - struct viawget_hostapd_param *param) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int uNodeIndex; - - if (!BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) - BSSvCreateOneNode(pDevice, &uNodeIndex); - - memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, param->sta_addr, WLAN_ADDR_LEN); - pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC; - pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = param->u.add_sta.capability; -/* TODO listenInterval */ - pMgmt->sNodeDBTable[uNodeIndex].bPSEnable = false; - pMgmt->sNodeDBTable[uNodeIndex].bySuppRate = param->u.add_sta.tx_supp_rates; - - /* set max tx rate */ - pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = - pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate; - /* set max basic rate */ - pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate = RATE_2M; - /* Todo: check sta preamble, if ap can't support, set status code */ - pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = - WLAN_GET_CAP_INFO_SHORTPREAMBLE(pMgmt->sNodeDBTable[uNodeIndex].wCapInfo); - - pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)param->u.add_sta.aid; - - pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer = jiffies; - - pr_debug("Add STA AID= %d\n", pMgmt->sNodeDBTable[uNodeIndex].wAID); - pr_debug("MAC=%pM\n", param->sta_addr); - pr_debug("Max Support rate = %d\n", - pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate); - - return 0; -} - -/* - * Description: - * get station info - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ - -static int hostap_get_info_sta(struct vnt_private *pDevice, - struct viawget_hostapd_param *param) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int uNodeIndex; - - if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) { - param->u.get_info_sta.inactive_sec = - (jiffies - pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer) / HZ; - } else { - return -ENOENT; - } - - return 0; -} - -/* - * Description: - * set station flag - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ -static int hostap_set_flags_sta(struct vnt_private *pDevice, - struct viawget_hostapd_param *param) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int uNodeIndex; - - if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) { - pMgmt->sNodeDBTable[uNodeIndex].dwFlags |= param->u.set_flags_sta.flags_or; - pMgmt->sNodeDBTable[uNodeIndex].dwFlags &= param->u.set_flags_sta.flags_and; - pr_debug(" dwFlags = %x\n", - (unsigned int)pMgmt->sNodeDBTable[uNodeIndex].dwFlags); - } else { - return -ENOENT; - } - - return 0; -} - -/* - * Description: - * set generic element (wpa ie) - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ -static int hostap_set_generic_element(struct vnt_private *pDevice, - struct viawget_hostapd_param *param) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - - if (param->u.generic_elem.len > sizeof(pMgmt->abyWPAIE)) - return -EINVAL; - - memcpy(pMgmt->abyWPAIE, - param->u.generic_elem.data, - param->u.generic_elem.len - ); - - pMgmt->wWPAIELen = param->u.generic_elem.len; - - pr_debug("pMgmt->wWPAIELen = %d\n", pMgmt->wWPAIELen); - - /* disable wpa */ - if (pMgmt->wWPAIELen == 0) { - pMgmt->eAuthenMode = WMAC_AUTH_OPEN; - pr_debug(" No WPAIE, Disable WPA\n"); - } else { - /* enable wpa */ - if ((pMgmt->abyWPAIE[0] == WLAN_EID_RSN_WPA) || - (pMgmt->abyWPAIE[0] == WLAN_EID_RSN)) { - pMgmt->eAuthenMode = WMAC_AUTH_WPANONE; - pr_debug("Set WPAIE enable WPA\n"); - } else - return -EINVAL; - } - - return 0; -} - -/* - * Description: - * flush station nodes table. - * - * Parameters: - * In: - * pDevice - - * Out: - * - * Return Value: - * - */ - -static void hostap_flush_sta(struct vnt_private *pDevice) -{ - /* reserved node index =0 for multicast node. */ - BSSvClearNodeDBTable(pDevice, 1); - pDevice->uAssocCount = 0; -} - -/* - * Description: - * set each stations encryption key - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ -static int hostap_set_encryption(struct vnt_private *pDevice, - struct viawget_hostapd_param *param, - int param_len) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned long dwKeyIndex = 0; - unsigned char abyKey[MAX_KEY_LEN]; - unsigned char abySeq[MAX_KEY_LEN]; - u64 KeyRSC; - unsigned char byKeyDecMode = KEY_CTL_WEP; - int iNodeIndex = -1; - int ii; - bool bKeyTableFull = false; - unsigned short wKeyCtl = 0; - - param->u.crypt.err = 0; - - if (param->u.crypt.alg > WPA_ALG_CCMP) - return -EINVAL; - - if ((param->u.crypt.idx > 3) || (param->u.crypt.key_len > MAX_KEY_LEN)) { - param->u.crypt.err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED; - pr_debug(" HOSTAP_CRYPT_ERR_KEY_SET_FAILED\n"); - return -EINVAL; - } - - if (is_broadcast_ether_addr(param->sta_addr)) { - if (param->u.crypt.idx >= MAX_GROUP_KEY) - return -EINVAL; - iNodeIndex = 0; - - } else { - if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == false) { - param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; - pr_debug(" HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n"); - return -EINVAL; - } - } - pr_debug(" hostap_set_encryption: sta_index %d\n", iNodeIndex); - pr_debug(" hostap_set_encryption: alg %d\n", param->u.crypt.alg); - - if (param->u.crypt.alg == WPA_ALG_NONE) { - if (pMgmt->sNodeDBTable[iNodeIndex].bOnFly) { - if (!KeybRemoveKey(&(pDevice->sKey), - param->sta_addr, - pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex, - pDevice->PortOffset)) { - pr_debug("KeybRemoveKey fail\n"); - } - pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; - } - pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = 0; - pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = 0; - pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = 0; - pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = 0; - pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0; - pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0; - pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = 0; - memset(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], - 0, - MAX_KEY_LEN -); - - return 0; - } - - memcpy(abyKey, param->u.crypt.key, param->u.crypt.key_len); - /* copy to node key tbl */ - pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = param->u.crypt.idx; - pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = param->u.crypt.key_len; - memcpy(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], - param->u.crypt.key, - param->u.crypt.key_len -); - - dwKeyIndex = (unsigned long)(param->u.crypt.idx); - if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) { - pDevice->byKeyIndex = (unsigned char)dwKeyIndex; - pDevice->bTransmitKey = true; - dwKeyIndex |= (1 << 31); - } - - if (param->u.crypt.alg == WPA_ALG_WEP) { - if ((pDevice->bEnable8021x == false) || (iNodeIndex == 0)) { - KeybSetDefaultKey(&(pDevice->sKey), - dwKeyIndex & ~(BIT30 | USE_KEYRSC), - param->u.crypt.key_len, - NULL, - abyKey, - KEY_CTL_WEP, - pDevice->PortOffset, - pDevice->byLocalID); - - } else { - /* 8021x enable, individual key */ - dwKeyIndex |= (1 << 30); /* set pairwise key */ - if (KeybSetKey(&(pDevice->sKey), - ¶m->sta_addr[0], - dwKeyIndex & ~(USE_KEYRSC), - param->u.crypt.key_len, - (u64 *) &KeyRSC, - (unsigned char *)abyKey, - KEY_CTL_WEP, - pDevice->PortOffset, - pDevice->byLocalID)) { - pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; - - } else { - /* Key Table Full */ - pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; - bKeyTableFull = true; - } - } - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - pDevice->bEncryptionEnable = true; - pMgmt->byCSSPK = KEY_CTL_WEP; - pMgmt->byCSSGK = KEY_CTL_WEP; - pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = KEY_CTL_WEP; - pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex; - return 0; - } - - if (param->u.crypt.seq) { - memcpy(&abySeq, param->u.crypt.seq, 8); - for (ii = 0; ii < 8; ii++) - KeyRSC |= (u64)abySeq[ii] << (ii * 8); - - dwKeyIndex |= 1 << 29; - pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = KeyRSC; - } - - if (param->u.crypt.alg == WPA_ALG_TKIP) { - if (param->u.crypt.key_len != MAX_KEY_LEN) - return -EINVAL; - pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; - byKeyDecMode = KEY_CTL_TKIP; - pMgmt->byCSSPK = KEY_CTL_TKIP; - pMgmt->byCSSGK = KEY_CTL_TKIP; - } - - if (param->u.crypt.alg == WPA_ALG_CCMP) { - if ((param->u.crypt.key_len != AES_KEY_LEN) || - (pDevice->byLocalID <= REV_ID_VT3253_A1)) - return -EINVAL; - pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; - byKeyDecMode = KEY_CTL_CCMP; - pMgmt->byCSSPK = KEY_CTL_CCMP; - pMgmt->byCSSGK = KEY_CTL_CCMP; - } - - if (iNodeIndex == 0) { - KeybSetDefaultKey(&(pDevice->sKey), - dwKeyIndex, - param->u.crypt.key_len, - (u64 *) &KeyRSC, - abyKey, - byKeyDecMode, - pDevice->PortOffset, - pDevice->byLocalID); - pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; - - } else { - dwKeyIndex |= (1 << 30); /* set pairwise key */ - if (KeybSetKey(&(pDevice->sKey), - ¶m->sta_addr[0], - dwKeyIndex, - param->u.crypt.key_len, - (u64 *) &KeyRSC, - (unsigned char *)abyKey, - byKeyDecMode, - pDevice->PortOffset, - pDevice->byLocalID)) { - pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; - - } else { - /* Key Table Full */ - pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; - bKeyTableFull = true; - pr_debug(" Key Table Full\n"); - } - - } - - if (bKeyTableFull) { - wKeyCtl &= 0x7F00; /* clear all key control filed */ - wKeyCtl |= (byKeyDecMode << 4); - wKeyCtl |= (byKeyDecMode); - wKeyCtl |= 0x0044; /* use group key for all address */ - wKeyCtl |= 0x4000; /* disable KeyTable[MAX_KEY_TABLE-1] on-fly to genernate rx int */ - MACvSetDefaultKeyCtl(pDevice->PortOffset, wKeyCtl, MAX_KEY_TABLE-1, pDevice->byLocalID); - } - - pr_debug(" Set key sta_index= %d\n", iNodeIndex); - pr_debug(" tx_index=%d len=%d\n", - param->u.crypt.idx, param->u.crypt.key_len); - pr_debug(" key=%x-%x-%x-%x-%x-xxxxx\n", - pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], - pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[1], - pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[2], - pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[3], - pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[4]); - - /* set wep key */ - pDevice->bEncryptionEnable = true; - pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = byKeyDecMode; - pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex; - pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0; - pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0; - - return 0; -} - -/* - * Description: - * get each stations encryption key - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ -static int hostap_get_encryption(struct vnt_private *pDevice, - struct viawget_hostapd_param *param, - int param_len) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - int ii; - int iNodeIndex = 0; - - param->u.crypt.err = 0; - - if (is_broadcast_ether_addr(param->sta_addr)) { - iNodeIndex = 0; - } else { - if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == false) { - param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; - pr_debug("hostap_get_encryption: HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n"); - return -EINVAL; - } - } - pr_debug("hostap_get_encryption: %d\n", iNodeIndex); - memset(param->u.crypt.seq, 0, 8); - for (ii = 0; ii < 8; ii++) - param->u.crypt.seq[ii] = (unsigned char)pMgmt->sNodeDBTable[iNodeIndex].KeyRSC >> (ii * 8); - - return 0; -} - -/* - * Description: - * vt6655_hostap_ioctl main function supported for hostap deamon. - * - * Parameters: - * In: - * pDevice - - * iw_point - - * Out: - * - * Return Value: - * - */ -int vt6655_hostap_ioctl(struct vnt_private *pDevice, struct iw_point *p) -{ - struct viawget_hostapd_param *param; - int ret = 0; - int ap_ioctl = 0; - - if (p->length < sizeof(struct viawget_hostapd_param) || - p->length > VIAWGET_HOSTAPD_MAX_BUF_SIZE || !p->pointer) - return -EINVAL; - - param = kmalloc((int)p->length, GFP_KERNEL); - if (param == NULL) - return -ENOMEM; - - if (copy_from_user(param, p->pointer, p->length)) { - ret = -EFAULT; - goto out; - } - - switch (param->cmd) { - case VIAWGET_HOSTAPD_SET_ENCRYPTION: - pr_debug("VIAWGET_HOSTAPD_SET_ENCRYPTION\n"); - spin_lock_irq(&pDevice->lock); - ret = hostap_set_encryption(pDevice, param, p->length); - spin_unlock_irq(&pDevice->lock); - break; - case VIAWGET_HOSTAPD_GET_ENCRYPTION: - pr_debug("VIAWGET_HOSTAPD_GET_ENCRYPTION\n"); - spin_lock_irq(&pDevice->lock); - ret = hostap_get_encryption(pDevice, param, p->length); - spin_unlock_irq(&pDevice->lock); - break; - case VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR: - pr_debug("VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR\n"); - ret = -EOPNOTSUPP; - goto out; - case VIAWGET_HOSTAPD_FLUSH: - pr_debug("VIAWGET_HOSTAPD_FLUSH\n"); - spin_lock_irq(&pDevice->lock); - hostap_flush_sta(pDevice); - spin_unlock_irq(&pDevice->lock); - break; - case VIAWGET_HOSTAPD_ADD_STA: - pr_debug("VIAWGET_HOSTAPD_ADD_STA\n"); - spin_lock_irq(&pDevice->lock); - ret = hostap_add_sta(pDevice, param); - spin_unlock_irq(&pDevice->lock); - break; - case VIAWGET_HOSTAPD_REMOVE_STA: - pr_debug("VIAWGET_HOSTAPD_REMOVE_STA\n"); - spin_lock_irq(&pDevice->lock); - ret = hostap_remove_sta(pDevice, param); - spin_unlock_irq(&pDevice->lock); - break; - case VIAWGET_HOSTAPD_GET_INFO_STA: - pr_debug("VIAWGET_HOSTAPD_GET_INFO_STA\n"); - ret = hostap_get_info_sta(pDevice, param); - ap_ioctl = 1; - break; - case VIAWGET_HOSTAPD_SET_FLAGS_STA: - pr_debug("VIAWGET_HOSTAPD_SET_FLAGS_STA\n"); - ret = hostap_set_flags_sta(pDevice, param); - break; - case VIAWGET_HOSTAPD_MLME: - pr_debug("VIAWGET_HOSTAPD_MLME\n"); - ret = -EOPNOTSUPP; - goto out; - case VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT: - pr_debug("VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT\n"); - ret = hostap_set_generic_element(pDevice, param); - break; - case VIAWGET_HOSTAPD_SCAN_REQ: - pr_debug("VIAWGET_HOSTAPD_SCAN_REQ\n"); - ret = -EOPNOTSUPP; - goto out; - case VIAWGET_HOSTAPD_STA_CLEAR_STATS: - pr_debug("VIAWGET_HOSTAPD_STA_CLEAR_STATS\n"); - ret = -EOPNOTSUPP; - goto out; - default: - pr_debug("vt6655_hostap_ioctl: unknown cmd=%d\n", - (int)param->cmd); - ret = -EOPNOTSUPP; - goto out; - } - - if ((ret == 0) && ap_ioctl) { - if (copy_to_user(p->pointer, param, p->length)) - ret = -EFAULT; - } - -out: - kfree(param); - return ret; -} diff --git a/drivers/staging/vt6655/hostap.h b/drivers/staging/vt6655/hostap.h deleted file mode 100644 index 17df4e403fcf..000000000000 --- a/drivers/staging/vt6655/hostap.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: hostap.h - * - * Purpose: - * - * Author: Lyndon Chen - * - * Date: May 21, 2003 - * - */ - -#ifndef __HOSTAP_H__ -#define __HOSTAP_H__ - -#include "device.h" - -#define WLAN_RATE_1M BIT0 -#define WLAN_RATE_2M BIT1 -#define WLAN_RATE_5M5 BIT2 -#define WLAN_RATE_11M BIT3 -#define WLAN_RATE_6M BIT4 -#define WLAN_RATE_9M BIT5 -#define WLAN_RATE_12M BIT6 -#define WLAN_RATE_18M BIT7 -#define WLAN_RATE_24M BIT8 -#define WLAN_RATE_36M BIT9 -#define WLAN_RATE_48M BIT10 -#define WLAN_RATE_54M BIT11 - -#ifndef ETH_P_PAE -#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ -#endif /* ETH_P_PAE */ - -#ifndef ARPHRD_IEEE80211 -#define ARPHRD_IEEE80211 801 -#endif - -int vt6655_hostap_set_hostapd(struct vnt_private *, int val, int rtnl_locked); -int vt6655_hostap_ioctl(struct vnt_private *, struct iw_point *p); - -#endif // __HOSTAP_H__ diff --git a/drivers/staging/vt6655/iocmd.h b/drivers/staging/vt6655/iocmd.h deleted file mode 100644 index a665cfd8a482..000000000000 --- a/drivers/staging/vt6655/iocmd.h +++ /dev/null @@ -1,408 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: iocmd.h - * - * Purpose: Handles the viawget ioctl private interface functions - * - * Author: Lyndon Chen - * - * Date: May 8, 2002 - * - */ - -#ifndef __IOCMD_H__ -#define __IOCMD_H__ - -#include "ttype.h" - -// ioctl Command code -#define MAGIC_CODE 0x3142 -#define IOCTL_CMD_TEST (SIOCDEVPRIVATE + 0) -#define IOCTL_CMD_SET (SIOCDEVPRIVATE + 1) -#define IOCTL_CMD_HOSTAPD (SIOCDEVPRIVATE + 2) -#define IOCTL_CMD_WPA (SIOCDEVPRIVATE + 3) - -typedef enum tagWMAC_CMD { - WLAN_CMD_BSS_SCAN, - WLAN_CMD_BSS_JOIN, - WLAN_CMD_DISASSOC, - WLAN_CMD_SET_WEP, - WLAN_CMD_GET_LINK, - WLAN_CMD_GET_LISTLEN, - WLAN_CMD_GET_LIST, - WLAN_CMD_GET_MIB, - WLAN_CMD_GET_STAT, - WLAN_CMD_STOP_MAC, - WLAN_CMD_START_MAC, - WLAN_CMD_AP_START, - WLAN_CMD_SET_HOSTAPD, - WLAN_CMD_SET_HOSTAPD_STA, - WLAN_CMD_SET_802_1X, - WLAN_CMD_SET_HOST_WEP, - WLAN_CMD_SET_WPA, - WLAN_CMD_GET_NODE_CNT, - WLAN_CMD_ZONETYPE_SET, - WLAN_CMD_GET_NODE_LIST -} WMAC_CMD, *PWMAC_CMD; - -typedef enum tagWZONETYPE { - ZoneType_USA = 0, - ZoneType_Japan = 1, - ZoneType_Europe = 2 -} WZONETYPE; - -#define ADHOC 0 -#define INFRA 1 -#define BOTH 2 -#define AP 3 - -#define ADHOC_STARTED 1 -#define ADHOC_JOINTED 2 - -#define PHY80211a 0 -#define PHY80211b 1 -#define PHY80211g 2 - -#define SSID_ID 0 -#define SSID_MAXLEN 32 -#define BSSID_LEN 6 -#define WEP_NKEYS 4 -#define WEP_KEYMAXLEN 29 -#define WEP_40BIT_LEN 5 -#define WEP_104BIT_LEN 13 -#define WEP_232BIT_LEN 16 - -// Ioctl interface structure -// Command structure -// -#pragma pack(1) -typedef struct tagSCmdRequest { - u8 name[16]; - void __user *data; - u16 wResult; - u16 wCmdCode; -} SCmdRequest, *PSCmdRequest; - -// -// Scan -// - -typedef struct tagSCmdScan { - u8 ssid[SSID_MAXLEN + 2]; -} SCmdScan, *PSCmdScan; - -// -// BSS Join -// - -typedef struct tagSCmdBSSJoin { - u16 wBSSType; - u16 wBBPType; - u8 ssid[SSID_MAXLEN + 2]; - u32 uChannel; - bool bPSEnable; - bool bShareKeyAuth; -} SCmdBSSJoin, *PSCmdBSSJoin; - -// -// Zonetype Setting -// - -typedef struct tagSCmdZoneTypeSet { - bool bWrite; - WZONETYPE ZoneType; -} SCmdZoneTypeSet, *PSCmdZoneTypeSet; - -#ifdef WPA_SM_Transtatus -typedef struct tagSWPAResult { - char ifname[100]; - u8 proto; - u8 key_mgmt; - u8 eap_type; - bool authenticated; -} SWPAResult, *PSWPAResult; -#endif - -typedef struct tagSCmdStartAP { - u16 wBSSType; - u16 wBBPType; - u8 ssid[SSID_MAXLEN + 2]; - u32 uChannel; - u32 uBeaconInt; - bool bShareKeyAuth; - u8 byBasicRate; -} SCmdStartAP, *PSCmdStartAP; - -typedef struct tagSCmdSetWEP { - bool bEnableWep; - u8 byKeyIndex; - u8 abyWepKey[WEP_NKEYS][WEP_KEYMAXLEN]; - bool bWepKeyAvailable[WEP_NKEYS]; - u32 auWepKeyLength[WEP_NKEYS]; -} SCmdSetWEP, *PSCmdSetWEP; - -typedef struct tagSBSSIDItem { - u32 uChannel; - u8 abyBSSID[BSSID_LEN]; - u8 abySSID[SSID_MAXLEN + 1]; - u8 byNetType; - u16 wBeaconInterval; - u16 wCapInfo; // for address of byNetType at align 4 - - bool bWEPOn; - u32 uRSSI; -} SBSSIDItem; - -typedef struct tagSBSSIDList { - u32 uItem; - SBSSIDItem sBSSIDList[0]; -} SBSSIDList, *PSBSSIDList; - -typedef struct tagSCmdLinkStatus { - bool bLink; - u16 wBSSType; - u8 byState; - u8 abyBSSID[BSSID_LEN]; - u8 abySSID[SSID_MAXLEN + 2]; - u32 uChannel; - u32 uLinkRate; -} SCmdLinkStatus, *PSCmdLinkStatus; - -// -// 802.11 counter -// -typedef struct tagSDot11MIBCount { - u32 TransmittedFragmentCount; - u32 MulticastTransmittedFrameCount; - u32 FailedCount; - u32 RetryCount; - u32 MultipleRetryCount; - u32 RTSSuccessCount; - u32 RTSFailureCount; - u32 ACKFailureCount; - u32 FrameDuplicateCount; - u32 ReceivedFragmentCount; - u32 MulticastReceivedFrameCount; - u32 FCSErrorCount; -} SDot11MIBCount, *PSDot11MIBCount; - -// -// statistic counter -// -typedef struct tagSStatMIBCount { - // - // ISR status count - // - u32 dwIsrTx0OK; - u32 dwIsrTx1OK; - u32 dwIsrBeaconTxOK; - u32 dwIsrRxOK; - u32 dwIsrTBTTInt; - u32 dwIsrSTIMERInt; - u32 dwIsrUnrecoverableError; - u32 dwIsrSoftInterrupt; - u32 dwIsrRxNoBuf; - - u32 dwIsrUnknown; - - // RSR status count - // - u32 dwRsrFrmAlgnErr; - u32 dwRsrErr; - u32 dwRsrCRCErr; - u32 dwRsrCRCOk; - u32 dwRsrBSSIDOk; - u32 dwRsrADDROk; - u32 dwRsrICVOk; - u32 dwNewRsrShortPreamble; - u32 dwRsrLong; - u32 dwRsrRunt; - - u32 dwRsrRxControl; - u32 dwRsrRxData; - u32 dwRsrRxManage; - - u32 dwRsrRxPacket; - u32 dwRsrRxOctet; - u32 dwRsrBroadcast; - u32 dwRsrMulticast; - u32 dwRsrDirected; - // 64-bit OID - u32 ullRsrOK; - - // for some optional OIDs (64 bits) and DMI support - u32 ullRxBroadcastBytes; - u32 ullRxMulticastBytes; - u32 ullRxDirectedBytes; - u32 ullRxBroadcastFrames; - u32 ullRxMulticastFrames; - u32 ullRxDirectedFrames; - - u32 dwRsrRxFragment; - u32 dwRsrRxFrmLen64; - u32 dwRsrRxFrmLen65_127; - u32 dwRsrRxFrmLen128_255; - u32 dwRsrRxFrmLen256_511; - u32 dwRsrRxFrmLen512_1023; - u32 dwRsrRxFrmLen1024_1518; - - // TSR0,1 status count - // - u32 dwTsrTotalRetry[2]; // total collision retry count - u32 dwTsrOnceRetry[2]; // this packet only occur one collision - u32 dwTsrMoreThanOnceRetry[2]; // this packet occur more than one collision - u32 dwTsrRetry[2]; // this packet has ever occur collision, - // that is (dwTsrOnceCollision0 + dwTsrMoreThanOnceCollision0) - u32 dwTsrACKData[2]; - u32 dwTsrErr[2]; - u32 dwAllTsrOK[2]; - u32 dwTsrRetryTimeout[2]; - u32 dwTsrTransmitTimeout[2]; - - u32 dwTsrTxPacket[2]; - u32 dwTsrTxOctet[2]; - u32 dwTsrBroadcast[2]; - u32 dwTsrMulticast[2]; - u32 dwTsrDirected[2]; - - // RD/TD count - u32 dwCntRxFrmLength; - u32 dwCntTxBufLength; - - u8 abyCntRxPattern[16]; - u8 abyCntTxPattern[16]; - - // Software check.... - u32 dwCntRxDataErr; // rx buffer data software compare CRC err count - u32 dwCntDecryptErr; // rx buffer data software compare CRC err count - u32 dwCntRxICVErr; // rx buffer data software compare CRC err count - u32 idxRxErrorDesc; // index for rx data error RD - - // 64-bit OID - u32 ullTsrOK[2]; - - // for some optional OIDs (64 bits) and DMI support - u32 ullTxBroadcastFrames[2]; - u32 ullTxMulticastFrames[2]; - u32 ullTxDirectedFrames[2]; - u32 ullTxBroadcastBytes[2]; - u32 ullTxMulticastBytes[2]; - u32 ullTxDirectedBytes[2]; -} SStatMIBCount, *PSStatMIBCount; - -typedef struct tagSNodeItem { - // STA info - u16 wAID; - u8 abyMACAddr[6]; - u16 wTxDataRate; - u16 wInActiveCount; - u16 wEnQueueCnt; - u16 wFlags; - bool bPWBitOn; - u8 byKeyIndex; - u16 wWepKeyLength; - u8 abyWepKey[WEP_KEYMAXLEN]; - // Auto rate fallback vars - bool bIsInFallback; - u32 uTxFailures; - u32 uTxAttempts; - u16 wFailureRatio; -} SNodeItem; - -typedef struct tagSNodeList { - u32 uItem; - SNodeItem sNodeList[0]; -} SNodeList, *PSNodeList; - -typedef struct tagSCmdValue { - u32 dwValue; -} SCmdValue, *PSCmdValue; - -// -// hostapd & viawget ioctl related -// - -enum { - VIAWGET_HOSTAPD_FLUSH = 1, - VIAWGET_HOSTAPD_ADD_STA = 2, - VIAWGET_HOSTAPD_REMOVE_STA = 3, - VIAWGET_HOSTAPD_GET_INFO_STA = 4, - VIAWGET_HOSTAPD_SET_ENCRYPTION = 5, - VIAWGET_HOSTAPD_GET_ENCRYPTION = 6, - VIAWGET_HOSTAPD_SET_FLAGS_STA = 7, - VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR = 8, - VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT = 9, - VIAWGET_HOSTAPD_MLME = 10, - VIAWGET_HOSTAPD_SCAN_REQ = 11, - VIAWGET_HOSTAPD_STA_CLEAR_STATS = 12, -}; - -#define VIAWGET_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \ - ((int)(&((struct viawget_hostapd_param *)0)->u.generic_elem.data)) - -// Maximum length for algorithm names (-1 for nul termination) used in ioctl() - -struct viawget_hostapd_param { - u32 cmd; - u8 sta_addr[6]; - union { - struct { - u16 aid; - u16 capability; - u8 tx_supp_rates; - } add_sta; - struct { - u32 inactive_sec; - } get_info_sta; - struct { - u8 alg; - u32 flags; - u32 err; - u8 idx; - u8 seq[8]; - u16 key_len; - u8 key[0]; - } crypt; - struct { - u32 flags_and; - u32 flags_or; - } set_flags_sta; - struct { - u16 rid; - u16 len; - u8 data[0]; - } rid; - struct { - u8 len; - u8 data[0]; - } generic_elem; - struct { - u16 cmd; - u16 reason_code; - } mlme; - struct { - u8 ssid_len; - u8 ssid[32]; - } scan_req; - } u; -}; - -#pragma pack() - -#endif //__IOCMD_H__ diff --git a/drivers/staging/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c deleted file mode 100644 index 970e80d92fb9..000000000000 --- a/drivers/staging/vt6655/ioctl.c +++ /dev/null @@ -1,658 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: ioctl.c - * - * Purpose: private ioctl functions - * - * Author: Lyndon Chen - * - * Date: Auguest 20, 2003 - * - * Functions: - * - * Revision History: - * - */ - -#include "ioctl.h" -#include "iocmd.h" -#include "mac.h" -#include "card.h" -#include "hostap.h" -#include "wpactl.h" -#include "rf.h" - -#ifdef WPA_SM_Transtatus -SWPAResult wpa_Result; -#endif - -int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) -{ - PSCmdRequest pReq = (PSCmdRequest)rq; - PSMgmtObject pMgmt = pDevice->pMgmt; - int result = 0; - PWLAN_IE_SSID pItemSSID; - SCmdBSSJoin sJoinCmd; - SCmdZoneTypeSet sZoneTypeCmd; - SCmdScan sScanCmd; - SCmdStartAP sStartAPCmd; - SCmdSetWEP sWEPCmd; - SCmdValue sValue; - SBSSIDList sList; - SNodeList sNodeList; - PSBSSIDList pList; - PSNodeList pNodeList; - unsigned int cbListCount; - PKnownBSS pBSS; - PKnownNodeDB pNode; - unsigned int ii, jj; - unsigned char abySuppRates[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16}; - unsigned char abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - unsigned long dwKeyIndex = 0; - unsigned char abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - long ldBm; - - pReq->wResult = 0; - - switch (pReq->wCmdCode) { - case WLAN_CMD_BSS_SCAN: - pr_debug("WLAN_CMD_BSS_SCAN..begin\n"); - if (copy_from_user(&sScanCmd, pReq->data, sizeof(SCmdScan))) { - result = -EFAULT; - break; - } - - pItemSSID = (PWLAN_IE_SSID)sScanCmd.ssid; - if (pItemSSID->len > WLAN_SSID_MAXLEN + 1) - return -EINVAL; - if (pItemSSID->len != 0) { - memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - memcpy(abyScanSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN); - } - - if (pDevice->bMACSuspend == true) { - if (pDevice->bRadioOff == true) - CARDbRadioPowerOn(pDevice); - vMgrTimerInit(pDevice); - MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); - add_timer(&pMgmt->sTimerSecondCallback); - pDevice->bMACSuspend = false; - } - spin_lock_irq(&pDevice->lock); - if (memcmp(pMgmt->abyCurrBSSID, &abyNullAddr[0], 6) == 0) - BSSvClearBSSList((void *)pDevice, false); - else - BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); - - if (pItemSSID->len != 0) - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); - else - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); - spin_unlock_irq(&pDevice->lock); - break; - - case WLAN_CMD_ZONETYPE_SET: - /* mike add :can't support. */ - result = -EOPNOTSUPP; - break; - - if (copy_from_user(&sZoneTypeCmd, pReq->data, sizeof(SCmdZoneTypeSet))) { - result = -EFAULT; - break; - } - - if (sZoneTypeCmd.bWrite == true) { - /* write zonetype */ - if (sZoneTypeCmd.ZoneType == ZoneType_USA) { - /* set to USA */ - pr_debug("set_ZoneType:USA\n"); - } else if (sZoneTypeCmd.ZoneType == ZoneType_Japan) { - /* set to Japan */ - pr_debug("set_ZoneType:Japan\n"); - } else if (sZoneTypeCmd.ZoneType == ZoneType_Europe) { - /* set to Europe */ - pr_debug("set_ZoneType:Europe\n"); - } - } else { - /* read zonetype */ - unsigned char zonetype = 0; - - if (zonetype == 0x00) { /* USA */ - sZoneTypeCmd.ZoneType = ZoneType_USA; - } else if (zonetype == 0x01) { /* Japan */ - sZoneTypeCmd.ZoneType = ZoneType_Japan; - } else if (zonetype == 0x02) { /* Europe */ - sZoneTypeCmd.ZoneType = ZoneType_Europe; - } else { /* Unknown ZoneType */ - pr_err("Error:ZoneType[%x] Unknown ???\n", zonetype); - result = -EFAULT; - break; - } - if (copy_to_user(pReq->data, &sZoneTypeCmd, sizeof(SCmdZoneTypeSet))) { - result = -EFAULT; - break; - } - } - break; - - case WLAN_CMD_BSS_JOIN: - if (pDevice->bMACSuspend == true) { - if (pDevice->bRadioOff == true) - CARDbRadioPowerOn(pDevice); - vMgrTimerInit(pDevice); - MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); - add_timer(&pMgmt->sTimerSecondCallback); - pDevice->bMACSuspend = false; - } - - if (copy_from_user(&sJoinCmd, pReq->data, sizeof(SCmdBSSJoin))) { - result = -EFAULT; - break; - } - - pItemSSID = (PWLAN_IE_SSID)sJoinCmd.ssid; - if (pItemSSID->len > WLAN_SSID_MAXLEN + 1) - return -EINVAL; - memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - memcpy(pMgmt->abyDesireSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN); - if (sJoinCmd.wBSSType == ADHOC) { - pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; - pr_debug("ioct set to adhoc mode\n"); - } else { - pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; - pr_debug("ioct set to STA mode\n"); - } - if (sJoinCmd.bPSEnable == true) { - pDevice->ePSMode = WMAC_POWER_FAST; - pMgmt->wListenInterval = 2; - pr_debug("Power Saving On\n"); - } else { - pDevice->ePSMode = WMAC_POWER_CAM; - pMgmt->wListenInterval = 1; - pr_debug("Power Saving Off\n"); - } - - if (sJoinCmd.bShareKeyAuth == true) { - pMgmt->bShareKeyAlgorithm = true; - pr_debug("Share Key\n"); - } else { - pMgmt->bShareKeyAlgorithm = false; - pr_debug("Open System\n"); - } - pDevice->uChannel = sJoinCmd.uChannel; - netif_stop_queue(pDevice->dev); - spin_lock_irq(&pDevice->lock); - pMgmt->eCurrState = WMAC_STATE_IDLE; - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); - spin_unlock_irq(&pDevice->lock); - break; - - case WLAN_CMD_SET_WEP: - pr_debug("WLAN_CMD_SET_WEP Key\n"); - memset(&sWEPCmd, 0, sizeof(SCmdSetWEP)); - if (copy_from_user(&sWEPCmd, pReq->data, sizeof(SCmdSetWEP))) { - result = -EFAULT; - break; - } - if (sWEPCmd.bEnableWep != true) { - pDevice->bEncryptionEnable = false; - pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - MACvDisableDefaultKey(pDevice->PortOffset); - pr_debug("WEP function disable\n"); - break; - } - - for (ii = 0; ii < WLAN_WEP_NKEYS; ii++) { - if (sWEPCmd.bWepKeyAvailable[ii]) { - if (ii == sWEPCmd.byKeyIndex) - dwKeyIndex = ii | (1 << 31); - else - dwKeyIndex = ii; - - KeybSetDefaultKey(&(pDevice->sKey), - dwKeyIndex, - sWEPCmd.auWepKeyLength[ii], - NULL, - (unsigned char *)&sWEPCmd.abyWepKey[ii][0], - KEY_CTL_WEP, - pDevice->PortOffset, - pDevice->byLocalID); - } - } - pDevice->byKeyIndex = sWEPCmd.byKeyIndex; - pDevice->bTransmitKey = true; - pDevice->bEncryptionEnable = true; - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - break; - - case WLAN_CMD_GET_LINK: { - SCmdLinkStatus sLinkStatus; - - pr_debug("WLAN_CMD_GET_LINK status\n"); - - memset(&sLinkStatus, 0, sizeof(sLinkStatus)); - - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) - sLinkStatus.wBSSType = ADHOC; - else - sLinkStatus.wBSSType = INFRA; - - if (pMgmt->eCurrState == WMAC_STATE_JOINTED) - sLinkStatus.byState = ADHOC_JOINTED; - else - sLinkStatus.byState = ADHOC_STARTED; - - sLinkStatus.uChannel = pMgmt->uCurrChannel; - if (pDevice->bLinkPass == true) { - sLinkStatus.bLink = true; - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - memcpy(sLinkStatus.abySSID, pItemSSID->abySSID, pItemSSID->len); - memcpy(sLinkStatus.abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - sLinkStatus.uLinkRate = pMgmt->sNodeDBTable[0].wTxDataRate; - pr_debug(" Link Success!\n"); - } else { - sLinkStatus.bLink = false; - sLinkStatus.uLinkRate = 0; - } - if (copy_to_user(pReq->data, &sLinkStatus, sizeof(SCmdLinkStatus))) { - result = -EFAULT; - break; - } - break; - } - case WLAN_CMD_GET_LISTLEN: - cbListCount = 0; - pBSS = &(pMgmt->sBSSList[0]); - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - pBSS = &(pMgmt->sBSSList[ii]); - if (!pBSS->bActive) - continue; - cbListCount++; - } - sList.uItem = cbListCount; - if (copy_to_user(pReq->data, &sList, sizeof(SBSSIDList))) { - result = -EFAULT; - break; - } - pReq->wResult = 0; - break; - - case WLAN_CMD_GET_LIST: - if (copy_from_user(&sList, pReq->data, sizeof(SBSSIDList))) { - result = -EFAULT; - break; - } - if (sList.uItem > (ULONG_MAX - sizeof(SBSSIDList)) / sizeof(SBSSIDItem)) { - result = -EINVAL; - break; - } - pList = (PSBSSIDList)kmalloc(sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)), - GFP_ATOMIC); - if (pList == NULL) { - result = -ENOMEM; - break; - } - pList->uItem = sList.uItem; - pBSS = &(pMgmt->sBSSList[0]); - for (ii = 0, jj = 0; jj < MAX_BSS_NUM; jj++) { - pBSS = &(pMgmt->sBSSList[jj]); - if (pBSS->bActive) { - pList->sBSSIDList[ii].uChannel = pBSS->uChannel; - pList->sBSSIDList[ii].wBeaconInterval = pBSS->wBeaconInterval; - pList->sBSSIDList[ii].wCapInfo = pBSS->wCapInfo; - RFvRSSITodBm(pDevice, (unsigned char)(pBSS->uRSSI), &ldBm); - pList->sBSSIDList[ii].uRSSI = (unsigned int)ldBm; - memcpy(pList->sBSSIDList[ii].abyBSSID, pBSS->abyBSSID, WLAN_BSSID_LEN); - pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; - memset(pList->sBSSIDList[ii].abySSID, 0, WLAN_SSID_MAXLEN + 1); - memcpy(pList->sBSSIDList[ii].abySSID, pItemSSID->abySSID, pItemSSID->len); - if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) - pList->sBSSIDList[ii].byNetType = INFRA; - else - pList->sBSSIDList[ii].byNetType = ADHOC; - - if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) - pList->sBSSIDList[ii].bWEPOn = true; - else - pList->sBSSIDList[ii].bWEPOn = false; - - ii++; - if (ii >= pList->uItem) - break; - } - } - - if (copy_to_user(pReq->data, pList, sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)))) { - result = -EFAULT; - break; - } - kfree(pList); - pReq->wResult = 0; - break; - - case WLAN_CMD_GET_MIB: - if (copy_to_user(pReq->data, &(pDevice->s802_11Counter), sizeof(SDot11MIBCount))) { - result = -EFAULT; - break; - } - break; - - case WLAN_CMD_GET_STAT: - if (copy_to_user(pReq->data, &(pDevice->scStatistic), sizeof(SStatCounter))) { - result = -EFAULT; - break; - } - break; - - case WLAN_CMD_STOP_MAC: - pr_debug("WLAN_CMD_STOP_MAC\n"); - netif_stop_queue(pDevice->dev); - - spin_lock_irq(&pDevice->lock); - if (pDevice->bRadioOff == false) - CARDbRadioPowerOff(pDevice); - - pDevice->bLinkPass = false; - memset(pMgmt->abyCurrBSSID, 0, 6); - pMgmt->eCurrState = WMAC_STATE_IDLE; - del_timer(&pDevice->sTimerCommand); - del_timer(&pMgmt->sTimerSecondCallback); - pDevice->bCmdRunning = false; - pDevice->bMACSuspend = true; - MACvIntDisable(pDevice->PortOffset); - spin_unlock_irq(&pDevice->lock); - break; - - case WLAN_CMD_START_MAC: - pr_debug("WLAN_CMD_START_MAC\n"); - - if (pDevice->bMACSuspend == true) { - if (pDevice->bRadioOff == true) - CARDbRadioPowerOn(pDevice); - vMgrTimerInit(pDevice); - MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); - add_timer(&pMgmt->sTimerSecondCallback); - pDevice->bMACSuspend = false; - } - break; - - case WLAN_CMD_SET_HOSTAPD: - pr_debug("WLAN_CMD_SET_HOSTAPD\n"); - - if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) { - result = -EFAULT; - break; - } - if (sValue.dwValue == 1) { - if (vt6655_hostap_set_hostapd(pDevice, 1, 1) == 0) { - pr_debug("Enable HOSTAP\n"); - } else { - result = -EFAULT; - break; - } - } else { - vt6655_hostap_set_hostapd(pDevice, 0, 1); - pr_debug("Disable HOSTAP\n"); - } - break; - - case WLAN_CMD_SET_HOSTAPD_STA: - pr_debug("WLAN_CMD_SET_HOSTAPD_STA\n"); - break; - - case WLAN_CMD_SET_802_1X: - pr_debug("WLAN_CMD_SET_802_1X\n"); - if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) { - result = -EFAULT; - break; - } - - if (sValue.dwValue == 1) { - pDevice->bEnable8021x = true; - pr_debug("Enable 802.1x\n"); - } else { - pDevice->bEnable8021x = false; - pr_debug("Disable 802.1x\n"); - } - break; - - case WLAN_CMD_SET_HOST_WEP: - pr_debug("WLAN_CMD_SET_HOST_WEP\n"); - if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) { - result = -EFAULT; - break; - } - - if (sValue.dwValue == 1) { - pDevice->bEnableHostWEP = true; - pr_debug("Enable HostWEP\n"); - } else { - pDevice->bEnableHostWEP = false; - pr_debug("Disable HostWEP\n"); - } - break; - - case WLAN_CMD_SET_WPA: - pr_debug("WLAN_CMD_SET_WPA\n"); - - if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) { - result = -EFAULT; - break; - } - if (sValue.dwValue == 1) { - pr_debug("up wpadev\n"); - eth_hw_addr_inherit(pDevice->wpadev, pDevice->dev); - pDevice->bWPADEVUp = true; - } else { - pr_debug("close wpadev\n"); - pDevice->bWPADEVUp = false; - } - break; - - case WLAN_CMD_AP_START: - pr_debug("WLAN_CMD_AP_START\n"); - if (pDevice->bRadioOff == true) { - CARDbRadioPowerOn(pDevice); - vMgrTimerInit(pDevice); - MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); - add_timer(&pMgmt->sTimerSecondCallback); - } - if (copy_from_user(&sStartAPCmd, pReq->data, sizeof(SCmdStartAP))) { - result = -EFAULT; - break; - } - - if (sStartAPCmd.wBSSType == AP) { - pMgmt->eConfigMode = WMAC_CONFIG_AP; - pr_debug("ioct set to AP mode\n"); - } else { - pr_debug("ioct BSS type not set to AP mode\n"); - result = -EFAULT; - break; - } - - if (sStartAPCmd.wBBPType == PHY80211g) - pMgmt->byAPBBType = PHY_TYPE_11G; - else if (sStartAPCmd.wBBPType == PHY80211a) - pMgmt->byAPBBType = PHY_TYPE_11A; - else - pMgmt->byAPBBType = PHY_TYPE_11B; - - pItemSSID = (PWLAN_IE_SSID)sStartAPCmd.ssid; - if (pItemSSID->len > WLAN_SSID_MAXLEN + 1) - return -EINVAL; - memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - memcpy(pMgmt->abyDesireSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN); - - if ((sStartAPCmd.uChannel > 0) && (sStartAPCmd.uChannel <= 14)) - pDevice->uChannel = sStartAPCmd.uChannel; - - if ((sStartAPCmd.uBeaconInt >= 20) && (sStartAPCmd.uBeaconInt <= 1000)) - pMgmt->wIBSSBeaconPeriod = sStartAPCmd.uBeaconInt; - else - pMgmt->wIBSSBeaconPeriod = 100; - - if (sStartAPCmd.bShareKeyAuth == true) { - pMgmt->bShareKeyAlgorithm = true; - pr_debug("Share Key\n"); - } else { - pMgmt->bShareKeyAlgorithm = false; - pr_debug("Open System\n"); - } - memcpy(pMgmt->abyIBSSSuppRates, abySuppRates, 6); - - if (sStartAPCmd.byBasicRate & BIT3) { - pMgmt->abyIBSSSuppRates[2] |= BIT7; - pMgmt->abyIBSSSuppRates[3] |= BIT7; - pMgmt->abyIBSSSuppRates[4] |= BIT7; - pMgmt->abyIBSSSuppRates[5] |= BIT7; - } else if (sStartAPCmd.byBasicRate & BIT2) { - pMgmt->abyIBSSSuppRates[2] |= BIT7; - pMgmt->abyIBSSSuppRates[3] |= BIT7; - pMgmt->abyIBSSSuppRates[4] |= BIT7; - } else if (sStartAPCmd.byBasicRate & BIT1) { - pMgmt->abyIBSSSuppRates[2] |= BIT7; - pMgmt->abyIBSSSuppRates[3] |= BIT7; - } else if (sStartAPCmd.byBasicRate & BIT1) { - pMgmt->abyIBSSSuppRates[2] |= BIT7; - } else { - /* default 1,2M */ - pMgmt->abyIBSSSuppRates[2] |= BIT7; - pMgmt->abyIBSSSuppRates[3] |= BIT7; - } - - pr_debug("Support Rate= %*ph\n", - 4, pMgmt->abyIBSSSuppRates + 2); - - netif_stop_queue(pDevice->dev); - spin_lock_irq(&pDevice->lock); - bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL); - spin_unlock_irq(&pDevice->lock); - break; - - case WLAN_CMD_GET_NODE_CNT: - cbListCount = 0; - pNode = &(pMgmt->sNodeDBTable[0]); - for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) { - pNode = &(pMgmt->sNodeDBTable[ii]); - if (!pNode->bActive) - continue; - cbListCount++; - } - - sNodeList.uItem = cbListCount; - if (copy_to_user(pReq->data, &sNodeList, sizeof(SNodeList))) { - result = -EFAULT; - break; - } - pReq->wResult = 0; - break; - - case WLAN_CMD_GET_NODE_LIST: - if (copy_from_user(&sNodeList, pReq->data, sizeof(SNodeList))) { - result = -EFAULT; - break; - } - if (sNodeList.uItem > (ULONG_MAX - sizeof(SNodeList)) / sizeof(SNodeItem)) { - result = -EINVAL; - break; - } - pNodeList = (PSNodeList)kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), - GFP_ATOMIC); - if (pNodeList == NULL) { - result = -ENOMEM; - break; - } - pNodeList->uItem = sNodeList.uItem; - pNode = &(pMgmt->sNodeDBTable[0]); - for (ii = 0, jj = 0; ii < (MAX_NODE_NUM + 1); ii++) { - pNode = &(pMgmt->sNodeDBTable[ii]); - if (pNode->bActive) { - pNodeList->sNodeList[jj].wAID = pNode->wAID; - memcpy(pNodeList->sNodeList[jj].abyMACAddr, pNode->abyMACAddr, WLAN_ADDR_LEN); - pNodeList->sNodeList[jj].wTxDataRate = pNode->wTxDataRate; - pNodeList->sNodeList[jj].wInActiveCount = (unsigned short)pNode->uInActiveCount; - pNodeList->sNodeList[jj].wEnQueueCnt = (unsigned short)pNode->wEnQueueCnt; - pNodeList->sNodeList[jj].wFlags = (unsigned short)pNode->dwFlags; - pNodeList->sNodeList[jj].bPWBitOn = pNode->bPSEnable; - pNodeList->sNodeList[jj].byKeyIndex = pNode->byKeyIndex; - pNodeList->sNodeList[jj].wWepKeyLength = pNode->uWepKeyLength; - memcpy(&(pNodeList->sNodeList[jj].abyWepKey[0]), &(pNode->abyWepKey[0]), WEP_KEYMAXLEN); - pr_debug("key= %2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", - pNodeList->sNodeList[jj].abyWepKey[0], - pNodeList->sNodeList[jj].abyWepKey[1], - pNodeList->sNodeList[jj].abyWepKey[2], - pNodeList->sNodeList[jj].abyWepKey[3], - pNodeList->sNodeList[jj].abyWepKey[4]); - pNodeList->sNodeList[jj].bIsInFallback = pNode->bIsInFallback; - pNodeList->sNodeList[jj].uTxFailures = pNode->uTxFailures; - pNodeList->sNodeList[jj].uTxAttempts = pNode->uTxAttempts; - pNodeList->sNodeList[jj].wFailureRatio = (unsigned short)pNode->uFailureRatio; - jj++; - if (jj >= pNodeList->uItem) - break; - } - } - if (copy_to_user(pReq->data, pNodeList, sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)))) { - result = -EFAULT; - break; - } - kfree(pNodeList); - pReq->wResult = 0; - break; - -#ifdef WPA_SM_Transtatus - case 0xFF: - memset(wpa_Result.ifname, 0, sizeof(wpa_Result.ifname)); - wpa_Result.proto = 0; - wpa_Result.key_mgmt = 0; - wpa_Result.eap_type = 0; - wpa_Result.authenticated = false; - pDevice->fWPA_Authened = false; - if (copy_from_user(&wpa_Result, pReq->data, sizeof(wpa_Result))) { - result = -EFAULT; - break; - } - - if (wpa_Result.authenticated == true) { -#ifdef SndEvt_ToAPI - { - union iwreq_data wrqu; - - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.flags = RT_WPACONNECTED_EVENT_FLAG; - wrqu.data.length = pItemSSID->len; - wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, pItemSSID->abySSID); - } -#endif - pDevice->fWPA_Authened = true; /* is successful peer to wpa_Result.authenticated? */ - } - pReq->wResult = 0; - break; -#endif - - default: - pr_debug("Private command not support..\n"); - } - - return result; -} diff --git a/drivers/staging/vt6655/ioctl.h b/drivers/staging/vt6655/ioctl.h deleted file mode 100644 index 2dc5a5743e8d..000000000000 --- a/drivers/staging/vt6655/ioctl.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: hostap.h - * - * Purpose: - * - * Author: Lyndon Chen - * - * Date: May 21, 2003 - * - */ - -#ifndef __IOCTL_H__ -#define __IOCTL_H__ - -#include "device.h" - -int private_ioctl(struct vnt_private *, struct ifreq *rq); - -#endif // __IOCTL_H__ diff --git a/drivers/staging/vt6655/iowpa.h b/drivers/staging/vt6655/iowpa.h deleted file mode 100644 index fe4b22ed49f4..000000000000 --- a/drivers/staging/vt6655/iowpa.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: iowpa.h - * - * Purpose: Handles wpa supplicant ioctl interface - * - * Author: Lyndon Chen - * - * Date: May 8, 2002 - * - */ - -#ifndef __IOWPA_H__ -#define __IOWPA_H__ - -#define WPA_IE_LEN 64 - -//WPA related - -enum { - VIAWGET_SET_WPA = 1, - VIAWGET_SET_KEY = 2, - VIAWGET_SET_SCAN = 3, - VIAWGET_GET_SCAN = 4, - VIAWGET_GET_SSID = 5, - VIAWGET_GET_BSSID = 6, - VIAWGET_SET_DROP_UNENCRYPT = 7, - VIAWGET_SET_DEAUTHENTICATE = 8, - VIAWGET_SET_ASSOCIATE = 9, - VIAWGET_SET_DISASSOCIATE = 10 -}; - -enum { - VIAWGET_ASSOC_MSG = 1, - VIAWGET_DISASSOC_MSG = 2, - VIAWGET_PTK_MIC_MSG = 3, - VIAWGET_GTK_MIC_MSG = 4, - VIAWGET_CCKM_ROAM_MSG = 5, - VIAWGET_DEVICECLOSE_MSG = 6 -}; - -#pragma pack(1) -typedef struct viawget_wpa_header { - u8 type; - u16 req_ie_len; - u16 resp_ie_len; -} viawget_wpa_header; - -struct viawget_wpa_param { - u32 cmd; - u8 addr[6]; - union { - struct { - u8 len; - u8 data[0]; - } generic_elem; - - struct { - u8 bssid[6]; - u8 ssid[32]; - u8 ssid_len; - u8 __user *wpa_ie; - u16 wpa_ie_len; - int pairwise_suite; - int group_suite; - int key_mgmt_suite; - int auth_alg; - int mode; - - } wpa_associate; - - struct { - int alg_name; - u16 key_index; - u16 set_tx; - u8 *seq; - u16 seq_len; - u8 *key; - u16 key_len; - } wpa_key; - - struct { - u8 ssid_len; - u8 ssid[32]; - } scan_req; - - struct { - u16 scan_count; - u8 __user *buf; - } scan_results; - - } u; -}; - -#pragma pack(1) -struct viawget_scan_result { - u8 bssid[6]; - u8 ssid[32]; - u16 ssid_len; - u8 wpa_ie[WPA_IE_LEN]; - u16 wpa_ie_len; - u8 rsn_ie[WPA_IE_LEN]; - u16 rsn_ie_len; - int freq; // MHz - int caps; // e.g. privacy - int qual; // signal quality - int noise; - int level; - int maxrate; -}; - -#pragma pack() - -#endif //__IOWPA_H__ diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c deleted file mode 100644 index 14a62bdae278..000000000000 --- a/drivers/staging/vt6655/iwctl.c +++ /dev/null @@ -1,1937 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: iwctl.c - * - * Purpose: wireless ext & ioctl functions - * - * Author: Lyndon Chen - * - * Date: July 5, 2006 - * - * Functions: - * - * Revision History: - * - */ - -#include "device.h" -#include "ioctl.h" -#include "iocmd.h" -#include "iwctl.h" -#include "mac.h" -#include "card.h" -#include "hostap.h" -#include "power.h" -#include "rf.h" - -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -#include "iowpa.h" -#include "wpactl.h" -#endif - -#include <net/iw_handler.h> -extern unsigned short TxRate_iwconfig;//2008-5-8 <add> by chester - -/*--------------------- Static Definitions -------------------------*/ - -//2008-0409-07, <Add> by Einsn Liu -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -#define SUPPORTED_WIRELESS_EXT 18 -#else -#define SUPPORTED_WIRELESS_EXT 17 -#endif - -static const long frequency_list[] = { - 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484, - 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980, - 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240, - 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, - 5700, 5745, 5765, 5785, 5805, 5825 -}; - -/*--------------------- Static Classes ----------------------------*/ -/*--------------------- Static Variables --------------------------*/ -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev) -{ - struct vnt_private *pDevice = netdev_priv(dev); - long ldBm; - - pDevice->wstats.status = pDevice->op_mode; -#ifdef Calcu_LinkQual - if (pDevice->scStatistic.LinkQuality > 100) - pDevice->scStatistic.LinkQuality = 100; - pDevice->wstats.qual.qual = (unsigned char)pDevice->scStatistic.LinkQuality; -#else - pDevice->wstats.qual.qual = pDevice->byCurrSQ; -#endif - RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm); - pDevice->wstats.qual.level = ldBm; - pDevice->wstats.qual.noise = 0; - pDevice->wstats.qual.updated = 1; - pDevice->wstats.discard.nwid = 0; - pDevice->wstats.discard.code = 0; - pDevice->wstats.discard.fragment = 0; - pDevice->wstats.discard.retries = (unsigned long)pDevice->scStatistic.dwTsrErr; - pDevice->wstats.discard.misc = 0; - pDevice->wstats.miss.beacon = 0; - - return &pDevice->wstats; -} - -/*------------------------------------------------------------------*/ - -static int iwctl_commit(struct net_device *dev, - struct iw_request_info *info, - void *wrq, - char *extra) -{ - pr_debug(" SIOCSIWCOMMIT\n"); - - return 0; -} -/* - * Wireless Handler : get protocol name - */ - -int iwctl_giwname(struct net_device *dev, - struct iw_request_info *info, - char *wrq, - char *extra) -{ - strcpy(wrq, "802.11-a/b/g"); - return 0; -} - -/* - * Wireless Handler : set scan - */ - -static int iwctl_siwscan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - struct iw_scan_req *req = (struct iw_scan_req *)extra; - unsigned char abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - PWLAN_IE_SSID pItemSSID = NULL; - - pr_debug(" SIOCSIWSCAN\n"); - - if (pDevice->byReAssocCount > 0) { //reject scan when re-associating! -//send scan event to wpa_Supplicant - union iwreq_data wrqu; - - PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n"); - memset(&wrqu, 0, sizeof(wrqu)); - wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL); - return 0; - } - - spin_lock_irq(&pDevice->lock); - BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); - -//mike add: active scan OR passive scan OR desire_ssid scan - if (wrq->length == sizeof(struct iw_scan_req)) { - if (wrq->flags & IW_SCAN_THIS_ESSID) { //desire_ssid scan - memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - pItemSSID = (PWLAN_IE_SSID)abyScanSSID; - pItemSSID->byElementID = WLAN_EID_SSID; - memcpy(pItemSSID->abySSID, req->essid, (int)req->essid_len); - if (pItemSSID->abySSID[req->essid_len - 1] == '\0') { - if (req->essid_len > 0) - pItemSSID->len = req->essid_len - 1; - } else - pItemSSID->len = req->essid_len; - pMgmt->eScanType = WMAC_SCAN_PASSIVE; - PRINT_K("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n", ((PWLAN_IE_SSID)abyScanSSID)->abySSID, - ((PWLAN_IE_SSID)abyScanSSID)->len); - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); - spin_unlock_irq(&pDevice->lock); - - return 0; - } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { //passive scan - pMgmt->eScanType = WMAC_SCAN_PASSIVE; - } - } else { //active scan - pMgmt->eScanType = WMAC_SCAN_ACTIVE; - } - - pMgmt->eScanType = WMAC_SCAN_PASSIVE; - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); - spin_unlock_irq(&pDevice->lock); - - return 0; -} - -/* - * Wireless Handler : get scan results - */ - -static int iwctl_giwscan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) -{ - int ii, jj, kk; - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - PKnownBSS pBSS; - PWLAN_IE_SSID pItemSSID; - PWLAN_IE_SUPP_RATES pSuppRates, pExtSuppRates; - char *current_ev = extra; - char *end_buf = extra + IW_SCAN_MAX_DATA; - char *current_val = NULL; - struct iw_event iwe; - long ldBm; - char buf[MAX_WPA_IE_LEN * 2 + 30]; - - pr_debug(" SIOCGIWSCAN\n"); - - if (pMgmt->eScanState == WMAC_IS_SCANNING) { - // In scanning.. - return -EAGAIN; - } - pBSS = &(pMgmt->sBSSList[0]); - for (ii = 0, jj = 0; jj < MAX_BSS_NUM; jj++) { - if (current_ev >= end_buf) - break; - pBSS = &(pMgmt->sBSSList[jj]); - if (pBSS->bActive) { - //ADD mac address - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, pBSS->abyBSSID, WLAN_BSSID_LEN); - current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); - //ADD ssid - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWESSID; - pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; - iwe.u.data.length = pItemSSID->len; - iwe.u.data.flags = 1; - current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pItemSSID->abySSID); - //ADD mode - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWMODE; - if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) - iwe.u.mode = IW_MODE_INFRA; - else - iwe.u.mode = IW_MODE_ADHOC; - - iwe.len = IW_EV_UINT_LEN; - current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN); - //ADD frequency - pSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abySuppRates; - pExtSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abyExtSuppRates; - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = pBSS->uChannel; - iwe.u.freq.e = 0; - iwe.u.freq.i = 0; - current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); - //2008-0409-04, <Add> by Einsn Liu - { - int f = (int)pBSS->uChannel - 1; - - if (f < 0)f = 0; - iwe.u.freq.m = frequency_list[f] * 100000; - iwe.u.freq.e = 1; - } - current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); - //ADD quality - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVQUAL; - RFvRSSITodBm(pDevice, (unsigned char)(pBSS->uRSSI), &ldBm); - iwe.u.qual.level = ldBm; - iwe.u.qual.noise = 0; -//2008-0409-01, <Add> by Einsn Liu - if (-ldBm < 50) - iwe.u.qual.qual = 100; - else if (-ldBm > 90) - iwe.u.qual.qual = 0; - else - iwe.u.qual.qual = (40 - (-ldBm - 50)) * 100 / 40; - - iwe.u.qual.updated = 7; - - current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWENCODE; - iwe.u.data.length = 0; - if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - - current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pItemSSID->abySSID); - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWRATE; - iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; - current_val = current_ev + IW_EV_LCP_LEN; - - for (kk = 0; kk < 12; kk++) { - if (pSuppRates->abyRates[kk] == 0) - break; - // Bit rate given in 500 kb/s units (+ 0x80) - iwe.u.bitrate.value = ((pSuppRates->abyRates[kk] & 0x7f) * 500000); - current_val = iwe_stream_add_value(info, current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); - } - for (kk = 0; kk < 8; kk++) { - if (pExtSuppRates->abyRates[kk] == 0) - break; - // Bit rate given in 500 kb/s units (+ 0x80) - iwe.u.bitrate.value = ((pExtSuppRates->abyRates[kk] & 0x7f) * 500000); - current_val = iwe_stream_add_value(info, current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); - } - - if ((current_val - current_ev) > IW_EV_LCP_LEN) - current_ev = current_val; - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - sprintf(buf, "bcn_int=%d", pBSS->wBeaconInterval); - iwe.u.data.length = strlen(buf); - current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, buf); - - if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) { - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = pBSS->wWPALen; - current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pBSS->byWPAIE); - } - - if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) { - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = pBSS->wRSNLen; - current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pBSS->byRSNIE); - } - - } - }// for - - wrq->length = current_ev - extra; - return 0; -} - -/* - * Wireless Handler : set frequency or channel - */ - -int iwctl_siwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - int rc = 0; - - pr_debug(" SIOCSIWFREQ\n"); - - // If setting by frequency, convert to a channel - if ((wrq->e == 1) && - (wrq->m >= (int) 2.412e8) && - (wrq->m <= (int) 2.487e8)) { - int f = wrq->m / 100000; - int c = 0; - - while ((c < 14) && (f != frequency_list[c])) - c++; - wrq->e = 0; - wrq->m = c + 1; - } - // Setting by channel number - if ((wrq->m > 14) || (wrq->e > 0)) - rc = -EOPNOTSUPP; - else { - int channel = wrq->m; - - if ((channel < 1) || (channel > 14)) { - pr_debug("%s: New channel value of %d is invalid!\n", - dev->name, wrq->m); - rc = -EINVAL; - } else { - // Yes ! We can set it !!! - pr_debug(" Set to channel = %d\n", channel); - pDevice->uChannel = channel; - //2007-0207-04,<Add> by EinsnLiu - //Make change effect at once - pDevice->bCommit = true; - } - } - - return rc; -} - -/* - * Wireless Handler : get frequency or channel - */ - -int iwctl_giwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - - pr_debug(" SIOCGIWFREQ\n"); - -#ifdef WEXT_USECHANNELS - wrq->m = (int)pMgmt->uCurrChannel; - wrq->e = 0; -#else - { - int f = (int)pMgmt->uCurrChannel - 1; - - if (f < 0) - f = 0; - wrq->m = frequency_list[f] * 100000; - wrq->e = 1; - } -#endif - - return 0; -} - -/* - * Wireless Handler : set operation mode - */ - -int iwctl_siwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *wmode, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int rc = 0; - - pr_debug(" SIOCSIWMODE\n"); - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP && pDevice->bEnableHostapd) { - pr_debug("Can't set operation mode, hostapd is running\n"); - return rc; - } - - switch (*wmode) { - case IW_MODE_ADHOC: - if (pMgmt->eConfigMode != WMAC_CONFIG_IBSS_STA) { - pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; - if (pDevice->flags & DEVICE_FLAGS_OPENED) - pDevice->bCommit = true; - - } - pr_debug("set mode to ad-hoc\n"); - break; - case IW_MODE_AUTO: - case IW_MODE_INFRA: - if (pMgmt->eConfigMode != WMAC_CONFIG_ESS_STA) { - pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; - if (pDevice->flags & DEVICE_FLAGS_OPENED) - pDevice->bCommit = true; - - } - pr_debug("set mode to infrastructure\n"); - break; - case IW_MODE_MASTER: - - pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; - rc = -EOPNOTSUPP; - break; - - if (pMgmt->eConfigMode != WMAC_CONFIG_AP) { - pMgmt->eConfigMode = WMAC_CONFIG_AP; - if (pDevice->flags & DEVICE_FLAGS_OPENED) - pDevice->bCommit = true; - - } - pr_debug("set mode to Access Point\n"); - break; - - case IW_MODE_REPEAT: - pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; - rc = -EOPNOTSUPP; - break; - default: - rc = -EINVAL; - } - - return rc; -} - -/* - * Wireless Handler : get operation mode - */ - -int iwctl_giwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *wmode, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - - pr_debug(" SIOCGIWMODE\n"); - // If not managed, assume it's ad-hoc - switch (pMgmt->eConfigMode) { - case WMAC_CONFIG_ESS_STA: - *wmode = IW_MODE_INFRA; - break; - case WMAC_CONFIG_IBSS_STA: - *wmode = IW_MODE_ADHOC; - break; - case WMAC_CONFIG_AUTO: - *wmode = IW_MODE_INFRA; - break; - case WMAC_CONFIG_AP: - *wmode = IW_MODE_MASTER; - break; - default: - *wmode = IW_MODE_ADHOC; - } - - return 0; -} - -/* - * Wireless Handler : get capability range - */ - -int iwctl_giwrange(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) -{ - struct iw_range *range = (struct iw_range *)extra; - int i, k; - unsigned char abySupportedRates[13] = {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; - - pr_debug(" SIOCGIWRANGE\n"); - if (wrq->pointer) { - wrq->length = sizeof(struct iw_range); - memset(range, 0, sizeof(struct iw_range)); - range->min_nwid = 0x0000; - range->max_nwid = 0x0000; - range->num_channels = 14; - // Should be based on cap_rid.country to give only - // what the current card support - k = 0; - for (i = 0; i < 14; i++) { - range->freq[k].i = i + 1; // List index - range->freq[k].m = frequency_list[i] * 100000; - range->freq[k++].e = 1; // Values in table in MHz -> * 10^5 * 10 - } - range->num_frequency = k; - // Hum... Should put the right values there -#ifdef Calcu_LinkQual - range->max_qual.qual = 100; -#else - range->max_qual.qual = 255; -#endif - range->max_qual.level = 0; - range->max_qual.noise = 0; - range->sensitivity = 255; - - for (i = 0; i < 13; i++) { - range->bitrate[i] = abySupportedRates[i] * 500000; - if (range->bitrate[i] == 0) - break; - } - range->num_bitrates = i; - - // Set an indication of the max TCP throughput - // in bit/s that we can expect using this interface. - // May be use for QoS stuff... Jean II - if (i > 2) - range->throughput = 5 * 1000 * 1000; - else - range->throughput = 1.5 * 1000 * 1000; - - range->min_rts = 0; - range->max_rts = 2312; - range->min_frag = 256; - range->max_frag = 2312; - - // the encoding capabilities - range->num_encoding_sizes = 3; - // 64(40) bits WEP - range->encoding_size[0] = 5; - // 128(104) bits WEP - range->encoding_size[1] = 13; - // 256 bits for WPA-PSK - range->encoding_size[2] = 32; - // 4 keys are allowed - range->max_encoding_tokens = 4; - - range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | - IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; - - range->min_pmp = 0; - range->max_pmp = 1000000;// 1 secs - range->min_pmt = 0; - range->max_pmt = 1000000;// 1 secs - range->pmp_flags = IW_POWER_PERIOD; - range->pmt_flags = IW_POWER_TIMEOUT; - range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R; - - // Transmit Power - values are in mW - - range->txpower[0] = 100; - range->num_txpower = 1; - range->txpower_capa = IW_TXPOW_MWATT; - range->we_version_source = SUPPORTED_WIRELESS_EXT; - range->we_version_compiled = WIRELESS_EXT; - range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME; - range->retry_flags = IW_RETRY_LIMIT; - range->r_time_flags = IW_RETRY_LIFETIME; - range->min_retry = 1; - range->max_retry = 65535; - range->min_r_time = 1024; - range->max_r_time = 65535 * 1024; - // Experimental measurements - boundary 11/5.5 Mb/s - // Note : with or without the (local->rssi), results - // are somewhat different. - Jean II - range->avg_qual.qual = 6; - range->avg_qual.level = 176; // -80 dBm - range->avg_qual.noise = 0; - } - - return 0; -} - -/* - * Wireless Handler : set ap mac address - */ - -int iwctl_siwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int rc = 0; - unsigned char ZeroBSSID[WLAN_BSSID_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - pr_debug(" SIOCSIWAP\n"); - if (pMgmt->eScanState == WMAC_IS_SCANNING) { - // In scanning.. - pr_debug("SIOCSIWAP(??)-->In scanning..\n"); - } - if (wrq->sa_family != ARPHRD_ETHER) - rc = -EINVAL; - else { - memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6); - //2008-0409-05, <Add> by Einsn Liu - if ((pDevice->bLinkPass == true) && - (memcmp(pMgmt->abyDesireBSSID, pMgmt->abyCurrBSSID, 6) == 0)) { - return rc; - } - //mike :add - if ((is_broadcast_ether_addr(pMgmt->abyDesireBSSID)) || - (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)) { - PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n"); - return rc; - } - //mike add: if desired AP is hidden ssid(there are two same BSSID in list), - // then ignore,because you don't known which one to be connect with?? - { - unsigned int ii, uSameBssidNum = 0; - - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - if (pMgmt->sBSSList[ii].bActive && - ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID, - pMgmt->abyDesireBSSID)) { - uSameBssidNum++; - } - } - if (uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! - PRINT_K("SIOCSIWAP:ignore for desired AP in hidden mode\n"); - return rc; - } - } - - if (pDevice->flags & DEVICE_FLAGS_OPENED) - pDevice->bCommit = true; - - } - return rc; -} - -/* - * Wireless Handler : get ap mac address - */ - -int iwctl_giwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - - pr_debug(" SIOCGIWAP\n"); - - memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6); - //2008-0410,<Modify> by Einsn Liu - if ((pDevice->bLinkPass == false) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)) - memset(wrq->sa_data, 0, 6); - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) - memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6); - - wrq->sa_family = ARPHRD_ETHER; - - return 0; -} - -/* - * Wireless Handler : get ap list - */ - -int iwctl_giwaplist(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) -{ - int ii, jj, rc = 0; - struct sockaddr *sock = NULL; - struct sockaddr *s = NULL; - struct iw_quality *qual = NULL; - struct iw_quality *q = NULL; - PKnownBSS pBSS = NULL; - - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - - pr_debug(" SIOCGIWAPLIST\n"); - - if (!capable(CAP_NET_ADMIN)) { - rc = -EPERM; - goto exit; - } - - if (!wrq->pointer) - goto exit; - - sock = kmalloc_array(IW_MAX_AP, sizeof(struct sockaddr), GFP_KERNEL); - if (!sock) { - rc = -ENOMEM; - goto exit; - } - - qual = kmalloc_array(IW_MAX_AP, sizeof(struct iw_quality), GFP_KERNEL); - if (!qual) { - rc = -ENOMEM; - goto exit; - } - - for (ii = 0, jj = 0; ii < MAX_BSS_NUM; ii++) { - pBSS = &(pMgmt->sBSSList[ii]); - - if (!pBSS->bActive) - continue; - if (jj >= IW_MAX_AP) - break; - - s = &sock[jj]; - q = &qual[jj]; - - memcpy(s->sa_data, pBSS->abyBSSID, 6); - s->sa_family = ARPHRD_ETHER; - q->level = pBSS->uRSSI; - q->qual = 0; - q->noise = 0; - q->updated = 2; - jj++; - } - - wrq->flags = 1; /* Should be define'd */ - wrq->length = jj; - memcpy(extra, sock, sizeof(struct sockaddr) * jj); - memcpy(extra + sizeof(struct sockaddr) * jj, - qual, - sizeof(struct iw_quality) * jj); -exit: - kfree(sock); - kfree(qual); - return rc; -} - -/* - * Wireless Handler : set essid - */ - -int iwctl_siwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - PWLAN_IE_SSID pItemSSID; - //2008-0409-05, <Add> by Einsn Liu - unsigned char len; - - pr_debug(" SIOCSIWESSID\n"); - pDevice->fWPA_Authened = false; - if (pMgmt->eScanState == WMAC_IS_SCANNING) { - // In scanning.. - pr_debug("SIOCSIWESSID(??)-->In scanning..\n"); - } - // Check if we asked for `any' - if (wrq->flags == 0) { - // Just send an empty SSID list - memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - memset(pMgmt->abyDesireBSSID, 0xFF, 6); - PRINT_K("set essid to 'any'\n"); -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - return 0; -#endif - } else { - // Set the SSID - memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; - pItemSSID->byElementID = WLAN_EID_SSID; - - memcpy(pItemSSID->abySSID, extra, wrq->length); - if (pItemSSID->abySSID[wrq->length - 1] == '\0') { - if (wrq->length > 0) - pItemSSID->len = wrq->length - 1; - } else - pItemSSID->len = wrq->length; - pr_debug("set essid to %s\n", pItemSSID->abySSID); - //2008-0409-05, <Add> by Einsn Liu - len = (pItemSSID->len > ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) ? pItemSSID->len : ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len; - if ((pDevice->bLinkPass == true) && - (memcmp(pItemSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, len) == 0)) - return 0; - - //mike:need clear desiredBSSID - if (pItemSSID->len == 0) { - memset(pMgmt->abyDesireBSSID, 0xFF, 6); - return 0; - } - -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - //Wext wil order another command of siwap to link with desired AP, - //so here need not associate?? - if (pDevice->bWPASuppWextEnabled == true) { - /*******search if in hidden ssid mode ****/ - { - PKnownBSS pCurr = NULL; - unsigned char abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - unsigned int ii, uSameBssidNum = 0; - - memcpy(abyTmpDesireSSID, pMgmt->abyDesireSSID, sizeof(abyTmpDesireSSID)); - pCurr = BSSpSearchBSSList(pDevice, - NULL, - abyTmpDesireSSID, - pMgmt->eConfigPHYMode -); - - if (pCurr == NULL) { - PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n"); - vResetCommandTimer((void *)pDevice); - pMgmt->eScanType = WMAC_SCAN_ACTIVE; - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); - } else { //mike:to find out if that desired SSID is a hidden-ssid AP , - // by means of judging if there are two same BSSID exist in list ? - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - if (pMgmt->sBSSList[ii].bActive && - ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID, - pCurr->abyBSSID)) { - uSameBssidNum++; - } - } - if (uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! - pr_debug("SIOCSIWESSID:hidden ssid directly associate.......\n"); - vResetCommandTimer((void *)pDevice); - pMgmt->eScanType = WMAC_SCAN_PASSIVE; //this scan type,you'll submit scan result! - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); - } - } - } - return 0; - } -#endif - - pr_debug("set essid = %s\n", pItemSSID->abySSID); - } - - if (pDevice->flags & DEVICE_FLAGS_OPENED) - pDevice->bCommit = true; - - return 0; -} - -/* - * Wireless Handler : get essid - */ - -int iwctl_giwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - PWLAN_IE_SSID pItemSSID; - - pr_debug(" SIOCGIWESSID\n"); - - // Note : if wrq->u.data.flags != 0, we should - // get the relevant SSID from the SSID list... - - // Get the current SSID - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - memcpy(extra, pItemSSID->abySSID , pItemSSID->len); - extra[pItemSSID->len] = '\0'; - wrq->length = pItemSSID->len + 1; - //2008-0409-03, <Add> by Einsn Liu - wrq->length = pItemSSID->len; - wrq->flags = 1; // active - - return 0; -} - -/* - * Wireless Handler : set data rate - */ - -int iwctl_siwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - int rc = 0; - u8 brate = 0; - int i; - unsigned char abySupportedRates[13] = {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; - - pr_debug(" SIOCSIWRATE\n"); - if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) { - rc = -EINVAL; - return rc; - } - - // First : get a valid bit rate value - - // Which type of value - if ((wrq->value < 13) && - (wrq->value >= 0)) { - // Setting by rate index - // Find value in the magic rate table - brate = wrq->value; - } else { - // Setting by frequency value - u8 normvalue = (u8) (wrq->value/500000); - - // Check if rate is valid - for (i = 0; i < 13; i++) { - if (normvalue == abySupportedRates[i]) { - brate = i; - break; - } - } - } - // -1 designed the max rate (mostly auto mode) - if (wrq->value == -1) { - // Get the highest available rate - for (i = 0; i < 13; i++) { - if (abySupportedRates[i] == 0) - break; - } - if (i != 0) - brate = i - 1; - - } - // Check that it is valid - // brate is index of abySupportedRates[] - if (brate > 13) { - rc = -EINVAL; - return rc; - } - - // Now, check if we want a fixed or auto value - if (wrq->fixed != 0) { - // Fixed mode - // One rate, fixed - pr_debug("Rate Fix\n"); - pDevice->bFixRate = true; - if ((pDevice->byBBType == BB_TYPE_11B) && (brate > 3)) { - pDevice->uConnectionRate = 3; - } else { - pDevice->uConnectionRate = brate; - pr_debug("Fixed to Rate %d\n", - pDevice->uConnectionRate); - } - - } else { - pDevice->bFixRate = false; - pDevice->uConnectionRate = 13; - pr_debug("auto rate:connection_rate is 13\n"); - } - - return rc; -} - -/* - * Wireless Handler : get data rate - */ - -int iwctl_giwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); -//2007-0118-05,<Mark> by EinsnLiu -//Mark the unnecessary sentences. -// PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - - pr_debug(" SIOCGIWRATE\n"); - { - unsigned char abySupportedRates[13] = {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; - int brate = 0; -//2008-5-8 <modify> by chester - if (pDevice->bLinkPass) { - if (pDevice->bFixRate == true) { - if (pDevice->uConnectionRate < 13) { - brate = abySupportedRates[pDevice->uConnectionRate]; - } else { - if (pDevice->byBBType == BB_TYPE_11B) - brate = 0x16; - if (pDevice->byBBType == BB_TYPE_11G) - brate = 0x6C; - if (pDevice->byBBType == BB_TYPE_11A) - brate = 0x6C; - } - } else { - brate = abySupportedRates[TxRate_iwconfig]; - } - } else brate = 0; - - wrq->value = brate * 500000; - // If more than one rate, set auto - if (pDevice->bFixRate == true) - wrq->fixed = true; - } - - return 0; -} - -/* - * Wireless Handler : set rts threshold - */ - -int iwctl_siwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - int rc = 0; - - pr_debug(" SIOCSIWRTS\n"); - - { - int rthr = wrq->value; - - if (wrq->disabled) - rthr = 2312; - - if ((rthr < 0) || (rthr > 2312)) - rc = -EINVAL; - else - pDevice->wRTSThreshold = rthr; - } - - return 0; -} - -/* - * Wireless Handler : get rts - */ - -int iwctl_giwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - - pr_debug(" SIOCGIWRTS\n"); - wrq->value = pDevice->wRTSThreshold; - wrq->disabled = (wrq->value >= 2312); - wrq->fixed = 1; - - return 0; -} - -/* - * Wireless Handler : set fragment threshold - */ - -int iwctl_siwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - int rc = 0; - int fthr = wrq->value; - - pr_debug(" SIOCSIWFRAG\n"); - - if (wrq->disabled) - fthr = 2312; - if ((fthr < 256) || (fthr > 2312)) { - rc = -EINVAL; - } else { - fthr &= ~0x1; // Get an even value - pDevice->wFragmentationThreshold = (u16)fthr; - } - - return rc; -} - -/* - * Wireless Handler : get fragment threshold - */ - -int iwctl_giwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - - pr_debug(" SIOCGIWFRAG\n"); - wrq->value = pDevice->wFragmentationThreshold; - wrq->disabled = (wrq->value >= 2312); - wrq->fixed = 1; - - return 0; -} - -/* - * Wireless Handler : set retry threshold - */ -int iwctl_siwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - int rc = 0; - - pr_debug(" SIOCSIWRETRY\n"); - - if (wrq->disabled) { - rc = -EINVAL; - return rc; - } - - if (wrq->flags & IW_RETRY_LIMIT) { - if (wrq->flags & IW_RETRY_MAX) - pDevice->byLongRetryLimit = wrq->value; - else if (wrq->flags & IW_RETRY_MIN) - pDevice->byShortRetryLimit = wrq->value; - else { - // No modifier : set both - pDevice->byShortRetryLimit = wrq->value; - pDevice->byLongRetryLimit = wrq->value; - } - } - if (wrq->flags & IW_RETRY_LIFETIME) - pDevice->wMaxTransmitMSDULifetime = wrq->value; - - return rc; -} - -/* - * Wireless Handler : get retry threshold - */ -int iwctl_giwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - - pr_debug(" SIOCGIWRETRY\n"); - wrq->disabled = 0; // Can't be disabled - - // Note : by default, display the min retry number - if ((wrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { - wrq->flags = IW_RETRY_LIFETIME; - wrq->value = (int)pDevice->wMaxTransmitMSDULifetime; //ms - } else if ((wrq->flags & IW_RETRY_MAX)) { - wrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; - wrq->value = (int)pDevice->byLongRetryLimit; - } else { - wrq->flags = IW_RETRY_LIMIT; - wrq->value = (int)pDevice->byShortRetryLimit; - if ((int)pDevice->byShortRetryLimit != (int)pDevice->byLongRetryLimit) - wrq->flags |= IW_RETRY_MIN; - } - - return 0; -} - -/* - * Wireless Handler : set encode mode - */ -int iwctl_siwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - unsigned long dwKeyIndex = (unsigned long)(wrq->flags & IW_ENCODE_INDEX); - int ii, uu, rc = 0; - int index = (wrq->flags & IW_ENCODE_INDEX); - -//2007-0207-07,<Modify> by EinsnLiu -//There are some problems when using iwconfig encode/key command to set the WEP key. -//I almost rewrite this function. -//now it support:(assume the wireless interface's name is eth0) -//iwconfig eth0 key [1] 1122334455 open /*set key stirng to index 1,and driver using key index is set to 1*/ -//iwconfig eth0 key [3] /*set driver using key index to 3,the key string no change */ -//iwconfig eth0 key 1122334455 /*set key string to driver using index*/ -//iwconfig eth0 key restricted /*enable share key*/ - - PSKeyTable pkeytab; - - pr_debug(" SIOCSIWENCODE\n"); - - if ((wrq->flags & IW_ENCODE_DISABLED) == 0) { - //Not disable encryption - - if (dwKeyIndex > WLAN_WEP_NKEYS) { - rc = -EINVAL; - return rc; - } - - if (dwKeyIndex < 1 && ((wrq->flags & IW_ENCODE_NOKEY) == 0)) {//set default key - if (pDevice->byKeyIndex < WLAN_WEP_NKEYS) - dwKeyIndex = pDevice->byKeyIndex; - else - dwKeyIndex = 0; - } else { - dwKeyIndex--; - } - - // Check the size of the key - if (wrq->length > WLAN_WEP232_KEYLEN) { - rc = -EINVAL; - return rc; - } - - if (wrq->length > 0) {//have key - - if (wrq->length == WLAN_WEP232_KEYLEN) { - pr_debug("Set 232 bit wep key\n"); - } else if (wrq->length == WLAN_WEP104_KEYLEN) { - pr_debug("Set 104 bit wep key\n"); - } else if (wrq->length == WLAN_WEP40_KEYLEN) { - pr_debug("Set 40 bit wep key, index= %d\n", - (int)dwKeyIndex); - } else {//no support length - rc = -EINVAL; - return rc; - } - memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN); - memcpy(pDevice->abyKey, extra, wrq->length); - - pr_debug("abyKey: "); - for (ii = 0; ii < wrq->length; ii++) - pr_debug("%02x ", pDevice->abyKey[ii]); - - if (pDevice->flags & DEVICE_FLAGS_OPENED) { - spin_lock_irq(&pDevice->lock); - KeybSetDefaultKey(&(pDevice->sKey), - (unsigned long)(dwKeyIndex | (1 << 31)), - wrq->length, - NULL, - pDevice->abyKey, - KEY_CTL_WEP, - pDevice->PortOffset, - pDevice->byLocalID -); - spin_unlock_irq(&pDevice->lock); - } - pDevice->byKeyIndex = (unsigned char)dwKeyIndex; - pDevice->uKeyLength = wrq->length; - pDevice->bTransmitKey = true; - pDevice->bEncryptionEnable = true; - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - - } else if (index > 0) { - //when the length is 0 the request only changes the default transmit key index - //check the new key if it has a non zero length - if (pDevice->bEncryptionEnable == false) { - rc = -EINVAL; - return rc; - } - pr_debug("Just set Default key Index:\n"); - pkeytab = &(pDevice->sKey.KeyTable[MAX_KEY_TABLE - 1]); - if (pkeytab->GroupKey[(unsigned char)dwKeyIndex].uKeyLength == 0) { - pr_debug("Default key len is 0\n"); - rc = -EINVAL; - return rc; - } - pDevice->byKeyIndex = (unsigned char)dwKeyIndex; - pkeytab->dwGTKeyIndex = dwKeyIndex | (1 << 31); - pkeytab->GroupKey[(unsigned char)dwKeyIndex].dwKeyIndex = dwKeyIndex | (1 << 31); - } - - } else {//disable the key - pr_debug("Disable WEP function\n"); - if (pDevice->bEncryptionEnable == false) - return 0; - pMgmt->bShareKeyAlgorithm = false; - pDevice->bEncryptionEnable = false; - pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - if (pDevice->flags & DEVICE_FLAGS_OPENED) { - spin_lock_irq(&pDevice->lock); - for (uu = 0; uu < MAX_KEY_TABLE; uu++) - MACvDisableKeyEntry(pDevice->PortOffset, uu); - spin_unlock_irq(&pDevice->lock); - } - } -//End Modify,Einsn - - if (wrq->flags & IW_ENCODE_RESTRICTED) { - pr_debug("Enable WEP & ShareKey System\n"); - pMgmt->bShareKeyAlgorithm = true; - } - if (wrq->flags & IW_ENCODE_OPEN) { - pr_debug("Enable WEP & Open System\n"); - pMgmt->bShareKeyAlgorithm = false; - } - return rc; -} - -int iwctl_giwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - char abyKey[WLAN_WEP232_KEYLEN]; - - unsigned int index = (unsigned int)(wrq->flags & IW_ENCODE_INDEX); - PSKeyItem pKey = NULL; - - pr_debug(" SIOCGIWENCODE\n"); - - if (index > WLAN_WEP_NKEYS) - return -EINVAL; - - if (index < 1) {//get default key - if (pDevice->byKeyIndex < WLAN_WEP_NKEYS) - index = pDevice->byKeyIndex; - else - index = 0; - } else { - index--; - } - - memset(abyKey, 0, WLAN_WEP232_KEYLEN); - // Check encryption mode - wrq->flags = IW_ENCODE_NOKEY; - // Is WEP enabled ??? - if (pDevice->bEncryptionEnable) - wrq->flags |= IW_ENCODE_ENABLED; - else - wrq->flags |= IW_ENCODE_DISABLED; - - if (pMgmt->bShareKeyAlgorithm) - wrq->flags |= IW_ENCODE_RESTRICTED; - else - wrq->flags |= IW_ENCODE_OPEN; - wrq->length = 0; - - if ((index == 0) && (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled || - pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)) {//get wpa pairwise key - if (KeybGetKey(&(pDevice->sKey), pMgmt->abyCurrBSSID, 0xffffffff, &pKey)) { - wrq->length = pKey->uKeyLength; - memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); - memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); - } - } else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (unsigned char)index , &pKey)) { - wrq->length = pKey->uKeyLength; - memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); - memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); - } - - wrq->flags |= index+1; - - return 0; -} - -/* - * Wireless Handler : set power mode - */ -int iwctl_siwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int rc = 0; - - pr_debug(" SIOCSIWPOWER\n"); - - if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) { - rc = -EINVAL; - return rc; - } - - if (wrq->disabled) { - pDevice->ePSMode = WMAC_POWER_CAM; - PSvDisablePowerSaving(pDevice); - return rc; - } - if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { - pDevice->ePSMode = WMAC_POWER_FAST; - PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); - - } else if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) { - pDevice->ePSMode = WMAC_POWER_FAST; - PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); - } - switch (wrq->flags & IW_POWER_MODE) { - case IW_POWER_UNICAST_R: - pr_debug(" SIOCSIWPOWER: IW_POWER_UNICAST_R\n"); - rc = -EINVAL; - break; - case IW_POWER_ALL_R: - pr_debug(" SIOCSIWPOWER: IW_POWER_ALL_R\n"); - rc = -EINVAL; - case IW_POWER_ON: - pr_debug(" SIOCSIWPOWER: IW_POWER_ON\n"); - break; - default: - rc = -EINVAL; - } - - return rc; -} - -/* - * Wireless Handler : get power mode - */ -int iwctl_giwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int mode = pDevice->ePSMode; - - pr_debug(" SIOCGIWPOWER\n"); - - wrq->disabled = (mode == WMAC_POWER_CAM); - if (wrq->disabled) - return 0; - - if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { - wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10); - wrq->flags = IW_POWER_TIMEOUT; - } else { - wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10); - wrq->flags = IW_POWER_PERIOD; - } - wrq->flags |= IW_POWER_ALL_R; - - return 0; -} - -/* - * Wireless Handler : get Sensitivity - */ -int iwctl_giwsens(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - long ldBm; - - pr_debug(" SIOCGIWSENS\n"); - if (pDevice->bLinkPass == true) { - RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm); - wrq->value = ldBm; - } else { - wrq->value = 0; - } - wrq->disabled = (wrq->value == 0); - wrq->fixed = 1; - - return 0; -} - -//2008-0409-07, <Add> by Einsn Liu -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - -int iwctl_siwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int ret = 0; - static int wpa_version = 0; //must be static to save the last value,einsn liu - static int pairwise = 0; - - pr_debug(" SIOCSIWAUTH\n"); - switch (wrq->flags & IW_AUTH_INDEX) { - case IW_AUTH_WPA_VERSION: - wpa_version = wrq->value; - if (wrq->value == IW_AUTH_WPA_VERSION_DISABLED) - PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n"); - else if (wrq->value == IW_AUTH_WPA_VERSION_WPA) - PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n"); - else - PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n"); - - break; - case IW_AUTH_CIPHER_PAIRWISE: - pairwise = wrq->value; - if (pairwise == IW_AUTH_CIPHER_CCMP) - pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; - else if (pairwise == IW_AUTH_CIPHER_TKIP) - pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; - else if (pairwise == IW_AUTH_CIPHER_WEP40 || pairwise == IW_AUTH_CIPHER_WEP104) - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - else if (pairwise == IW_AUTH_CIPHER_NONE) - ; /* do nothing,einsn liu */ - else - pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - - break; - case IW_AUTH_CIPHER_GROUP: - if (wpa_version == IW_AUTH_WPA_VERSION_DISABLED) - break; - if (pairwise == IW_AUTH_CIPHER_NONE) { - if (wrq->value == IW_AUTH_CIPHER_CCMP) - pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; - else - pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; - } - break; - case IW_AUTH_KEY_MGMT: - - if (wpa_version == IW_AUTH_WPA_VERSION_WPA2) { - if (wrq->value == IW_AUTH_KEY_MGMT_PSK) - pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK; - else - pMgmt->eAuthenMode = WMAC_AUTH_WPA2; - } else if (wpa_version == IW_AUTH_WPA_VERSION_WPA) { - if (wrq->value == 0) - pMgmt->eAuthenMode = WMAC_AUTH_WPANONE; - else if (wrq->value == IW_AUTH_KEY_MGMT_PSK) - pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK; - else - pMgmt->eAuthenMode = WMAC_AUTH_WPA; - } - - break; - case IW_AUTH_TKIP_COUNTERMEASURES: - break; /* FIXME */ - case IW_AUTH_DROP_UNENCRYPTED: - break; - case IW_AUTH_80211_AUTH_ALG: - if (wrq->value == IW_AUTH_ALG_OPEN_SYSTEM) - pMgmt->bShareKeyAlgorithm = false; - else if (wrq->value == IW_AUTH_ALG_SHARED_KEY) - pMgmt->bShareKeyAlgorithm = true; - - break; - case IW_AUTH_WPA_ENABLED: - break; - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - break; - case IW_AUTH_ROAMING_CONTROL: - ret = -EOPNOTSUPP; - break; - case IW_AUTH_PRIVACY_INVOKED: - pDevice->bEncryptionEnable = !!wrq->value; - if (pDevice->bEncryptionEnable == false) { - wpa_version = 0; - pairwise = 0; - pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - pMgmt->bShareKeyAlgorithm = false; - pMgmt->eAuthenMode = false; - } - - break; - default: - ret = -EOPNOTSUPP; - break; - } - - return ret; -} - -int iwctl_giwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - return -EOPNOTSUPP; -} - -int iwctl_siwgenie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char __user *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int ret = 0; - char length; - - if (wrq->length) { - if (wrq->length < 2) - return -EINVAL; - - ret = get_user(length, extra + 1); - if (ret) - return ret; - - if (length + 2 != wrq->length) - return -EINVAL; - - if (wrq->length > MAX_WPA_IE_LEN) { - ret = -ENOMEM; - goto out; - } - memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN); - if (copy_from_user(pMgmt->abyWPAIE, extra, wrq->length)) { - ret = -EFAULT; - goto out; - } - pMgmt->wWPAIELen = wrq->length; - } else { - memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN); - pMgmt->wWPAIELen = 0; - } - -out://not completely ...not necessary in wpa_supplicant 0.5.8 - return ret; -} - -int iwctl_giwgenie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char __user *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int ret = 0; - int space = wrq->length; - - wrq->length = 0; - if (pMgmt->wWPAIELen > 0) { - wrq->length = pMgmt->wWPAIELen; - if (pMgmt->wWPAIELen <= space) { - if (copy_to_user(extra, pMgmt->abyWPAIE, pMgmt->wWPAIELen)) - ret = -EFAULT; - - } else { - ret = -E2BIG; - } - } - - return ret; -} - -int iwctl_siwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; - struct viawget_wpa_param *param = NULL; -//original member - enum wpa_alg alg_name; - u8 addr[6]; - int key_idx, set_tx = 0; - u8 seq[IW_ENCODE_SEQ_MAX_SIZE]; - u8 key[64]; - size_t seq_len = 0, key_len = 0; - - u8 key_array[64]; - int ret = 0; - - PRINT_K("SIOCSIWENCODEEXT......\n"); - - param = kzalloc(sizeof(*param), GFP_KERNEL); - if (param == NULL) - return -ENOMEM; - -//recover alg_name - switch (ext->alg) { - case IW_ENCODE_ALG_NONE: - alg_name = WPA_ALG_NONE; - break; - case IW_ENCODE_ALG_WEP: - alg_name = WPA_ALG_WEP; - break; - case IW_ENCODE_ALG_TKIP: - alg_name = WPA_ALG_TKIP; - break; - case IW_ENCODE_ALG_CCMP: - alg_name = WPA_ALG_CCMP; - break; - default: - PRINT_K("Unknown alg = %d\n", ext->alg); - ret = -ENOMEM; - goto error; - } -//recover addr - memcpy(addr, ext->addr.sa_data, ETH_ALEN); -//recover key_idx - key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1; -//recover set_tx - if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) - set_tx = 1; -//recover seq,seq_len - if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { - seq_len = IW_ENCODE_SEQ_MAX_SIZE; - memcpy(seq, ext->rx_seq, seq_len); - } -//recover key,key_len - if (ext->key_len) { - key_len = ext->key_len; - memcpy(key, &ext->key[0], key_len); - } - - memset(key_array, 0, 64); - if (key_len > 0) { - memcpy(key_array, key, key_len); - if (key_len == 32) { - // notice ! the oder - memcpy(&key_array[16], &key[24], 8); - memcpy(&key_array[24], &key[16], 8); - } - } - -/**************Translate iw_encode_ext to viawget_wpa_param****************/ - memcpy(param->addr, addr, ETH_ALEN); - param->u.wpa_key.alg_name = (int)alg_name; - param->u.wpa_key.set_tx = set_tx; - param->u.wpa_key.key_index = key_idx; - param->u.wpa_key.key_len = key_len; - param->u.wpa_key.key = (u8 *)key_array; - param->u.wpa_key.seq = (u8 *)seq; - param->u.wpa_key.seq_len = seq_len; - -//****set if current action is Network Manager count?? -//****this method is so foolish,but there is no other way??? - if (param->u.wpa_key.alg_name == WPA_ALG_NONE) { - if (param->u.wpa_key.key_index == 0) - pDevice->bwextcount++; - - if ((pDevice->bwextcount == 1) && (param->u.wpa_key.key_index == 1)) - pDevice->bwextcount++; - - if ((pDevice->bwextcount == 2) && (param->u.wpa_key.key_index == 2)) - pDevice->bwextcount++; - - if ((pDevice->bwextcount == 3) && (param->u.wpa_key.key_index == 3)) - pDevice->bwextcount++; - - } - if (pDevice->bwextcount == 4) { - pr_debug("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n"); - pDevice->bwextcount = 0; - pDevice->bWPASuppWextEnabled = true; - } -//****** - - spin_lock_irq(&pDevice->lock); - ret = wpa_set_keys(pDevice, param, true); - spin_unlock_irq(&pDevice->lock); - -error: - kfree(param); - return ret; -} - -int iwctl_giwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) -{ - return -EOPNOTSUPP; -} - -int iwctl_siwmlme(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char __user *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - struct iw_mlme mime; - - int ret = 0; - - ret = copy_from_user(&mime, extra, sizeof(mime)); - if (ret) - return -EFAULT; - - if (memcmp(pMgmt->abyCurrBSSID, mime.addr.sa_data, ETH_ALEN)) { - ret = -EINVAL; - return ret; - } - switch (mime.cmd) { - case IW_MLME_DEAUTH: - //this command seems to be not complete,please test it --einsnliu - //bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (unsigned char *)&reason); - break; - case IW_MLME_DISASSOC: - if (pDevice->bLinkPass == true) { - pr_debug("iwctl_siwmlme--->send DISASSOCIATE\n"); - //clear related flags - memset(pMgmt->abyDesireBSSID, 0xFF, 6); - KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); - bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL); - } - break; - default: - ret = -EOPNOTSUPP; - } - - return ret; -} - -#endif - -/*------------------------------------------------------------------*/ -/* - * Structures to export the Wireless Handlers - */ - -static const iw_handler iwctl_handler[] = -{ - (iw_handler) iwctl_commit, // SIOCSIWCOMMIT - (iw_handler) NULL, // SIOCGIWNAME - (iw_handler) NULL, // SIOCSIWNWID - (iw_handler) NULL, // SIOCGIWNWID - (iw_handler) NULL, // SIOCSIWFREQ - (iw_handler) NULL, // SIOCGIWFREQ - (iw_handler) NULL, // SIOCSIWMODE - (iw_handler) NULL, // SIOCGIWMODE - (iw_handler) NULL, // SIOCSIWSENS - (iw_handler) NULL, // SIOCGIWSENS - (iw_handler) NULL, // SIOCSIWRANGE - (iw_handler) iwctl_giwrange, // SIOCGIWRANGE - (iw_handler) NULL, // SIOCSIWPRIV - (iw_handler) NULL, // SIOCGIWPRIV - (iw_handler) NULL, // SIOCSIWSTATS - (iw_handler) NULL, // SIOCGIWSTATS - (iw_handler) NULL, // SIOCSIWSPY - (iw_handler) NULL, // SIOCGIWSPY - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // SIOCSIWAP - (iw_handler) NULL, // SIOCGIWAP - (iw_handler) NULL, // -- hole -- 0x16 - (iw_handler) NULL, // SIOCGIWAPLIST - (iw_handler) iwctl_siwscan, // SIOCSIWSCAN - (iw_handler) iwctl_giwscan, // SIOCGIWSCAN - (iw_handler) NULL, // SIOCSIWESSID - (iw_handler) NULL, // SIOCGIWESSID - (iw_handler) NULL, // SIOCSIWNICKN - (iw_handler) NULL, // SIOCGIWNICKN - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // SIOCSIWRATE 0x20 - (iw_handler) NULL, // SIOCGIWRATE - (iw_handler) NULL, // SIOCSIWRTS - (iw_handler) NULL, // SIOCGIWRTS - (iw_handler) NULL, // SIOCSIWFRAG - (iw_handler) NULL, // SIOCGIWFRAG - (iw_handler) NULL, // SIOCSIWTXPOW - (iw_handler) NULL, // SIOCGIWTXPOW - (iw_handler) NULL, // SIOCSIWRETRY - (iw_handler) NULL, // SIOCGIWRETRY - (iw_handler) NULL, // SIOCSIWENCODE - (iw_handler) NULL, // SIOCGIWENCODE - (iw_handler) NULL, // SIOCSIWPOWER - (iw_handler) NULL, // SIOCGIWPOWER - -//2008-0409-07, <Add> by Einsn Liu - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // SIOCSIWGENIE - (iw_handler) NULL, // SIOCGIWGENIE - (iw_handler) NULL, // SIOCSIWAUTH - (iw_handler) NULL, // SIOCGIWAUTH - (iw_handler) NULL, // SIOCSIWENCODEEXT - (iw_handler) NULL, // SIOCGIWENCODEEXT - (iw_handler) NULL, // SIOCSIWPMKSA - (iw_handler) NULL, // -- hole -- -}; - -static const iw_handler iwctl_private_handler[] = -{ - NULL, // SIOCIWFIRSTPRIV -}; - -struct iw_priv_args iwctl_private_args[] = { - { IOCTL_CMD_SET, - IW_PRIV_TYPE_CHAR | 1024, 0, - "set"}, -}; - -const struct iw_handler_def iwctl_handler_def = -{ - .get_wireless_stats = &iwctl_get_wireless_stats, - .num_standard = sizeof(iwctl_handler)/sizeof(iw_handler), - .num_private = 0, - .num_private_args = 0, - .standard = (iw_handler *)iwctl_handler, - .private = NULL, - .private_args = NULL, -}; diff --git a/drivers/staging/vt6655/iwctl.h b/drivers/staging/vt6655/iwctl.h deleted file mode 100644 index 7dd63102182d..000000000000 --- a/drivers/staging/vt6655/iwctl.h +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: iwctl.h - * - * Purpose: - * - * Author: Lyndon Chen - * - * Date: May 21, 2004 - * - */ - -#ifndef __IWCTL_H__ -#define __IWCTL_H__ - -#include "device.h" - -/*--------------------- Export Definitions -------------------------*/ - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev); - -int iwctl_siwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *wrq, - char *extra); - -int iwctl_giwrange(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_giwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *wmode, - char *extra); - -int iwctl_siwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *wmode, - char *extra); - -int iwctl_giwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *wrq, - char *extra); - -int iwctl_siwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *wrq, - char *extra); - -int iwctl_giwname(struct net_device *dev, - struct iw_request_info *info, - char *wrq, - char *extra); - -int iwctl_giwsens(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_giwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *wrq, - char *extra); - -int iwctl_giwaplist(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_siwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_giwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_siwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_giwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_siwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_giwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_siwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_giwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_siwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_giwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_siwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_giwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_siwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_giwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -//2008-0409-07, <Add> by Einsn Liu -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -int iwctl_siwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_giwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_siwgenie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char __user *extra); - -int iwctl_giwgenie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char __user *extra); - -int iwctl_siwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_giwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_siwmlme(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char __user *extra); -#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -//End Add -- //2008-0409-07, <Add> by Einsn Liu - -extern const struct iw_handler_def iwctl_handler_def; -extern struct iw_priv_args iwctl_private_args[]; - -#endif // __IWCTL_H__ diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c index 211afae306c7..f2b3fea90533 100644 --- a/drivers/staging/vt6655/key.c +++ b/drivers/staging/vt6655/key.c @@ -25,770 +25,144 @@ * * Date: May 29, 2003 * - * Functions: - * KeyvInitTable - Init Key management table - * KeybGetKey - Get Key from table - * KeybSetKey - Set Key to table - * KeybRemoveKey - Remove Key from table - * KeybGetTransmitKey - Get Transmit Key from table - * - * Revision History: - * */ #include "tmacro.h" #include "key.h" #include "mac.h" -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/*--------------------- Static Functions --------------------------*/ -static void -s_vCheckKeyTableValid(PSKeyManagement pTable, void __iomem *dwIoBase) -{ - int i; - - for (i = 0; i < MAX_KEY_TABLE; i++) { - if (pTable->KeyTable[i].bInUse && - !pTable->KeyTable[i].PairwiseKey.bKeyValid && - !pTable->KeyTable[i].GroupKey[0].bKeyValid && - !pTable->KeyTable[i].GroupKey[1].bKeyValid && - !pTable->KeyTable[i].GroupKey[2].bKeyValid && - !pTable->KeyTable[i].GroupKey[3].bKeyValid) { - pTable->KeyTable[i].bInUse = false; - pTable->KeyTable[i].wKeyCtl = 0; - pTable->KeyTable[i].bSoftWEP = false; - MACvDisableKeyEntry(dwIoBase, i); - } - } -} - -/*--------------------- Export Functions --------------------------*/ - -/* - * Description: Init Key management table - * - * Parameters: - * In: - * pTable - Pointer to Key table - * Out: - * none - * - * Return Value: none - * - */ -void KeyvInitTable(PSKeyManagement pTable, void __iomem *dwIoBase) -{ - int i; - int jj; - - for (i = 0; i < MAX_KEY_TABLE; i++) { - pTable->KeyTable[i].bInUse = false; - pTable->KeyTable[i].PairwiseKey.bKeyValid = false; - pTable->KeyTable[i].PairwiseKey.pvKeyTable = (void *)&pTable->KeyTable[i]; - for (jj = 0; jj < MAX_GROUP_KEY; jj++) { - pTable->KeyTable[i].GroupKey[jj].bKeyValid = false; - pTable->KeyTable[i].GroupKey[jj].pvKeyTable = (void *)&pTable->KeyTable[i]; - } - pTable->KeyTable[i].wKeyCtl = 0; - pTable->KeyTable[i].dwGTKeyIndex = 0; - pTable->KeyTable[i].bSoftWEP = false; - MACvDisableKeyEntry(dwIoBase, i); - } -} - -/* - * Description: Get Key from table - * - * Parameters: - * In: - * pTable - Pointer to Key table - * pbyBSSID - BSSID of Key - * dwKeyIndex - Key Index (0xFFFFFFFF means pairwise key) - * Out: - * pKey - Key return - * - * Return Value: true if found otherwise false - * - */ -bool KeybGetKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyIndex, - PSKeyItem *pKey -) -{ - int i; - - pr_debug("KeybGetKey()\n"); - - *pKey = NULL; - for (i = 0; i < MAX_KEY_TABLE; i++) { - if (pTable->KeyTable[i].bInUse && - ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { - if (dwKeyIndex == 0xFFFFFFFF) { - if (pTable->KeyTable[i].PairwiseKey.bKeyValid) { - *pKey = &(pTable->KeyTable[i].PairwiseKey); - return true; - } else { - return false; - } - } else if (dwKeyIndex < MAX_GROUP_KEY) { - if (pTable->KeyTable[i].GroupKey[dwKeyIndex].bKeyValid) { - *pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex]); - return true; - } else { - return false; - } - } else { - return false; - } - } - } - return false; -} - -/* - * Description: Set Key to table - * - * Parameters: - * In: - * pTable - Pointer to Key table - * pbyBSSID - BSSID of Key - * dwKeyIndex - Key index (reference to NDIS DDK) - * uKeyLength - Key length - * KeyRSC - Key RSC - * pbyKey - Pointer to key - * Out: - * none - * - * Return Value: true if success otherwise false - * - */ -bool KeybSetKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyIndex, - unsigned long uKeyLength, - u64 *pKeyRSC, - unsigned char *pbyKey, - unsigned char byKeyDecMode, - void __iomem *dwIoBase, - unsigned char byLocalID -) -{ - int i, j; - unsigned int ii; - PSKeyItem pKey; - unsigned int uKeyIdx; - - pr_debug("Enter KeybSetKey: %lX\n", dwKeyIndex); - - j = (MAX_KEY_TABLE-1); - for (i = 0; i < (MAX_KEY_TABLE - 1); i++) { - if (!pTable->KeyTable[i].bInUse && (j == (MAX_KEY_TABLE-1))) { - // found empty table - j = i; - } - if (pTable->KeyTable[i].bInUse && - ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { - // found table already exist - if ((dwKeyIndex & PAIRWISE_KEY) != 0) { - // Pairwise key - pKey = &(pTable->KeyTable[i].PairwiseKey); - pTable->KeyTable[i].wKeyCtl &= 0xFFF0; // clear pairwise key control filed - pTable->KeyTable[i].wKeyCtl |= byKeyDecMode; - uKeyIdx = 4; // use HW key entry 4 for pairwise key - } else { - // Group key - if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) - return false; - pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]); - if ((dwKeyIndex & TRANSMIT_KEY) != 0) { - // Group transmit key - pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex; - pr_debug("Group transmit key(R)[%lX]: %d\n", - pTable->KeyTable[i].dwGTKeyIndex, i); - } - pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed - pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4); - pTable->KeyTable[i].wKeyCtl |= 0x0040; // use group key for group address - uKeyIdx = (dwKeyIndex & 0x000000FF); - } - pTable->KeyTable[i].wKeyCtl |= 0x8000; // enable on-fly - - pKey->bKeyValid = true; - pKey->uKeyLength = uKeyLength; - pKey->dwKeyIndex = dwKeyIndex; - pKey->byCipherSuite = byKeyDecMode; - memcpy(pKey->abyKey, pbyKey, uKeyLength); - if (byKeyDecMode == KEY_CTL_WEP) { - if (uKeyLength == WLAN_WEP40_KEYLEN) - pKey->abyKey[15] &= 0x7F; - if (uKeyLength == WLAN_WEP104_KEYLEN) - pKey->abyKey[15] |= 0x80; - } - MACvSetKeyEntry(dwIoBase, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pbyBSSID, (u32 *)pKey->abyKey, byLocalID); - - if ((dwKeyIndex & USE_KEYRSC) == 0) { - // RSC set by NIC - pKey->KeyRSC = 0; - } else { - pKey->KeyRSC = *pKeyRSC; - } - pKey->dwTSC47_16 = 0; - pKey->wTSC15_0 = 0; - - pr_debug("KeybSetKey(R):\n"); - pr_debug("pKey->bKeyValid: %d\n ", pKey->bKeyValid); - pr_debug("pKey->abyKey: "); - for (ii = 0; ii < pKey->uKeyLength; ii++) - pr_debug("%02x ", pKey->abyKey[ii]); - - pr_debug("\n"); - - pr_debug("pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16); - pr_debug("pKey->wTSC15_0: %x\n ", pKey->wTSC15_0); - pr_debug("pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex); - - return true; - } - } - if (j < (MAX_KEY_TABLE-1)) { - memcpy(pTable->KeyTable[j].abyBSSID, pbyBSSID, ETH_ALEN); - pTable->KeyTable[j].bInUse = true; - if ((dwKeyIndex & PAIRWISE_KEY) != 0) { - // Pairwise key - pKey = &(pTable->KeyTable[j].PairwiseKey); - pTable->KeyTable[j].wKeyCtl &= 0xFFF0; // clear pairwise key control filed - pTable->KeyTable[j].wKeyCtl |= byKeyDecMode; - uKeyIdx = 4; // use HW key entry 4 for pairwise key - } else { - // Group key - if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) - return false; - pKey = &(pTable->KeyTable[j].GroupKey[dwKeyIndex & 0x000000FF]); - if ((dwKeyIndex & TRANSMIT_KEY) != 0) { - // Group transmit key - pTable->KeyTable[j].dwGTKeyIndex = dwKeyIndex; - pr_debug("Group transmit key(N)[%lX]: %d\n", - pTable->KeyTable[j].dwGTKeyIndex, j); - } - pTable->KeyTable[j].wKeyCtl &= 0xFF0F; // clear group key control filed - pTable->KeyTable[j].wKeyCtl |= (byKeyDecMode << 4); - pTable->KeyTable[j].wKeyCtl |= 0x0040; // use group key for group address - uKeyIdx = (dwKeyIndex & 0x000000FF); - } - pTable->KeyTable[j].wKeyCtl |= 0x8000; // enable on-fly - - pKey->bKeyValid = true; - pKey->uKeyLength = uKeyLength; - pKey->dwKeyIndex = dwKeyIndex; - pKey->byCipherSuite = byKeyDecMode; - memcpy(pKey->abyKey, pbyKey, uKeyLength); - if (byKeyDecMode == KEY_CTL_WEP) { - if (uKeyLength == WLAN_WEP40_KEYLEN) - pKey->abyKey[15] &= 0x7F; - if (uKeyLength == WLAN_WEP104_KEYLEN) - pKey->abyKey[15] |= 0x80; - } - MACvSetKeyEntry(dwIoBase, pTable->KeyTable[j].wKeyCtl, j, uKeyIdx, pbyBSSID, (u32 *)pKey->abyKey, byLocalID); - - if ((dwKeyIndex & USE_KEYRSC) == 0) { - // RSC set by NIC - pKey->KeyRSC = 0; - } else { - pKey->KeyRSC = *pKeyRSC; - } - pKey->dwTSC47_16 = 0; - pKey->wTSC15_0 = 0; - - pr_debug("KeybSetKey(N):\n"); - pr_debug("pKey->bKeyValid: %d\n ", pKey->bKeyValid); - pr_debug("pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength); - pr_debug("pKey->abyKey: "); - for (ii = 0; ii < pKey->uKeyLength; ii++) - pr_debug("%02x ", pKey->abyKey[ii]); - - pr_debug("\n"); - - pr_debug("pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16); - pr_debug("pKey->wTSC15_0: %x\n ", pKey->wTSC15_0); - pr_debug("pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex); - - return true; - } - return false; -} - -/* - * Description: Remove Key from table - * - * Parameters: - * In: - * pTable - Pointer to Key table - * pbyBSSID - BSSID of Key - * dwKeyIndex - Key Index (reference to NDIS DDK) - * Out: - * none - * - * Return Value: true if success otherwise false - * - */ -bool KeybRemoveKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyIndex, - void __iomem *dwIoBase -) -{ - int i; - - if (is_broadcast_ether_addr(pbyBSSID)) { - // delete all keys - if ((dwKeyIndex & PAIRWISE_KEY) != 0) { - for (i = 0; i < MAX_KEY_TABLE; i++) - pTable->KeyTable[i].PairwiseKey.bKeyValid = false; - - s_vCheckKeyTableValid(pTable, dwIoBase); - return true; - } else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) { - for (i = 0; i < MAX_KEY_TABLE; i++) { - pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false; - if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) { - // remove Group transmit key - pTable->KeyTable[i].dwGTKeyIndex = 0; - } - } - s_vCheckKeyTableValid(pTable, dwIoBase); - return true; - } else { - return false; - } - } - - for (i = 0; i < MAX_KEY_TABLE; i++) { - if (pTable->KeyTable[i].bInUse && - ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { - if ((dwKeyIndex & PAIRWISE_KEY) != 0) { - pTable->KeyTable[i].PairwiseKey.bKeyValid = false; - s_vCheckKeyTableValid(pTable, dwIoBase); - return true; - } else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) { - pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false; - if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) { - // remove Group transmit key - pTable->KeyTable[i].dwGTKeyIndex = 0; - } - s_vCheckKeyTableValid(pTable, dwIoBase); - return true; - } else { - return false; - } - } - } - return false; -} - -/* - * Description: Remove Key from table - * - * Parameters: - * In: - * pTable - Pointer to Key table - * pbyBSSID - BSSID of Key - * Out: - * none - * - * Return Value: true if success otherwise false - * - */ -bool KeybRemoveAllKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - void __iomem *dwIoBase -) +int vnt_key_init_table(struct vnt_private *priv) { - int i, u; + u32 i; - for (i = 0; i < MAX_KEY_TABLE; i++) { - if (pTable->KeyTable[i].bInUse && - ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { - pTable->KeyTable[i].PairwiseKey.bKeyValid = false; - for (u = 0; u < MAX_GROUP_KEY; u++) - pTable->KeyTable[i].GroupKey[u].bKeyValid = false; + for (i = 0; i < MAX_KEY_TABLE; i++) + MACvDisableKeyEntry(priv->PortOffset, i); - pTable->KeyTable[i].dwGTKeyIndex = 0; - s_vCheckKeyTableValid(pTable, dwIoBase); - return true; - } - } - return false; + return 0; } -/* - * Description: Remove WEP Key from table - * - * Parameters: - * In: - * pTable - Pointer to Key table - * Out: - * none - * - * Return Value: true if success otherwise false - * - */ -void KeyvRemoveWEPKey( - PSKeyManagement pTable, - unsigned long dwKeyIndex, - void __iomem *dwIoBase -) +static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr, + struct ieee80211_key_conf *key, u32 key_type, u32 mode, + bool onfly_latch) { - if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) { - if (pTable->KeyTable[MAX_KEY_TABLE-1].bInUse) { - if (pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].byCipherSuite == KEY_CTL_WEP) { - pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false; - if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex & 0x7FFFFFFF)) { - // remove Group transmit key - pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = 0; - } + struct vnt_private *priv = hw->priv; + u8 broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + u16 key_mode = 0; + u32 entry = 0; + u8 *bssid; + u8 key_inx = key->keyidx; + u8 i; + + if (mac_addr) + bssid = mac_addr; + else + bssid = &broadcast[0]; + + if (key_type != VNT_KEY_DEFAULTKEY) { + for (i = 0; i < (MAX_KEY_TABLE - 1); i++) { + if (!test_bit(i, &priv->key_entry_inuse)) { + set_bit(i, &priv->key_entry_inuse); + + key->hw_key_idx = i; + entry = key->hw_key_idx; + break; } } - s_vCheckKeyTableValid(pTable, dwIoBase); } -} -void KeyvRemoveAllWEPKey( - PSKeyManagement pTable, - void __iomem *dwIoBase -) -{ - int i; - - for (i = 0; i < MAX_GROUP_KEY; i++) - KeyvRemoveWEPKey(pTable, i, dwIoBase); + switch (key_type) { + /* fallthrough */ + case VNT_KEY_DEFAULTKEY: + /* default key last entry */ + entry = MAX_KEY_TABLE - 1; + key->hw_key_idx = entry; + case VNT_KEY_ALLGROUP: + key_mode |= VNT_KEY_ALLGROUP; + if (onfly_latch) + key_mode |= VNT_KEY_ONFLY_ALL; + case VNT_KEY_GROUP_ADDRESS: + key_mode |= mode; + case VNT_KEY_GROUP: + key_mode |= (mode << 4); + key_mode |= VNT_KEY_GROUP; + break; + case VNT_KEY_PAIRWISE: + key_mode |= mode; + key_inx = 4; + break; + default: + return -EINVAL; + } + + if (onfly_latch) + key_mode |= VNT_KEY_ONFLY; + + if (mode == KEY_CTL_WEP) { + if (key->keylen == WLAN_KEY_LEN_WEP40) + key->key[15] &= 0x7f; + if (key->keylen == WLAN_KEY_LEN_WEP104) + key->key[15] |= 0x80; + } + + MACvSetKeyEntry(priv->PortOffset, key_mode, entry, key_inx, + bssid, (u32 *)key->key, priv->byLocalID); + + return 0; } -/* - * Description: Get Transmit Key from table - * - * Parameters: - * In: - * pTable - Pointer to Key table - * pbyBSSID - BSSID of Key - * Out: - * pKey - Key return - * - * Return Value: true if found otherwise false - * - */ -bool KeybGetTransmitKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyType, - PSKeyItem *pKey -) +int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta, + struct ieee80211_vif *vif, struct ieee80211_key_conf *key) { - int i, ii; - - *pKey = NULL; - for (i = 0; i < MAX_KEY_TABLE; i++) { - if (pTable->KeyTable[i].bInUse && - ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { - if (dwKeyType == PAIRWISE_KEY) { - if (pTable->KeyTable[i].PairwiseKey.bKeyValid) { - *pKey = &(pTable->KeyTable[i].PairwiseKey); - - pr_debug("KeybGetTransmitKey:"); - pr_debug("PAIRWISE_KEY: KeyTable.abyBSSID: "); - for (ii = 0; ii < 6; ii++) - pr_debug("%x ", - pTable->KeyTable[i].abyBSSID[ii]); - - pr_debug("\n"); + struct ieee80211_bss_conf *conf = &vif->bss_conf; + struct vnt_private *priv = hw->priv; + u8 *mac_addr = NULL; + u8 key_dec_mode = 0; + int ret = 0; + u32 u; - return true; - } else { - pr_debug("PairwiseKey.bKeyValid == false\n"); - return false; - } - } // End of Type == PAIRWISE - else { - if (pTable->KeyTable[i].dwGTKeyIndex == 0) { - pr_debug("ERROR: dwGTKeyIndex == 0 !!!\n"); - return false; - } - if (pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)].bKeyValid) { - *pKey = &(pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)]); - - pr_debug("KeybGetTransmitKey:"); - pr_debug("GROUP_KEY: KeyTable.abyBSSID\n"); - for (ii = 0; ii < 6; ii++) - pr_debug("%x ", - pTable->KeyTable[i].abyBSSID[ii]); - - pr_debug("\n"); - pr_debug("dwGTKeyIndex: %lX\n", - pTable->KeyTable[i].dwGTKeyIndex); - - return true; - } else { - pr_debug("GroupKey.bKeyValid == false\n"); - return false; - } - } // End of Type = GROUP - } // BSSID match - } - pr_debug("ERROR: NO Match BSSID !!! "); - for (ii = 0; ii < 6; ii++) - pr_debug("%02x ", *(pbyBSSID+ii)); - - pr_debug("\n"); - return false; -} - -/* - * Description: Check Pairewise Key - * - * Parameters: - * In: - * pTable - Pointer to Key table - * Out: - * none - * - * Return Value: true if found otherwise false - * - */ -bool KeybCheckPairewiseKey( - PSKeyManagement pTable, - PSKeyItem *pKey -) -{ - int i; + if (sta) + mac_addr = &sta->addr[0]; - *pKey = NULL; - for (i = 0; i < MAX_KEY_TABLE; i++) { - if (pTable->KeyTable[i].bInUse && - pTable->KeyTable[i].PairwiseKey.bKeyValid) { - *pKey = &(pTable->KeyTable[i].PairwiseKey); - return true; - } - } - return false; -} + switch (key->cipher) { + case 0: + for (u = 0 ; u < MAX_KEY_TABLE; u++) + MACvDisableKeyEntry(priv->PortOffset, u); + return ret; -/* - * Description: Set Key to table - * - * Parameters: - * In: - * pTable - Pointer to Key table - * dwKeyIndex - Key index (reference to NDIS DDK) - * uKeyLength - Key length - * KeyRSC - Key RSC - * pbyKey - Pointer to key - * Out: - * none - * - * Return Value: true if success otherwise false - * - */ -bool KeybSetDefaultKey( - PSKeyManagement pTable, - unsigned long dwKeyIndex, - unsigned long uKeyLength, - u64 *pKeyRSC, - unsigned char *pbyKey, - unsigned char byKeyDecMode, - void __iomem *dwIoBase, - unsigned char byLocalID -) -{ - unsigned int ii; - PSKeyItem pKey; - unsigned int uKeyIdx; + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + for (u = 0; u < MAX_KEY_TABLE; u++) + MACvDisableKeyEntry(priv->PortOffset, u); - pr_debug("Enter KeybSetDefaultKey: %1x, %d\n", - (int)dwKeyIndex, (int)uKeyLength); + vnt_set_keymode(hw, mac_addr, + key, VNT_KEY_DEFAULTKEY, KEY_CTL_WEP, true); - if ((dwKeyIndex & PAIRWISE_KEY) != 0) // Pairwise key - return false; - else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) - return false; + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - if (uKeyLength > MAX_KEY_LEN) - return false; + return ret; + case WLAN_CIPHER_SUITE_TKIP: + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - pTable->KeyTable[MAX_KEY_TABLE - 1].bInUse = true; - for (ii = 0; ii < ETH_ALEN; ii++) - pTable->KeyTable[MAX_KEY_TABLE - 1].abyBSSID[ii] = 0xFF; + key_dec_mode = KEY_CTL_TKIP; - // Group key - pKey = &(pTable->KeyTable[MAX_KEY_TABLE - 1].GroupKey[dwKeyIndex & 0x000000FF]); - if ((dwKeyIndex & TRANSMIT_KEY) != 0) { - // Group transmit key - pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = dwKeyIndex; - pr_debug("Group transmit key(R)[%lX]: %d\n", - pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex, - MAX_KEY_TABLE-1); + break; + case WLAN_CIPHER_SUITE_CCMP: + key_dec_mode = KEY_CTL_CCMP; + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; } - pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl &= 0x7F00; // clear all key control filed - pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode << 4); - pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode); - pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x0044; // use group key for all address - uKeyIdx = (dwKeyIndex & 0x000000FF); - if ((uKeyLength == WLAN_WEP232_KEYLEN) && - (byKeyDecMode == KEY_CTL_WEP)) { - pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x4000; // disable on-fly disable address match - pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP = true; + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { + vnt_set_keymode(hw, mac_addr, + key, VNT_KEY_PAIRWISE, key_dec_mode, true); } else { - if (!pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP) - pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0xC000; // enable on-fly disable address match - } + vnt_set_keymode(hw, mac_addr, + key, VNT_KEY_DEFAULTKEY, key_dec_mode, true); - pKey->bKeyValid = true; - pKey->uKeyLength = uKeyLength; - pKey->dwKeyIndex = dwKeyIndex; - pKey->byCipherSuite = byKeyDecMode; - memcpy(pKey->abyKey, pbyKey, uKeyLength); - if (byKeyDecMode == KEY_CTL_WEP) { - if (uKeyLength == WLAN_WEP40_KEYLEN) - pKey->abyKey[15] &= 0x7F; - if (uKeyLength == WLAN_WEP104_KEYLEN) - pKey->abyKey[15] |= 0x80; - } - MACvSetKeyEntry(dwIoBase, pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl, MAX_KEY_TABLE-1, uKeyIdx, pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID, (u32 *)pKey->abyKey, byLocalID); - - if ((dwKeyIndex & USE_KEYRSC) == 0) { - // RSC set by NIC - pKey->KeyRSC = 0; - } else { - pKey->KeyRSC = *pKeyRSC; + vnt_set_keymode(hw, (u8 *)conf->bssid, + key, VNT_KEY_GROUP_ADDRESS, key_dec_mode, true); } - pKey->dwTSC47_16 = 0; - pKey->wTSC15_0 = 0; - - pr_debug("KeybSetKey(R):\n"); - pr_debug("pKey->bKeyValid: %d\n", pKey->bKeyValid); - pr_debug("pKey->uKeyLength: %d\n", (int)pKey->uKeyLength); - pr_debug("pKey->abyKey:\n"); - for (ii = 0; ii < pKey->uKeyLength; ii++) - pr_debug("%x", pKey->abyKey[ii]); - - pr_debug("\n"); - - pr_debug("pKey->dwTSC47_16: %lx\n", pKey->dwTSC47_16); - pr_debug("pKey->wTSC15_0: %x\n", pKey->wTSC15_0); - pr_debug("pKey->dwKeyIndex: %lx\n", pKey->dwKeyIndex); - - return true; -} -/* - * Description: Set Key to table - * - * Parameters: - * In: - * pTable - Pointer to Key table - * dwKeyIndex - Key index (reference to NDIS DDK) - * uKeyLength - Key length - * KeyRSC - Key RSC - * pbyKey - Pointer to key - * Out: - * none - * - * Return Value: true if success otherwise false - * - */ -bool KeybSetAllGroupKey( - PSKeyManagement pTable, - unsigned long dwKeyIndex, - unsigned long uKeyLength, - u64 *pKeyRSC, - unsigned char *pbyKey, - unsigned char byKeyDecMode, - void __iomem *dwIoBase, - unsigned char byLocalID -) -{ - int i; - unsigned int ii; - PSKeyItem pKey; - unsigned int uKeyIdx; - - pr_debug("Enter KeybSetAllGroupKey: %lX\n", dwKeyIndex); - - if ((dwKeyIndex & PAIRWISE_KEY) != 0) // Pairwise key - return false; - else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) - return false; - - for (i = 0; i < MAX_KEY_TABLE - 1; i++) { - if (pTable->KeyTable[i].bInUse) { - // found table already exist - // Group key - pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]); - if ((dwKeyIndex & TRANSMIT_KEY) != 0) { - // Group transmit key - pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex; - pr_debug("Group transmit key(R)[%lX]: %d\n", - pTable->KeyTable[i].dwGTKeyIndex, i); - - } - pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed - pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4); - pTable->KeyTable[i].wKeyCtl |= 0x0040; // use group key for group address - uKeyIdx = (dwKeyIndex & 0x000000FF); - - pTable->KeyTable[i].wKeyCtl |= 0x8000; // enable on-fly - - pKey->bKeyValid = true; - pKey->uKeyLength = uKeyLength; - pKey->dwKeyIndex = dwKeyIndex; - pKey->byCipherSuite = byKeyDecMode; - memcpy(pKey->abyKey, pbyKey, uKeyLength); - if (byKeyDecMode == KEY_CTL_WEP) { - if (uKeyLength == WLAN_WEP40_KEYLEN) - pKey->abyKey[15] &= 0x7F; - if (uKeyLength == WLAN_WEP104_KEYLEN) - pKey->abyKey[15] |= 0x80; - } - MACvSetKeyEntry(dwIoBase, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pTable->KeyTable[i].abyBSSID, (u32 *)pKey->abyKey, byLocalID); - - if ((dwKeyIndex & USE_KEYRSC) == 0) { - // RSC set by NIC - pKey->KeyRSC = 0; - } else { - pKey->KeyRSC = *pKeyRSC; - } - pKey->dwTSC47_16 = 0; - pKey->wTSC15_0 = 0; - - pr_debug("KeybSetKey(R):\n"); - pr_debug("pKey->bKeyValid: %d\n ", pKey->bKeyValid); - pr_debug("pKey->uKeyLength: %d\n ", - (int)pKey->uKeyLength); - pr_debug("pKey->abyKey: "); - for (ii = 0; ii < pKey->uKeyLength; ii++) - pr_debug("%02x ", pKey->abyKey[ii]); - - pr_debug("\n"); - - } // (pTable->KeyTable[i].bInUse == true) - } - return true; + return 0; } diff --git a/drivers/staging/vt6655/key.h b/drivers/staging/vt6655/key.h index 44efe18315af..c01d4afb6ab8 100644 --- a/drivers/staging/vt6655/key.h +++ b/drivers/staging/vt6655/key.h @@ -30,9 +30,7 @@ #ifndef __KEY_H__ #define __KEY_H__ -#include "ttype.h" -#include "tether.h" -#include "80211mgr.h" +#include <net/mac80211.h> /*--------------------- Export Definitions -------------------------*/ #define MAX_GROUP_KEY 4 @@ -53,124 +51,19 @@ #define KEY_CTL_CCMP 0x03 #define KEY_CTL_INVALID 0xFF -typedef struct tagSKeyItem { - bool bKeyValid; - unsigned long uKeyLength; - unsigned char abyKey[MAX_KEY_LEN]; - u64 KeyRSC; - unsigned long dwTSC47_16; - unsigned short wTSC15_0; - unsigned char byCipherSuite; - unsigned char byReserved0; - unsigned long dwKeyIndex; - void *pvKeyTable; -} SKeyItem, *PSKeyItem; //64 +#define VNT_KEY_DEFAULTKEY 0x1 +#define VNT_KEY_GROUP_ADDRESS 0x2 +#define VNT_KEY_ALLGROUP 0x4 +#define VNT_KEY_GROUP 0x40 +#define VNT_KEY_PAIRWISE 0x00 +#define VNT_KEY_ONFLY 0x8000 +#define VNT_KEY_ONFLY_ALL 0x4000 -typedef struct tagSKeyTable { - unsigned char abyBSSID[ETH_ALEN]; //6 - unsigned char byReserved0[2]; //8 - SKeyItem PairwiseKey; - SKeyItem GroupKey[MAX_GROUP_KEY]; //64*5 = 320, 320+8=328 - unsigned long dwGTKeyIndex; // GroupTransmitKey Index - bool bInUse; - //2006-1116-01,<Modify> by NomadZhao - bool bSoftWEP; - unsigned short wKeyCtl; // for address of wKeyCtl at align 4 +struct vnt_private; - unsigned char byReserved1[6]; -} SKeyTable, *PSKeyTable; //348 +int vnt_key_init_table(struct vnt_private *); -typedef struct tagSKeyManagement { - SKeyTable KeyTable[MAX_KEY_TABLE]; -} SKeyManagement, *PSKeyManagement; - -/*--------------------- Export Types ------------------------------*/ - -/*--------------------- Export Macros ------------------------------*/ - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -void KeyvInitTable(PSKeyManagement pTable, void __iomem *dwIoBase); - -bool KeybGetKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyIndex, - PSKeyItem *pKey -); - -bool KeybSetKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyIndex, - unsigned long uKeyLength, - u64 *pKeyRSC, - unsigned char *pbyKey, - unsigned char byKeyDecMode, - void __iomem *dwIoBase, - unsigned char byLocalID -); - -bool KeybSetDefaultKey( - PSKeyManagement pTable, - unsigned long dwKeyIndex, - unsigned long uKeyLength, - u64 *pKeyRSC, - unsigned char *pbyKey, - unsigned char byKeyDecMode, - void __iomem *dwIoBase, - unsigned char byLocalID -); - -bool KeybRemoveKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyIndex, - void __iomem *dwIoBase -); - -bool KeybGetTransmitKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyType, - PSKeyItem *pKey -); - -bool KeybCheckPairewiseKey( - PSKeyManagement pTable, - PSKeyItem *pKey -); - -bool KeybRemoveAllKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - void __iomem *dwIoBase -); - -void KeyvRemoveWEPKey( - PSKeyManagement pTable, - unsigned long dwKeyIndex, - void __iomem *dwIoBase -); - -void KeyvRemoveAllWEPKey( - PSKeyManagement pTable, - void __iomem *dwIoBase -); - -bool KeybSetAllGroupKey( - PSKeyManagement pTable, - unsigned long dwKeyIndex, - unsigned long uKeyLength, - u64 *pKeyRSC, - unsigned char *pbyKey, - unsigned char byKeyDecMode, - void __iomem *dwIoBase, - unsigned char byLocalID -); +int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta, + struct ieee80211_vif *vif, struct ieee80211_key_conf *key); #endif // __KEY_H__ diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c index e3b0b7f7ca85..8f0d652fea7c 100644 --- a/drivers/staging/vt6655/mac.c +++ b/drivers/staging/vt6655/mac.c @@ -26,30 +26,15 @@ * Date: May 21, 1996 * * Functions: - * MACvReadAllRegs - Read All MAC Registers to buffer * MACbIsRegBitsOn - Test if All test Bits On * MACbIsRegBitsOff - Test if All test Bits Off * MACbIsIntDisable - Test if MAC interrupt disable - * MACbyReadMultiAddr - Read Multicast Address Mask Pattern - * MACvWriteMultiAddr - Write Multicast Address Mask Pattern - * MACvSetMultiAddrByHash - Set Multicast Address Mask by Hash value - * MACvResetMultiAddrByHash - Clear Multicast Address Mask by Hash value - * MACvSetRxThreshold - Set Rx Threshold value - * MACvGetRxThreshold - Get Rx Threshold value - * MACvSetTxThreshold - Set Tx Threshold value - * MACvGetTxThreshold - Get Tx Threshold value - * MACvSetDmaLength - Set Dma Length value - * MACvGetDmaLength - Get Dma Length value * MACvSetShortRetryLimit - Set 802.11 Short Retry limit * MACvGetShortRetryLimit - Get 802.11 Short Retry limit * MACvSetLongRetryLimit - Set 802.11 Long Retry limit - * MACvGetLongRetryLimit - Get 802.11 Long Retry limit * MACvSetLoopbackMode - Set MAC Loopback Mode - * MACbIsInLoopbackMode - Test if MAC in Loopback mode - * MACvSetPacketFilter - Set MAC Address Filter * MACvSaveContext - Save Context of MAC Registers * MACvRestoreContext - Restore Context of MAC Registers - * MACbCompareContext - Compare if values of MAC Registers same as Context * MACbSoftwareReset - Software Reset MAC * MACbSafeRxOff - Turn Off MAC Rx * MACbSafeTxOff - Turn Off MAC Tx @@ -69,54 +54,8 @@ */ #include "tmacro.h" -#include "tether.h" #include "mac.h" -unsigned short TxRate_iwconfig;//2008-5-8 <add> by chester -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -/* - * Description: - * Read All MAC Registers to buffer - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * Out: - * pbyMacRegs - buffer to read - * - * Return Value: none - * - */ -void MACvReadAllRegs(void __iomem *dwIoBase, unsigned char *pbyMacRegs) -{ - int ii; - - // read page0 register - for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE0; ii++) { - VNSvInPortB(dwIoBase + ii, pbyMacRegs); - pbyMacRegs++; - } - - MACvSelectPage1(dwIoBase); - - // read page1 register - for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) { - VNSvInPortB(dwIoBase + ii, pbyMacRegs); - pbyMacRegs++; - } - - MACvSelectPage0(dwIoBase); -} - /* * Description: * Test if all test bits on @@ -189,252 +128,6 @@ bool MACbIsIntDisable(void __iomem *dwIoBase) /* * Description: - * Read MAC Multicast Address Mask - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * uByteidx - Index of Mask - * Out: - * none - * - * Return Value: Mask Value read - * - */ -unsigned char MACbyReadMultiAddr(void __iomem *dwIoBase, unsigned int uByteIdx) -{ - unsigned char byData; - - MACvSelectPage1(dwIoBase); - VNSvInPortB(dwIoBase + MAC_REG_MAR0 + uByteIdx, &byData); - MACvSelectPage0(dwIoBase); - return byData; -} - -/* - * Description: - * Write MAC Multicast Address Mask - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * uByteidx - Index of Mask - * byData - Mask Value to write - * Out: - * none - * - * Return Value: none - * - */ -void MACvWriteMultiAddr(void __iomem *dwIoBase, unsigned int uByteIdx, unsigned char byData) -{ - MACvSelectPage1(dwIoBase); - VNSvOutPortB(dwIoBase + MAC_REG_MAR0 + uByteIdx, byData); - MACvSelectPage0(dwIoBase); -} - -/* - * Description: - * Set this hash index into multicast address register bit - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * byHashIdx - Hash index to set - * Out: - * none - * - * Return Value: none - * - */ -void MACvSetMultiAddrByHash(void __iomem *dwIoBase, unsigned char byHashIdx) -{ - unsigned int uByteIdx; - unsigned char byBitMask; - unsigned char byOrgValue; - - // calculate byte position - uByteIdx = byHashIdx / 8; - ASSERT(uByteIdx < 8); - // calculate bit position - byBitMask = 1; - byBitMask <<= (byHashIdx % 8); - // turn on the bit - byOrgValue = MACbyReadMultiAddr(dwIoBase, uByteIdx); - MACvWriteMultiAddr(dwIoBase, uByteIdx, (unsigned char)(byOrgValue | byBitMask)); -} - -/* - * Description: - * Reset this hash index into multicast address register bit - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * byHashIdx - Hash index to clear - * Out: - * none - * - * Return Value: none - * - */ -void MACvResetMultiAddrByHash(void __iomem *dwIoBase, unsigned char byHashIdx) -{ - unsigned int uByteIdx; - unsigned char byBitMask; - unsigned char byOrgValue; - - // calculate byte position - uByteIdx = byHashIdx / 8; - ASSERT(uByteIdx < 8); - // calculate bit position - byBitMask = 1; - byBitMask <<= (byHashIdx % 8); - // turn off the bit - byOrgValue = MACbyReadMultiAddr(dwIoBase, uByteIdx); - MACvWriteMultiAddr(dwIoBase, uByteIdx, (unsigned char)(byOrgValue & (~byBitMask))); -} - -/* - * Description: - * Set Rx Threshold - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * byThreshold - Threshold Value - * Out: - * none - * - * Return Value: none - * - */ -void MACvSetRxThreshold(void __iomem *dwIoBase, unsigned char byThreshold) -{ - unsigned char byOrgValue; - - ASSERT(byThreshold < 4); - - // set FCR0 - VNSvInPortB(dwIoBase + MAC_REG_FCR0, &byOrgValue); - byOrgValue = (byOrgValue & 0xCF) | (byThreshold << 4); - VNSvOutPortB(dwIoBase + MAC_REG_FCR0, byOrgValue); -} - -/* - * Description: - * Get Rx Threshold - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * Out: - * pbyThreshold- Threshold Value Get - * - * Return Value: none - * - */ -void MACvGetRxThreshold(void __iomem *dwIoBase, unsigned char *pbyThreshold) -{ - // get FCR0 - VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyThreshold); - *pbyThreshold = (*pbyThreshold >> 4) & 0x03; -} - -/* - * Description: - * Set Tx Threshold - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * byThreshold - Threshold Value - * Out: - * none - * - * Return Value: none - * - */ -void MACvSetTxThreshold(void __iomem *dwIoBase, unsigned char byThreshold) -{ - unsigned char byOrgValue; - - ASSERT(byThreshold < 4); - - // set FCR0 - VNSvInPortB(dwIoBase + MAC_REG_FCR0, &byOrgValue); - byOrgValue = (byOrgValue & 0xF3) | (byThreshold << 2); - VNSvOutPortB(dwIoBase + MAC_REG_FCR0, byOrgValue); -} - -/* - * Description: - * Get Tx Threshold - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * Out: - * pbyThreshold- Threshold Value Get - * - * Return Value: none - * - */ -void MACvGetTxThreshold(void __iomem *dwIoBase, unsigned char *pbyThreshold) -{ - // get FCR0 - VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyThreshold); - *pbyThreshold = (*pbyThreshold >> 2) & 0x03; -} - -/* - * Description: - * Set Dma Length - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * byDmaLength - Dma Length Value - * Out: - * none - * - * Return Value: none - * - */ -void MACvSetDmaLength(void __iomem *dwIoBase, unsigned char byDmaLength) -{ - unsigned char byOrgValue; - - ASSERT(byDmaLength < 4); - - // set FCR0 - VNSvInPortB(dwIoBase + MAC_REG_FCR0, &byOrgValue); - byOrgValue = (byOrgValue & 0xFC) | byDmaLength; - VNSvOutPortB(dwIoBase + MAC_REG_FCR0, byOrgValue); -} - -/* - * Description: - * Get Dma Length - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * Out: - * pbyDmaLength- Dma Length Value Get - * - * Return Value: none - * - */ -void MACvGetDmaLength(void __iomem *dwIoBase, unsigned char *pbyDmaLength) -{ - // get FCR0 - VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyDmaLength); - *pbyDmaLength &= 0x03; -} - -/* - * Description: * Set 802.11 Short Retry Limit * * Parameters: @@ -494,25 +187,6 @@ void MACvSetLongRetryLimit(void __iomem *dwIoBase, unsigned char byRetryLimit) /* * Description: - * Get 802.11 Long Retry Limit - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * Out: - * pbyRetryLimit - Retry Limit Get - * - * Return Value: none - * - */ -void MACvGetLongRetryLimit(void __iomem *dwIoBase, unsigned char *pbyRetryLimit) -{ - // get LRT - VNSvInPortB(dwIoBase + MAC_REG_LRT, pbyRetryLimit); -} - -/* - * Description: * Set MAC Loopback mode * * Parameters: @@ -540,89 +214,6 @@ void MACvSetLoopbackMode(void __iomem *dwIoBase, unsigned char byLoopbackMode) /* * Description: - * Test if MAC in Loopback mode - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * Out: - * none - * - * Return Value: true if in Loopback mode; otherwise false - * - */ -bool MACbIsInLoopbackMode(void __iomem *dwIoBase) -{ - unsigned char byOrgValue; - - VNSvInPortB(dwIoBase + MAC_REG_TEST, &byOrgValue); - if (byOrgValue & (TEST_LBINT | TEST_LBEXT)) - return true; - return false; -} - -/* - * Description: - * Set MAC Address filter - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * wFilterType - Filter Type - * Out: - * none - * - * Return Value: none - * - */ -void MACvSetPacketFilter(void __iomem *dwIoBase, unsigned short wFilterType) -{ - unsigned char byOldRCR; - unsigned char byNewRCR = 0; - - // if only in DIRECTED mode, multicast-address will set to zero, - // but if other mode exist (e.g. PROMISCUOUS), multicast-address - // will be open - if (wFilterType & PKT_TYPE_DIRECTED) { - // set multicast address to accept none - MACvSelectPage1(dwIoBase); - VNSvOutPortD(dwIoBase + MAC_REG_MAR0, 0L); - VNSvOutPortD(dwIoBase + MAC_REG_MAR0 + sizeof(unsigned long), 0L); - MACvSelectPage0(dwIoBase); - } - - if (wFilterType & (PKT_TYPE_PROMISCUOUS | PKT_TYPE_ALL_MULTICAST)) { - // set multicast address to accept all - MACvSelectPage1(dwIoBase); - VNSvOutPortD(dwIoBase + MAC_REG_MAR0, 0xFFFFFFFFL); - VNSvOutPortD(dwIoBase + MAC_REG_MAR0 + sizeof(unsigned long), 0xFFFFFFFFL); - MACvSelectPage0(dwIoBase); - } - - if (wFilterType & PKT_TYPE_PROMISCUOUS) { - byNewRCR |= (RCR_RXALLTYPE | RCR_UNICAST | RCR_MULTICAST | RCR_BROADCAST); - - byNewRCR &= ~RCR_BSSID; - } - - if (wFilterType & (PKT_TYPE_ALL_MULTICAST | PKT_TYPE_MULTICAST)) - byNewRCR |= RCR_MULTICAST; - - if (wFilterType & PKT_TYPE_BROADCAST) - byNewRCR |= RCR_BROADCAST; - - if (wFilterType & PKT_TYPE_ERROR_CRC) - byNewRCR |= RCR_ERRCRC; - - VNSvInPortB(dwIoBase + MAC_REG_RCR, &byOldRCR); - if (byNewRCR != byOldRCR) { - // Modify the Receive Command Register - VNSvOutPortB(dwIoBase + MAC_REG_RCR, byNewRCR); - } -} - -/* - * Description: * Save MAC registers to context buffer * * Parameters: @@ -702,47 +293,6 @@ void MACvRestoreContext(void __iomem *dwIoBase, unsigned char *pbyCxtBuf) /* * Description: - * Compare if MAC registers same as context buffer - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * pbyCxtBuf - Context buffer - * Out: - * none - * - * Return Value: true if all values are the same; otherwise false - * - */ -bool MACbCompareContext(void __iomem *dwIoBase, unsigned char *pbyCxtBuf) -{ - unsigned long dwData; - - // compare MAC context to determine if this is a power lost init, - // return true for power remaining init, return false for power lost init - - // compare CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR - VNSvInPortD(dwIoBase + MAC_REG_TXDMAPTR0, &dwData); - if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_TXDMAPTR0)) - return false; - - VNSvInPortD(dwIoBase + MAC_REG_AC0DMAPTR, &dwData); - if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_AC0DMAPTR)) - return false; - - VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR0, &dwData); - if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR0)) - return false; - - VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR1, &dwData); - if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR1)) - return false; - - return true; -} - -/* - * Description: * Software Reset MAC * * Parameters: @@ -1018,11 +568,6 @@ void MACvInitialize(void __iomem *dwIoBase) VNSvOutPortB(dwIoBase + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); // enable TSF counter VNSvOutPortB(dwIoBase + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); - - // set packet filter - // receive directed and broadcast address - - MACvSetPacketFilter(dwIoBase, PKT_TYPE_DIRECTED | PKT_TYPE_BROADCAST); } /* @@ -1234,27 +779,6 @@ void MACvTimer0MicroSDelay(void __iomem *dwIoBase, unsigned int uDelay) * Return Value: none * */ -void MACvOneShotTimer0MicroSec(void __iomem *dwIoBase, unsigned int uDelayTime) -{ - VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0); - VNSvOutPortD(dwIoBase + MAC_REG_TMDATA0, uDelayTime); - VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, (TMCTL_TMD | TMCTL_TE)); -} - -/* - * Description: - * Micro Second One shot timer via MAC - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * uDelay - Delay time - * Out: - * none - * - * Return Value: none - * - */ void MACvOneShotTimer1MicroSec(void __iomem *dwIoBase, unsigned int uDelayTime) { VNSvOutPortB(dwIoBase + MAC_REG_TMCTL1, 0); @@ -1271,102 +795,6 @@ void MACvSetMISCFifo(void __iomem *dwIoBase, unsigned short wOffset, unsigned lo VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); } -bool MACbTxDMAOff(void __iomem *dwIoBase, unsigned int idx) -{ - unsigned char byData; - unsigned int ww = 0; - - if (idx == TYPE_TXDMA0) { - VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0+2, DMACTL_RUN); - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byData); - if (!(byData & DMACTL_RUN)) - break; - } - } else if (idx == TYPE_AC0DMA) { - VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL+2, DMACTL_RUN); - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byData); - if (!(byData & DMACTL_RUN)) - break; - } - } - if (ww == W_MAX_TIMEOUT) { - DBG_PORT80(0x29); - pr_debug(" DBG_PORT80(0x29)\n"); - return false; - } - return true; -} - -void MACvClearBusSusInd(void __iomem *dwIoBase) -{ - unsigned long dwOrgValue; - unsigned int ww; - // check if BcnSusInd enabled - VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); - if (!(dwOrgValue & EnCFG_BcnSusInd)) - return; - //Set BcnSusClr - dwOrgValue = dwOrgValue | EnCFG_BcnSusClr; - VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); - if (!(dwOrgValue & EnCFG_BcnSusInd)) - break; - } - if (ww == W_MAX_TIMEOUT) { - DBG_PORT80(0x33); - pr_debug(" DBG_PORT80(0x33)\n"); - } -} - -void MACvEnableBusSusEn(void __iomem *dwIoBase) -{ - unsigned char byOrgValue; - unsigned long dwOrgValue; - unsigned int ww; - // check if BcnSusInd enabled - VNSvInPortB(dwIoBase + MAC_REG_CFG , &byOrgValue); - - //Set BcnSusEn - byOrgValue = byOrgValue | CFG_BCNSUSEN; - VNSvOutPortB(dwIoBase + MAC_REG_ENCFG, byOrgValue); - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); - if (dwOrgValue & EnCFG_BcnSusInd) - break; - } - if (ww == W_MAX_TIMEOUT) { - DBG_PORT80(0x34); - pr_debug(" DBG_PORT80(0x34)\n"); - } -} - -bool MACbFlushSYNCFifo(void __iomem *dwIoBase) -{ - unsigned char byOrgValue; - unsigned int ww; - // Read MACCR - VNSvInPortB(dwIoBase + MAC_REG_MACCR , &byOrgValue); - - // Set SYNCFLUSH - byOrgValue = byOrgValue | MACCR_SYNCFLUSH; - VNSvOutPortB(dwIoBase + MAC_REG_MACCR, byOrgValue); - - // Check if SyncFlushOK - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortB(dwIoBase + MAC_REG_MACCR , &byOrgValue); - if (byOrgValue & MACCR_SYNCFLUSHOK) - break; - } - if (ww == W_MAX_TIMEOUT) { - DBG_PORT80(0x35); - pr_debug(" DBG_PORT80(0x33)\n"); - } - return true; -} - bool MACbPSWakeup(void __iomem *dwIoBase) { unsigned char byOrgValue; @@ -1484,211 +912,3 @@ void MACvDisableKeyEntry(void __iomem *dwIoBase, unsigned int uEntryIdx) VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, 0); VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); } - -/* - * Description: - * Set the default Key (KeyEntry[10]) by MISCFIFO - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * - * Out: - * none - * - * Return Value: none - * - */ - -void MACvSetDefaultKeyEntry(void __iomem *dwIoBase, unsigned int uKeyLen, - unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID) -{ - unsigned short wOffset; - unsigned long dwData; - int ii; - - if (byLocalID <= 1) - return; - - pr_debug("MACvSetDefaultKeyEntry\n"); - wOffset = MISCFIFO_KEYETRY0; - wOffset += (10 * MISCFIFO_KEYENTRYSIZE); - - wOffset++; - wOffset++; - wOffset += (uKeyIdx * 4); - // always push 128 bits - for (ii = 0; ii < 3; ii++) { - pr_debug("(%d) wOffset: %d, Data: %lX\n", - ii, wOffset+ii, *pdwKey); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii); - VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); - } - dwData = *pdwKey; - if (uKeyLen == WLAN_WEP104_KEYLEN) - dwData |= 0x80000000; - - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+3); - VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); - pr_debug("End. wOffset: %d, Data: %lX\n", wOffset+3, dwData); -} - -/* - * Description: - * Enable default Key (KeyEntry[10]) by MISCFIFO - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * - * Out: - * none - * - * Return Value: none - * - */ -/* - void MACvEnableDefaultKey(void __iomem *dwIoBase, unsigned char byLocalID) - { - unsigned short wOffset; - unsigned long dwData; - - if (byLocalID <= 1) - return; - - wOffset = MISCFIFO_KEYETRY0; - wOffset += (10 * MISCFIFO_KEYENTRYSIZE); - - dwData = 0xC0440000; - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); - VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); - pr_debug("MACvEnableDefaultKey: wOffset: %d, Data: %lX\n", wOffset, dwData); - - } -*/ - -/* - * Description: - * Disable default Key (KeyEntry[10]) by MISCFIFO - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * - * Out: - * none - * - * Return Value: none - * - */ -void MACvDisableDefaultKey(void __iomem *dwIoBase) -{ - unsigned short wOffset; - unsigned long dwData; - - wOffset = MISCFIFO_KEYETRY0; - wOffset += (10 * MISCFIFO_KEYENTRYSIZE); - - dwData = 0x0; - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); - VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); - pr_debug("MACvDisableDefaultKey: wOffset: %d, Data: %lX\n", - wOffset, dwData); -} - -/* - * Description: - * Set the default TKIP Group Key (KeyEntry[10]) by MISCFIFO - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * - * Out: - * none - * - * Return Value: none - * - */ -void MACvSetDefaultTKIPKeyEntry(void __iomem *dwIoBase, unsigned int uKeyLen, - unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID) -{ - unsigned short wOffset; - unsigned long dwData; - int ii; - - if (byLocalID <= 1) - return; - - pr_debug("MACvSetDefaultTKIPKeyEntry\n"); - wOffset = MISCFIFO_KEYETRY0; - // Kyle test : change offset from 10 -> 0 - wOffset += (10 * MISCFIFO_KEYENTRYSIZE); - - dwData = 0xC0660000; - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); - VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); - wOffset++; - - dwData = 0; - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); - VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); - wOffset++; - - wOffset += (uKeyIdx * 4); - pr_debug("1. wOffset: %d, Data: %lX, idx:%d\n", - wOffset, *pdwKey, uKeyIdx); - // always push 128 bits - for (ii = 0; ii < 4; ii++) { - pr_debug("2.(%d) wOffset: %d, Data: %lX\n", - ii, wOffset+ii, *pdwKey); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii); - VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); - } -} - -/* - * Description: - * Set the Key Control by MISCFIFO - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * - * Out: - * none - * - * Return Value: none - * - */ - -void MACvSetDefaultKeyCtl(void __iomem *dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx, unsigned char byLocalID) -{ - unsigned short wOffset; - unsigned long dwData; - - if (byLocalID <= 1) - return; - - pr_debug("MACvSetKeyEntry\n"); - wOffset = MISCFIFO_KEYETRY0; - wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE); - - dwData = 0; - dwData |= wKeyCtl; - dwData <<= 16; - dwData |= 0xffff; - pr_debug("1. wOffset: %d, Data: %lX, KeyCtl:%X\n", - wOffset, dwData, wKeyCtl); - - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); - VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); -} diff --git a/drivers/staging/vt6655/mac.h b/drivers/staging/vt6655/mac.h index 0bf93759b6af..e1e7e10435f6 100644 --- a/drivers/staging/vt6655/mac.h +++ b/drivers/staging/vt6655/mac.h @@ -34,7 +34,6 @@ #ifndef __MAC_H__ #define __MAC_H__ -#include "ttype.h" #include "tmacro.h" #include "upc.h" @@ -575,17 +574,6 @@ #define MAC_LB_INTERNAL 0x01 // #define MAC_LB_NONE 0x00 // -// Ethernet address filter type -#define PKT_TYPE_NONE 0x00 // turn off receiver -#define PKT_TYPE_ALL_MULTICAST 0x80 -#define PKT_TYPE_PROMISCUOUS 0x40 -#define PKT_TYPE_DIRECTED 0x20 // obsolete, directed address is always accepted -#define PKT_TYPE_BROADCAST 0x10 -#define PKT_TYPE_MULTICAST 0x08 -#define PKT_TYPE_ERROR_WPA 0x04 -#define PKT_TYPE_ERROR_CRC 0x02 -#define PKT_TYPE_BSSID 0x01 - #define Default_BI 0x200 // MiscFIFO Offset @@ -965,48 +953,20 @@ do { \ #define MACvSetRFLE_LatchBase(dwIoBase) \ MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_RFLEOPT) -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -extern unsigned short TxRate_iwconfig;//2008-5-8 <add> by chester -void MACvReadAllRegs(void __iomem *dwIoBase, unsigned char *pbyMacRegs); - bool MACbIsRegBitsOn(void __iomem *dwIoBase, unsigned char byRegOfs, unsigned char byTestBits); bool MACbIsRegBitsOff(void __iomem *dwIoBase, unsigned char byRegOfs, unsigned char byTestBits); bool MACbIsIntDisable(void __iomem *dwIoBase); -unsigned char MACbyReadMultiAddr(void __iomem *dwIoBase, unsigned int uByteIdx); -void MACvWriteMultiAddr(void __iomem *dwIoBase, unsigned int uByteIdx, unsigned char byData); -void MACvSetMultiAddrByHash(void __iomem *dwIoBase, unsigned char byHashIdx); -void MACvResetMultiAddrByHash(void __iomem *dwIoBase, unsigned char byHashIdx); - -void MACvSetRxThreshold(void __iomem *dwIoBase, unsigned char byThreshold); -void MACvGetRxThreshold(void __iomem *dwIoBase, unsigned char *pbyThreshold); - -void MACvSetTxThreshold(void __iomem *dwIoBase, unsigned char byThreshold); -void MACvGetTxThreshold(void __iomem *dwIoBase, unsigned char *pbyThreshold); - -void MACvSetDmaLength(void __iomem *dwIoBase, unsigned char byDmaLength); -void MACvGetDmaLength(void __iomem *dwIoBase, unsigned char *pbyDmaLength); - void MACvSetShortRetryLimit(void __iomem *dwIoBase, unsigned char byRetryLimit); -void MACvGetShortRetryLimit(void __iomem *dwIoBase, unsigned char *pbyRetryLimit); void MACvSetLongRetryLimit(void __iomem *dwIoBase, unsigned char byRetryLimit); void MACvGetLongRetryLimit(void __iomem *dwIoBase, unsigned char *pbyRetryLimit); void MACvSetLoopbackMode(void __iomem *dwIoBase, unsigned char byLoopbackMode); -bool MACbIsInLoopbackMode(void __iomem *dwIoBase); - -void MACvSetPacketFilter(void __iomem *dwIoBase, unsigned short wFilterType); void MACvSaveContext(void __iomem *dwIoBase, unsigned char *pbyCxtBuf); void MACvRestoreContext(void __iomem *dwIoBase, unsigned char *pbyCxtBuf); -bool MACbCompareContext(void __iomem *dwIoBase, unsigned char *pbyCxtBuf); bool MACbSoftwareReset(void __iomem *dwIoBase); bool MACbSafeSoftwareReset(void __iomem *dwIoBase); @@ -1023,27 +983,14 @@ void MACvSetCurrAC0DescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAd void MACvSetCurrSyncDescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAddr); void MACvSetCurrATIMDescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAddr); void MACvTimer0MicroSDelay(void __iomem *dwIoBase, unsigned int uDelay); -void MACvOneShotTimer0MicroSec(void __iomem *dwIoBase, unsigned int uDelayTime); void MACvOneShotTimer1MicroSec(void __iomem *dwIoBase, unsigned int uDelayTime); void MACvSetMISCFifo(void __iomem *dwIoBase, unsigned short wOffset, unsigned long dwData); -bool MACbTxDMAOff(void __iomem *dwIoBase, unsigned int idx); - -void MACvClearBusSusInd(void __iomem *dwIoBase); -void MACvEnableBusSusEn(void __iomem *dwIoBase); - -bool MACbFlushSYNCFifo(void __iomem *dwIoBase); bool MACbPSWakeup(void __iomem *dwIoBase); void MACvSetKeyEntry(void __iomem *dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx, unsigned int uKeyIdx, unsigned char *pbyAddr, u32 *pdwKey, unsigned char byLocalID); void MACvDisableKeyEntry(void __iomem *dwIoBase, unsigned int uEntryIdx); -void MACvSetDefaultKeyEntry(void __iomem *dwIoBase, unsigned int uKeyLen, - unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID); -void MACvDisableDefaultKey(void __iomem *dwIoBase); -void MACvSetDefaultTKIPKeyEntry(void __iomem *dwIoBase, unsigned int uKeyLen, - unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID); -void MACvSetDefaultKeyCtl(void __iomem *dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx, unsigned char byLocalID); #endif // __MAC_H__ diff --git a/drivers/staging/vt6655/mib.c b/drivers/staging/vt6655/mib.c index 111c01877086..d2f351d19ff8 100644 --- a/drivers/staging/vt6655/mib.c +++ b/drivers/staging/vt6655/mib.c @@ -25,24 +25,15 @@ * Date: May 21, 1996 * * Functions: - * STAvClearAllCounter - Clear All MIB Counter * STAvUpdateIstStatCounter - Update ISR statistic counter - * STAvUpdateRDStatCounter - Update Rx statistic counter - * STAvUpdateRDStatCounterEx - Update Rx statistic counter and copy rcv data - * STAvUpdateTDStatCounter - Update Tx statistic counter - * STAvUpdateTDStatCounterEx - Update Tx statistic counter and copy tx data * STAvUpdate802_11Counter - Update 802.11 mib counter * * Revision History: * */ -#include "upc.h" #include "mac.h" -#include "tether.h" #include "mib.h" -#include "wctl.h" -#include "baseband.h" /*--------------------- Static Classes ----------------------------*/ @@ -55,24 +46,6 @@ /*--------------------- Export Functions --------------------------*/ /* - * Description: Clear All Statistic Counter - * - * Parameters: - * In: - * pStatistic - Pointer to Statistic Counter Data Structure - * Out: - * none - * - * Return Value: none - * - */ -void STAvClearAllCounter(PSStatCounter pStatistic) -{ - // set memory to zero - memset(pStatistic, 0, sizeof(SStatCounter)); -} - -/* * Description: Update Isr Statistic Counter * * Parameters: @@ -139,373 +112,6 @@ void STAvUpdateIsrStatCounter(PSStatCounter pStatistic, unsigned long dwIsr) } /* - * Description: Update Rx Statistic Counter - * - * Parameters: - * In: - * pStatistic - Pointer to Statistic Counter Data Structure - * byRSR - Rx Status - * byNewRSR - Rx Status - * pbyBuffer - Rx Buffer - * cbFrameLength - Rx Length - * Out: - * none - * - * Return Value: none - * - */ -void STAvUpdateRDStatCounter(PSStatCounter pStatistic, - unsigned char byRSR, unsigned char byNewRSR, unsigned char byRxRate, - unsigned char *pbyBuffer, unsigned int cbFrameLength) -{ - //need change - PS802_11Header pHeader = (PS802_11Header)pbyBuffer; - - if (byRSR & RSR_ADDROK) - pStatistic->dwRsrADDROk++; - if (byRSR & RSR_CRCOK) { - pStatistic->dwRsrCRCOk++; - - pStatistic->ullRsrOK++; - - if (cbFrameLength >= ETH_ALEN) { - // update counters in case of successful transmit - if (byRSR & RSR_ADDRBROAD) { - pStatistic->ullRxBroadcastFrames++; - pStatistic->ullRxBroadcastBytes += (unsigned long long) cbFrameLength; - } else if (byRSR & RSR_ADDRMULTI) { - pStatistic->ullRxMulticastFrames++; - pStatistic->ullRxMulticastBytes += (unsigned long long) cbFrameLength; - } else { - pStatistic->ullRxDirectedFrames++; - pStatistic->ullRxDirectedBytes += (unsigned long long) cbFrameLength; - } - } - } - - if (byRxRate == 22) { - pStatistic->CustomStat.ullRsr11M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr11MCRCOk++; - - pr_debug("11M: ALL[%d], OK[%d]:[%02x]\n", - (int)pStatistic->CustomStat.ullRsr11M, - (int)pStatistic->CustomStat.ullRsr11MCRCOk, byRSR); - } else if (byRxRate == 11) { - pStatistic->CustomStat.ullRsr5M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr5MCRCOk++; - - pr_debug(" 5M: ALL[%d], OK[%d]:[%02x]\n", - (int)pStatistic->CustomStat.ullRsr5M, - (int)pStatistic->CustomStat.ullRsr5MCRCOk, byRSR); - } else if (byRxRate == 4) { - pStatistic->CustomStat.ullRsr2M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr2MCRCOk++; - - pr_debug(" 2M: ALL[%d], OK[%d]:[%02x]\n", - (int)pStatistic->CustomStat.ullRsr2M, - (int)pStatistic->CustomStat.ullRsr2MCRCOk, byRSR); - } else if (byRxRate == 2) { - pStatistic->CustomStat.ullRsr1M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr1MCRCOk++; - - pr_debug(" 1M: ALL[%d], OK[%d]:[%02x]\n", - (int)pStatistic->CustomStat.ullRsr1M, - (int)pStatistic->CustomStat.ullRsr1MCRCOk, byRSR); - } else if (byRxRate == 12) { - pStatistic->CustomStat.ullRsr6M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr6MCRCOk++; - - pr_debug(" 6M: ALL[%d], OK[%d]\n", - (int)pStatistic->CustomStat.ullRsr6M, - (int)pStatistic->CustomStat.ullRsr6MCRCOk); - } else if (byRxRate == 18) { - pStatistic->CustomStat.ullRsr9M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr9MCRCOk++; - - pr_debug(" 9M: ALL[%d], OK[%d]\n", - (int)pStatistic->CustomStat.ullRsr9M, - (int)pStatistic->CustomStat.ullRsr9MCRCOk); - } else if (byRxRate == 24) { - pStatistic->CustomStat.ullRsr12M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr12MCRCOk++; - - pr_debug("12M: ALL[%d], OK[%d]\n", - (int)pStatistic->CustomStat.ullRsr12M, - (int)pStatistic->CustomStat.ullRsr12MCRCOk); - } else if (byRxRate == 36) { - pStatistic->CustomStat.ullRsr18M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr18MCRCOk++; - - pr_debug("18M: ALL[%d], OK[%d]\n", - (int)pStatistic->CustomStat.ullRsr18M, - (int)pStatistic->CustomStat.ullRsr18MCRCOk); - } else if (byRxRate == 48) { - pStatistic->CustomStat.ullRsr24M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr24MCRCOk++; - - pr_debug("24M: ALL[%d], OK[%d]\n", - (int)pStatistic->CustomStat.ullRsr24M, - (int)pStatistic->CustomStat.ullRsr24MCRCOk); - } else if (byRxRate == 72) { - pStatistic->CustomStat.ullRsr36M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr36MCRCOk++; - - pr_debug("36M: ALL[%d], OK[%d]\n", - (int)pStatistic->CustomStat.ullRsr36M, - (int)pStatistic->CustomStat.ullRsr36MCRCOk); - } else if (byRxRate == 96) { - pStatistic->CustomStat.ullRsr48M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr48MCRCOk++; - - pr_debug("48M: ALL[%d], OK[%d]\n", - (int)pStatistic->CustomStat.ullRsr48M, - (int)pStatistic->CustomStat.ullRsr48MCRCOk); - } else if (byRxRate == 108) { - pStatistic->CustomStat.ullRsr54M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr54MCRCOk++; - - pr_debug("54M: ALL[%d], OK[%d]\n", - (int)pStatistic->CustomStat.ullRsr54M, - (int)pStatistic->CustomStat.ullRsr54MCRCOk); - } else { - pr_debug("Unknown: Total[%d], CRCOK[%d]\n", - (int)pStatistic->dwRsrRxPacket+1, - (int)pStatistic->dwRsrCRCOk); - } - - if (byRSR & RSR_BSSIDOK) - pStatistic->dwRsrBSSIDOk++; - - if (byRSR & RSR_BCNSSIDOK) - pStatistic->dwRsrBCNSSIDOk++; - if (byRSR & RSR_IVLDLEN) //invalid len (> 2312 byte) - pStatistic->dwRsrLENErr++; - if (byRSR & RSR_IVLDTYP) //invalid packet type - pStatistic->dwRsrTYPErr++; - if (byRSR & (RSR_IVLDTYP | RSR_IVLDLEN)) - pStatistic->dwRsrErr++; - - if (byNewRSR & NEWRSR_DECRYPTOK) - pStatistic->dwNewRsrDECRYPTOK++; - if (byNewRSR & NEWRSR_CFPIND) - pStatistic->dwNewRsrCFP++; - if (byNewRSR & NEWRSR_HWUTSF) - pStatistic->dwNewRsrUTSF++; - if (byNewRSR & NEWRSR_BCNHITAID) - pStatistic->dwNewRsrHITAID++; - if (byNewRSR & NEWRSR_BCNHITAID0) - pStatistic->dwNewRsrHITAID0++; - - // increase rx packet count - pStatistic->dwRsrRxPacket++; - pStatistic->dwRsrRxOctet += cbFrameLength; - - if (IS_TYPE_DATA(pbyBuffer)) - pStatistic->dwRsrRxData++; - else if (IS_TYPE_MGMT(pbyBuffer)) - pStatistic->dwRsrRxManage++; - else if (IS_TYPE_CONTROL(pbyBuffer)) - pStatistic->dwRsrRxControl++; - - if (byRSR & RSR_ADDRBROAD) - pStatistic->dwRsrBroadcast++; - else if (byRSR & RSR_ADDRMULTI) - pStatistic->dwRsrMulticast++; - else - pStatistic->dwRsrDirected++; - - if (WLAN_GET_FC_MOREFRAG(pHeader->wFrameCtl)) - pStatistic->dwRsrRxFragment++; - - if (cbFrameLength < ETH_ZLEN + 4) - pStatistic->dwRsrRunt++; - else if (cbFrameLength == ETH_ZLEN + 4) - pStatistic->dwRsrRxFrmLen64++; - else if ((65 <= cbFrameLength) && (cbFrameLength <= 127)) - pStatistic->dwRsrRxFrmLen65_127++; - else if ((128 <= cbFrameLength) && (cbFrameLength <= 255)) - pStatistic->dwRsrRxFrmLen128_255++; - else if ((256 <= cbFrameLength) && (cbFrameLength <= 511)) - pStatistic->dwRsrRxFrmLen256_511++; - else if ((512 <= cbFrameLength) && (cbFrameLength <= 1023)) - pStatistic->dwRsrRxFrmLen512_1023++; - else if ((1024 <= cbFrameLength) && (cbFrameLength <= ETH_FRAME_LEN + 4)) - pStatistic->dwRsrRxFrmLen1024_1518++; - else if (cbFrameLength > ETH_FRAME_LEN + 4) - pStatistic->dwRsrLong++; -} - -/* - * Description: Update Rx Statistic Counter and copy Rx buffer - * - * Parameters: - * In: - * pStatistic - Pointer to Statistic Counter Data Structure - * byRSR - Rx Status - * byNewRSR - Rx Status - * pbyBuffer - Rx Buffer - * cbFrameLength - Rx Length - * Out: - * none - * - * Return Value: none - * - */ - -void -STAvUpdateRDStatCounterEx( - PSStatCounter pStatistic, - unsigned char byRSR, - unsigned char byNewRSR, - unsigned char byRxRate, - unsigned char *pbyBuffer, - unsigned int cbFrameLength -) -{ - STAvUpdateRDStatCounter( - pStatistic, - byRSR, - byNewRSR, - byRxRate, - pbyBuffer, - cbFrameLength -); - - // rx length - pStatistic->dwCntRxFrmLength = cbFrameLength; - // rx pattern, we just see 10 bytes for sample - memcpy(pStatistic->abyCntRxPattern, (unsigned char *)pbyBuffer, 10); -} - -/* - * Description: Update Tx Statistic Counter - * - * Parameters: - * In: - * pStatistic - Pointer to Statistic Counter Data Structure - * byTSR0 - Tx Status - * byTSR1 - Tx Status - * pbyBuffer - Tx Buffer - * cbFrameLength - Tx Length - * uIdx - Index of Tx DMA - * Out: - * none - * - * Return Value: none - * - */ -void -STAvUpdateTDStatCounter( - PSStatCounter pStatistic, - unsigned char byTSR0, - unsigned char byTSR1, - unsigned char *pbyBuffer, - unsigned int cbFrameLength, - unsigned int uIdx -) -{ - PWLAN_80211HDR_A4 pHeader; - unsigned char *pbyDestAddr; - unsigned char byTSR0_NCR = byTSR0 & TSR0_NCR; - - pHeader = (PWLAN_80211HDR_A4) pbyBuffer; - if (WLAN_GET_FC_TODS(pHeader->wFrameCtl) == 0) - pbyDestAddr = &(pHeader->abyAddr1[0]); - else - pbyDestAddr = &(pHeader->abyAddr3[0]); - - // increase tx packet count - pStatistic->dwTsrTxPacket[uIdx]++; - pStatistic->dwTsrTxOctet[uIdx] += cbFrameLength; - - if (byTSR0_NCR != 0) { - pStatistic->dwTsrRetry[uIdx]++; - pStatistic->dwTsrTotalRetry[uIdx] += byTSR0_NCR; - - if (byTSR0_NCR == 1) - pStatistic->dwTsrOnceRetry[uIdx]++; - else - pStatistic->dwTsrMoreThanOnceRetry[uIdx]++; - } - - if ((byTSR1&(TSR1_TERR|TSR1_RETRYTMO|TSR1_TMO|ACK_DATA)) == 0) { - pStatistic->ullTsrOK[uIdx]++; - pStatistic->CustomStat.ullTsrAllOK = - (pStatistic->ullTsrOK[TYPE_AC0DMA] + pStatistic->ullTsrOK[TYPE_TXDMA0]); - // update counters in case that successful transmit - if (is_broadcast_ether_addr(pbyDestAddr)) { - pStatistic->ullTxBroadcastFrames[uIdx]++; - pStatistic->ullTxBroadcastBytes[uIdx] += (unsigned long long) cbFrameLength; - } else if (is_multicast_ether_addr(pbyDestAddr)) { - pStatistic->ullTxMulticastFrames[uIdx]++; - pStatistic->ullTxMulticastBytes[uIdx] += (unsigned long long) cbFrameLength; - } else { - pStatistic->ullTxDirectedFrames[uIdx]++; - pStatistic->ullTxDirectedBytes[uIdx] += (unsigned long long) cbFrameLength; - } - } else { - if (byTSR1 & TSR1_TERR) - pStatistic->dwTsrErr[uIdx]++; - if (byTSR1 & TSR1_RETRYTMO) - pStatistic->dwTsrRetryTimeout[uIdx]++; - if (byTSR1 & TSR1_TMO) - pStatistic->dwTsrTransmitTimeout[uIdx]++; - if (byTSR1 & ACK_DATA) - pStatistic->dwTsrACKData[uIdx]++; - } - - if (is_broadcast_ether_addr(pbyDestAddr)) - pStatistic->dwTsrBroadcast[uIdx]++; - else if (is_multicast_ether_addr(pbyDestAddr)) - pStatistic->dwTsrMulticast[uIdx]++; - else - pStatistic->dwTsrDirected[uIdx]++; -} - -/* - * Description: Update Tx Statistic Counter and copy Tx buffer - * - * Parameters: - * In: - * pStatistic - Pointer to Statistic Counter Data Structure - * pbyBuffer - Tx Buffer - * cbFrameLength - Tx Length - * Out: - * none - * - * Return Value: none - * - */ -void -STAvUpdateTDStatCounterEx( - PSStatCounter pStatistic, - unsigned char *pbyBuffer, - unsigned long cbFrameLength -) -{ - unsigned int uPktLength; - - uPktLength = (unsigned int)cbFrameLength; - - // tx length - pStatistic->dwCntTxBufLength = uPktLength; - // tx pattern, we just see 16 bytes for sample - memcpy(pStatistic->abyCntTxPattern, pbyBuffer, 16); -} - -/* * Description: Update 802.11 mib counter * * Parameters: @@ -526,37 +132,8 @@ STAvUpdate802_11Counter( unsigned long dwCounter ) { - p802_11Counter->MulticastTransmittedFrameCount = (unsigned long long) (pStatistic->dwTsrBroadcast[TYPE_AC0DMA] + - pStatistic->dwTsrBroadcast[TYPE_TXDMA0] + - pStatistic->dwTsrMulticast[TYPE_AC0DMA] + - pStatistic->dwTsrMulticast[TYPE_TXDMA0]); - p802_11Counter->FailedCount = (unsigned long long) (pStatistic->dwTsrErr[TYPE_AC0DMA] + pStatistic->dwTsrErr[TYPE_TXDMA0]); - p802_11Counter->RetryCount = (unsigned long long) (pStatistic->dwTsrRetry[TYPE_AC0DMA] + pStatistic->dwTsrRetry[TYPE_TXDMA0]); - p802_11Counter->MultipleRetryCount = (unsigned long long) (pStatistic->dwTsrMoreThanOnceRetry[TYPE_AC0DMA] + - pStatistic->dwTsrMoreThanOnceRetry[TYPE_TXDMA0]); p802_11Counter->RTSSuccessCount += (unsigned long long) (dwCounter & 0x000000ff); p802_11Counter->RTSFailureCount += (unsigned long long) ((dwCounter & 0x0000ff00) >> 8); p802_11Counter->ACKFailureCount += (unsigned long long) ((dwCounter & 0x00ff0000) >> 16); p802_11Counter->FCSErrorCount += (unsigned long long) ((dwCounter & 0xff000000) >> 24); - p802_11Counter->MulticastReceivedFrameCount = (unsigned long long) (pStatistic->dwRsrBroadcast + - pStatistic->dwRsrMulticast); -} - -/* - * Description: Clear 802.11 mib counter - * - * Parameters: - * In: - * p802_11Counter - Pointer to 802.11 mib counter - * Out: - * none - * - * Return Value: none - * - */ -void -STAvClear802_11Counter(PSDot11Counters p802_11Counter) -{ - // set memory to zero - memset(p802_11Counter, 0, sizeof(SDot11Counters)); } diff --git a/drivers/staging/vt6655/mib.h b/drivers/staging/vt6655/mib.h index 732bddaf5b91..5cb59b8a1c7c 100644 --- a/drivers/staging/vt6655/mib.h +++ b/drivers/staging/vt6655/mib.h @@ -29,8 +29,6 @@ #ifndef __MIB_H__ #define __MIB_H__ -#include "ttype.h" -#include "tether.h" #include "desc.h" // @@ -38,136 +36,16 @@ // typedef struct tagSDot11Counters { - unsigned long Length; - unsigned long long TransmittedFragmentCount; - unsigned long long MulticastTransmittedFrameCount; - unsigned long long FailedCount; - unsigned long long RetryCount; - unsigned long long MultipleRetryCount; unsigned long long RTSSuccessCount; unsigned long long RTSFailureCount; unsigned long long ACKFailureCount; - unsigned long long FrameDuplicateCount; - unsigned long long ReceivedFragmentCount; - unsigned long long MulticastReceivedFrameCount; unsigned long long FCSErrorCount; - unsigned long long TKIPLocalMICFailures; - unsigned long long TKIPRemoteMICFailures; - unsigned long long TKIPICVErrors; - unsigned long long TKIPCounterMeasuresInvoked; - unsigned long long TKIPReplays; - unsigned long long CCMPFormatErrors; - unsigned long long CCMPReplays; - unsigned long long CCMPDecryptErrors; - unsigned long long FourWayHandshakeFailures; } SDot11Counters, *PSDot11Counters; // -// MIB2 counter -// -typedef struct tagSMib2Counter { - long ifIndex; - char ifDescr[256]; - long ifType; - long ifMtu; - unsigned long ifSpeed; - unsigned char ifPhysAddress[ETH_ALEN]; - long ifAdminStatus; - long ifOperStatus; - unsigned long ifLastChange; - unsigned long ifInOctets; - unsigned long ifInUcastPkts; - unsigned long ifInNUcastPkts; - unsigned long ifInDiscards; - unsigned long ifInErrors; - unsigned long ifInUnknownProtos; - unsigned long ifOutOctets; - unsigned long ifOutUcastPkts; - unsigned long ifOutNUcastPkts; - unsigned long ifOutDiscards; - unsigned long ifOutErrors; - unsigned long ifOutQLen; - unsigned long ifSpecific; -} SMib2Counter, *PSMib2Counter; - -// Value in the ifType entry -#define WIRELESSLANIEEE80211b 6 - -// Value in the ifAdminStatus/ifOperStatus entry -#define UP 1 -#define DOWN 2 -#define TESTING 3 - -// -// RMON counter -// -typedef struct tagSRmonCounter { - long etherStatsIndex; - unsigned long etherStatsDataSource; - unsigned long etherStatsDropEvents; - unsigned long etherStatsOctets; - unsigned long etherStatsPkts; - unsigned long etherStatsBroadcastPkts; - unsigned long etherStatsMulticastPkts; - unsigned long etherStatsCRCAlignErrors; - unsigned long etherStatsUndersizePkts; - unsigned long etherStatsOversizePkts; - unsigned long etherStatsFragments; - unsigned long etherStatsJabbers; - unsigned long etherStatsCollisions; - unsigned long etherStatsPkt64Octets; - unsigned long etherStatsPkt65to127Octets; - unsigned long etherStatsPkt128to255Octets; - unsigned long etherStatsPkt256to511Octets; - unsigned long etherStatsPkt512to1023Octets; - unsigned long etherStatsPkt1024to1518Octets; - unsigned long etherStatsOwners; - unsigned long etherStatsStatus; -} SRmonCounter, *PSRmonCounter; - -// -// Custom counter -// -typedef struct tagSCustomCounters { - unsigned long Length; - - unsigned long long ullTsrAllOK; - - unsigned long long ullRsr11M; - unsigned long long ullRsr5M; - unsigned long long ullRsr2M; - unsigned long long ullRsr1M; - - unsigned long long ullRsr11MCRCOk; - unsigned long long ullRsr5MCRCOk; - unsigned long long ullRsr2MCRCOk; - unsigned long long ullRsr1MCRCOk; - - unsigned long long ullRsr54M; - unsigned long long ullRsr48M; - unsigned long long ullRsr36M; - unsigned long long ullRsr24M; - unsigned long long ullRsr18M; - unsigned long long ullRsr12M; - unsigned long long ullRsr9M; - unsigned long long ullRsr6M; - - unsigned long long ullRsr54MCRCOk; - unsigned long long ullRsr48MCRCOk; - unsigned long long ullRsr36MCRCOk; - unsigned long long ullRsr24MCRCOk; - unsigned long long ullRsr18MCRCOk; - unsigned long long ullRsr12MCRCOk; - unsigned long long ullRsr9MCRCOk; - unsigned long long ullRsr6MCRCOk; -} SCustomCounters, *PSCustomCounters; - -// // Custom counter // typedef struct tagSISRCounters { - unsigned long Length; - unsigned long dwIsrTx0OK; unsigned long dwIsrAC0TxOK; unsigned long dwIsrBeaconTxOK; @@ -183,161 +61,22 @@ typedef struct tagSISRCounters { unsigned long dwIsrUnknown; unsigned long dwIsrRx1OK; - unsigned long dwIsrATIMTxOK; - unsigned long dwIsrSYNCTxOK; - unsigned long dwIsrCFPEnd; - unsigned long dwIsrATIMEnd; - unsigned long dwIsrSYNCFlushOK; unsigned long dwIsrSTIMER1Int; } SISRCounters, *PSISRCounters; -// Value in the etherStatsStatus entry -#define VALID 1 -#define CREATE_REQUEST 2 -#define UNDER_CREATION 3 -#define INVALID 4 - // // statistic counter // typedef struct tagSStatCounter { - // RSR status count - // - unsigned long dwRsrFrmAlgnErr; - unsigned long dwRsrErr; - unsigned long dwRsrCRCErr; - unsigned long dwRsrCRCOk; - unsigned long dwRsrBSSIDOk; - unsigned long dwRsrADDROk; - unsigned long dwRsrBCNSSIDOk; - unsigned long dwRsrLENErr; - unsigned long dwRsrTYPErr; - - unsigned long dwNewRsrDECRYPTOK; - unsigned long dwNewRsrCFP; - unsigned long dwNewRsrUTSF; - unsigned long dwNewRsrHITAID; - unsigned long dwNewRsrHITAID0; - - unsigned long dwRsrLong; - unsigned long dwRsrRunt; - - unsigned long dwRsrRxControl; - unsigned long dwRsrRxData; - unsigned long dwRsrRxManage; - - unsigned long dwRsrRxPacket; - unsigned long dwRsrRxOctet; - unsigned long dwRsrBroadcast; - unsigned long dwRsrMulticast; - unsigned long dwRsrDirected; - // 64-bit OID - unsigned long long ullRsrOK; - - // for some optional OIDs (64 bits) and DMI support - unsigned long long ullRxBroadcastBytes; - unsigned long long ullRxMulticastBytes; - unsigned long long ullRxDirectedBytes; - unsigned long long ullRxBroadcastFrames; - unsigned long long ullRxMulticastFrames; - unsigned long long ullRxDirectedFrames; - - unsigned long dwRsrRxFragment; - unsigned long dwRsrRxFrmLen64; - unsigned long dwRsrRxFrmLen65_127; - unsigned long dwRsrRxFrmLen128_255; - unsigned long dwRsrRxFrmLen256_511; - unsigned long dwRsrRxFrmLen512_1023; - unsigned long dwRsrRxFrmLen1024_1518; - - // TSR status count - // - unsigned long dwTsrTotalRetry[TYPE_MAXTD]; // total collision retry count - unsigned long dwTsrOnceRetry[TYPE_MAXTD]; // this packet only occur one collision - unsigned long dwTsrMoreThanOnceRetry[TYPE_MAXTD]; // this packet occur more than one collision - unsigned long dwTsrRetry[TYPE_MAXTD]; // this packet has ever occur collision, - // that is (dwTsrOnceCollision0 + dwTsrMoreThanOnceCollision0) - unsigned long dwTsrACKData[TYPE_MAXTD]; - unsigned long dwTsrErr[TYPE_MAXTD]; - unsigned long dwAllTsrOK[TYPE_MAXTD]; - unsigned long dwTsrRetryTimeout[TYPE_MAXTD]; - unsigned long dwTsrTransmitTimeout[TYPE_MAXTD]; - - unsigned long dwTsrTxPacket[TYPE_MAXTD]; - unsigned long dwTsrTxOctet[TYPE_MAXTD]; - unsigned long dwTsrBroadcast[TYPE_MAXTD]; - unsigned long dwTsrMulticast[TYPE_MAXTD]; - unsigned long dwTsrDirected[TYPE_MAXTD]; - - // RD/TD count - unsigned long dwCntRxFrmLength; - unsigned long dwCntTxBufLength; - - unsigned char abyCntRxPattern[16]; - unsigned char abyCntTxPattern[16]; - - // Software check.... - unsigned long dwCntRxDataErr; // rx buffer data software compare CRC err count - unsigned long dwCntDecryptErr; // rx buffer data software compare CRC err count - unsigned long dwCntRxICVErr; // rx buffer data software compare CRC err count - unsigned int idxRxErrorDesc[TYPE_MAXRD]; // index for rx data error RD - - // 64-bit OID - unsigned long long ullTsrOK[TYPE_MAXTD]; - - // for some optional OIDs (64 bits) and DMI support - unsigned long long ullTxBroadcastFrames[TYPE_MAXTD]; - unsigned long long ullTxMulticastFrames[TYPE_MAXTD]; - unsigned long long ullTxDirectedFrames[TYPE_MAXTD]; - unsigned long long ullTxBroadcastBytes[TYPE_MAXTD]; - unsigned long long ullTxMulticastBytes[TYPE_MAXTD]; - unsigned long long ullTxDirectedBytes[TYPE_MAXTD]; - SISRCounters ISRStat; - - SCustomCounters CustomStat; - -#ifdef Calcu_LinkQual - //Tx count: - unsigned long TxNoRetryOkCount; - unsigned long TxRetryOkCount; - unsigned long TxFailCount; - //Rx count: - unsigned long RxOkCnt; - unsigned long RxFcsErrCnt; - //statistic - unsigned long SignalStren; - unsigned long LinkQuality; -#endif } SStatCounter, *PSStatCounter; -void STAvClearAllCounter(PSStatCounter pStatistic); - void STAvUpdateIsrStatCounter(PSStatCounter pStatistic, unsigned long dwIsr); -void STAvUpdateRDStatCounter(PSStatCounter pStatistic, - unsigned char byRSR, unsigned char byNewRSR, unsigned char byRxRate, - unsigned char *pbyBuffer, unsigned int cbFrameLength); - -void STAvUpdateRDStatCounterEx(PSStatCounter pStatistic, - unsigned char byRSR, unsigned char byNewRsr, unsigned char byRxRate, - unsigned char *pbyBuffer, unsigned int cbFrameLength); - -void STAvUpdateTDStatCounter(PSStatCounter pStatistic, unsigned char byTSR0, unsigned char byTSR1, - unsigned char *pbyBuffer, unsigned int cbFrameLength, unsigned int uIdx); - -void STAvUpdateTDStatCounterEx( - PSStatCounter pStatistic, - unsigned char *pbyBuffer, - unsigned long cbFrameLength -); - void STAvUpdate802_11Counter( PSDot11Counters p802_11Counter, PSStatCounter pStatistic, unsigned long dwCounter ); -void STAvClear802_11Counter(PSDot11Counters p802_11Counter); - #endif // __MIB_H__ diff --git a/drivers/staging/vt6655/michael.c b/drivers/staging/vt6655/michael.c deleted file mode 100644 index edee48777aac..000000000000 --- a/drivers/staging/vt6655/michael.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: michael.cpp - * - * Purpose: The implementation of LIST data structure. - * - * Author: Kyle Hsu - * - * Date: Sep 4, 2002 - * - * Functions: - * s_dwGetUINT32 - Convert from unsigned char [] to unsigned long in a portable way - * s_vPutUINT32 - Convert from unsigned long to unsigned char [] in a portable way - * s_vClear - Reset the state to the empty message. - * s_vSetKey - Set the key. - * MIC_vInit - Set the key. - * s_vAppendByte - Append the byte to our word-sized buffer. - * MIC_vAppend - call s_vAppendByte. - * MIC_vGetMIC - Append the minimum padding and call s_vAppendByte. - * - * Revision History: - * - */ - -#include "tmacro.h" -#include "michael.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -static void s_vClear(void); // Clear the internal message, -// resets the object to the state just after construction. -static void s_vSetKey(u32 dwK0, u32 dwK1); -static void s_vAppendByte(unsigned char b); // Add a single byte to the internal message - -/*--------------------- Export Variables --------------------------*/ -static u32 L, R; /* Current state */ - -static u32 K0, K1; /* Key */ -static u32 M; /* Message accumulator (single word) */ -static unsigned int nBytesInM; // # bytes in M - -/*--------------------- Export Functions --------------------------*/ - -static void s_vClear(void) -{ - // Reset the state to the empty message. - L = K0; - R = K1; - nBytesInM = 0; - M = 0; -} - -static void s_vSetKey(u32 dwK0, u32 dwK1) -{ - // Set the key - K0 = dwK0; - K1 = dwK1; - // and reset the message - s_vClear(); -} - -static void s_vAppendByte(unsigned char b) -{ - // Append the byte to our word-sized buffer - M |= b << (8*nBytesInM); - nBytesInM++; - // Process the word if it is full. - if (nBytesInM >= 4) { - L ^= M; - R ^= ROL32(L, 17); - L += R; - R ^= ((L & 0xff00ff00) >> 8) | ((L & 0x00ff00ff) << 8); - L += R; - R ^= ROL32(L, 3); - L += R; - R ^= ROR32(L, 2); - L += R; - // Clear the buffer - M = 0; - nBytesInM = 0; - } -} - -void MIC_vInit(u32 dwK0, u32 dwK1) -{ - // Set the key - s_vSetKey(dwK0, dwK1); -} - -void MIC_vUnInit(void) -{ - // Wipe the key material - K0 = 0; - K1 = 0; - - // And the other fields as well. - //Note that this sets (L,R) to (K0,K1) which is just fine. - s_vClear(); -} - -void MIC_vAppend(unsigned char *src, unsigned int nBytes) -{ - // This is simple - while (nBytes > 0) { - s_vAppendByte(*src++); - nBytes--; - } -} - -void MIC_vGetMIC(u32 *pdwL, u32 *pdwR) -{ - // Append the minimum padding - s_vAppendByte(0x5a); - s_vAppendByte(0); - s_vAppendByte(0); - s_vAppendByte(0); - s_vAppendByte(0); - // and then zeroes until the length is a multiple of 4 - while (nBytesInM != 0) - s_vAppendByte(0); - - // The s_vAppendByte function has already computed the result. - *pdwL = L; - *pdwR = R; - // Reset to the empty message. - s_vClear(); -} diff --git a/drivers/staging/vt6655/michael.h b/drivers/staging/vt6655/michael.h deleted file mode 100644 index 86cb140e3087..000000000000 --- a/drivers/staging/vt6655/michael.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: Michael.h - * - * Purpose: Reference implementation for Michael - * written by Niels Ferguson - * - * Author: Kyle Hsu - * - * Date: Jan 2, 2003 - * - */ - -#ifndef __MICHAEL_H__ -#define __MICHAEL_H__ - -#include <linux/types.h> - -void MIC_vInit(u32 dwK0, u32 dwK1); - -void MIC_vUnInit(void); - -/* Append bytes to the message to be MICed */ -void MIC_vAppend(unsigned char *src, unsigned int nBytes); - -/* Get the MIC result. Destination should accept 8 bytes of result. */ -/* This also resets the message to empty. */ -void MIC_vGetMIC(u32 *pdwL, u32 *pdwR); - -/* Rotation functions on 32 bit values */ -#define ROL32(A, n) \ - (((A) << (n)) | (((A)>>(32-(n))) & ((1UL << (n)) - 1))) -#define ROR32(A, n) ROL32((A), 32-(n)) - -#endif /*__MICHAEL_H__ */ diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c index 08241b917777..e826f07e91c0 100644 --- a/drivers/staging/vt6655/power.c +++ b/drivers/staging/vt6655/power.c @@ -37,13 +37,9 @@ * */ -#include "ttype.h" #include "mac.h" #include "device.h" -#include "wmgr.h" #include "power.h" -#include "wcmd.h" -#include "rxtx.h" #include "card.h" /*--------------------- Static Definitions -------------------------*/ @@ -73,8 +69,7 @@ PSvEnablePowerSaving( ) { struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned short wAID = pMgmt->wCurrAID | BIT14 | BIT15; + u16 wAID = pDevice->current_aid | BIT(14) | BIT(15); // set period of power up before TBTT VNSvOutPortW(pDevice->PortOffset + MAC_REG_PWBT, C_PWBT); @@ -83,7 +78,9 @@ PSvEnablePowerSaving( VNSvOutPortW(pDevice->PortOffset + MAC_REG_AIDATIM, wAID); } else { // set ATIM Window +#if 0 /* TODO atim window */ MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow); +#endif } // Set AutoSleep MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); @@ -95,22 +92,15 @@ PSvEnablePowerSaving( MACvRegBitsOff(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN); // first time set listen next beacon MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN); - pMgmt->wCountToWakeUp = wListenInterval; } else { // always listen beacon MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN); - pMgmt->wCountToWakeUp = 0; } // enable power saving hw function MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN); pDevice->bEnablePSMode = true; - /* We don't send null pkt in ad hoc mode since beacon will handle this. */ - if (pDevice->op_mode != NL80211_IFTYPE_ADHOC && - pDevice->op_mode == NL80211_IFTYPE_STATION) - PSbSendNullPacket(pDevice); - pDevice->bPWBitOn = true; pr_debug("PS:Power Saving Mode Enable...\n"); } @@ -143,182 +133,9 @@ PSvDisablePowerSaving( pDevice->bEnablePSMode = false; - if (pDevice->op_mode == NL80211_IFTYPE_STATION) - PSbSendNullPacket(pDevice); - pDevice->bPWBitOn = false; } -/*+ - * - * Routine Description: - * Consider to power down when no more packets to tx or rx. - * - * Return Value: - * true, if power down success - * false, if fail - -*/ - -bool -PSbConsiderPowerDown( - void *hDeviceContext, - bool bCheckRxDMA, - bool bCheckCountToWakeUp -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int uIdx; - - // check if already in Doze mode - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) - return true; - - if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { - // check if in TIM wake period - if (pMgmt->bInTIMWake) - return false; - } - - // check scan state - if (pDevice->bCmdRunning) - return false; - - // Force PSEN on - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN); - - // check if all TD are empty, - for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx++) { - if (pDevice->iTDUsed[uIdx] != 0) - return false; - } - - // check if rx isr is clear - if (bCheckRxDMA && - ((pDevice->dwIsr & ISR_RXDMA0) != 0) && - ((pDevice->dwIsr & ISR_RXDMA1) != 0)) { - return false; - } - - if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { - if (bCheckCountToWakeUp && - (pMgmt->wCountToWakeUp == 0 || pMgmt->wCountToWakeUp == 1)) { - return false; - } - } - - // no Tx, no Rx isr, now go to Doze - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_GO2DOZE); - pr_debug("Go to Doze ZZZZZZZZZZZZZZZ\n"); - return true; -} - -/*+ - * - * Routine Description: - * Send PS-POLL packet - * - * Return Value: - * None. - * - -*/ - -void -PSvSendPSPOLL( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - PSTxMgmtPacket pTxPacket = NULL; - - memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_HDR_ADDR2_LEN); - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool; - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - pTxPacket->p80211Header->sA2.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_CTL) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PSPOLL) | - WLAN_SET_FC_PWRMGT(0) -)); - pTxPacket->p80211Header->sA2.wDurationID = pMgmt->wCurrAID | BIT14 | BIT15; - memcpy(pTxPacket->p80211Header->sA2.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); - memcpy(pTxPacket->p80211Header->sA2.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - pTxPacket->cbMPDULen = WLAN_HDR_ADDR2_LEN; - pTxPacket->cbPayloadLen = 0; - // send the frame - if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) - pr_debug("Send PS-Poll packet failed..\n"); -} - -/*+ - * - * Routine Description: - * Send NULL packet to AP for notification power state of STA - * - * Return Value: - * None. - * - -*/ -bool -PSbSendNullPacket( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSTxMgmtPacket pTxPacket = NULL; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int uIdx; - - if (!pDevice->bLinkPass) - return false; - - if (!pDevice->bEnablePSMode && !pDevice->fTxDataInSleep) - return false; - - if (pDevice->bEnablePSMode) { - for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx++) { - if (pDevice->iTDUsed[uIdx] != 0) - return false; - } - } - - memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_NULLDATA_FR_MAXLEN); - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool; - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - - if (pDevice->bEnablePSMode) { - pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) | - WLAN_SET_FC_PWRMGT(1) -)); - } else { - pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) | - WLAN_SET_FC_PWRMGT(0) -)); - } - - if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) - pTxPacket->p80211Header->sA3.wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_TODS(1)); - - memcpy(pTxPacket->p80211Header->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); - memcpy(pTxPacket->p80211Header->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(pTxPacket->p80211Header->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - pTxPacket->cbMPDULen = WLAN_HDR_ADDR3_LEN; - pTxPacket->cbPayloadLen = 0; - // send the frame - if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { - pr_debug("Send Null Packet failed !\n"); - return false; - } - - return true; -} /*+ * @@ -336,21 +153,14 @@ PSbIsNextTBTTWakeUp( ) { struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; + struct ieee80211_hw *hw = pDevice->hw; + struct ieee80211_conf *conf = &hw->conf; bool bWakeUp = false; - if (pMgmt->wListenInterval >= 2) { - if (pMgmt->wCountToWakeUp == 0) - pMgmt->wCountToWakeUp = pMgmt->wListenInterval; - - pMgmt->wCountToWakeUp--; - - if (pMgmt->wCountToWakeUp == 1) { - // Turn on wake up to listen next beacon - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN); - bWakeUp = true; - } - + if (conf->listen_interval == 1) { + /* Turn on wake up to listen next beacon */ + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN); + bWakeUp = true; } return bWakeUp; diff --git a/drivers/staging/vt6655/power.h b/drivers/staging/vt6655/power.h index 936f171a6b19..1083341b2a47 100644 --- a/drivers/staging/vt6655/power.h +++ b/drivers/staging/vt6655/power.h @@ -33,13 +33,6 @@ #define PS_FAST_INTERVAL 1 // Fast power saving listen interval #define PS_MAX_INTERVAL 4 // MAX power saving listen interval -bool -PSbConsiderPowerDown( - void *hDeviceContext, - bool bCheckRxDMA, - bool bCheckCountToWakeUp -); - void PSvDisablePowerSaving( void *hDeviceContext @@ -51,15 +44,6 @@ PSvEnablePowerSaving( unsigned short wListenInterval ); -void -PSvSendPSPOLL( - void *hDeviceContext -); - -bool -PSbSendNullPacket( - void *hDeviceContext -); bool PSbIsNextTBTTWakeUp( diff --git a/drivers/staging/vt6655/rc4.c b/drivers/staging/vt6655/rc4.c deleted file mode 100644 index b7819bc702de..000000000000 --- a/drivers/staging/vt6655/rc4.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: rc4.c - * - * Purpose: - * - * Functions: - * - * Revision History: - * - * Author: Kyle Hsu - * - * Date: Sep 4, 2002 - * - */ - -#include "rc4.h" - -void rc4_init(PRC4Ext pRC4, unsigned char *pbyKey, unsigned int cbKey_len) -{ - unsigned int ust1, ust2; - unsigned int keyindex; - unsigned int stateindex; - unsigned char *pbyst; - unsigned int idx; - - pbyst = pRC4->abystate; - pRC4->ux = 0; - pRC4->uy = 0; - for (idx = 0; idx < 256; idx++) - pbyst[idx] = (unsigned char)idx; - keyindex = 0; - stateindex = 0; - for (idx = 0; idx < 256; idx++) { - ust1 = pbyst[idx]; - stateindex = (stateindex + pbyKey[keyindex] + ust1) & 0xff; - ust2 = pbyst[stateindex]; - pbyst[stateindex] = (unsigned char)ust1; - pbyst[idx] = (unsigned char)ust2; - if (++keyindex >= cbKey_len) - keyindex = 0; - } -} - -unsigned int rc4_byte(PRC4Ext pRC4) -{ - unsigned int ux; - unsigned int uy; - unsigned int ustx, usty; - unsigned char *pbyst; - - pbyst = pRC4->abystate; - ux = (pRC4->ux + 1) & 0xff; - ustx = pbyst[ux]; - uy = (ustx + pRC4->uy) & 0xff; - usty = pbyst[uy]; - pRC4->ux = ux; - pRC4->uy = uy; - pbyst[uy] = (unsigned char)ustx; - pbyst[ux] = (unsigned char)usty; - - return pbyst[(ustx + usty) & 0xff]; -} - -void rc4_encrypt(PRC4Ext pRC4, unsigned char *pbyDest, - unsigned char *pbySrc, unsigned int cbData_len) -{ - unsigned int ii; - - for (ii = 0; ii < cbData_len; ii++) - pbyDest[ii] = (unsigned char)(pbySrc[ii] ^ rc4_byte(pRC4)); -} diff --git a/drivers/staging/vt6655/rc4.h b/drivers/staging/vt6655/rc4.h deleted file mode 100644 index 74b2eed9bce3..000000000000 --- a/drivers/staging/vt6655/rc4.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * File: rc4.h - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Purpose: - * - * Functions: - * - * Revision History: - * - * Author: Kyle Hsu - * - * Date: Sep 4, 2002 - * - */ - -#ifndef __RC4_H__ -#define __RC4_H__ - -#include "ttype.h" - -/*--------------------- Export Definitions -------------------------*/ -/*--------------------- Export Types ------------------------------*/ -typedef struct { - unsigned int ux; - unsigned int uy; - unsigned char abystate[256]; -} RC4Ext, *PRC4Ext; - -void rc4_init(PRC4Ext pRC4, unsigned char *pbyKey, unsigned int cbKey_len); -unsigned int rc4_byte(PRC4Ext pRC4); -void rc4_encrypt(PRC4Ext pRC4, unsigned char *pbyDest, unsigned char *pbySrc, unsigned int cbData_len); - -#endif //__RC4_H__ diff --git a/drivers/staging/vt6655/rf.c b/drivers/staging/vt6655/rf.c index e505af91bfd0..32ef99341e20 100644 --- a/drivers/staging/vt6655/rf.c +++ b/drivers/staging/vt6655/rf.c @@ -29,6 +29,8 @@ * IFRFbWriteEmbedded - Embedded write RF register via MAC * * Revision History: + * RobertYu 2005 + * chester 2008 * */ @@ -37,8 +39,6 @@ #include "rf.h" #include "baseband.h" -/*--------------------- Static Definitions -------------------------*/ - #define BY_AL2230_REG_LEN 23 //24bit #define CB_AL2230_INIT_SEQ 15 #define SWITCH_CHANNEL_DELAY_AL2230 200 //us @@ -49,10 +49,6 @@ #define SWITCH_CHANNEL_DELAY_AL7230 200 //us #define AL7230_PWR_IDX_LEN 64 -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - static const unsigned long dwAL2230InitTable[CB_AL2230_INIT_SEQ] = { 0x03F79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // 0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // @@ -172,7 +168,6 @@ static unsigned long dwAL2230PowerTable[AL2230_PWR_IDX_LEN] = { 0x0407F900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW }; -//{{ RobertYu:20050104 // 40MHz reference frequency // Need to Pull PLLON(PE3) low when writing channel registers through 3-wire. static const unsigned long dwAL7230InitTable[CB_AL7230_INIT_SEQ] = { @@ -408,9 +403,6 @@ static const unsigned long dwAL7230ChannelTable2[CB_MAX_CHANNEL] = { 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 161, Tf = 5805MHz (55) 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW // channel = 165, Tf = 5825MHz (56) }; -//}} RobertYu - -/*--------------------- Static Functions --------------------------*/ /* * Description: AIROHA IFRF chip init function @@ -424,137 +416,81 @@ static const unsigned long dwAL7230ChannelTable2[CB_MAX_CHANNEL] = { * Return Value: true if succeeded; false if failed. * */ -static bool s_bAL7230Init(void __iomem *dwIoBase) +static bool s_bAL7230Init(struct vnt_private *priv) { + void __iomem *dwIoBase = priv->PortOffset; int ii; bool bResult; bResult = true; - //3-wire control for normal mode + /* 3-wire control for normal mode */ VNSvOutPortB(dwIoBase + MAC_REG_SOFTPWRCTL, 0); MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPECTI | SOFTPWRCTL_TXPEINV)); - BBvPowerSaveModeOFF(dwIoBase); //RobertYu:20050106, have DC value for Calibration + BBvPowerSaveModeOFF(priv); /* RobertYu:20050106, have DC value for Calibration */ for (ii = 0; ii < CB_AL7230_INIT_SEQ; ii++) - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[ii]); + bResult &= IFRFbWriteEmbedded(priv, dwAL7230InitTable[ii]); - // PLL On + /* PLL On */ MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); - //Calibration + /* Calibration */ MACvTimer0MicroSDelay(dwIoBase, 150);//150us - bResult &= IFRFbWriteEmbedded(dwIoBase, (0x9ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW)); //TXDCOC:active, RCK:disable + /* TXDCOC:active, RCK:disable */ + bResult &= IFRFbWriteEmbedded(priv, (0x9ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW)); MACvTimer0MicroSDelay(dwIoBase, 30);//30us - bResult &= IFRFbWriteEmbedded(dwIoBase, (0x3ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW)); //TXDCOC:disable, RCK:active + /* TXDCOC:disable, RCK:active */ + bResult &= IFRFbWriteEmbedded(priv, (0x3ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW)); MACvTimer0MicroSDelay(dwIoBase, 30);//30us - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[CB_AL7230_INIT_SEQ-1]); //TXDCOC:disable, RCK:disable + /* TXDCOC:disable, RCK:disable */ + bResult &= IFRFbWriteEmbedded(priv, dwAL7230InitTable[CB_AL7230_INIT_SEQ-1]); MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE3 | SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPECTI | SOFTPWRCTL_TXPEINV)); - BBvPowerSaveModeON(dwIoBase); // RobertYu:20050106 + BBvPowerSaveModeON(priv); /* RobertYu:20050106 */ - // PE1: TX_ON, PE2: RX_ON, PE3: PLLON - //3-wire control for power saving mode + /* PE1: TX_ON, PE2: RX_ON, PE3: PLLON */ + /* 3-wire control for power saving mode */ VNSvOutPortB(dwIoBase + MAC_REG_PSPWRSIG, (PSSIG_WPE3 | PSSIG_WPE2)); //1100 0000 return bResult; } -// Need to Pull PLLON low when writing channel registers through 3-wire interface -static bool s_bAL7230SelectChannel(void __iomem *dwIoBase, unsigned char byChannel) +/* Need to Pull PLLON low when writing channel registers through + * 3-wire interface */ +static bool s_bAL7230SelectChannel(struct vnt_private *priv, unsigned char byChannel) { + void __iomem *dwIoBase = priv->PortOffset; bool bResult; bResult = true; - // PLLON Off + /* PLLON Off */ MACvWordRegBitsOff(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230ChannelTable0[byChannel - 1]); //Reg0 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230ChannelTable1[byChannel - 1]); //Reg1 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230ChannelTable2[byChannel - 1]); //Reg4 + bResult &= IFRFbWriteEmbedded(priv, dwAL7230ChannelTable0[byChannel - 1]); + bResult &= IFRFbWriteEmbedded(priv, dwAL7230ChannelTable1[byChannel - 1]); + bResult &= IFRFbWriteEmbedded(priv, dwAL7230ChannelTable2[byChannel - 1]); - // PLLOn On + /* PLLOn On */ MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); - // Set Channel[7] = 0 to tell H/W channel is changing now. + /* Set Channel[7] = 0 to tell H/W channel is changing now. */ VNSvOutPortB(dwIoBase + MAC_REG_CHANNEL, (byChannel & 0x7F)); MACvTimer0MicroSDelay(dwIoBase, SWITCH_CHANNEL_DELAY_AL7230); - // Set Channel[7] = 1 to tell H/W channel change is done. + /* Set Channel[7] = 1 to tell H/W channel change is done. */ VNSvOutPortB(dwIoBase + MAC_REG_CHANNEL, (byChannel | 0x80)); return bResult; } /* - * Description: Select channel with UW2452 chip - * - * Parameters: - * In: - * dwIoBase - I/O base address - * uChannel - Channel number - * Out: - * none - * - * Return Value: true if succeeded; false if failed. - * - */ - -//{{ RobertYu: 20041210 -/* - * Description: UW2452 IFRF chip init function - * - * Parameters: - * In: - * dwIoBase - I/O base address - * Out: - * none - * - * Return Value: true if succeeded; false if failed. - * - */ - -//}} RobertYu -//////////////////////////////////////////////////////////////////////////////// - -/* - * Description: VT3226 IFRF chip init function - * - * Parameters: - * In: - * dwIoBase - I/O base address - * Out: - * none - * - * Return Value: true if succeeded; false if failed. - * - */ - -/* - * Description: Select channel with VT3226 chip - * - * Parameters: - * In: - * dwIoBase - I/O base address - * uChannel - Channel number - * Out: - * none - * - * Return Value: true if succeeded; false if failed. - * - */ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -/* * Description: Write to IF/RF, by embedded programming * * Parameters: @@ -567,14 +503,15 @@ static bool s_bAL7230SelectChannel(void __iomem *dwIoBase, unsigned char byChann * Return Value: true if succeeded; false if failed. * */ -bool IFRFbWriteEmbedded(void __iomem *dwIoBase, unsigned long dwData) +bool IFRFbWriteEmbedded(struct vnt_private *priv, unsigned long dwData) { + void __iomem *dwIoBase = priv->PortOffset; unsigned short ww; unsigned long dwValue; VNSvOutPortD(dwIoBase + MAC_REG_IFREGCTL, dwData); - // W_MAX_TIMEOUT is the timeout period + /* W_MAX_TIMEOUT is the timeout period */ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { VNSvInPortD(dwIoBase + MAC_REG_IFREGCTL, &dwValue); if (dwValue & IFREGCTL_DONE) @@ -588,33 +525,6 @@ bool IFRFbWriteEmbedded(void __iomem *dwIoBase, unsigned long dwData) } /* - * Description: RFMD RF2959 IFRF chip init function - * - * Parameters: - * In: - * dwIoBase - I/O base address - * Out: - * none - * - * Return Value: true if succeeded; false if failed. - * - */ - -/* - * Description: Select channel with RFMD 2959 chip - * - * Parameters: - * In: - * dwIoBase - I/O base address - * uChannel - Channel number - * Out: - * none - * - * Return Value: true if succeeded; false if failed. - * - */ - -/* * Description: AIROHA IFRF chip init function * * Parameters: @@ -626,113 +536,70 @@ bool IFRFbWriteEmbedded(void __iomem *dwIoBase, unsigned long dwData) * Return Value: true if succeeded; false if failed. * */ -static bool RFbAL2230Init(void __iomem *dwIoBase) +static bool RFbAL2230Init(struct vnt_private *priv) { + void __iomem *dwIoBase = priv->PortOffset; int ii; bool bResult; bResult = true; - //3-wire control for normal mode + /* 3-wire control for normal mode */ VNSvOutPortB(dwIoBase + MAC_REG_SOFTPWRCTL, 0); MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPECTI | SOFTPWRCTL_TXPEINV)); -//2008-8-21 chester <add> - // PLL Off - + /* PLL Off */ MACvWordRegBitsOff(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); - //patch abnormal AL2230 frequency output -//2008-8-21 chester <add> - IFRFbWriteEmbedded(dwIoBase, (0x07168700+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW)); + /* patch abnormal AL2230 frequency output */ + IFRFbWriteEmbedded(priv, (0x07168700+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW)); for (ii = 0; ii < CB_AL2230_INIT_SEQ; ii++) - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL2230InitTable[ii]); -//2008-8-21 chester <add> + bResult &= IFRFbWriteEmbedded(priv, dwAL2230InitTable[ii]); MACvTimer0MicroSDelay(dwIoBase, 30); //delay 30 us - // PLL On + /* PLL On */ MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); MACvTimer0MicroSDelay(dwIoBase, 150);//150us - bResult &= IFRFbWriteEmbedded(dwIoBase, (0x00d80f00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW)); + bResult &= IFRFbWriteEmbedded(priv, (0x00d80f00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW)); MACvTimer0MicroSDelay(dwIoBase, 30);//30us - bResult &= IFRFbWriteEmbedded(dwIoBase, (0x00780f00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW)); + bResult &= IFRFbWriteEmbedded(priv, (0x00780f00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW)); MACvTimer0MicroSDelay(dwIoBase, 30);//30us - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL2230InitTable[CB_AL2230_INIT_SEQ-1]); + bResult &= IFRFbWriteEmbedded(priv, dwAL2230InitTable[CB_AL2230_INIT_SEQ-1]); MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE3 | SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPECTI | SOFTPWRCTL_TXPEINV)); - //3-wire control for power saving mode + /* 3-wire control for power saving mode */ VNSvOutPortB(dwIoBase + MAC_REG_PSPWRSIG, (PSSIG_WPE3 | PSSIG_WPE2)); //1100 0000 return bResult; } -static bool RFbAL2230SelectChannel(void __iomem *dwIoBase, unsigned char byChannel) +static bool RFbAL2230SelectChannel(struct vnt_private *priv, unsigned char byChannel) { + void __iomem *dwIoBase = priv->PortOffset; bool bResult; bResult = true; - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL2230ChannelTable0[byChannel - 1]); - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL2230ChannelTable1[byChannel - 1]); + bResult &= IFRFbWriteEmbedded(priv, dwAL2230ChannelTable0[byChannel - 1]); + bResult &= IFRFbWriteEmbedded(priv, dwAL2230ChannelTable1[byChannel - 1]); - // Set Channel[7] = 0 to tell H/W channel is changing now. + /* Set Channel[7] = 0 to tell H/W channel is changing now. */ VNSvOutPortB(dwIoBase + MAC_REG_CHANNEL, (byChannel & 0x7F)); MACvTimer0MicroSDelay(dwIoBase, SWITCH_CHANNEL_DELAY_AL2230); - // Set Channel[7] = 1 to tell H/W channel change is done. + /* Set Channel[7] = 1 to tell H/W channel change is done. */ VNSvOutPortB(dwIoBase + MAC_REG_CHANNEL, (byChannel | 0x80)); return bResult; } /* - * Description: UW2451 IFRF chip init function - * - * Parameters: - * In: - * dwIoBase - I/O base address - * Out: - * none - * - * Return Value: true if succeeded; false if failed. - * - */ - -/* - * Description: Select channel with UW2451 chip - * - * Parameters: - * In: - * dwIoBase - I/O base address - * uChannel - Channel number - * Out: - * none - * - * Return Value: true if succeeded; false if failed. - * - */ - -/* - * Description: Set sleep mode to UW2451 chip - * - * Parameters: - * In: - * dwIoBase - I/O base address - * uChannel - Channel number - * Out: - * none - * - * Return Value: true if succeeded; false if failed. - * - */ - -/* * Description: RF init function * * Parameters: @@ -746,20 +613,20 @@ static bool RFbAL2230SelectChannel(void __iomem *dwIoBase, unsigned char byChann * */ bool RFbInit( - struct vnt_private *pDevice + struct vnt_private *priv ) { bool bResult = true; - switch (pDevice->byRFType) { + switch (priv->byRFType) { case RF_AIROHA: case RF_AL2230S: - pDevice->byMaxPwrLevel = AL2230_PWR_IDX_LEN; - bResult = RFbAL2230Init(pDevice->PortOffset); + priv->byMaxPwrLevel = AL2230_PWR_IDX_LEN; + bResult = RFbAL2230Init(priv); break; case RF_AIROHA7230: - pDevice->byMaxPwrLevel = AL7230_PWR_IDX_LEN; - bResult = s_bAL7230Init(pDevice->PortOffset); + priv->byMaxPwrLevel = AL7230_PWR_IDX_LEN; + bResult = s_bAL7230Init(priv); break; case RF_NOTHING: bResult = true; @@ -784,18 +651,18 @@ bool RFbInit( * Return Value: true if succeeded; false if failed. * */ -bool RFbSelectChannel(void __iomem *dwIoBase, unsigned char byRFType, unsigned char byChannel) +bool RFbSelectChannel(struct vnt_private *priv, unsigned char byRFType, unsigned char byChannel) { bool bResult = true; switch (byRFType) { case RF_AIROHA: case RF_AL2230S: - bResult = RFbAL2230SelectChannel(dwIoBase, byChannel); + bResult = RFbAL2230SelectChannel(priv, byChannel); break; //{{ RobertYu: 20050104 case RF_AIROHA7230: - bResult = s_bAL7230SelectChannel(dwIoBase, byChannel); + bResult = s_bAL7230SelectChannel(priv, byChannel); break; //}} RobertYu case RF_NOTHING: @@ -820,8 +687,9 @@ bool RFbSelectChannel(void __iomem *dwIoBase, unsigned char byRFType, unsigned c * Return Value: None. * */ -bool RFvWriteWakeProgSyn(void __iomem *dwIoBase, unsigned char byRFType, unsigned int uChannel) +bool RFvWriteWakeProgSyn(struct vnt_private *priv, unsigned char byRFType, unsigned int uChannel) { + void __iomem *dwIoBase = priv->PortOffset; int ii; unsigned char byInitCount = 0; unsigned char bySleepCount = 0; @@ -834,7 +702,8 @@ bool RFvWriteWakeProgSyn(void __iomem *dwIoBase, unsigned char byRFType, unsigne if (uChannel > CB_MAX_CHANNEL_24G) return false; - byInitCount = CB_AL2230_INIT_SEQ + 2; // Init Reg + Channel Reg (2) + /* Init Reg + Channel Reg (2) */ + byInitCount = CB_AL2230_INIT_SEQ + 2; bySleepCount = 0; if (byInitCount > (MISCFIFO_SYNDATASIZE - bySleepCount)) return false; @@ -847,10 +716,10 @@ bool RFvWriteWakeProgSyn(void __iomem *dwIoBase, unsigned char byRFType, unsigne MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL2230ChannelTable1[uChannel-1]); break; - //{{ RobertYu: 20050104 - // Need to check, PLLON need to be low for channel setting + /* Need to check, PLLON need to be low for channel setting */ case RF_AIROHA7230: - byInitCount = CB_AL7230_INIT_SEQ + 3; // Init Reg + Channel Reg (3) + /* Init Reg + Channel Reg (3) */ + byInitCount = CB_AL7230_INIT_SEQ + 3; bySleepCount = 0; if (byInitCount > (MISCFIFO_SYNDATASIZE - bySleepCount)) return false; @@ -869,7 +738,6 @@ bool RFvWriteWakeProgSyn(void __iomem *dwIoBase, unsigned char byRFType, unsigne ii++; MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230ChannelTable2[uChannel-1]); break; - //}} RobertYu case RF_NOTHING: return true; @@ -897,7 +765,7 @@ bool RFvWriteWakeProgSyn(void __iomem *dwIoBase, unsigned char byRFType, unsigne * */ bool RFbSetPower( - struct vnt_private *pDevice, + struct vnt_private *priv, unsigned int uRATE, unsigned int uCH ) @@ -907,7 +775,7 @@ bool RFbSetPower( unsigned char byDec = 0; unsigned char byPwrdBm = 0; - if (pDevice->dwDiagRefCount != 0) + if (priv->dwDiagRefCount != 0) return true; if ((uCH < 1) || (uCH > CB_MAX_CHANNEL)) @@ -918,22 +786,22 @@ bool RFbSetPower( case RATE_2M: case RATE_5M: case RATE_11M: - byPwr = pDevice->abyCCKPwrTbl[uCH]; - byPwrdBm = pDevice->abyCCKDefaultPwr[uCH]; + byPwr = priv->abyCCKPwrTbl[uCH]; + byPwrdBm = priv->abyCCKDefaultPwr[uCH]; break; case RATE_6M: case RATE_9M: case RATE_18M: - byPwr = pDevice->abyOFDMPwrTbl[uCH]; - if (pDevice->byRFType == RF_UW2452) + byPwr = priv->abyOFDMPwrTbl[uCH]; + if (priv->byRFType == RF_UW2452) byDec = byPwr + 14; else byDec = byPwr + 10; - if (byDec >= pDevice->byMaxPwrLevel) - byDec = pDevice->byMaxPwrLevel-1; + if (byDec >= priv->byMaxPwrLevel) + byDec = priv->byMaxPwrLevel-1; - if (pDevice->byRFType == RF_UW2452) { + if (priv->byRFType == RF_UW2452) { byPwrdBm = byDec - byPwr; byPwrdBm /= 3; } else { @@ -941,24 +809,24 @@ bool RFbSetPower( byPwrdBm >>= 1; } - byPwrdBm += pDevice->abyOFDMDefaultPwr[uCH]; + byPwrdBm += priv->abyOFDMDefaultPwr[uCH]; byPwr = byDec; break; case RATE_24M: case RATE_36M: case RATE_48M: case RATE_54M: - byPwr = pDevice->abyOFDMPwrTbl[uCH]; - byPwrdBm = pDevice->abyOFDMDefaultPwr[uCH]; + byPwr = priv->abyOFDMPwrTbl[uCH]; + byPwrdBm = priv->abyOFDMDefaultPwr[uCH]; break; } - if (pDevice->byCurPwr == byPwr) + if (priv->byCurPwr == byPwr) return true; - bResult = RFbRawSetPower(pDevice, byPwr, uRATE); + bResult = RFbRawSetPower(priv, byPwr, uRATE); if (bResult) - pDevice->byCurPwr = byPwr; + priv->byCurPwr = byPwr; return bResult; } @@ -978,7 +846,7 @@ bool RFbSetPower( */ bool RFbRawSetPower( - struct vnt_private *pDevice, + struct vnt_private *priv, unsigned char byPwr, unsigned int uRATE ) @@ -986,37 +854,38 @@ bool RFbRawSetPower( bool bResult = true; unsigned long dwMax7230Pwr = 0; - if (byPwr >= pDevice->byMaxPwrLevel) + if (byPwr >= priv->byMaxPwrLevel) return false; - switch (pDevice->byRFType) { + switch (priv->byRFType) { case RF_AIROHA: - bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, dwAL2230PowerTable[byPwr]); + bResult &= IFRFbWriteEmbedded(priv, dwAL2230PowerTable[byPwr]); if (uRATE <= RATE_11M) - bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x0001B400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(priv, 0x0001B400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); else - bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(priv, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); break; case RF_AL2230S: - bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, dwAL2230PowerTable[byPwr]); + bResult &= IFRFbWriteEmbedded(priv, dwAL2230PowerTable[byPwr]); if (uRATE <= RATE_11M) { - bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x040C1400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); - bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x00299B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(priv, 0x040C1400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(priv, 0x00299B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); } else { - bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); - bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x00099B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(priv, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(priv, 0x00099B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); } break; case RF_AIROHA7230: - // 0x080F1B00 for 3 wire control TxGain(D10) and 0x31 as TX Gain value + /* 0x080F1B00 for 3 wire control TxGain(D10) + * and 0x31 as TX Gain value */ dwMax7230Pwr = 0x080C0B00 | ((byPwr) << 12) | (BY_AL7230_REG_LEN << 3) | IFREGCTL_REGW; - bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, dwMax7230Pwr); + bResult &= IFRFbWriteEmbedded(priv, dwMax7230Pwr); break; default: @@ -1032,7 +901,7 @@ bool RFbRawSetPower( * * Parameters: * In: - * pDevice - The adapter to be translated + * priv - The adapter to be translated * byCurrRSSI - RSSI to be translated * Out: * pdwdbm - Translated dbm number @@ -1042,7 +911,7 @@ bool RFbRawSetPower( -*/ void RFvRSSITodBm( - struct vnt_private *pDevice, + struct vnt_private *priv, unsigned char byCurrRSSI, long *pldBm ) @@ -1052,10 +921,10 @@ RFvRSSITodBm( long a = 0; unsigned char abyAIROHARF[4] = {0, 18, 0, 40}; - switch (pDevice->byRFType) { + switch (priv->byRFType) { case RF_AIROHA: case RF_AL2230S: - case RF_AIROHA7230: //RobertYu: 20040104 + case RF_AIROHA7230: a = abyAIROHARF[byIdx]; break; default: @@ -1065,42 +934,38 @@ RFvRSSITodBm( *pldBm = -1 * (a + b * 2); } -//////////////////////////////////////////////////////////////////////////////// -//{{ RobertYu: 20050104 - -// Post processing for the 11b/g and 11a. -// for save time on changing Reg2,3,5,7,10,12,15 -bool RFbAL7230SelectChannelPostProcess(void __iomem *dwIoBase, unsigned char byOldChannel, unsigned char byNewChannel) +/* Post processing for the 11b/g and 11a. + * for save time on changing Reg2,3,5,7,10,12,15 */ +bool RFbAL7230SelectChannelPostProcess(struct vnt_private *priv, + unsigned char byOldChannel, + unsigned char byNewChannel) { bool bResult; bResult = true; - // if change between 11 b/g and 11a need to update the following register - // Channel Index 1~14 - + /* if change between 11 b/g and 11a need to update the following + * register + * Channel Index 1~14 */ if ((byOldChannel <= CB_MAX_CHANNEL_24G) && (byNewChannel > CB_MAX_CHANNEL_24G)) { - // Change from 2.4G to 5G - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[2]); //Reg2 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[3]); //Reg3 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[5]); //Reg5 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[7]); //Reg7 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[10]);//Reg10 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[12]);//Reg12 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[15]);//Reg15 + /* Change from 2.4G to 5G [Reg] */ + bResult &= IFRFbWriteEmbedded(priv, dwAL7230InitTableAMode[2]); + bResult &= IFRFbWriteEmbedded(priv, dwAL7230InitTableAMode[3]); + bResult &= IFRFbWriteEmbedded(priv, dwAL7230InitTableAMode[5]); + bResult &= IFRFbWriteEmbedded(priv, dwAL7230InitTableAMode[7]); + bResult &= IFRFbWriteEmbedded(priv, dwAL7230InitTableAMode[10]); + bResult &= IFRFbWriteEmbedded(priv, dwAL7230InitTableAMode[12]); + bResult &= IFRFbWriteEmbedded(priv, dwAL7230InitTableAMode[15]); } else if ((byOldChannel > CB_MAX_CHANNEL_24G) && (byNewChannel <= CB_MAX_CHANNEL_24G)) { - // change from 5G to 2.4G - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[2]); //Reg2 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[3]); //Reg3 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[5]); //Reg5 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[7]); //Reg7 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[10]);//Reg10 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[12]);//Reg12 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[15]);//Reg15 + /* Change from 5G to 2.4G [Reg] */ + bResult &= IFRFbWriteEmbedded(priv, dwAL7230InitTable[2]); + bResult &= IFRFbWriteEmbedded(priv, dwAL7230InitTable[3]); + bResult &= IFRFbWriteEmbedded(priv, dwAL7230InitTable[5]); + bResult &= IFRFbWriteEmbedded(priv, dwAL7230InitTable[7]); + bResult &= IFRFbWriteEmbedded(priv, dwAL7230InitTable[10]); + bResult &= IFRFbWriteEmbedded(priv, dwAL7230InitTable[12]); + bResult &= IFRFbWriteEmbedded(priv, dwAL7230InitTable[15]); } return bResult; } - -//}} RobertYu -//////////////////////////////////////////////////////////////////////////////// diff --git a/drivers/staging/vt6655/rf.h b/drivers/staging/vt6655/rf.h index be4ef88b7666..8a6e2cfedaa5 100644 --- a/drivers/staging/vt6655/rf.h +++ b/drivers/staging/vt6655/rf.h @@ -30,7 +30,6 @@ #ifndef __RF_H__ #define __RF_H__ -#include "ttype.h" #include "device.h" /*--------------------- Export Definitions -------------------------*/ @@ -74,12 +73,12 @@ /*--------------------- Export Functions --------------------------*/ -bool IFRFbWriteEmbedded(void __iomem *dwIoBase, unsigned long dwData); -bool RFbSelectChannel(void __iomem *dwIoBase, unsigned char byRFType, unsigned char byChannel); +bool IFRFbWriteEmbedded(struct vnt_private *, unsigned long dwData); +bool RFbSelectChannel(struct vnt_private *, unsigned char byRFType, unsigned char byChannel); bool RFbInit( struct vnt_private * ); -bool RFvWriteWakeProgSyn(void __iomem *dwIoBase, unsigned char byRFType, unsigned int uChannel); +bool RFvWriteWakeProgSyn(struct vnt_private *, unsigned char byRFType, unsigned int uChannel); bool RFbSetPower(struct vnt_private *, unsigned int uRATE, unsigned int uCH); bool RFbRawSetPower( struct vnt_private *, @@ -95,7 +94,7 @@ RFvRSSITodBm( ); //{{ RobertYu: 20050104 -bool RFbAL7230SelectChannelPostProcess(void __iomem *dwIoBase, unsigned char byOldChannel, unsigned char byNewChannel); +bool RFbAL7230SelectChannelPostProcess(struct vnt_private *, unsigned char byOldChannel, unsigned char byNewChannel); //}} RobertYu #endif // __RF_H__ diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 7a183f55e7eb..b5b0155961f2 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -50,17 +50,9 @@ #include "device.h" #include "rxtx.h" -#include "tether.h" #include "card.h" -#include "bssdb.h" #include "mac.h" #include "baseband.h" -#include "michael.h" -#include "tkip.h" -#include "tcrc.h" -#include "wctl.h" -#include "wroute.h" -#include "hostap.h" #include "rf.h" /*--------------------- Static Definitions -------------------------*/ @@ -105,19 +97,6 @@ static const unsigned short wFB_Opt1[2][5] = { #define DATADUR_A_F1 13 /*--------------------- Static Functions --------------------------*/ - -static -void -s_vFillTxKey( - struct vnt_private *pDevice, - unsigned char *pbyBuf, - unsigned char *pbyIVHead, - PSKeyItem pTransmitKey, - unsigned char *pbyHdrBuf, - unsigned short wPayloadLen, - unsigned char *pMICHDR -); - static void s_vFillRTSHead( @@ -127,7 +106,7 @@ s_vFillRTSHead( unsigned int cbFrameLength, bool bNeedAck, bool bDisCRC, - PSEthernetHeader psEthHeader, + struct ieee80211_hdr *hdr, unsigned short wCurrentRate, unsigned char byFBOption ); @@ -144,26 +123,15 @@ s_vGenerateTxParameter( unsigned int cbFrameSize, bool bNeedACK, unsigned int uDMAIdx, - PSEthernetHeader psEthHeader, + void *psEthHeader, unsigned short wCurrentRate ); -static void s_vFillFragParameter( - struct vnt_private *pDevice, - unsigned char *pbyBuffer, - unsigned int uTxType, - void *pvtdCurr, - unsigned short wFragType, - unsigned int cbReqCount -); - static unsigned int s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, - unsigned char *pbyTxBufferAddr, unsigned int cbFrameBodySize, + unsigned char *pbyTxBufferAddr, unsigned int uDMAIdx, PSTxDesc pHeadTD, - PSEthernetHeader psEthHeader, unsigned char *pPacket, - bool bNeedEncrypt, PSKeyItem pTransmitKey, - unsigned int uNodeIndex, unsigned int *puMACfragNum); + unsigned int uNodeIndex); static __le16 @@ -178,165 +146,12 @@ s_uFillDataHead( unsigned int cbLastFragmentSize, unsigned int uMACfragNum, unsigned char byFBOption, - unsigned short wCurrentRate + unsigned short wCurrentRate, + bool is_pspoll ); /*--------------------- Export Variables --------------------------*/ -static -void -s_vFillTxKey( - struct vnt_private *pDevice, - unsigned char *pbyBuf, - unsigned char *pbyIVHead, - PSKeyItem pTransmitKey, - unsigned char *pbyHdrBuf, - unsigned short wPayloadLen, - unsigned char *pMICHDR -) -{ - struct vnt_mic_hdr *mic_hdr = (struct vnt_mic_hdr *)pMICHDR; - unsigned long *pdwIV = (unsigned long *)pbyIVHead; - unsigned long *pdwExtIV = (unsigned long *)((unsigned char *)pbyIVHead+4); - PS802_11Header pMACHeader = (PS802_11Header)pbyHdrBuf; - unsigned long dwRevIVCounter; - unsigned char byKeyIndex = 0; - - //Fill TXKEY - if (pTransmitKey == NULL) - return; - - dwRevIVCounter = cpu_to_le32(pDevice->dwIVCounter); - *pdwIV = pDevice->dwIVCounter; - byKeyIndex = pTransmitKey->dwKeyIndex & 0xf; - - if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { - if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN) { - memcpy(pDevice->abyPRNG, (unsigned char *)&(dwRevIVCounter), 3); - memcpy(pDevice->abyPRNG+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength); - } else { - memcpy(pbyBuf, (unsigned char *)&(dwRevIVCounter), 3); - memcpy(pbyBuf+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength); - if (pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) { - memcpy(pbyBuf+8, (unsigned char *)&(dwRevIVCounter), 3); - memcpy(pbyBuf+11, pTransmitKey->abyKey, pTransmitKey->uKeyLength); - } - memcpy(pDevice->abyPRNG, pbyBuf, 16); - } - // Append IV after Mac Header - *pdwIV &= WEP_IV_MASK;//00000000 11111111 11111111 11111111 - *pdwIV |= (unsigned long)byKeyIndex << 30; - *pdwIV = cpu_to_le32(*pdwIV); - pDevice->dwIVCounter++; - if (pDevice->dwIVCounter > WEP_IV_MASK) - pDevice->dwIVCounter = 0; - - } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { - pTransmitKey->wTSC15_0++; - if (pTransmitKey->wTSC15_0 == 0) - pTransmitKey->dwTSC47_16++; - - TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr, - pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG); - memcpy(pbyBuf, pDevice->abyPRNG, 16); - // Make IV - memcpy(pdwIV, pDevice->abyPRNG, 3); - - *(pbyIVHead+3) = (unsigned char)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV - // Append IV&ExtIV after Mac Header - *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16); - pr_debug("vFillTxKey()---- pdwExtIV: %lx\n", *pdwExtIV); - - } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { - pTransmitKey->wTSC15_0++; - if (pTransmitKey->wTSC15_0 == 0) - pTransmitKey->dwTSC47_16++; - - memcpy(pbyBuf, pTransmitKey->abyKey, 16); - - // Make IV - *pdwIV = 0; - *(pbyIVHead+3) = (unsigned char)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV - *pdwIV |= cpu_to_le16((unsigned short)(pTransmitKey->wTSC15_0)); - //Append IV&ExtIV after Mac Header - *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16); - - /* MICHDR0 */ - mic_hdr->id = 0x59; - mic_hdr->tx_priority = 0; - memcpy(mic_hdr->mic_addr2, pMACHeader->abyAddr2, ETH_ALEN); - - /* ccmp pn big endian order */ - mic_hdr->ccmp_pn[0] = (u8)(pTransmitKey->dwTSC47_16 >> 24); - mic_hdr->ccmp_pn[1] = (u8)(pTransmitKey->dwTSC47_16 >> 16); - mic_hdr->ccmp_pn[2] = (u8)(pTransmitKey->dwTSC47_16 >> 8); - mic_hdr->ccmp_pn[3] = (u8)pTransmitKey->dwTSC47_16; - mic_hdr->ccmp_pn[4] = (u8)(pTransmitKey->wTSC15_0 >> 8); - mic_hdr->ccmp_pn[5] = (u8)pTransmitKey->wTSC15_0; - - /* MICHDR1 */ - mic_hdr->payload_len = cpu_to_be16(wPayloadLen); - - if (pDevice->bLongHeader) - mic_hdr->hlen = cpu_to_be16(28); - else - mic_hdr->hlen = cpu_to_be16(22); - - memcpy(mic_hdr->addr1, pMACHeader->abyAddr1, ETH_ALEN); - memcpy(mic_hdr->addr2, pMACHeader->abyAddr2, ETH_ALEN); - - /* MICHDR2 */ - memcpy(mic_hdr->addr3, pMACHeader->abyAddr3, ETH_ALEN); - mic_hdr->frame_control = - cpu_to_le16(pMACHeader->wFrameCtl & 0xc78f); - mic_hdr->seq_ctrl = cpu_to_le16(pMACHeader->wSeqCtl & 0xf); - - if (pDevice->bLongHeader) - memcpy(mic_hdr->addr4, pMACHeader->abyAddr4, ETH_ALEN); - } -} - -static -void -s_vSWencryption( - struct vnt_private *pDevice, - PSKeyItem pTransmitKey, - unsigned char *pbyPayloadHead, - unsigned short wPayloadSize -) -{ - unsigned int cbICVlen = 4; - unsigned long dwICV = 0xFFFFFFFFL; - unsigned long *pdwICV; - - if (pTransmitKey == NULL) - return; - - if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { - //======================================================================= - // Append ICV after payload - dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload) - pdwICV = (unsigned long *)(pbyPayloadHead + wPayloadSize); - // finally, we must invert dwCRC to get the correct answer - *pdwICV = cpu_to_le32(~dwICV); - // RC4 encryption - rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength + 3); - rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen); - //======================================================================= - } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { - //======================================================================= - //Append ICV after payload - dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload) - pdwICV = (unsigned long *)(pbyPayloadHead + wPayloadSize); - // finally, we must invert dwCRC to get the correct answer - *pdwICV = cpu_to_le32(~dwICV); - // RC4 encryption - rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN); - rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen); - //======================================================================= - } -} - static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate) { return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2] @@ -683,7 +498,8 @@ s_uFillDataHead( unsigned int cbLastFragmentSize, unsigned int uMACfragNum, unsigned char byFBOption, - unsigned short wCurrentRate + unsigned short wCurrentRate, + bool is_pspoll ) { @@ -702,15 +518,24 @@ s_uFillDataHead( pDevice->byTopCCKBasicRate, PK_TYPE_11B, &buf->b); - /* Get Duration and TimeStamp */ - buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, - byPktType, wCurrentRate, bNeedAck, uFragIdx, - cbLastFragmentSize, uMACfragNum, - byFBOption)); - buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, - PK_TYPE_11B, pDevice->byTopCCKBasicRate, - bNeedAck, uFragIdx, cbLastFragmentSize, - uMACfragNum, byFBOption)); + if (is_pspoll) { + __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15)); + + buf->duration_a = dur; + buf->duration_b = dur; + } else { + /* Get Duration and TimeStamp */ + buf->duration_a = + cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, + byPktType, wCurrentRate, bNeedAck, uFragIdx, + cbLastFragmentSize, uMACfragNum, + byFBOption)); + buf->duration_b = + cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, + PK_TYPE_11B, pDevice->byTopCCKBasicRate, + bNeedAck, uFragIdx, cbLastFragmentSize, + uMACfragNum, byFBOption)); + } buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate); buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate); @@ -764,11 +589,18 @@ s_uFillDataHead( vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate, byPktType, &buf->ab); - /* Get Duration and TimeStampOff */ - buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, + if (is_pspoll) { + __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15)); + + buf->duration = dur; + } else { + /* Get Duration and TimeStampOff */ + buf->duration = + cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); + } buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate); return buf->duration; @@ -778,17 +610,27 @@ s_uFillDataHead( /* Get SignalField, ServiceField & Length */ vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate, byPktType, &buf->ab); - /* Get Duration and TimeStampOff */ - buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType, + + if (is_pspoll) { + __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15)); + + buf->duration = dur; + } else { + /* Get Duration and TimeStampOff */ + buf->duration = + cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); + } + buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate); return buf->duration; } return 0; } + static void s_vFillRTSHead( @@ -798,7 +640,7 @@ s_vFillRTSHead( unsigned int cbFrameLength, bool bNeedAck, bool bDisCRC, - PSEthernetHeader psEthHeader, + struct ieee80211_hdr *hdr, unsigned short wCurrentRate, unsigned char byFBOption ) @@ -850,18 +692,8 @@ s_vFillRTSHead( cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); - - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - memcpy(&buf->data.ra, psEthHeader->abyDstAddr, ETH_ALEN); - } else { - memcpy(&buf->data.ra, pDevice->abyBSSID, ETH_ALEN); - } - if (pDevice->op_mode == NL80211_IFTYPE_AP) - memcpy(&buf->data.ta, pDevice->abyBSSID, ETH_ALEN); - else - memcpy(&buf->data.ta, psEthHeader->abySrcAddr, ETH_ALEN); - + ether_addr_copy(buf->data.ra, hdr->addr1); + ether_addr_copy(buf->data.ta, hdr->addr2); } else { struct vnt_rts_g_fb *buf = pvRTS; /* Get SignalField, ServiceField & Length */ @@ -914,19 +746,8 @@ s_vFillRTSHead( cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); - - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - memcpy(&buf->data.ra, psEthHeader->abyDstAddr, ETH_ALEN); - } else { - memcpy(&buf->data.ra, pDevice->abyBSSID, ETH_ALEN); - } - - if (pDevice->op_mode == NL80211_IFTYPE_AP) - memcpy(&buf->data.ta, pDevice->abyBSSID, ETH_ALEN); - else - memcpy(&buf->data.ta, psEthHeader->abySrcAddr, ETH_ALEN); - + ether_addr_copy(buf->data.ra, hdr->addr1); + ether_addr_copy(buf->data.ta, hdr->addr2); } // if (byFBOption == AUTO_FB_NONE) } else if (byPktType == PK_TYPE_11A) { if (byFBOption == AUTO_FB_NONE) { @@ -947,19 +768,8 @@ s_vFillRTSHead( cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); - - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - memcpy(&buf->data.ra, psEthHeader->abyDstAddr, ETH_ALEN); - } else { - memcpy(&buf->data.ra, pDevice->abyBSSID, ETH_ALEN); - } - - if (pDevice->op_mode == NL80211_IFTYPE_AP) - memcpy(&buf->data.ta, pDevice->abyBSSID, ETH_ALEN); - else - memcpy(&buf->data.ta, psEthHeader->abySrcAddr, ETH_ALEN); - + ether_addr_copy(buf->data.ra, hdr->addr1); + ether_addr_copy(buf->data.ta, hdr->addr2); } else { struct vnt_rts_a_fb *buf = pvRTS; /* Get SignalField, ServiceField & Length */ @@ -988,16 +798,8 @@ s_vFillRTSHead( cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - memcpy(&buf->data.ra, psEthHeader->abyDstAddr, ETH_ALEN); - } else { - memcpy(&buf->data.ra, pDevice->abyBSSID, ETH_ALEN); - } - if (pDevice->op_mode == NL80211_IFTYPE_AP) - memcpy(&buf->data.ta, pDevice->abyBSSID, ETH_ALEN); - else - memcpy(&buf->data.ta, psEthHeader->abySrcAddr, ETH_ALEN); + ether_addr_copy(buf->data.ra, hdr->addr1); + ether_addr_copy(buf->data.ta, hdr->addr2); } } else if (byPktType == PK_TYPE_11B) { struct vnt_rts_ab *buf = pvRTS; @@ -1016,17 +818,8 @@ s_vFillRTSHead( buf->data.frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - memcpy(&buf->data.ra, psEthHeader->abyDstAddr, ETH_ALEN); - } else { - memcpy(&buf->data.ra, pDevice->abyBSSID, ETH_ALEN); - } - - if (pDevice->op_mode == NL80211_IFTYPE_AP) - memcpy(&buf->data.ta, pDevice->abyBSSID, ETH_ALEN); - else - memcpy(&buf->data.ta, psEthHeader->abySrcAddr, ETH_ALEN); + ether_addr_copy(buf->data.ra, hdr->addr1); + ether_addr_copy(buf->data.ta, hdr->addr2); } } @@ -1093,7 +886,8 @@ s_vFillCTSHead( buf->reserved2 = 0x0; - memcpy(&buf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN); + ether_addr_copy(buf->data.ra, + pDevice->abyCurrentNetAddr); } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) struct vnt_cts *buf = pvCTS; /* Get SignalField, ServiceField & Length */ @@ -1116,7 +910,8 @@ s_vFillCTSHead( IEEE80211_STYPE_CTS); buf->reserved2 = 0x0; - memcpy(&buf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN); + ether_addr_copy(buf->data.ra, + pDevice->abyCurrentNetAddr); } } } @@ -1156,11 +951,10 @@ s_vGenerateTxParameter( unsigned int cbFrameSize, bool bNeedACK, unsigned int uDMAIdx, - PSEthernetHeader psEthHeader, + void *psEthHeader, unsigned short wCurrentRate ) { - unsigned int cbMACHdLen = WLAN_HDR_ADDR3_LEN; //24 unsigned short wFifoCtl; bool bDisCRC = false; unsigned char byFBOption = AUTO_FB_NONE; @@ -1178,9 +972,6 @@ s_vGenerateTxParameter( else if (wFifoCtl & FIFOCTL_AUTO_FB_1) byFBOption = AUTO_FB_1; - if (pDevice->bLongHeader) - cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6; - if (!pvRrvTime) return; @@ -1237,90 +1028,30 @@ s_vGenerateTxParameter( } } -static -void -s_vFillFragParameter( - struct vnt_private *pDevice, - unsigned char *pbyBuffer, - unsigned int uTxType, - void *pvtdCurr, - unsigned short wFragType, - unsigned int cbReqCount -) -{ - PSTxBufHead pTxBufHead = (PSTxBufHead) pbyBuffer; - - if (uTxType == TYPE_SYNCDMA) { - PSTxSyncDesc ptdCurr = (PSTxSyncDesc)pvtdCurr; - - //Set FIFOCtl & TimeStamp in TxSyncDesc - ptdCurr->m_wFIFOCtl = pTxBufHead->wFIFOCtl; - ptdCurr->m_wTimeStamp = pTxBufHead->wTimeStamp; - //Set TSR1 & ReqCount in TxDescHead - ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount)); - if (wFragType == FRAGCTL_ENDFRAG) //Last Fragmentation - ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); - else - ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP); - } else { - PSTxDesc ptdCurr = (PSTxDesc)pvtdCurr; - //Set TSR1 & ReqCount in TxDescHead - ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount)); - if (wFragType == FRAGCTL_ENDFRAG) //Last Fragmentation - ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); - else - ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP); - } - - pTxBufHead->wFragCtl |= (unsigned short)wFragType;//0x0001; //0000 0000 0000 0001 -} - static unsigned int s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, - unsigned char *pbyTxBufferAddr, unsigned int cbFrameBodySize, + unsigned char *pbyTxBufferAddr, unsigned int uDMAIdx, PSTxDesc pHeadTD, - PSEthernetHeader psEthHeader, unsigned char *pPacket, - bool bNeedEncrypt, PSKeyItem pTransmitKey, - unsigned int uNodeIndex, unsigned int *puMACfragNum) + unsigned int is_pspoll) { - unsigned int cbMACHdLen; + PDEVICE_TD_INFO td_info = pHeadTD->pTDInfo; + struct sk_buff *skb = td_info->skb; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct vnt_tx_fifo_head *tx_buffer_head = + (struct vnt_tx_fifo_head *)td_info->buf; + u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl); unsigned int cbFrameSize; - unsigned int cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS - unsigned int cbFragPayloadSize; - unsigned int cbLastFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS - unsigned int cbLastFragPayloadSize; - unsigned int uFragIdx; - unsigned char *pbyPayloadHead; - unsigned char *pbyIVHead; - unsigned char *pbyMacHdr; - unsigned short wFragType; //00:Non-Frag, 01:Start, 10:Mid, 11:Last __le16 uDuration; unsigned char *pbyBuffer; - unsigned int cbIVlen = 0; - unsigned int cbICVlen = 0; - unsigned int cbMIClen = 0; - unsigned int cbFCSlen = 4; - unsigned int cb802_1_H_len = 0; unsigned int uLength = 0; - unsigned int uTmpLen = 0; unsigned int cbMICHDR = 0; - u32 dwMICKey0, dwMICKey1; - u32 dwMIC_Priority; - u32 *pdwMIC_L; - u32 *pdwMIC_R; - u32 dwSafeMIC_L, dwSafeMIC_R; /* Fix "Last Frag Size" < "MIC length". */ - bool bMIC2Frag = false; - unsigned int uMICFragLen = 0; unsigned int uMACfragNum = 1; unsigned int uPadding = 0; unsigned int cbReqCount = 0; - - bool bNeedACK; - bool bRTS; - bool bIsAdhoc; - unsigned char *pbyType; + bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK); + bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS); PSTxDesc ptdCurr; - PSTxBufHead psTxBufHd = (PSTxBufHead) pbyTxBufferAddr; unsigned int cbHeaderLength = 0; void *pvRrvTime; struct vnt_mic_hdr *pMICHDR; @@ -1328,72 +1059,35 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, void *pvCTS; void *pvTxDataHd; unsigned short wTxBufSize; // FFinfo size - unsigned int uTotalCopyLength = 0; unsigned char byFBOption = AUTO_FB_NONE; - bool bIsWEP256 = false; - PSMgmtObject pMgmt = pDevice->pMgmt; pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL; - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0]))) - bNeedACK = false; - else - bNeedACK = true; - bIsAdhoc = true; - } else { - // MSDUs in Infra mode always need ACK - bNeedACK = true; - bIsAdhoc = false; - } + cbFrameSize = skb->len + 4; - if (pDevice->bLongHeader) - cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6; - else - cbMACHdLen = WLAN_HDR_ADDR3_LEN; - - if ((bNeedEncrypt == true) && (pTransmitKey != NULL)) { - if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { - cbIVlen = 4; - cbICVlen = 4; - if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN) - bIsWEP256 = true; - } - if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { - cbIVlen = 8;//IV+ExtIV - cbMIClen = 8; - cbICVlen = 4; - } - if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { - cbIVlen = 8;//RSN Header - cbICVlen = 8;//MIC + if (info->control.hw_key) { + switch (info->control.hw_key->cipher) { + case WLAN_CIPHER_SUITE_CCMP: cbMICHDR = sizeof(struct vnt_mic_hdr); + default: + break; } + + cbFrameSize += info->control.hw_key->icv_len; + if (pDevice->byLocalID > REV_ID_VT3253_A1) { //MAC Header should be padding 0 to DW alignment. - uPadding = 4 - (cbMACHdLen%4); + uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4); uPadding %= 4; } } - cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen; - - if ((bNeedACK == false) || - (cbFrameSize < pDevice->wRTSThreshold) || - ((cbFrameSize >= pDevice->wFragmentationThreshold) && (pDevice->wFragmentationThreshold <= pDevice->wRTSThreshold)) -) { - bRTS = false; - } else { - bRTS = true; - psTxBufHd->wFIFOCtl |= (FIFOCTL_RTS | FIFOCTL_LRETRY); - } // // Use for AUTO FALL BACK // - if (psTxBufHd->wFIFOCtl & FIFOCTL_AUTO_FB_0) + if (fifo_ctl & FIFOCTL_AUTO_FB_0) byFBOption = AUTO_FB_0; - else if (psTxBufHd->wFIFOCtl & FIFOCTL_AUTO_FB_1) + else if (fifo_ctl & FIFOCTL_AUTO_FB_1) byFBOption = AUTO_FB_1; ////////////////////////////////////////////////////// @@ -1487,1477 +1181,342 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, } } // Auto Fall Back } - memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize)); - -////////////////////////////////////////////////////////////////// - if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - if (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]); - dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]); - } else if ((pTransmitKey->dwKeyIndex & AUTHENTICATOR_KEY) != 0) { - dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]); - dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]); - } else { - dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[24]); - dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[28]); - } - // DO Software Michael - MIC_vInit(dwMICKey0, dwMICKey1); - MIC_vAppend((unsigned char *)&(psEthHeader->abyDstAddr[0]), 12); - dwMIC_Priority = 0; - MIC_vAppend((unsigned char *)&dwMIC_Priority, 4); - pr_debug("MIC KEY: %X, %X\n", dwMICKey0, dwMICKey1); - } - -/////////////////////////////////////////////////////////////////// - - pbyMacHdr = (unsigned char *)(pbyTxBufferAddr + cbHeaderLength); - pbyPayloadHead = (unsigned char *)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen); - pbyIVHead = (unsigned char *)(pbyMacHdr + cbMACHdLen + uPadding); - - if ((cbFrameSize > pDevice->wFragmentationThreshold) && (bNeedACK == true) && (bIsWEP256 == false)) { - // Fragmentation - // FragThreshold = Fragment size(Hdr+(IV)+fragment payload+(MIC)+(ICV)+FCS) - cbFragmentSize = pDevice->wFragmentationThreshold; - cbFragPayloadSize = cbFragmentSize - cbMACHdLen - cbIVlen - cbICVlen - cbFCSlen; - //FragNum = (FrameSize-(Hdr+FCS))/(Fragment Size -(Hrd+FCS))) - uMACfragNum = (unsigned short) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize); - cbLastFragPayloadSize = (cbFrameBodySize + cbMIClen) % cbFragPayloadSize; - if (cbLastFragPayloadSize == 0) - cbLastFragPayloadSize = cbFragPayloadSize; - else - uMACfragNum++; - - //[Hdr+(IV)+last fragment payload+(MIC)+(ICV)+FCS] - cbLastFragmentSize = cbMACHdLen + cbLastFragPayloadSize + cbIVlen + cbICVlen + cbFCSlen; - - for (uFragIdx = 0; uFragIdx < uMACfragNum; uFragIdx++) { - if (uFragIdx == 0) { - //========================= - // Start Fragmentation - //========================= - pr_debug("Start Fragmentation...\n"); - wFragType = FRAGCTL_STAFRAG; - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS, - cbFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); - //Fill DataHead - uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK, - uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate); - // Generate TX MAC Header - vGenerateMACHeader(pDevice, pbyMacHdr, uDuration, psEthHeader, bNeedEncrypt, - wFragType, uDMAIdx, uFragIdx); - - if (bNeedEncrypt == true) { - //Fill TXKEY - s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (unsigned short)cbFragPayloadSize, (unsigned char *)pMICHDR); - //Fill IV(ExtIV,RSNHDR) - if (pDevice->bEnableHostWEP) { - pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; - pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; - } - } - - // 802.1H - if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) { - if ((psEthHeader->wType == TYPE_PKT_IPX) || - (psEthHeader->wType == cpu_to_le16(0xF380))) { - memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6); - } else { - memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6); - } - pbyType = (unsigned char *)(pbyPayloadHead + 6); - memcpy(pbyType, &(psEthHeader->wType), sizeof(unsigned short)); - cb802_1_H_len = 8; - } - - cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbFragPayloadSize; - //--------------------------- - // S/W or H/W Encryption - //--------------------------- - pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; - - uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len; - //copy TxBufferHeader + MacHeader to desc - memcpy(pbyBuffer, (void *)psTxBufHd, uLength); - - // Copy the Packet into a tx Buffer - memcpy((pbyBuffer + uLength), (pPacket + 14), (cbFragPayloadSize - cb802_1_H_len)); - - uTotalCopyLength += cbFragPayloadSize - cb802_1_H_len; - - if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - pr_debug("Start MIC: %d\n", - cbFragPayloadSize); - MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFragPayloadSize); - - } - - //--------------------------- - // S/W Encryption - //--------------------------- - if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { - if (bNeedEncrypt) { - s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength - cb802_1_H_len), (unsigned short)cbFragPayloadSize); - cbReqCount += cbICVlen; - } - } - - ptdCurr = (PSTxDesc)pHeadTD; - //-------------------- - //1.Set TSR1 & ReqCount in TxDescHead - //2.Set FragCtl in TxBufferHead - //3.Set Frame Control - //4.Set Sequence Control - //5.Get S/W generate FCS - //-------------------- - s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (void *)ptdCurr, wFragType, cbReqCount); - - ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; - ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; - ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; - ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); - pDevice->iTDUsed[uDMAIdx]++; - pHeadTD = ptdCurr->next; - } else if (uFragIdx == (uMACfragNum-1)) { - //========================= - // Last Fragmentation - //========================= - pr_debug("Last Fragmentation...\n"); - - wFragType = FRAGCTL_ENDFRAG; - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS, - cbLastFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); - //Fill DataHead - uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbLastFragmentSize, uDMAIdx, bNeedACK, - uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate); - - // Generate TX MAC Header - vGenerateMACHeader(pDevice, pbyMacHdr, uDuration, psEthHeader, bNeedEncrypt, - wFragType, uDMAIdx, uFragIdx); - - if (bNeedEncrypt == true) { - //Fill TXKEY - s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (unsigned short)cbLastFragPayloadSize, (unsigned char *)pMICHDR); - - if (pDevice->bEnableHostWEP) { - pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; - pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; - } - - } - - cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbLastFragPayloadSize; - //--------------------------- - // S/W or H/W Encryption - //--------------------------- - - pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; - - uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen; - - //copy TxBufferHeader + MacHeader to desc - memcpy(pbyBuffer, (void *)psTxBufHd, uLength); - - // Copy the Packet into a tx Buffer - if (bMIC2Frag == false) { - memcpy((pbyBuffer + uLength), - (pPacket + 14 + uTotalCopyLength), - (cbLastFragPayloadSize - cbMIClen) -); - //TODO check uTmpLen ! - uTmpLen = cbLastFragPayloadSize - cbMIClen; - - } - if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - pr_debug("LAST: uMICFragLen:%d, cbLastFragPayloadSize:%d, uTmpLen:%d\n", - uMICFragLen, - cbLastFragPayloadSize, - uTmpLen); - - if (bMIC2Frag == false) { - if (uTmpLen != 0) - MIC_vAppend((pbyBuffer + uLength), uTmpLen); - pdwMIC_L = (u32 *)(pbyBuffer + uLength + uTmpLen); - pdwMIC_R = (u32 *)(pbyBuffer + uLength + uTmpLen + 4); - MIC_vGetMIC(pdwMIC_L, pdwMIC_R); - pr_debug("Last MIC:%X, %X\n", - *pdwMIC_L, *pdwMIC_R); - } else { - if (uMICFragLen >= 4) { - memcpy((pbyBuffer + uLength), ((unsigned char *)&dwSafeMIC_R + (uMICFragLen - 4)), - (cbMIClen - uMICFragLen)); - pr_debug("LAST: uMICFragLen >= 4: %X, %d\n", - *(unsigned char *)((unsigned char *)&dwSafeMIC_R + (uMICFragLen - 4)), - (cbMIClen - uMICFragLen)); - - } else { - memcpy((pbyBuffer + uLength), ((unsigned char *)&dwSafeMIC_L + uMICFragLen), - (4 - uMICFragLen)); - memcpy((pbyBuffer + uLength + (4 - uMICFragLen)), &dwSafeMIC_R, 4); - pr_debug("LAST: uMICFragLen < 4: %X, %d\n", - *(unsigned char *)((unsigned char *)&dwSafeMIC_R + uMICFragLen - 4), - (cbMIClen - uMICFragLen)); - } - } - MIC_vUnInit(); - } else { - ASSERT(uTmpLen == (cbLastFragPayloadSize - cbMIClen)); - } - - //--------------------------- - // S/W Encryption - //--------------------------- - if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { - if (bNeedEncrypt) { - s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength), (unsigned short)cbLastFragPayloadSize); - cbReqCount += cbICVlen; - } - } - - ptdCurr = (PSTxDesc)pHeadTD; - - //-------------------- - //1.Set TSR1 & ReqCount in TxDescHead - //2.Set FragCtl in TxBufferHead - //3.Set Frame Control - //4.Set Sequence Control - //5.Get S/W generate FCS - //-------------------- - - s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (void *)ptdCurr, wFragType, cbReqCount); - - ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; - ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; - ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; - ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); - pDevice->iTDUsed[uDMAIdx]++; - pHeadTD = ptdCurr->next; - - } else { - //========================= - // Middle Fragmentation - //========================= - pr_debug("Middle Fragmentation...\n"); - - wFragType = FRAGCTL_MIDFRAG; - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS, - cbFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); - //Fill DataHead - uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK, - uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate); - - // Generate TX MAC Header - vGenerateMACHeader(pDevice, pbyMacHdr, uDuration, psEthHeader, bNeedEncrypt, - wFragType, uDMAIdx, uFragIdx); - - if (bNeedEncrypt == true) { - //Fill TXKEY - s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (unsigned short)cbFragPayloadSize, (unsigned char *)pMICHDR); - - if (pDevice->bEnableHostWEP) { - pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; - pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; - } - } - - cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbFragPayloadSize; - //--------------------------- - // S/W or H/W Encryption - //--------------------------- - - pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; - uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen; - - //copy TxBufferHeader + MacHeader to desc - memcpy(pbyBuffer, (void *)psTxBufHd, uLength); - - // Copy the Packet into a tx Buffer - memcpy((pbyBuffer + uLength), - (pPacket + 14 + uTotalCopyLength), - cbFragPayloadSize -); - uTmpLen = cbFragPayloadSize; - - uTotalCopyLength += uTmpLen; - - if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - MIC_vAppend((pbyBuffer + uLength), uTmpLen); - - if (uTmpLen < cbFragPayloadSize) { - bMIC2Frag = true; - uMICFragLen = cbFragPayloadSize - uTmpLen; - ASSERT(uMICFragLen < cbMIClen); - - pdwMIC_L = (u32 *)(pbyBuffer + uLength + uTmpLen); - pdwMIC_R = (u32 *)(pbyBuffer + uLength + uTmpLen + 4); - MIC_vGetMIC(pdwMIC_L, pdwMIC_R); - dwSafeMIC_L = *pdwMIC_L; - dwSafeMIC_R = *pdwMIC_R; - - pr_debug("MIDDLE: uMICFragLen:%d, cbFragPayloadSize:%d, uTmpLen:%d\n", - uMICFragLen, - cbFragPayloadSize, - uTmpLen); - pr_debug("Fill MIC in Middle frag [%d]\n", - uMICFragLen); - pr_debug("Get MIC:%X, %X\n", - *pdwMIC_L, *pdwMIC_R); - } - pr_debug("Middle frag len: %d\n", - uTmpLen); - - } else { - ASSERT(uTmpLen == (cbFragPayloadSize)); - } - - if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { - if (bNeedEncrypt) { - s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength), (unsigned short)cbFragPayloadSize); - cbReqCount += cbICVlen; - } - } - - ptdCurr = (PSTxDesc)pHeadTD; - - //-------------------- - //1.Set TSR1 & ReqCount in TxDescHead - //2.Set FragCtl in TxBufferHead - //3.Set Frame Control - //4.Set Sequence Control - //5.Get S/W generate FCS - //-------------------- - - s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (void *)ptdCurr, wFragType, cbReqCount); - - ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; - ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; - ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; - ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); - pDevice->iTDUsed[uDMAIdx]++; - pHeadTD = ptdCurr->next; - } - } // for (uMACfragNum) - } else { - //========================= - // No Fragmentation - //========================= - wFragType = FRAGCTL_NONFRAG; - - //Set FragCtl in TxBufferHead - psTxBufHd->wFragCtl |= (unsigned short)wFragType; - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS, - cbFrameSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); - //Fill DataHead - uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK, - 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate); - - // Generate TX MAC Header - vGenerateMACHeader(pDevice, pbyMacHdr, uDuration, psEthHeader, bNeedEncrypt, - wFragType, uDMAIdx, 0); - - if (bNeedEncrypt == true) { - //Fill TXKEY - s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (unsigned short)cbFrameBodySize, (unsigned char *)pMICHDR); - - if (pDevice->bEnableHostWEP) { - pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; - pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; - } - } - - // 802.1H - if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) { - if ((psEthHeader->wType == TYPE_PKT_IPX) || - (psEthHeader->wType == cpu_to_le16(0xF380))) { - memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6); - } else { - memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6); - } - pbyType = (unsigned char *)(pbyPayloadHead + 6); - memcpy(pbyType, &(psEthHeader->wType), sizeof(unsigned short)); - cb802_1_H_len = 8; - } - - cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen); - //--------------------------- - // S/W or H/W Encryption - //--------------------------- - pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; - uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len; - //copy TxBufferHeader + MacHeader to desc - memcpy(pbyBuffer, (void *)psTxBufHd, uLength); + td_info->mic_hdr = pMICHDR; - // Copy the Packet into a tx Buffer - memcpy((pbyBuffer + uLength), - (pPacket + 14), - cbFrameBodySize - cb802_1_H_len -); - - if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - pr_debug("Length:%d, %d\n", - cbFrameBodySize - cb802_1_H_len, uLength); - - MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFrameBodySize); - - pdwMIC_L = (u32 *)(pbyBuffer + uLength - cb802_1_H_len + cbFrameBodySize); - pdwMIC_R = (u32 *)(pbyBuffer + uLength - cb802_1_H_len + cbFrameBodySize + 4); - - MIC_vGetMIC(pdwMIC_L, pdwMIC_R); - MIC_vUnInit(); - - if (pDevice->bTxMICFail == true) { - *pdwMIC_L = 0; - *pdwMIC_R = 0; - pDevice->bTxMICFail = false; - } + memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize)); - pr_debug("uLength: %d, %d\n", uLength, cbFrameBodySize); - pr_debug("cbReqCount:%d, %d, %d, %d\n", - cbReqCount, cbHeaderLength, uPadding, cbIVlen); - pr_debug("MIC:%x, %x\n", *pdwMIC_L, *pdwMIC_R); + /* Fill FIFO,RrvTime,RTS,and CTS */ + s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS, + cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate); + /* Fill DataHead */ + uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK, + 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll); - } + hdr->duration_id = uDuration; - if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { - if (bNeedEncrypt) { - s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength - cb802_1_H_len), - (unsigned short)(cbFrameBodySize + cbMIClen)); - cbReqCount += cbICVlen; - } - } + cbReqCount = cbHeaderLength + uPadding + skb->len; + pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; + uLength = cbHeaderLength + uPadding; - ptdCurr = (PSTxDesc)pHeadTD; + /* Copy the Packet into a tx Buffer */ + memcpy((pbyBuffer + uLength), skb->data, skb->len); - ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; - ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; - ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; - ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); - //Set TSR1 & ReqCount in TxDescHead - ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); - ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount)); + ptdCurr = (PSTxDesc)pHeadTD; - pDevice->iTDUsed[uDMAIdx]++; - - } - *puMACfragNum = uMACfragNum; + ptdCurr->pTDInfo->dwReqCount = cbReqCount; + ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; + ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; + ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); return cbHeaderLength; } -void -vGenerateFIFOHeader(struct vnt_private *pDevice, unsigned char byPktType, - unsigned char *pbyTxBufferAddr, bool bNeedEncrypt, - unsigned int cbPayloadSize, unsigned int uDMAIdx, - PSTxDesc pHeadTD, PSEthernetHeader psEthHeader, unsigned char *pPacket, - PSKeyItem pTransmitKey, unsigned int uNodeIndex, unsigned int *puMACfragNum, - unsigned int *pcbHeaderSize) +static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer, + struct ieee80211_key_conf *tx_key, + struct sk_buff *skb, u16 payload_len, + struct vnt_mic_hdr *mic_hdr) { - unsigned int wTxBufSize; // FFinfo size - bool bNeedACK; - bool bIsAdhoc; - unsigned short cbMacHdLen; - PSTxBufHead pTxBufHead = (PSTxBufHead) pbyTxBufferAddr; - - wTxBufSize = sizeof(STxBufHead); - - memset(pTxBufHead, 0, wTxBufSize); - //Set FIFOCTL_NEEDACK - - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0]))) { - bNeedACK = false; - pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK); - } else { - bNeedACK = true; - pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; + struct ieee80211_key_seq seq; + u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb)); + + /* strip header and icv len from payload */ + payload_len -= ieee80211_get_hdrlen_from_skb(skb); + payload_len -= tx_key->icv_len; + + switch (tx_key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + memcpy(key_buffer, iv, 3); + memcpy(key_buffer + 3, tx_key->key, tx_key->keylen); + + if (tx_key->keylen == WLAN_KEY_LEN_WEP40) { + memcpy(key_buffer + 8, iv, 3); + memcpy(key_buffer + 11, + tx_key->key, WLAN_KEY_LEN_WEP40); } - bIsAdhoc = true; - } else { - // MSDUs in Infra mode always need ACK - bNeedACK = true; - pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; - bIsAdhoc = false; - } - - pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN; - pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us); - - //Set FIFOCTL_LHEAD - if (pDevice->bLongHeader) - pTxBufHead->wFIFOCtl |= FIFOCTL_LHEAD; - //Set FIFOCTL_GENINT - - pTxBufHead->wFIFOCtl |= FIFOCTL_GENINT; - - //Set FIFOCTL_ISDMA0 - if (TYPE_TXDMA0 == uDMAIdx) - pTxBufHead->wFIFOCtl |= FIFOCTL_ISDMA0; - - //Set FRAGCTL_MACHDCNT - if (pDevice->bLongHeader) - cbMacHdLen = WLAN_HDR_ADDR3_LEN + 6; - else - cbMacHdLen = WLAN_HDR_ADDR3_LEN; - - pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)(cbMacHdLen << 10)); - - //Set packet type - if (byPktType == PK_TYPE_11A) //0000 0000 0000 0000 - ; - else if (byPktType == PK_TYPE_11B) //0000 0001 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11B; - else if (byPktType == PK_TYPE_11GB) //0000 0010 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11GB; - else if (byPktType == PK_TYPE_11GA) //0000 0011 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11GA; - - //Set FIFOCTL_GrpAckPolicy - if (pDevice->bGrpAckPolicy == true) //0000 0100 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK; - - //Set Auto Fallback Ctl - if (pDevice->wCurrentRate >= RATE_18M) { - if (pDevice->byAutoFBCtrl == AUTO_FB_0) - pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0; - else if (pDevice->byAutoFBCtrl == AUTO_FB_1) - pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1; - } - - //Set FRAGCTL_WEPTYP - pDevice->bAES = false; - - //Set FRAGCTL_WEPTYP - if (pDevice->byLocalID > REV_ID_VT3253_A1) { - if ((bNeedEncrypt) && (pTransmitKey != NULL)) { //WEP enabled - if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { - pTxBufHead->wFragCtl |= FRAGCTL_TKIP; - } else if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { //WEP40 or WEP104 - if (pTransmitKey->uKeyLength != WLAN_WEP232_KEYLEN) - pTxBufHead->wFragCtl |= FRAGCTL_LEGACY; - } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { //CCMP - pTxBufHead->wFragCtl |= FRAGCTL_AES; - } - } - } - - RFbSetPower(pDevice, pDevice->wCurrentRate, pDevice->byCurrentCh); - - pTxBufHead->byTxPower = pDevice->byCurPwr; - - *pcbHeaderSize = s_cbFillTxBufHead(pDevice, byPktType, pbyTxBufferAddr, cbPayloadSize, - uDMAIdx, pHeadTD, psEthHeader, pPacket, bNeedEncrypt, - pTransmitKey, uNodeIndex, puMACfragNum); -} + break; + case WLAN_CIPHER_SUITE_TKIP: + ieee80211_get_tkip_p2k(tx_key, skb, key_buffer); -/*+ - * - * Description: - * Translate 802.3 to 802.11 header - * - * Parameters: - * In: - * pDevice - Pointer to adapter - * dwTxBufferAddr - Transmit Buffer - * pPacket - Packet from upper layer - * cbPacketSize - Transmit Data Length - * Out: - * pcbHeadSize - Header size of MAC&Baseband control and 802.11 Header - * pcbAppendPayload - size of append payload for 802.1H translation - * - * Return Value: none - * - -*/ + break; + case WLAN_CIPHER_SUITE_CCMP: -void -vGenerateMACHeader( - struct vnt_private *pDevice, - unsigned char *pbyBufferAddr, - __le16 wDuration, - PSEthernetHeader psEthHeader, - bool bNeedEncrypt, - unsigned short wFragType, - unsigned int uDMAIdx, - unsigned int uFragIdx -) -{ - PS802_11Header pMACHeader = (PS802_11Header)pbyBufferAddr; + if (!mic_hdr) + return; - memset(pMACHeader, 0, (sizeof(S802_11Header))); + mic_hdr->id = 0x59; + mic_hdr->payload_len = cpu_to_be16(payload_len); + ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2); - if (uDMAIdx == TYPE_ATIMDMA) - pMACHeader->wFrameCtl = TYPE_802_11_ATIM; - else - pMACHeader->wFrameCtl = TYPE_802_11_DATA; + ieee80211_get_key_tx_seq(tx_key, &seq); - if (pDevice->op_mode == NL80211_IFTYPE_AP) { - memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr2[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); - pMACHeader->wFrameCtl |= FC_FROMDS; - } else { - if (pDevice->op_mode == NL80211_IFTYPE_ADHOC) { - memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr3[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); - } else { - memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr1[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); - pMACHeader->wFrameCtl |= FC_TODS; - } - } + memcpy(mic_hdr->ccmp_pn, seq.ccmp.pn, IEEE80211_CCMP_PN_LEN); - if (bNeedEncrypt) - pMACHeader->wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_ISWEP(1)); + if (ieee80211_has_a4(hdr->frame_control)) + mic_hdr->hlen = cpu_to_be16(28); + else + mic_hdr->hlen = cpu_to_be16(22); - pMACHeader->wDurationID = le16_to_cpu(wDuration); + ether_addr_copy(mic_hdr->addr1, hdr->addr1); + ether_addr_copy(mic_hdr->addr2, hdr->addr2); + ether_addr_copy(mic_hdr->addr3, hdr->addr3); - if (pDevice->bLongHeader) { - PWLAN_80211HDR_A4 pMACA4Header = (PWLAN_80211HDR_A4) pbyBufferAddr; + mic_hdr->frame_control = cpu_to_le16( + le16_to_cpu(hdr->frame_control) & 0xc78f); + mic_hdr->seq_ctrl = cpu_to_le16( + le16_to_cpu(hdr->seq_ctrl) & 0xf); - pMACHeader->wFrameCtl |= (FC_TODS | FC_FROMDS); - memcpy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN); - } - pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); + if (ieee80211_has_a4(hdr->frame_control)) + ether_addr_copy(mic_hdr->addr4, hdr->addr4); - //Set FragNumber in Sequence Control - pMACHeader->wSeqCtl |= cpu_to_le16((unsigned short)uFragIdx); + memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP); - if ((wFragType == FRAGCTL_ENDFRAG) || (wFragType == FRAGCTL_NONFRAG)) { - pDevice->wSeqCounter++; - if (pDevice->wSeqCounter > 0x0fff) - pDevice->wSeqCounter = 0; + break; + default: + break; } - - if ((wFragType == FRAGCTL_STAFRAG) || (wFragType == FRAGCTL_MIDFRAG)) //StartFrag or MidFrag - pMACHeader->wFrameCtl |= FC_MOREFRAG; } -CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, PSTxMgmtPacket pPacket) +int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx, + PSTxDesc head_td, struct sk_buff *skb) { - PSTxDesc pFrstTD; - unsigned char byPktType; - unsigned char *pbyTxBufferAddr; - void *pvRTS; - struct vnt_cts *pCTS; - void *pvTxDataHd; - unsigned int uDuration; - unsigned int cbReqCount; - PS802_11Header pMACHeader; - unsigned int cbHeaderSize; - unsigned int cbFrameBodySize; - bool bNeedACK; - bool bIsPSPOLL = false; - PSTxBufHead pTxBufHead; - unsigned int cbFrameSize; - unsigned int cbIVlen = 0; - unsigned int cbICVlen = 0; - unsigned int cbMIClen = 0; - unsigned int cbFCSlen = 4; - unsigned int uPadding = 0; - unsigned short wTxBufSize; - unsigned int cbMacHdLen; - SEthernetHeader sEthHeader; - void *pvRrvTime; - void *pMICHDR; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned short wCurrentRate = RATE_1M; - - if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) - return CMD_STATUS_RESOURCES; - - pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0]; - pbyTxBufferAddr = (unsigned char *)pFrstTD->pTDInfo->buf; - cbFrameBodySize = pPacket->cbPayloadLen; - pTxBufHead = (PSTxBufHead) pbyTxBufferAddr; - wTxBufSize = sizeof(STxBufHead); - memset(pTxBufHead, 0, wTxBufSize); - - if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { - wCurrentRate = RATE_6M; - byPktType = PK_TYPE_11A; - } else { - wCurrentRate = RATE_1M; - byPktType = PK_TYPE_11B; + PDEVICE_TD_INFO td_info = head_td->pTDInfo; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_tx_rate *tx_rate = &info->control.rates[0]; + struct ieee80211_rate *rate; + struct ieee80211_key_conf *tx_key; + struct ieee80211_hdr *hdr; + struct vnt_tx_fifo_head *tx_buffer_head = + (struct vnt_tx_fifo_head *)td_info->buf; + u16 tx_body_size = skb->len, current_rate; + u8 pkt_type; + bool is_pspoll = false; + + memset(tx_buffer_head, 0, sizeof(*tx_buffer_head)); + + hdr = (struct ieee80211_hdr *)(skb->data); + + rate = ieee80211_get_tx_rate(priv->hw, info); + + current_rate = rate->hw_value; + if (priv->wCurrentRate != current_rate && + !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) { + priv->wCurrentRate = current_rate; + + RFbSetPower(priv, priv->wCurrentRate, + priv->hw->conf.chandef.chan->hw_value); } - // SetPower will cause error power TX state for OFDM Date packet in TX buffer. - // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability. - // And cmd timer will wait data pkt TX finish before scanning so it's OK - // to set power here. - if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) - RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh); + if (current_rate > RATE_11M) + pkt_type = (u8)priv->byPacketType; else - RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel); - - pTxBufHead->byTxPower = pDevice->byCurPwr; - //+++++++++++++++++++++ Patch VT3253 A1 performance +++++++++++++++++++++++++++ - if (pDevice->byFOETuning) { - if ((pPacket->p80211Header->sA3.wFrameCtl & TYPE_DATE_NULL) == TYPE_DATE_NULL) { - wCurrentRate = RATE_24M; - byPktType = PK_TYPE_11GA; - } - } - - //Set packet type - if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000 - pTxBufHead->wFIFOCtl = 0; - } else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11B; - } else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11GB; - } else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11GA; + pkt_type = PK_TYPE_11B; + + /*Set fifo controls */ + if (pkt_type == PK_TYPE_11A) + tx_buffer_head->fifo_ctl = 0; + else if (pkt_type == PK_TYPE_11B) + tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B); + else if (pkt_type == PK_TYPE_11GB) + tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB); + else if (pkt_type == PK_TYPE_11GA) + tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA); + + /* generate interrupt */ + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT); + + if (!ieee80211_is_data(hdr->frame_control)) { + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN); + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0); + tx_buffer_head->time_stamp = + cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us); + } else { + tx_buffer_head->time_stamp = + cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us); } - pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN; - pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us); + if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK); - if (is_multicast_ether_addr(&(pPacket->p80211Header->sA3.abyAddr1[0]))) - bNeedACK = false; - else { - bNeedACK = true; - pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; - } + if (ieee80211_has_retry(hdr->frame_control)) + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY); - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || - (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { - pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY; - } + if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) + priv->byPreambleType = PREAMBLE_SHORT; + else + priv->byPreambleType = PREAMBLE_LONG; - pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0); + if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS) + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS); - if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) { - bIsPSPOLL = true; - cbMacHdLen = WLAN_HDR_ADDR2_LEN; - } else { - cbMacHdLen = WLAN_HDR_ADDR3_LEN; + if (ieee80211_has_a4(hdr->frame_control)) { + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD); + priv->bLongHeader = true; } - //Set FRAGCTL_MACHDCNT - pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)(cbMacHdLen << 10)); - - // Notes: - // Although spec says MMPDU can be fragmented; In most cases, - // no one will send a MMPDU under fragmentation. With RTS may occur. - pDevice->bAES = false; //Set FRAGCTL_WEPTYP - - if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) { - if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) { - cbIVlen = 4; - cbICVlen = 4; - pTxBufHead->wFragCtl |= FRAGCTL_LEGACY; - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { - cbIVlen = 8;//IV+ExtIV - cbMIClen = 8; - cbICVlen = 4; - pTxBufHead->wFragCtl |= FRAGCTL_TKIP; - //We need to get seed here for filling TxKey entry. - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - cbIVlen = 8;//RSN Header - cbICVlen = 8;//MIC - pTxBufHead->wFragCtl |= FRAGCTL_AES; - pDevice->bAES = true; + if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER) + is_pspoll = true; + + tx_buffer_head->frag_ctl = + cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10); + + if (info->control.hw_key) { + tx_key = info->control.hw_key; + + switch (info->control.hw_key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY); + break; + case WLAN_CIPHER_SUITE_TKIP: + tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP); + break; + case WLAN_CIPHER_SUITE_CCMP: + tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES); + default: + break; } - //MAC Header should be padding 0 to DW alignment. - uPadding = 4 - (cbMacHdLen%4); - uPadding %= 4; } - cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen; - - //Set FIFOCTL_GrpAckPolicy - if (pDevice->bGrpAckPolicy == true) //0000 0100 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK; + tx_buffer_head->current_rate = cpu_to_le16(current_rate); - //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter() + /* legacy rates TODO use ieee80211_tx_rate */ + if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) { + if (priv->byAutoFBCtrl == AUTO_FB_0) + tx_buffer_head->fifo_ctl |= + cpu_to_le16(FIFOCTL_AUTO_FB_0); + else if (priv->byAutoFBCtrl == AUTO_FB_1) + tx_buffer_head->fifo_ctl |= + cpu_to_le16(FIFOCTL_AUTO_FB_1); - //Set RrvTime/RTS/CTS Buffer - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet - pvRrvTime = (void *) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = NULL; - pvRTS = NULL; - pCTS = (struct vnt_cts *)(pbyTxBufferAddr + wTxBufSize + - sizeof(struct vnt_rrv_time_cts)); - pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + - sizeof(struct vnt_rrv_time_cts) + sizeof(struct vnt_cts)); - cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) + - sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g); - } else { // 802.11a/b packet - pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize); - pMICHDR = NULL; - pvRTS = NULL; - pCTS = NULL; - pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + - sizeof(struct vnt_rrv_time_ab)); - cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) + - sizeof(struct vnt_tx_datahead_ab); } - memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); - - memcpy(&(sEthHeader.abyDstAddr[0]), &(pPacket->p80211Header->sA3.abyAddr1[0]), ETH_ALEN); - memcpy(&(sEthHeader.abySrcAddr[0]), &(pPacket->p80211Header->sA3.abyAddr2[0]), ETH_ALEN); - //========================= - // No Fragmentation - //========================= - pTxBufHead->wFragCtl |= (unsigned short)FRAGCTL_NONFRAG; - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, pbyTxBufferAddr, pvRrvTime, pvRTS, pCTS, - cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, wCurrentRate); - - //Fill DataHead - uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK, - 0, 0, 1, AUTO_FB_NONE, wCurrentRate); - - pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize); - - cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize; - - if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) { - unsigned char *pbyIVHead; - unsigned char *pbyPayloadHead; - unsigned char *pbyBSSID; - PSKeyItem pTransmitKey = NULL; - - pbyIVHead = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding); - pbyPayloadHead = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen); - - //Fill TXKEY - //Kyle: Need fix: TKIP and AES did't encrypt Mnt Packet. - //s_vFillTxKey(pDevice, (unsigned char *)pTxBufHead->adwTxKey, NULL); - - //Fill IV(ExtIV,RSNHDR) - //s_vFillPrePayload(pDevice, pbyIVHead, NULL); - //--------------------------- - // S/W or H/W Encryption - //--------------------------- - do { - if ((pDevice->op_mode == NL80211_IFTYPE_STATION) && - (pDevice->bLinkPass == true)) { - pbyBSSID = pDevice->abyBSSID; - // get pairwise key - if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) { - // get group key - if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) { - pr_debug("Get GTK\n"); - break; - } - } else { - pr_debug("Get PTK\n"); - break; - } - } - // get group key - pbyBSSID = pDevice->abyBroadcastAddr; - if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) { - pTransmitKey = NULL; - pr_debug("KEY is NULL. OP Mode[%d]\n", - pDevice->op_mode); - } else { - pr_debug("Get GTK\n"); - } - } while (false); - //Fill TXKEY - s_vFillTxKey(pDevice, (unsigned char *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey, - (unsigned char *)pMACHeader, (unsigned short)cbFrameBodySize, NULL); - - memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen); - memcpy(pbyPayloadHead, ((unsigned char *)(pPacket->p80211Header) + cbMacHdLen), - cbFrameBodySize); - } else { - // Copy the Packet into a tx Buffer - memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen); - } + tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG); - pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); - pDevice->wSeqCounter++; - if (pDevice->wSeqCounter > 0x0fff) - pDevice->wSeqCounter = 0; - - if (bIsPSPOLL) { - // The MAC will automatically replace the Duration-field of MAC header by Duration-field - // of FIFO control header. - // This will cause AID-field of PS-POLL packet to be incorrect (Because PS-POLL's AID field is - // in the same place of other packet's Duration-field). - // And it will cause Cisco-AP to issue Disassociation-packet - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { - ((struct vnt_tx_datahead_g *)pvTxDataHd)->duration_a = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID); - ((struct vnt_tx_datahead_g *)pvTxDataHd)->duration_b = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID); - } else { - ((struct vnt_tx_datahead_ab *)pvTxDataHd)->duration = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID); - } - } + s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head, + dma_idx, head_td, is_pspoll); - // first TD is the only TD - //Set TSR1 & ReqCount in TxDescHead - pFrstTD->m_td1TD1.byTCR = (TCR_STP | TCR_EDP | EDMSDU); - pFrstTD->pTDInfo->skb_dma = pFrstTD->pTDInfo->buf_dma; - pFrstTD->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount)); - pFrstTD->buff_addr = cpu_to_le32(pFrstTD->pTDInfo->skb_dma); - pFrstTD->pTDInfo->byFlags = 0; - - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { - // Disable PS - MACbPSWakeup(pDevice->PortOffset); + if (info->control.hw_key) { + tx_key = info->control.hw_key; + if (tx_key->keylen > 0) + vnt_fill_txkey(hdr, tx_buffer_head->tx_key, + tx_key, skb, tx_body_size, td_info->mic_hdr); } - pDevice->bPWBitOn = false; - - wmb(); - pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC; - wmb(); - - pDevice->iTDUsed[TYPE_TXDMA0]++; - - if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1) - pr_debug(" available td0 <= 1\n"); - - pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next; - - pDevice->nTxDataTimeCout = 0; //2008-8-21 chester <add> for send null packet - // Poll Transmit the adapter - MACvTransmit0(pDevice->PortOffset); - - return CMD_STATUS_PENDING; + return 0; } -CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice, PSTxMgmtPacket pPacket) +static int vnt_beacon_xmit(struct vnt_private *priv, + struct sk_buff *skb) { - unsigned char byPktType; - unsigned char *pbyBuffer = (unsigned char *)pDevice->tx_beacon_bufs; - unsigned int cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN; - unsigned int cbHeaderSize = 0; struct vnt_tx_short_buf_head *short_head = - (struct vnt_tx_short_buf_head *)pbyBuffer; - PS802_11Header pMACHeader; - unsigned short wCurrentRate; - - memset(short_head, 0, sizeof(*short_head)); + (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs; + struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *) + (priv->tx_beacon_bufs + sizeof(*short_head)); + struct ieee80211_tx_info *info; + u32 frame_size = skb->len + 4; + u16 current_rate; - if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { - wCurrentRate = RATE_6M; - byPktType = PK_TYPE_11A; - } else { - wCurrentRate = RATE_2M; - byPktType = PK_TYPE_11B; - } + memset(priv->tx_beacon_bufs, 0, sizeof(*short_head)); - //Set Preamble type always long - pDevice->byPreambleType = PREAMBLE_LONG; + if (priv->byBBType == BB_TYPE_11A) { + current_rate = RATE_6M; - /* Set FIFOCTL_GENINT */ - short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT); - - /* Set packet type & Get Duration */ - if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000 - short_head->duration = - cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, - cbFrameSize, byPktType, wCurrentRate, false, - 0, 0, 1, AUTO_FB_NONE)); - } else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000 - short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B); + /* Get SignalField,ServiceField,Length */ + vnt_get_phy_field(priv, frame_size, current_rate, + PK_TYPE_11A, &short_head->ab); + /* Get Duration and TimeStampOff */ short_head->duration = - cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, - cbFrameSize, byPktType, wCurrentRate, false, - 0, 0, 1, AUTO_FB_NONE)); - } - - vnt_get_phy_field(pDevice, cbFrameSize, - wCurrentRate, byPktType, &short_head->ab); - - /* Get TimeStampOff */ - short_head->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate); - cbHeaderSize = sizeof(struct vnt_tx_short_buf_head); - - //Generate Beacon Header - pMACHeader = (PS802_11Header)(pbyBuffer + cbHeaderSize); - memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen); - - pMACHeader->wDurationID = 0; - pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); - pDevice->wSeqCounter++; - if (pDevice->wSeqCounter > 0x0fff) - pDevice->wSeqCounter = 0; - - // Set Beacon buffer length - pDevice->wBCNBufLen = pPacket->cbMPDULen + cbHeaderSize; - - MACvSetCurrBCNTxDescAddr(pDevice->PortOffset, (pDevice->tx_beacon_dma)); - - MACvSetCurrBCNLength(pDevice->PortOffset, pDevice->wBCNBufLen); - // Set auto Transmit on - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); - // Poll Transmit the adapter - MACvTransmitBCN(pDevice->PortOffset); - - return CMD_STATUS_PENDING; -} - -unsigned int -cbGetFragCount( - struct vnt_private *pDevice, - PSKeyItem pTransmitKey, - unsigned int cbFrameBodySize, - PSEthernetHeader psEthHeader -) -{ - unsigned int cbMACHdLen; - unsigned int cbFrameSize; - unsigned int cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS - unsigned int cbFragPayloadSize; - unsigned int cbLastFragPayloadSize; - unsigned int cbIVlen = 0; - unsigned int cbICVlen = 0; - unsigned int cbMIClen = 0; - unsigned int cbFCSlen = 4; - unsigned int uMACfragNum = 1; - bool bNeedACK; - - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0]))) - bNeedACK = false; - else - bNeedACK = true; - } else { - // MSDUs in Infra mode always need ACK - bNeedACK = true; - } - - if (pDevice->bLongHeader) - cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6; - else - cbMACHdLen = WLAN_HDR_ADDR3_LEN; - - if (pDevice->bEncryptionEnable == true) { - if (pTransmitKey == NULL) { - if ((pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) || - (pDevice->pMgmt->eAuthenMode < WMAC_AUTH_WPA)) { - cbIVlen = 4; - cbICVlen = 4; - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { - cbIVlen = 8;//IV+ExtIV - cbMIClen = 8; - cbICVlen = 4; - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - cbIVlen = 8;//RSN Header - cbICVlen = 8;//MIC - } - } else if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { - cbIVlen = 4; - cbICVlen = 4; - } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { - cbIVlen = 8;//IV+ExtIV - cbMIClen = 8; - cbICVlen = 4; - } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { - cbIVlen = 8;//RSN Header - cbICVlen = 8;//MIC - } - } - - cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen; - - if ((cbFrameSize > pDevice->wFragmentationThreshold) && (bNeedACK == true)) { - // Fragmentation - cbFragmentSize = pDevice->wFragmentationThreshold; - cbFragPayloadSize = cbFragmentSize - cbMACHdLen - cbIVlen - cbICVlen - cbFCSlen; - uMACfragNum = (unsigned short) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize); - cbLastFragPayloadSize = (cbFrameBodySize + cbMIClen) % cbFragPayloadSize; - if (cbLastFragPayloadSize == 0) - cbLastFragPayloadSize = cbFragPayloadSize; - else - uMACfragNum++; - } - return uMACfragNum; -} - -void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb, - unsigned char *pbMPDU, unsigned int cbMPDULen) -{ - PSTxDesc pFrstTD; - unsigned char byPktType; - unsigned char *pbyTxBufferAddr; - void *pvRTS; - void *pvCTS; - void *pvTxDataHd; - unsigned int uDuration; - unsigned int cbReqCount; - PS802_11Header pMACHeader; - unsigned int cbHeaderSize; - unsigned int cbFrameBodySize; - bool bNeedACK; - bool bIsPSPOLL = false; - PSTxBufHead pTxBufHead; - unsigned int cbFrameSize; - unsigned int cbIVlen = 0; - unsigned int cbICVlen = 0; - unsigned int cbMIClen = 0; - unsigned int cbFCSlen = 4; - unsigned int uPadding = 0; - unsigned int cbMICHDR = 0; - unsigned int uLength = 0; - u32 dwMICKey0, dwMICKey1; - u32 dwMIC_Priority; - u32 *pdwMIC_L; - u32 *pdwMIC_R; - unsigned short wTxBufSize; - unsigned int cbMacHdLen; - SEthernetHeader sEthHeader; - void *pvRrvTime; - void *pMICHDR; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned short wCurrentRate = RATE_1M; - PUWLAN_80211HDR p80211Header; - unsigned int uNodeIndex = 0; - bool bNodeExist = false; - SKeyItem STempKey; - PSKeyItem pTransmitKey = NULL; - unsigned char *pbyIVHead; - unsigned char *pbyPayloadHead; - unsigned char *pbyMacHdr; - - unsigned int cbExtSuppRate = 0; - - pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL; - - if (cbMPDULen <= WLAN_HDR_ADDR3_LEN) - cbFrameBodySize = 0; - else - cbFrameBodySize = cbMPDULen - WLAN_HDR_ADDR3_LEN; - - p80211Header = (PUWLAN_80211HDR)pbMPDU; + cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B, + frame_size, PK_TYPE_11A, current_rate, + false, 0, 0, 1, AUTO_FB_NONE)); - pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0]; - pbyTxBufferAddr = (unsigned char *)pFrstTD->pTDInfo->buf; - pTxBufHead = (PSTxBufHead) pbyTxBufferAddr; - wTxBufSize = sizeof(STxBufHead); - memset(pTxBufHead, 0, wTxBufSize); - - if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { - wCurrentRate = RATE_6M; - byPktType = PK_TYPE_11A; + short_head->time_stamp_off = + vnt_time_stamp_off(priv, current_rate); } else { - wCurrentRate = RATE_1M; - byPktType = PK_TYPE_11B; - } - - // SetPower will cause error power TX state for OFDM Date packet in TX buffer. - // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability. - // And cmd timer will wait data pkt TX to finish before scanning so it's OK - // to set power here. - if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) - RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh); - else - RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel); - - pTxBufHead->byTxPower = pDevice->byCurPwr; - - //+++++++++++++++++++++ Patch VT3253 A1 performance +++++++++++++++++++++++++++ - if (pDevice->byFOETuning) { - if ((p80211Header->sA3.wFrameCtl & TYPE_DATE_NULL) == TYPE_DATE_NULL) { - wCurrentRate = RATE_24M; - byPktType = PK_TYPE_11GA; - } - } - - pr_debug("vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x\n", - p80211Header->sA3.wFrameCtl); - - //Set packet type - if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000 - pTxBufHead->wFIFOCtl = 0; - } else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11B; - } else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11GB; - } else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11GA; - } - - pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN; - pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us); - - if (is_multicast_ether_addr(&(p80211Header->sA3.abyAddr1[0]))) { - bNeedACK = false; - if (pDevice->bEnableHostWEP) { - uNodeIndex = 0; - bNodeExist = true; - } - } else { - if (pDevice->bEnableHostWEP) { - if (BSSDBbIsSTAInNodeDB(pDevice->pMgmt, (unsigned char *)(p80211Header->sA3.abyAddr1), &uNodeIndex)) - bNodeExist = true; - } - bNeedACK = true; - pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; - } - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || - (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { - pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY; - } - - pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0); - - if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) { - bIsPSPOLL = true; - cbMacHdLen = WLAN_HDR_ADDR2_LEN; - } else { - cbMacHdLen = WLAN_HDR_ADDR3_LEN; - } - - // hostapd deamon ext support rate patch - if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) { - if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0) - cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN; + current_rate = RATE_1M; + short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B); - if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0) - cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN; + /* Get SignalField,ServiceField,Length */ + vnt_get_phy_field(priv, frame_size, current_rate, + PK_TYPE_11B, &short_head->ab); - if (cbExtSuppRate > 0) - cbFrameBodySize = WLAN_ASSOCRESP_OFF_SUPP_RATES; - } + /* Get Duration and TimeStampOff */ + short_head->duration = + cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B, + frame_size, PK_TYPE_11B, current_rate, + false, 0, 0, 1, AUTO_FB_NONE)); - //Set FRAGCTL_MACHDCNT - pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)cbMacHdLen << 10); - - // Notes: - // Although spec says MMPDU can be fragmented; In most cases, - // no one will send a MMPDU under fragmentation. With RTS may occur. - pDevice->bAES = false; //Set FRAGCTL_WEPTYP - - if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) { - if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) { - cbIVlen = 4; - cbICVlen = 4; - pTxBufHead->wFragCtl |= FRAGCTL_LEGACY; - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { - cbIVlen = 8;//IV+ExtIV - cbMIClen = 8; - cbICVlen = 4; - pTxBufHead->wFragCtl |= FRAGCTL_TKIP; - //We need to get seed here for filling TxKey entry. - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - cbIVlen = 8;//RSN Header - cbICVlen = 8;//MIC - cbMICHDR = sizeof(struct vnt_mic_hdr); - pTxBufHead->wFragCtl |= FRAGCTL_AES; - pDevice->bAES = true; - } - //MAC Header should be padding 0 to DW alignment. - uPadding = 4 - (cbMacHdLen%4); - uPadding %= 4; + short_head->time_stamp_off = + vnt_time_stamp_off(priv, current_rate); } - cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen + cbExtSuppRate; - - //Set FIFOCTL_GrpAckPolicy - if (pDevice->bGrpAckPolicy == true) //0000 0100 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK; - - //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter() + short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT); - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet + /* Copy Beacon */ + memcpy(mgmt_hdr, skb->data, skb->len); - pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize); - pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + - sizeof(struct vnt_rrv_time_cts)); - pvRTS = NULL; - pvCTS = (struct vnt_cts *)(pbyTxBufferAddr + wTxBufSize + - sizeof(struct vnt_rrv_time_cts) + cbMICHDR); - pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + - sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts)); - cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) + - cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g); + /* time stamp always 0 */ + mgmt_hdr->u.beacon.timestamp = 0; - } else {//802.11a/b packet - - pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize); - pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + - wTxBufSize + sizeof(struct vnt_rrv_time_ab)); - pvRTS = NULL; - pvCTS = NULL; - pvTxDataHd = (void *)(pbyTxBufferAddr + - wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR); - cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) + - cbMICHDR + sizeof(struct vnt_tx_datahead_ab); + info = IEEE80211_SKB_CB(skb); + if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr; + hdr->duration_id = 0; + hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4); } - memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); - memcpy(&(sEthHeader.abyDstAddr[0]), &(p80211Header->sA3.abyAddr1[0]), ETH_ALEN); - memcpy(&(sEthHeader.abySrcAddr[0]), &(p80211Header->sA3.abyAddr2[0]), ETH_ALEN); - //========================= - // No Fragmentation - //========================= - pTxBufHead->wFragCtl |= (unsigned short)FRAGCTL_NONFRAG; - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS, - cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, wCurrentRate); + priv->wSeqCounter++; + if (priv->wSeqCounter > 0x0fff) + priv->wSeqCounter = 0; - //Fill DataHead - uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK, - 0, 0, 1, AUTO_FB_NONE, wCurrentRate); + priv->wBCNBufLen = sizeof(*short_head) + skb->len; - pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize); + MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma); - cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate; + MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen); + /* Set auto Transmit on */ + MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); + /* Poll Transmit the adapter */ + MACvTransmitBCN(priv->PortOffset); - pbyMacHdr = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize); - pbyPayloadHead = (unsigned char *)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen); - pbyIVHead = (unsigned char *)(pbyMacHdr + cbMacHdLen + uPadding); + return 0; +} - // Copy the Packet into a tx Buffer - memcpy(pbyMacHdr, pbMPDU, cbMacHdLen); +int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif) +{ + struct sk_buff *beacon; - // version set to 0, patch for hostapd deamon - pMACHeader->wFrameCtl &= cpu_to_le16(0xfffc); - memcpy(pbyPayloadHead, (pbMPDU + cbMacHdLen), cbFrameBodySize); + beacon = ieee80211_beacon_get(priv->hw, vif); + if (!beacon) + return -ENOMEM; - // replace support rate, patch for hostapd deamon(only support 11M) - if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) { - if (cbExtSuppRate != 0) { - if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0) - memcpy((pbyPayloadHead + cbFrameBodySize), - pMgmt->abyCurrSuppRates, - ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN -); - if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0) - memcpy((pbyPayloadHead + cbFrameBodySize) + ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN, - pMgmt->abyCurrExtSuppRates, - ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN -); - } + if (vnt_beacon_xmit(priv, beacon)) { + ieee80211_free_txskb(priv->hw, beacon); + return -ENODEV; } - // Set wep - if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) { - if (pDevice->bEnableHostWEP) { - pTransmitKey = &STempKey; - pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite; - pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex; - pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength; - pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16; - pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0; - memcpy(pTransmitKey->abyKey, - &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0], - pTransmitKey->uKeyLength -); - } - - if ((pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]); - dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]); - - // DO Software Michael - MIC_vInit(dwMICKey0, dwMICKey1); - MIC_vAppend((unsigned char *)&(sEthHeader.abyDstAddr[0]), 12); - dwMIC_Priority = 0; - MIC_vAppend((unsigned char *)&dwMIC_Priority, 4); - pr_debug("DMA0_tx_8021:MIC KEY: %X, %X\n", - dwMICKey0, dwMICKey1); - - uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen; - - MIC_vAppend((pbyTxBufferAddr + uLength), cbFrameBodySize); - - pdwMIC_L = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize); - pdwMIC_R = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize + 4); - - MIC_vGetMIC(pdwMIC_L, pdwMIC_R); - MIC_vUnInit(); - - if (pDevice->bTxMICFail == true) { - *pdwMIC_L = 0; - *pdwMIC_R = 0; - pDevice->bTxMICFail = false; - } - - pr_debug("uLength: %d, %d\n", uLength, cbFrameBodySize); - pr_debug("cbReqCount:%d, %d, %d, %d\n", - cbReqCount, cbHeaderSize, uPadding, cbIVlen); - pr_debug("MIC:%x, %x\n", *pdwMIC_L, *pdwMIC_R); - - } - - s_vFillTxKey(pDevice, (unsigned char *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (unsigned short)cbFrameBodySize, (unsigned char *)pMICHDR); - - if (pDevice->bEnableHostWEP) { - pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; - pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; - } - - if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) - s_vSWencryption(pDevice, pTransmitKey, pbyPayloadHead, (unsigned short)(cbFrameBodySize + cbMIClen)); - } + return 0; +} - pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); - pDevice->wSeqCounter++; - if (pDevice->wSeqCounter > 0x0fff) - pDevice->wSeqCounter = 0; - - if (bIsPSPOLL) { - // The MAC will automatically replace the Duration-field of MAC header by Duration-field - // of FIFO control header. - // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is - // in the same place of other packet's Duration-field). - // And it will cause Cisco-AP to issue Disassociation-packet - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { - ((struct vnt_tx_datahead_g *)pvTxDataHd)->duration_a = cpu_to_le16(p80211Header->sA2.wDurationID); - ((struct vnt_tx_datahead_g *)pvTxDataHd)->duration_b = cpu_to_le16(p80211Header->sA2.wDurationID); - } else { - ((struct vnt_tx_datahead_ab *)pvTxDataHd)->duration = cpu_to_le16(p80211Header->sA2.wDurationID); - } - } +int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *conf) +{ + int ret; - // first TD is the only TD - //Set TSR1 & ReqCount in TxDescHead - pFrstTD->pTDInfo->skb = skb; - pFrstTD->m_td1TD1.byTCR = (TCR_STP | TCR_EDP | EDMSDU); - pFrstTD->pTDInfo->skb_dma = pFrstTD->pTDInfo->buf_dma; - pFrstTD->m_td1TD1.wReqCount = cpu_to_le16(cbReqCount); - pFrstTD->buff_addr = cpu_to_le32(pFrstTD->pTDInfo->skb_dma); - pFrstTD->pTDInfo->byFlags = 0; - pFrstTD->pTDInfo->byFlags |= TD_FLAGS_PRIV_SKB; - - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { - // Disable PS - MACbPSWakeup(pDevice->PortOffset); - } - pDevice->bPWBitOn = false; + VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); - wmb(); - pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC; - wmb(); + VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); - pDevice->iTDUsed[TYPE_TXDMA0]++; + CARDvSetFirstNextTBTT(priv, conf->beacon_int); - if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1) - pr_debug(" available td0 <= 1\n"); + CARDbSetBeaconPeriod(priv, conf->beacon_int); - pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next; + ret = vnt_beacon_make(priv, vif); - // Poll Transmit the adapter - MACvTransmit0(pDevice->PortOffset); + return ret; } diff --git a/drivers/staging/vt6655/rxtx.h b/drivers/staging/vt6655/rxtx.h index 8ee62887dee5..b9bd1639b13e 100644 --- a/drivers/staging/vt6655/rxtx.h +++ b/drivers/staging/vt6655/rxtx.h @@ -29,9 +29,11 @@ #ifndef __RXTX_H__ #define __RXTX_H__ -#include "ttype.h" #include "device.h" -#include "wcmd.h" + +#define DEFAULT_MSDU_LIFETIME_RES_64us 8000 /* 64us */ +#define DEFAULT_MGN_LIFETIME_RES_64us 125 /* 64us */ + /*--------------------- Export Definitions -------------------------*/ @@ -173,6 +175,14 @@ struct vnt_cts_fb { u16 reserved2; } __packed; +struct vnt_tx_fifo_head { + u8 tx_key[WLAN_KEY_LEN_CCMP]; + __le16 fifo_ctl; + __le16 time_stamp; + __le16 frag_ctl; + __le16 current_rate; +} __packed; + struct vnt_tx_short_buf_head { __le16 fifo_ctl; u16 time_stamp; @@ -181,38 +191,10 @@ struct vnt_tx_short_buf_head { __le16 time_stamp_off; } __packed; -void -vGenerateMACHeader( - struct vnt_private *, - unsigned char *pbyBufferAddr, - unsigned short wDuration, - PSEthernetHeader psEthHeader, - bool bNeedEncrypt, - unsigned short wFragType, - unsigned int uDMAIdx, - unsigned int uFragIdx -); - -unsigned int -cbGetFragCount( - struct vnt_private *, - PSKeyItem pTransmitKey, - unsigned int cbFrameBodySize, - PSEthernetHeader psEthHeader -); - -void -vGenerateFIFOHeader(struct vnt_private *, unsigned char byPktTyp, - unsigned char *pbyTxBufferAddr, bool bNeedEncrypt, - unsigned int cbPayloadSize, unsigned int uDMAIdx, - PSTxDesc pHeadTD, PSEthernetHeader psEthHeader, - unsigned char *pPacket, PSKeyItem pTransmitKey, - unsigned int uNodeIndex, unsigned int *puMACfragNum, - unsigned int *pcbHeaderSize); - -void vDMA0_tx_80211(struct vnt_private *, struct sk_buff *skb, - unsigned char *pbMPDU, unsigned int cbMPDULen); -CMD_STATUS csMgmt_xmit(struct vnt_private *, PSTxMgmtPacket pPacket); -CMD_STATUS csBeacon_xmit(struct vnt_private *, PSTxMgmtPacket pPacket); +int vnt_generate_fifo_header(struct vnt_private *, u32, + PSTxDesc head_td, struct sk_buff *); +int vnt_beacon_make(struct vnt_private *, struct ieee80211_vif *); +int vnt_beacon_enable(struct vnt_private *, struct ieee80211_vif *, + struct ieee80211_bss_conf *); #endif // __RXTX_H__ diff --git a/drivers/staging/vt6655/srom.c b/drivers/staging/vt6655/srom.c index 5396e5832c22..9ec49e653b61 100644 --- a/drivers/staging/vt6655/srom.c +++ b/drivers/staging/vt6655/srom.c @@ -44,7 +44,6 @@ #include "upc.h" #include "tmacro.h" -#include "tether.h" #include "mac.h" #include "srom.h" @@ -108,144 +107,6 @@ unsigned char SROMbyReadEmbedded(void __iomem *dwIoBase, unsigned char byContntO } /* - * Description: Write a byte to EEPROM, by MAC I2C - * - * Parameters: - * In: - * dwIoBase - I/O base address - * byContntOffset - address of EEPROM - * wData - data to write - * Out: - * none - * - * Return Value: true if succeeded; false if failed. - * - */ -bool SROMbWriteEmbedded(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byData) -{ - unsigned short wDelay, wNoACK; - unsigned char byWait; - - unsigned char byOrg; - - VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg); - /* turn off hardware retry for getting NACK */ - VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, (byOrg & (~I2MCFG_NORETRY))); - for (wNoACK = 0; wNoACK < W_MAX_I2CRETRY; wNoACK++) { - VNSvOutPortB(dwIoBase + MAC_REG_I2MTGID, EEP_I2C_DEV_ID); - VNSvOutPortB(dwIoBase + MAC_REG_I2MTGAD, byContntOffset); - VNSvOutPortB(dwIoBase + MAC_REG_I2MDOPT, byData); - - /* issue write command */ - VNSvOutPortB(dwIoBase + MAC_REG_I2MCSR, I2MCSR_EEMW); - /* wait DONE be set */ - for (wDelay = 0; wDelay < W_MAX_TIMEOUT; wDelay++) { - VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait); - if (byWait & (I2MCSR_DONE | I2MCSR_NACK)) - break; - PCAvDelayByIO(CB_DELAY_LOOP_WAIT); - } - - if ((wDelay < W_MAX_TIMEOUT) && - (!(byWait & I2MCSR_NACK))) { - break; - } - } - if (wNoACK == W_MAX_I2CRETRY) { - VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg); - return false; - } - VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg); - return true; -} - -/* - * Description: Turn bits on in eeprom - * - * Parameters: - * In: - * dwIoBase - I/O base address - * byContntOffset - address of EEPROM - * byBits - bits to turn on - * Out: - * none - * - * Return Value: none - * - */ -void SROMvRegBitsOn(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byBits) -{ - unsigned char byOrgData; - - byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset); - SROMbWriteEmbedded(dwIoBase, byContntOffset, (unsigned char)(byOrgData | byBits)); -} - -/* - * Description: Turn bits off in eeprom - * - * Parameters: - * In: - * dwIoBase - I/O base address - * byContntOffset - address of EEPROM - * byBits - bits to turn off - * Out: - * none - * - */ -void SROMvRegBitsOff(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byBits) -{ - unsigned char byOrgData; - - byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset); - SROMbWriteEmbedded(dwIoBase, byContntOffset, (unsigned char)(byOrgData & (~byBits))); -} - -/* - * Description: Test if bits on in eeprom - * - * Parameters: - * In: - * dwIoBase - I/O base address - * byContntOffset - address of EEPROM - * byTestBits - bits to test - * Out: - * none - * - * Return Value: true if all test bits on; otherwise false - * - */ -bool SROMbIsRegBitsOn(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byTestBits) -{ - unsigned char byOrgData; - - byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset); - return (byOrgData & byTestBits) == byTestBits; -} - -/* - * Description: Test if bits off in eeprom - * - * Parameters: - * In: - * dwIoBase - I/O base address - * byContntOffset - address of EEPROM - * byTestBits - bits to test - * Out: - * none - * - * Return Value: true if all test bits off; otherwise false - * - */ -bool SROMbIsRegBitsOff(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byTestBits) -{ - unsigned char byOrgData; - - byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset); - return !(byOrgData & byTestBits); -} - -/* * Description: Read all contents of eeprom to buffer * * Parameters: @@ -269,30 +130,6 @@ void SROMvReadAllContents(void __iomem *dwIoBase, unsigned char *pbyEepromRegs) } /* - * Description: Write all contents of buffer to eeprom - * - * Parameters: - * In: - * dwIoBase - I/O base address - * pbyEepromRegs - EEPROM content Buffer - * Out: - * none - * - * Return Value: none - * - */ -void SROMvWriteAllContents(void __iomem *dwIoBase, unsigned char *pbyEepromRegs) -{ - int ii; - - /* ii = Rom Address */ - for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) { - SROMbWriteEmbedded(dwIoBase, (unsigned char)ii, *pbyEepromRegs); - pbyEepromRegs++; - } -} - -/* * Description: Read Ethernet Address from eeprom to buffer * * Parameters: @@ -314,92 +151,3 @@ void SROMvReadEtherAddress(void __iomem *dwIoBase, unsigned char *pbyEtherAddres pbyEtherAddress++; } } - -/* - * Description: Write Ethernet Address from buffer to eeprom - * - * Parameters: - * In: - * dwIoBase - I/O base address - * pbyEtherAddress - Ethernet Address buffer - * Out: - * none - * - * Return Value: none - * - */ -void SROMvWriteEtherAddress(void __iomem *dwIoBase, unsigned char *pbyEtherAddress) -{ - unsigned char ii; - - /* ii = Rom Address */ - for (ii = 0; ii < ETH_ALEN; ii++) { - SROMbWriteEmbedded(dwIoBase, ii, *pbyEtherAddress); - pbyEtherAddress++; - } -} - -/* - * Description: Read Sub_VID and Sub_SysId from eeprom to buffer - * - * Parameters: - * In: - * dwIoBase - I/O base address - * Out: - * pdwSubSysVenId - Sub_VID and Sub_SysId read - * - * Return Value: none - * - */ -void SROMvReadSubSysVenId(void __iomem *dwIoBase, unsigned long *pdwSubSysVenId) -{ - unsigned char *pbyData; - - pbyData = (unsigned char *)pdwSubSysVenId; - /* sub vendor */ - *pbyData = SROMbyReadEmbedded(dwIoBase, 6); - *(pbyData+1) = SROMbyReadEmbedded(dwIoBase, 7); - /* sub system */ - *(pbyData+2) = SROMbyReadEmbedded(dwIoBase, 8); - *(pbyData+3) = SROMbyReadEmbedded(dwIoBase, 9); -} - -/* - * Description: Auto Load EEPROM to MAC register - * - * Parameters: - * In: - * dwIoBase - I/O base address - * Out: - * none - * - * Return Value: true if success; otherwise false - * - */ -bool SROMbAutoLoad(void __iomem *dwIoBase) -{ - unsigned char byWait; - int ii; - - unsigned char byOrg; - - VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg); - /* turn on hardware retry */ - VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, (byOrg | I2MCFG_NORETRY)); - - MACvRegBitsOn(dwIoBase, MAC_REG_I2MCSR, I2MCSR_AUTOLD); - - /* ii = Rom Address */ - for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) { - MACvTimer0MicroSDelay(dwIoBase, CB_EEPROM_READBYTE_WAIT); - VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait); - if (!(byWait & I2MCSR_AUTOLD)) - break; - } - - VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg); - - if (ii == EEP_MAX_CONTEXT_SIZE) - return false; - return true; -} diff --git a/drivers/staging/vt6655/srom.h b/drivers/staging/vt6655/srom.h index 3128e535bbd8..7d3e3ef9f17f 100644 --- a/drivers/staging/vt6655/srom.h +++ b/drivers/staging/vt6655/srom.h @@ -30,8 +30,6 @@ #ifndef __SROM_H__ #define __SROM_H__ -#include "ttype.h" - /*--------------------- Export Definitions -------------------------*/ #define EEP_MAX_CONTEXT_SIZE 256 @@ -91,40 +89,6 @@ /*--------------------- Export Types ------------------------------*/ -// AT24C02 eeprom contents -// 2048 bits = 256 bytes = 128 words -// -typedef struct tagSSromReg { - unsigned char abyPAR[6]; // 0x00 (unsigned short) - - unsigned short wSUB_VID; // 0x03 (unsigned short) - unsigned short wSUB_SID; - - unsigned char byBCFG0; // 0x05 (unsigned short) - unsigned char byBCFG1; - - unsigned char byFCR0; // 0x06 (unsigned short) - unsigned char byFCR1; - unsigned char byPMC0; // 0x07 (unsigned short) - unsigned char byPMC1; - unsigned char byMAXLAT; // 0x08 (unsigned short) - unsigned char byMINGNT; - unsigned char byCFG0; // 0x09 (unsigned short) - unsigned char byCFG1; - unsigned short wCISPTR; // 0x0A (unsigned short) - unsigned short wRsv0; // 0x0B (unsigned short) - unsigned short wRsv1; // 0x0C (unsigned short) - unsigned char byBBPAIR; // 0x0D (unsigned short) - unsigned char byRFTYPE; - unsigned char byMinChannel; // 0x0E (unsigned short) - unsigned char byMaxChannel; - unsigned char bySignature; // 0x0F (unsigned short) - unsigned char byCheckSum; - - unsigned char abyReserved0[96]; // 0x10 (unsigned short) - unsigned char abyCIS[128]; // 0x80 (unsigned short) -} SSromReg, *PSSromReg; - /*--------------------- Export Macros ------------------------------*/ /*--------------------- Export Classes ----------------------------*/ @@ -134,22 +98,9 @@ typedef struct tagSSromReg { /*--------------------- Export Functions --------------------------*/ unsigned char SROMbyReadEmbedded(void __iomem *dwIoBase, unsigned char byContntOffset); -bool SROMbWriteEmbedded(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byData); - -void SROMvRegBitsOn(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byBits); -void SROMvRegBitsOff(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byBits); - -bool SROMbIsRegBitsOn(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byTestBits); -bool SROMbIsRegBitsOff(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byTestBits); void SROMvReadAllContents(void __iomem *dwIoBase, unsigned char *pbyEepromRegs); -void SROMvWriteAllContents(void __iomem *dwIoBase, unsigned char *pbyEepromRegs); void SROMvReadEtherAddress(void __iomem *dwIoBase, unsigned char *pbyEtherAddress); -void SROMvWriteEtherAddress(void __iomem *dwIoBase, unsigned char *pbyEtherAddress); - -void SROMvReadSubSysVenId(void __iomem *dwIoBase, unsigned long *pdwSubSysVenId); - -bool SROMbAutoLoad(void __iomem *dwIoBase); #endif // __EEPROM_H__ diff --git a/drivers/staging/vt6655/tcrc.c b/drivers/staging/vt6655/tcrc.c deleted file mode 100644 index ddc5efd040f9..000000000000 --- a/drivers/staging/vt6655/tcrc.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2003 VIA Networking, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: tcrc.c - * - * Purpose: Implement functions to calculate CRC - * - * Author: Tevin Chen - * - * Date: May 21, 1996 - * - * Functions: - * CRCdwCrc32 - - * CRCdwGetCrc32 - - * CRCdwGetCrc32Ex - - * - * Revision History: - * - */ - -#include "tcrc.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/* 32-bit CRC table */ -static const unsigned long s_adwCrc32Table[256] = { - 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, - 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, - 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, - 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L, - 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL, - 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L, - 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL, - 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L, - 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L, - 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL, - 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L, - 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L, - 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L, - 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL, - 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L, - 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL, - 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL, - 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L, - 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L, - 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L, - 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL, - 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L, - 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL, - 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L, - 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L, - 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL, - 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L, - 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L, - 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L, - 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL, - 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L, - 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL, - 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL, - 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L, - 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L, - 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L, - 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL, - 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L, - 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL, - 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L, - 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L, - 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL, - 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L, - 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L, - 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L, - 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL, - 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L, - 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL, - 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL, - 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L, - 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L, - 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L, - 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL, - 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L, - 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL, - 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L, - 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L, - 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL, - 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L, - 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L, - 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L, - 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL, - 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L, - 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL -}; - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*+ - * - * Description: - * Generate a CRC-32 from the data stream - * - * Parameters: - * In: - * pbyData - the data stream - * cbByte - the length of the stream - * dwCrcSeed - Seed for CRC32 - * Out: - * none - * - * Return Value: CRC-32 - * - -*/ -unsigned long CRCdwCrc32(unsigned char *pbyData, unsigned int cbByte, unsigned long dwCrcSeed) -{ - unsigned long dwCrc; - - dwCrc = dwCrcSeed; - while (cbByte--) { - dwCrc = s_adwCrc32Table[(unsigned char)((dwCrc ^ (*pbyData)) & 0xFF)] ^ (dwCrc >> 8); - pbyData++; - } - - return dwCrc; -} - -/*+ - * - * Description: - * To test CRC generator, input 8 bytes packet - * -- 0xff 0xff 0xff 0xff 0x00 0x00 0x00 0x00 - * the generated CRC should be - * -- 0xff 0xff 0xff 0xff - * - * Parameters: - * In: - * pbyData - the data stream - * cbByte - the length of the stream - * Out: - * none - * - * Return Value: CRC-32 - * - -*/ -unsigned long CRCdwGetCrc32(unsigned char *pbyData, unsigned int cbByte) -{ - return ~CRCdwCrc32(pbyData, cbByte, 0xFFFFFFFFL); -} - -/*+ - * - * Description: - * - * NOTE.... Because CRCdwGetCrc32Ex() is an iteration function, - * this means we will use the output of CRCdwGetCrc32Ex() - * to be a new argument to do next CRCdwGetCrc32Ex() calculation. - * Thus, the final result must be inverted to be the - * correct answer. - * - * Parameters: - * In: - * pbyData - the data stream - * cbByte - the length of the stream - * Out: - * none - * - * Return Value: CRC-32 - * - -*/ -unsigned long CRCdwGetCrc32Ex(unsigned char *pbyData, unsigned int cbByte, unsigned long dwPreCRC) -{ - return CRCdwCrc32(pbyData, cbByte, dwPreCRC); -} diff --git a/drivers/staging/vt6655/tcrc.h b/drivers/staging/vt6655/tcrc.h deleted file mode 100644 index 82b5ddafae55..000000000000 --- a/drivers/staging/vt6655/tcrc.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2003 VIA Networking, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: tcrc.h - * - * Purpose: Implement functions to calculate CRC - * - * Author: Tevin Chen - * - * Date: Jan. 28, 1997 - * - */ - -#ifndef __TCRC_H__ -#define __TCRC_H__ - -#include "ttype.h" - -/*--------------------- Export Definitions -------------------------*/ - -/*--------------------- Export Types ------------------------------*/ - -/*--------------------- Export Macros ------------------------------*/ - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -unsigned long CRCdwCrc32(unsigned char *pbyData, unsigned int cbByte, unsigned long dwCrcSeed); -unsigned long CRCdwGetCrc32(unsigned char *pbyData, unsigned int cbByte); -unsigned long CRCdwGetCrc32Ex(unsigned char *pbyData, unsigned int cbByte, unsigned long dwPreCRC); - -#endif // __TCRC_H__ diff --git a/drivers/staging/vt6655/tether.c b/drivers/staging/vt6655/tether.c deleted file mode 100644 index 1e7d3e2115a9..000000000000 --- a/drivers/staging/vt6655/tether.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2003 VIA Networking, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: tether.c - * - * Purpose: - * - * Author: Tevin Chen - * - * Date: May 21, 1996 - * - * Functions: - * ETHbyGetHashIndexByCrc32 - Calculate multicast hash value by CRC32 - * ETHbIsBufferCrc32Ok - Check CRC value of the buffer if Ok or not - * - * Revision History: - * - */ - -#include "device.h" -#include "tmacro.h" -#include "tcrc.h" -#include "tether.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/* - * Description: Calculate multicast hash value by CRC32 - * - * Parameters: - * In: - * pbyMultiAddr - Multicast Address - * Out: - * none - * - * Return Value: Hash value - * - */ -unsigned char ETHbyGetHashIndexByCrc32(unsigned char *pbyMultiAddr) -{ - int ii; - unsigned char byTmpHash; - unsigned char byHash = 0; - - // get the least 6-bits from CRC generator - byTmpHash = (unsigned char)(CRCdwCrc32(pbyMultiAddr, ETH_ALEN, - 0xFFFFFFFFL) & 0x3F); - // reverse most bit to least bit - for (ii = 0; ii < (sizeof(byTmpHash) * 8); ii++) { - byHash <<= 1; - if (byTmpHash & 0x01) - byHash |= 1; - byTmpHash >>= 1; - } - - // adjust 6-bits to the right most - return byHash >> 2; -} - -/* - * Description: Check CRC value of the buffer if Ok or not - * - * Parameters: - * In: - * pbyBuffer - pointer of buffer (normally is rx buffer) - * cbFrameLength - length of buffer, including CRC portion - * Out: - * none - * - * Return Value: true if ok; false if error. - * - */ -bool ETHbIsBufferCrc32Ok(unsigned char *pbyBuffer, unsigned int cbFrameLength) -{ - unsigned long dwCRC; - - dwCRC = CRCdwGetCrc32(pbyBuffer, cbFrameLength - 4); - if (cpu_to_le32(*((unsigned long *)(pbyBuffer + cbFrameLength - 4))) != dwCRC) - return false; - - return true; -} diff --git a/drivers/staging/vt6655/tether.h b/drivers/staging/vt6655/tether.h deleted file mode 100644 index 94cc8830d8cc..000000000000 --- a/drivers/staging/vt6655/tether.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: tether.h - * - * Purpose: - * - * Author: Tevin Chen - * - * Date: Jan. 28, 1997 - * - */ - -#ifndef __TETHER_H__ -#define __TETHER_H__ - -#include <linux/etherdevice.h> -#include "ttype.h" - -/*--------------------- Export Definitions -------------------------*/ -// -// constants -// -#define U_ETHER_ADDR_STR_LEN (ETH_ALEN * 2 + 1) -// Ethernet address string length - -#define MAX_LOOKAHEAD_SIZE ETH_FRAME_LEN - -#define U_MULTI_ADDR_LEN 8 // multicast address length - -#ifdef __BIG_ENDIAN - -#define TYPE_PKT_IP 0x0800 // -#define TYPE_PKT_ARP 0x0806 // -#define TYPE_PKT_RARP 0x8035 // -#define TYPE_PKT_IPX 0x8137 // -#define TYPE_PKT_802_1x 0x888e -#define TYPE_PKT_PreAuth 0x88C7 - -#define TYPE_PKT_PING_M_REQ 0x8011 // master reguest -#define TYPE_PKT_PING_S_GNT 0x8022 // slave grant -#define TYPE_PKT_PING_M 0x8077 // pingpong master packet -#define TYPE_PKT_PING_S 0x8088 // pingpong slave packet -#define TYPE_PKT_WOL_M_REQ 0x8033 // WOL waker request -#define TYPE_PKT_WOL_S_GNT 0x8044 // WOL sleeper grant -#define TYPE_MGMT_PROBE_RSP 0x5000 -#define TYPE_PKT_VNT_DIAG 0x8011 // Diag Pkt -#define TYPE_PKT_VNT_PER 0x8888 // Diag PER Pkt -// -// wFrameCtl field in the S802_11Header -// -// NOTE.... -// in network byte order, high byte is going first -#define FC_TODS 0x0001 -#define FC_FROMDS 0x0002 -#define FC_MOREFRAG 0x0004 -#define FC_RETRY 0x0008 -#define FC_POWERMGT 0x0010 -#define FC_MOREDATA 0x0020 -#define FC_WEP 0x0040 -#define TYPE_802_11_ATIM 0x9000 - -#define TYPE_802_11_DATA 0x0800 -#define TYPE_802_11_CTL 0x0400 -#define TYPE_802_11_MGMT 0x0000 -#define TYPE_802_11_MASK 0x0C00 -#define TYPE_SUBTYPE_MASK 0xFC00 -#define TYPE_802_11_NODATA 0x4000 -#define TYPE_DATE_NULL 0x4800 - -#define TYPE_CTL_PSPOLL 0xa400 -#define TYPE_CTL_RTS 0xb400 -#define TYPE_CTL_CTS 0xc400 -#define TYPE_CTL_ACK 0xd400 - -#else //if LITTLE_ENDIAN -// -// wType field in the SEthernetHeader -// -// NOTE.... -// in network byte order, high byte is going first -#define TYPE_PKT_IP 0x0008 // -#define TYPE_PKT_ARP 0x0608 // -#define TYPE_PKT_RARP 0x3580 // -#define TYPE_PKT_IPX 0x3781 // - -#define TYPE_PKT_802_1x 0x8e88 -#define TYPE_PKT_PreAuth 0xC788 - -#define TYPE_PKT_PING_M_REQ 0x1180 // master reguest -#define TYPE_PKT_PING_S_GNT 0x2280 // slave grant -#define TYPE_PKT_PING_M 0x7780 // pingpong master packet -#define TYPE_PKT_PING_S 0x8880 // pingpong slave packet -#define TYPE_PKT_WOL_M_REQ 0x3380 // WOL waker request -#define TYPE_PKT_WOL_S_GNT 0x4480 // WOL sleeper grant -#define TYPE_MGMT_PROBE_RSP 0x0050 -#define TYPE_PKT_VNT_DIAG 0x1180 // Diag Pkt -#define TYPE_PKT_VNT_PER 0x8888 // Diag PER Pkt -// -// wFrameCtl field in the S802_11Header -// -// NOTE.... -// in network byte order, high byte is going first -#define FC_TODS 0x0100 -#define FC_FROMDS 0x0200 -#define FC_MOREFRAG 0x0400 -#define FC_RETRY 0x0800 -#define FC_POWERMGT 0x1000 -#define FC_MOREDATA 0x2000 -#define FC_WEP 0x4000 -#define TYPE_802_11_ATIM 0x0090 - -#define TYPE_802_11_DATA 0x0008 -#define TYPE_802_11_CTL 0x0004 -#define TYPE_802_11_MGMT 0x0000 -#define TYPE_802_11_MASK 0x000C -#define TYPE_SUBTYPE_MASK 0x00FC -#define TYPE_802_11_NODATA 0x0040 -#define TYPE_DATE_NULL 0x0048 - -#define TYPE_CTL_PSPOLL 0x00a4 -#define TYPE_CTL_RTS 0x00b4 -#define TYPE_CTL_CTS 0x00c4 -#define TYPE_CTL_ACK 0x00d4 - -#endif //#ifdef __BIG_ENDIAN - -#define WEP_IV_MASK 0x00FFFFFF - -/*--------------------- Export Types ------------------------------*/ -// -// Ethernet packet -// -typedef struct tagSEthernetHeader { - unsigned char abyDstAddr[ETH_ALEN]; - unsigned char abySrcAddr[ETH_ALEN]; - unsigned short wType; -} __attribute__ ((__packed__)) -SEthernetHeader, *PSEthernetHeader; - -// -// 802_3 packet -// -typedef struct tagS802_3Header { - unsigned char abyDstAddr[ETH_ALEN]; - unsigned char abySrcAddr[ETH_ALEN]; - unsigned short wLen; -} __attribute__ ((__packed__)) -S802_3Header, *PS802_3Header; - -// -// 802_11 packet -// -typedef struct tagS802_11Header { - unsigned short wFrameCtl; - unsigned short wDurationID; - unsigned char abyAddr1[ETH_ALEN]; - unsigned char abyAddr2[ETH_ALEN]; - unsigned char abyAddr3[ETH_ALEN]; - unsigned short wSeqCtl; - unsigned char abyAddr4[ETH_ALEN]; -} __attribute__ ((__packed__)) -S802_11Header, *PS802_11Header; - -/*--------------------- Export Macros ------------------------------*/ - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -unsigned char ETHbyGetHashIndexByCrc32(unsigned char *pbyMultiAddr); -//unsigned char ETHbyGetHashIndexByCrc(unsigned char *pbyMultiAddr); -bool ETHbIsBufferCrc32Ok(unsigned char *pbyBuffer, unsigned int cbFrameLength); - -#endif // __TETHER_H__ diff --git a/drivers/staging/vt6655/tkip.c b/drivers/staging/vt6655/tkip.c deleted file mode 100644 index f758d021c60e..000000000000 --- a/drivers/staging/vt6655/tkip.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: tkip.c - * - * Purpose: Implement functions for 802.11i TKIP - * - * Author: Jerry Chen - * - * Date: Mar. 11, 2003 - * - * Functions: - * TKIPvMixKey - Get TKIP RC4 Key from TK,TA, and TSC - * - * Revision History: - * - */ - -#include "tmacro.h" -#include "tkip.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/* The Sbox is reduced to 2 16-bit wide tables, each with 256 entries. */ -/* The 2nd table is the same as the 1st but with the upper and lower */ -/* bytes swapped. To allow an endian tolerant implementation, the byte */ -/* halves have been expressed independently here. */ -static const unsigned char TKIP_Sbox_Lower[256] = { - 0xA5, 0x84, 0x99, 0x8D, 0x0D, 0xBD, 0xB1, 0x54, - 0x50, 0x03, 0xA9, 0x7D, 0x19, 0x62, 0xE6, 0x9A, - 0x45, 0x9D, 0x40, 0x87, 0x15, 0xEB, 0xC9, 0x0B, - 0xEC, 0x67, 0xFD, 0xEA, 0xBF, 0xF7, 0x96, 0x5B, - 0xC2, 0x1C, 0xAE, 0x6A, 0x5A, 0x41, 0x02, 0x4F, - 0x5C, 0xF4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3F, - 0x0C, 0x52, 0x65, 0x5E, 0x28, 0xA1, 0x0F, 0xB5, - 0x09, 0x36, 0x9B, 0x3D, 0x26, 0x69, 0xCD, 0x9F, - 0x1B, 0x9E, 0x74, 0x2E, 0x2D, 0xB2, 0xEE, 0xFB, - 0xF6, 0x4D, 0x61, 0xCE, 0x7B, 0x3E, 0x71, 0x97, - 0xF5, 0x68, 0x00, 0x2C, 0x60, 0x1F, 0xC8, 0xED, - 0xBE, 0x46, 0xD9, 0x4B, 0xDE, 0xD4, 0xE8, 0x4A, - 0x6B, 0x2A, 0xE5, 0x16, 0xC5, 0xD7, 0x55, 0x94, - 0xCF, 0x10, 0x06, 0x81, 0xF0, 0x44, 0xBA, 0xE3, - 0xF3, 0xFE, 0xC0, 0x8A, 0xAD, 0xBC, 0x48, 0x04, - 0xDF, 0xC1, 0x75, 0x63, 0x30, 0x1A, 0x0E, 0x6D, - 0x4C, 0x14, 0x35, 0x2F, 0xE1, 0xA2, 0xCC, 0x39, - 0x57, 0xF2, 0x82, 0x47, 0xAC, 0xE7, 0x2B, 0x95, - 0xA0, 0x98, 0xD1, 0x7F, 0x66, 0x7E, 0xAB, 0x83, - 0xCA, 0x29, 0xD3, 0x3C, 0x79, 0xE2, 0x1D, 0x76, - 0x3B, 0x56, 0x4E, 0x1E, 0xDB, 0x0A, 0x6C, 0xE4, - 0x5D, 0x6E, 0xEF, 0xA6, 0xA8, 0xA4, 0x37, 0x8B, - 0x32, 0x43, 0x59, 0xB7, 0x8C, 0x64, 0xD2, 0xE0, - 0xB4, 0xFA, 0x07, 0x25, 0xAF, 0x8E, 0xE9, 0x18, - 0xD5, 0x88, 0x6F, 0x72, 0x24, 0xF1, 0xC7, 0x51, - 0x23, 0x7C, 0x9C, 0x21, 0xDD, 0xDC, 0x86, 0x85, - 0x90, 0x42, 0xC4, 0xAA, 0xD8, 0x05, 0x01, 0x12, - 0xA3, 0x5F, 0xF9, 0xD0, 0x91, 0x58, 0x27, 0xB9, - 0x38, 0x13, 0xB3, 0x33, 0xBB, 0x70, 0x89, 0xA7, - 0xB6, 0x22, 0x92, 0x20, 0x49, 0xFF, 0x78, 0x7A, - 0x8F, 0xF8, 0x80, 0x17, 0xDA, 0x31, 0xC6, 0xB8, - 0xC3, 0xB0, 0x77, 0x11, 0xCB, 0xFC, 0xD6, 0x3A -}; - -static const unsigned char TKIP_Sbox_Upper[256] = { - 0xC6, 0xF8, 0xEE, 0xF6, 0xFF, 0xD6, 0xDE, 0x91, - 0x60, 0x02, 0xCE, 0x56, 0xE7, 0xB5, 0x4D, 0xEC, - 0x8F, 0x1F, 0x89, 0xFA, 0xEF, 0xB2, 0x8E, 0xFB, - 0x41, 0xB3, 0x5F, 0x45, 0x23, 0x53, 0xE4, 0x9B, - 0x75, 0xE1, 0x3D, 0x4C, 0x6C, 0x7E, 0xF5, 0x83, - 0x68, 0x51, 0xD1, 0xF9, 0xE2, 0xAB, 0x62, 0x2A, - 0x08, 0x95, 0x46, 0x9D, 0x30, 0x37, 0x0A, 0x2F, - 0x0E, 0x24, 0x1B, 0xDF, 0xCD, 0x4E, 0x7F, 0xEA, - 0x12, 0x1D, 0x58, 0x34, 0x36, 0xDC, 0xB4, 0x5B, - 0xA4, 0x76, 0xB7, 0x7D, 0x52, 0xDD, 0x5E, 0x13, - 0xA6, 0xB9, 0x00, 0xC1, 0x40, 0xE3, 0x79, 0xB6, - 0xD4, 0x8D, 0x67, 0x72, 0x94, 0x98, 0xB0, 0x85, - 0xBB, 0xC5, 0x4F, 0xED, 0x86, 0x9A, 0x66, 0x11, - 0x8A, 0xE9, 0x04, 0xFE, 0xA0, 0x78, 0x25, 0x4B, - 0xA2, 0x5D, 0x80, 0x05, 0x3F, 0x21, 0x70, 0xF1, - 0x63, 0x77, 0xAF, 0x42, 0x20, 0xE5, 0xFD, 0xBF, - 0x81, 0x18, 0x26, 0xC3, 0xBE, 0x35, 0x88, 0x2E, - 0x93, 0x55, 0xFC, 0x7A, 0xC8, 0xBA, 0x32, 0xE6, - 0xC0, 0x19, 0x9E, 0xA3, 0x44, 0x54, 0x3B, 0x0B, - 0x8C, 0xC7, 0x6B, 0x28, 0xA7, 0xBC, 0x16, 0xAD, - 0xDB, 0x64, 0x74, 0x14, 0x92, 0x0C, 0x48, 0xB8, - 0x9F, 0xBD, 0x43, 0xC4, 0x39, 0x31, 0xD3, 0xF2, - 0xD5, 0x8B, 0x6E, 0xDA, 0x01, 0xB1, 0x9C, 0x49, - 0xD8, 0xAC, 0xF3, 0xCF, 0xCA, 0xF4, 0x47, 0x10, - 0x6F, 0xF0, 0x4A, 0x5C, 0x38, 0x57, 0x73, 0x97, - 0xCB, 0xA1, 0xE8, 0x3E, 0x96, 0x61, 0x0D, 0x0F, - 0xE0, 0x7C, 0x71, 0xCC, 0x90, 0x06, 0xF7, 0x1C, - 0xC2, 0x6A, 0xAE, 0x69, 0x17, 0x99, 0x3A, 0x27, - 0xD9, 0xEB, 0x2B, 0x22, 0xD2, 0xA9, 0x07, 0x33, - 0x2D, 0x3C, 0x15, 0xC9, 0x87, 0xAA, 0x50, 0xA5, - 0x03, 0x59, 0x09, 0x1A, 0x65, 0xD7, 0x84, 0xD0, - 0x82, 0x29, 0x5A, 0x1E, 0x7B, 0xA8, 0x6D, 0x2C -}; - -//STKIPKeyManagement sTKIPKeyTable[MAX_TKIP_KEY]; - -/*--------------------- Static Functions --------------------------*/ -unsigned int tkip_sbox(unsigned int index); -unsigned int rotr1(unsigned int a); - -/*--------------------- Export Variables --------------------------*/ - -/************************************************************/ -/* tkip_sbox() */ -/* Returns a 16 bit value from a 64K entry table. The Table */ -/* is synthesized from two 256 entry byte wide tables. */ -/************************************************************/ -unsigned int tkip_sbox(unsigned int index) -{ - unsigned int index_low; - unsigned int index_high; - unsigned int left, right; - - index_low = (index % 256); - index_high = ((index >> 8) % 256); - - left = TKIP_Sbox_Lower[index_low] + (TKIP_Sbox_Upper[index_low] * 256); - right = TKIP_Sbox_Upper[index_high] + (TKIP_Sbox_Lower[index_high] * 256); - - return left ^ right; -}; - -unsigned int rotr1(unsigned int a) -{ - unsigned int b; - - if ((a & 0x01) == 0x01) - b = (a >> 1) | 0x8000; - else - b = (a >> 1) & 0x7fff; - - b = b % 65536; - return b; -} - -/* - * Description: Calculate RC4Key fom TK, TA, and TSC - * - * Parameters: - * In: - * pbyTKey - TKey - * pbyTA - TA - * dwTSC - TSC - * Out: - * pbyRC4Key - RC4Key - * - * Return Value: none - * - */ -void TKIPvMixKey( - unsigned char *pbyTKey, - unsigned char *pbyTA, - unsigned short wTSC15_0, - unsigned long dwTSC47_16, - unsigned char *pbyRC4Key -) -{ - unsigned int p1k[5]; - unsigned int tsc0, tsc1, tsc2; - unsigned int ppk0, ppk1, ppk2, ppk3, ppk4, ppk5; - unsigned long int pnl, pnh; - - int i, j; - - pnl = wTSC15_0; - pnh = dwTSC47_16; - - tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */ - tsc1 = (unsigned int)(pnh % 65536); - tsc2 = (unsigned int)(pnl % 65536); /* lsb */ - - /* Phase 1, step 1 */ - p1k[0] = tsc1; - p1k[1] = tsc0; - p1k[2] = (unsigned int)(pbyTA[0] + (pbyTA[1]*256)); - p1k[3] = (unsigned int)(pbyTA[2] + (pbyTA[3]*256)); - p1k[4] = (unsigned int)(pbyTA[4] + (pbyTA[5]*256)); - - /* Phase 1, step 2 */ - for (i = 0; i < 8; i++) { - j = 2 * (i & 1); - p1k[0] = (p1k[0] + tkip_sbox((p1k[4] ^ ((256*pbyTKey[1+j]) + pbyTKey[j])) % 65536)) % 65536; - p1k[1] = (p1k[1] + tkip_sbox((p1k[0] ^ ((256*pbyTKey[5+j]) + pbyTKey[4+j])) % 65536)) % 65536; - p1k[2] = (p1k[2] + tkip_sbox((p1k[1] ^ ((256*pbyTKey[9+j]) + pbyTKey[8+j])) % 65536)) % 65536; - p1k[3] = (p1k[3] + tkip_sbox((p1k[2] ^ ((256*pbyTKey[13+j]) + pbyTKey[12+j])) % 65536)) % 65536; - p1k[4] = (p1k[4] + tkip_sbox((p1k[3] ^ (((256*pbyTKey[1+j]) + pbyTKey[j]))) % 65536)) % 65536; - p1k[4] = (p1k[4] + i) % 65536; - } - /* Phase 2, Step 1 */ - ppk0 = p1k[0]; - ppk1 = p1k[1]; - ppk2 = p1k[2]; - ppk3 = p1k[3]; - ppk4 = p1k[4]; - ppk5 = (p1k[4] + tsc2) % 65536; - - /* Phase2, Step 2 */ - ppk0 = ppk0 + tkip_sbox((ppk5 ^ ((256*pbyTKey[1]) + pbyTKey[0])) % 65536); - ppk1 = ppk1 + tkip_sbox((ppk0 ^ ((256*pbyTKey[3]) + pbyTKey[2])) % 65536); - ppk2 = ppk2 + tkip_sbox((ppk1 ^ ((256*pbyTKey[5]) + pbyTKey[4])) % 65536); - ppk3 = ppk3 + tkip_sbox((ppk2 ^ ((256*pbyTKey[7]) + pbyTKey[6])) % 65536); - ppk4 = ppk4 + tkip_sbox((ppk3 ^ ((256*pbyTKey[9]) + pbyTKey[8])) % 65536); - ppk5 = ppk5 + tkip_sbox((ppk4 ^ ((256*pbyTKey[11]) + pbyTKey[10])) % 65536); - - ppk0 = ppk0 + rotr1(ppk5 ^ ((256*pbyTKey[13]) + pbyTKey[12])); - ppk1 = ppk1 + rotr1(ppk0 ^ ((256*pbyTKey[15]) + pbyTKey[14])); - ppk2 = ppk2 + rotr1(ppk1); - ppk3 = ppk3 + rotr1(ppk2); - ppk4 = ppk4 + rotr1(ppk3); - ppk5 = ppk5 + rotr1(ppk4); - - /* Phase 2, Step 3 */ - pbyRC4Key[0] = (tsc2 >> 8) % 256; - pbyRC4Key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f; - pbyRC4Key[2] = tsc2 % 256; - pbyRC4Key[3] = ((ppk5 ^ ((256*pbyTKey[1]) + pbyTKey[0])) >> 1) % 256; - - pbyRC4Key[4] = ppk0 % 256; - pbyRC4Key[5] = (ppk0 >> 8) % 256; - - pbyRC4Key[6] = ppk1 % 256; - pbyRC4Key[7] = (ppk1 >> 8) % 256; - - pbyRC4Key[8] = ppk2 % 256; - pbyRC4Key[9] = (ppk2 >> 8) % 256; - - pbyRC4Key[10] = ppk3 % 256; - pbyRC4Key[11] = (ppk3 >> 8) % 256; - - pbyRC4Key[12] = ppk4 % 256; - pbyRC4Key[13] = (ppk4 >> 8) % 256; - - pbyRC4Key[14] = ppk5 % 256; - pbyRC4Key[15] = (ppk5 >> 8) % 256; -} diff --git a/drivers/staging/vt6655/tkip.h b/drivers/staging/vt6655/tkip.h deleted file mode 100644 index 3b6357ac6dee..000000000000 --- a/drivers/staging/vt6655/tkip.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: tkip.h - * - * Purpose: Implement functions for 802.11i TKIP - * - * Author: Jerry Chen - * - * Date: Mar. 11, 2003 - * - */ - -#ifndef __TKIP_H__ -#define __TKIP_H__ - -#include "ttype.h" -#include "tether.h" - -/*--------------------- Export Definitions -------------------------*/ -#define TKIP_KEY_LEN 16 - -/*--------------------- Export Types ------------------------------*/ - -/*--------------------- Export Macros ------------------------------*/ - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -void TKIPvMixKey( - unsigned char *pbyTKey, - unsigned char *pbyTA, - unsigned short wTSC15_0, - unsigned long dwTSC47_16, - unsigned char *pbyRC4Key -); - -#endif // __TKIP_H__ diff --git a/drivers/staging/vt6655/tmacro.h b/drivers/staging/vt6655/tmacro.h index 59c6e72f993a..607b78f7a6a0 100644 --- a/drivers/staging/vt6655/tmacro.h +++ b/drivers/staging/vt6655/tmacro.h @@ -29,8 +29,6 @@ #ifndef __TMACRO_H__ #define __TMACRO_H__ -#include "ttype.h" - /****** Common helper macros ***********************************************/ #if !defined(LOBYTE) diff --git a/drivers/staging/vt6655/ttype.h b/drivers/staging/vt6655/ttype.h deleted file mode 100644 index 747ef62ec9be..000000000000 --- a/drivers/staging/vt6655/ttype.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: ttype.h - * - * Purpose: define basic common types and macros - * - * Author: Tevin Chen - * - * Date: May 21, 1996 - * - */ - -#ifndef __TTYPE_H__ -#define __TTYPE_H__ - -/******* Common definitions and typedefs ***********************************/ - -#ifndef WPA_SM_Transtatus -#define WPA_SM_Transtatus -#endif - -#ifndef Calcu_LinkQual -#define Calcu_LinkQual -#endif - -#endif // __TTYPE_H__ diff --git a/drivers/staging/vt6655/upc.h b/drivers/staging/vt6655/upc.h index c5c889cade25..c53703a772f5 100644 --- a/drivers/staging/vt6655/upc.h +++ b/drivers/staging/vt6655/upc.h @@ -30,7 +30,6 @@ #define __UPC_H__ #include "device.h" -#include "ttype.h" /*--------------------- Export Definitions -------------------------*/ diff --git a/drivers/staging/vt6655/vntconfiguration.dat b/drivers/staging/vt6655/vntconfiguration.dat deleted file mode 100644 index 0064ddce7c11..000000000000 --- a/drivers/staging/vt6655/vntconfiguration.dat +++ /dev/null @@ -1 +0,0 @@ -ZONETYPE=EUROPE
\ No newline at end of file diff --git a/drivers/staging/vt6655/vntwifi.c b/drivers/staging/vt6655/vntwifi.c deleted file mode 100644 index 59f66fe47352..000000000000 --- a/drivers/staging/vt6655/vntwifi.c +++ /dev/null @@ -1,700 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: vntwifi.c - * - * Purpose: export functions for vntwifi lib - * - * Functions: - * - * Revision History: - * - * Author: Yiching Chen - * - * Date: feb. 2, 2005 - * - */ - -#include "vntwifi.h" -#include "IEEE11h.h" -#include "country.h" -#include "device.h" -#include "wmgr.h" -#include "datarate.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -/*+ - * - * Description: - * Set Operation Mode - * - * Parameters: - * In: - * pMgmtHandle - pointer to management object - * eOPMode - Operation Mode - * Out: - * none - * - * Return Value: none - * - -*/ -void -VNTWIFIvSetOPMode( - void *pMgmtHandle, - WMAC_CONFIG_MODE eOPMode -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - pMgmt->eConfigMode = eOPMode; -} - -/*+ - * - * Description: - * Set Operation Mode - * - * Parameters: - * In: - * pMgmtHandle - pointer to management object - * wBeaconPeriod - Beacon Period - * wATIMWindow - ATIM window - * uChannel - channel number - * Out: - * none - * - * Return Value: none - * - -*/ -void -VNTWIFIvSetIBSSParameter( - void *pMgmtHandle, - unsigned short wBeaconPeriod, - unsigned short wATIMWindow, - unsigned int uChannel -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - pMgmt->wIBSSBeaconPeriod = wBeaconPeriod; - pMgmt->wIBSSATIMWindow = wATIMWindow; - pMgmt->uIBSSChannel = uChannel; -} - -/*+ - * - * Description: - * Get current SSID - * - * Parameters: - * In: - * pMgmtHandle - pointer to management object - * Out: - * none - * - * Return Value: current SSID pointer. - * - -*/ -PWLAN_IE_SSID -VNTWIFIpGetCurrentSSID( - void *pMgmtHandle -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - return (PWLAN_IE_SSID) pMgmt->abyCurrSSID; -} - -/*+ - * - * Description: - * Get current link channel - * - * Parameters: - * In: - * pMgmtHandle - pointer to management object - * Out: - * none - * - * Return Value: current Channel. - * - -*/ -unsigned int -VNTWIFIpGetCurrentChannel( - void *pMgmtHandle -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - if (pMgmtHandle != NULL) - return pMgmt->uCurrChannel; - - return 0; -} - -/*+ - * - * Description: - * Get current Assoc ID - * - * Parameters: - * In: - * pMgmtHandle - pointer to management object - * Out: - * none - * - * Return Value: current Assoc ID - * - -*/ -unsigned short -VNTWIFIwGetAssocID( - void *pMgmtHandle -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - return pMgmt->wCurrAID; -} - -/*+ - * - * Description: - * This routine return max support rate of IES - * - * Parameters: - * In: - * pSupportRateIEs - * pExtSupportRateIEs - * - * Out: - * - * Return Value: max support rate - * - -*/ -unsigned char -VNTWIFIbyGetMaxSupportRate( - PWLAN_IE_SUPP_RATES pSupportRateIEs, - PWLAN_IE_SUPP_RATES pExtSupportRateIEs -) -{ - unsigned char byMaxSupportRate = RATE_1M; - unsigned char bySupportRate = RATE_1M; - unsigned int ii = 0; - - if (pSupportRateIEs) { - for (ii = 0; ii < pSupportRateIEs->len; ii++) { - bySupportRate = DATARATEbyGetRateIdx(pSupportRateIEs->abyRates[ii]); - if (bySupportRate > byMaxSupportRate) - byMaxSupportRate = bySupportRate; - - } - } - if (pExtSupportRateIEs) { - for (ii = 0; ii < pExtSupportRateIEs->len; ii++) { - bySupportRate = DATARATEbyGetRateIdx(pExtSupportRateIEs->abyRates[ii]); - if (bySupportRate > byMaxSupportRate) - byMaxSupportRate = bySupportRate; - - } - } - - return byMaxSupportRate; -} - -/*+ - * - * Description: - * This routine return data rate of ACK packtet - * - * Parameters: - * In: - * byRxDataRate - * pSupportRateIEs - * pExtSupportRateIEs - * - * Out: - * - * Return Value: max support rate - * - -*/ -unsigned char -VNTWIFIbyGetACKTxRate( - unsigned char byRxDataRate, - PWLAN_IE_SUPP_RATES pSupportRateIEs, - PWLAN_IE_SUPP_RATES pExtSupportRateIEs -) -{ - unsigned char byMaxAckRate; - unsigned char byBasicRate; - unsigned int ii; - - if (byRxDataRate <= RATE_11M) { - byMaxAckRate = RATE_1M; - } else { - /* 24M is mandatory for 802.11a and 802.11g */ - byMaxAckRate = RATE_24M; - } - if (pSupportRateIEs) { - for (ii = 0; ii < pSupportRateIEs->len; ii++) { - if (pSupportRateIEs->abyRates[ii] & 0x80) { - byBasicRate = DATARATEbyGetRateIdx(pSupportRateIEs->abyRates[ii]); - if ((byBasicRate <= byRxDataRate) && - (byBasicRate > byMaxAckRate)) { - byMaxAckRate = byBasicRate; - } - } - } - } - if (pExtSupportRateIEs) { - for (ii = 0; ii < pExtSupportRateIEs->len; ii++) { - if (pExtSupportRateIEs->abyRates[ii] & 0x80) { - byBasicRate = DATARATEbyGetRateIdx(pExtSupportRateIEs->abyRates[ii]); - if ((byBasicRate <= byRxDataRate) && - (byBasicRate > byMaxAckRate)) { - byMaxAckRate = byBasicRate; - } - } - } - } - - return byMaxAckRate; -} - -/*+ - * - * Description: - * Set Authentication Mode - * - * Parameters: - * In: - * pMgmtHandle - pointer to management object - * eAuthMode - Authentication mode - * Out: - * none - * - * Return Value: none - * - -*/ -void -VNTWIFIvSetAuthenticationMode( - void *pMgmtHandle, - WMAC_AUTHENTICATION_MODE eAuthMode -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - pMgmt->eAuthenMode = eAuthMode; - if ((eAuthMode == WMAC_AUTH_SHAREKEY) || - (eAuthMode == WMAC_AUTH_AUTO)) { - pMgmt->bShareKeyAlgorithm = true; - } else { - pMgmt->bShareKeyAlgorithm = false; - } -} - -/*+ - * - * Description: - * Set Encryption Mode - * - * Parameters: - * In: - * pMgmtHandle - pointer to management object - * eAuthMode - Authentication mode - * Out: - * none - * - * Return Value: none - * - -*/ -void -VNTWIFIvSetEncryptionMode( - void *pMgmtHandle, - WMAC_ENCRYPTION_MODE eEncryptionMode -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - pMgmt->eEncryptionMode = eEncryptionMode; - if ((eEncryptionMode == WMAC_ENCRYPTION_WEPEnabled) || - (eEncryptionMode == WMAC_ENCRYPTION_TKIPEnabled) || - (eEncryptionMode == WMAC_ENCRYPTION_AESEnabled)) { - pMgmt->bPrivacyInvoked = true; - } else { - pMgmt->bPrivacyInvoked = false; - } -} - -bool -VNTWIFIbConfigPhyMode( - void *pMgmtHandle, - CARD_PHY_TYPE ePhyType -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - if ((ePhyType != PHY_TYPE_AUTO) && - (ePhyType != pMgmt->eCurrentPHYMode)) { - if (CARDbSetPhyParameter(pMgmt->pAdapter, ePhyType, 0, 0, NULL, NULL) == true) - pMgmt->eCurrentPHYMode = ePhyType; - else - return false; - } - pMgmt->eConfigPHYMode = ePhyType; - return true; -} - -void -VNTWIFIbGetConfigPhyMode( - void *pMgmtHandle, - void *pePhyType -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - if ((pMgmt != NULL) && (pePhyType != NULL)) - *(PCARD_PHY_TYPE)pePhyType = pMgmt->eConfigPHYMode; -} - -/*+ - * - * Description: - * Clear BSS List Database except current assoc BSS - * - * Parameters: - * In: - * pMgmtHandle - Management Object structure - * bLinkPass - Current Link status - * Out: - * - * Return Value: None. - * - -*/ - -/*+ - * - * Description: - * Query BSS List in management database - * - * Parameters: - * In: - * pMgmtHandle - Management Object structure - * Out: - * puBSSCount - BSS count - * pvFirstBSS - pointer to first BSS - * - * Return Value: None. - * - -*/ - -void -VNTWIFIvQueryBSSList(void *pMgmtHandle, unsigned int *puBSSCount, void **pvFirstBSS) -{ - unsigned int ii = 0; - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - PKnownBSS pBSS = NULL; - unsigned int uCount = 0; - - *pvFirstBSS = NULL; - - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - pBSS = &(pMgmt->sBSSList[ii]); - if (!pBSS->bActive) - continue; - - if (*pvFirstBSS == NULL) - *pvFirstBSS = &(pMgmt->sBSSList[ii]); - - uCount++; - } - *puBSSCount = uCount; -} - -void -VNTWIFIvGetNextBSS( - void *pMgmtHandle, - void *pvCurrentBSS, - void **pvNextBSS -) -{ - PKnownBSS pBSS = (PKnownBSS) pvCurrentBSS; - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - *pvNextBSS = NULL; - - while (*pvNextBSS == NULL) { - pBSS++; - if (pBSS > &(pMgmt->sBSSList[MAX_BSS_NUM])) - return; - - if (pBSS->bActive == true) { - *pvNextBSS = pBSS; - return; - } - } -} - -/*+ - * - * Description: - * Update Tx attemps, Tx failure counter in Node DB - * - * In: - * Out: - * none - * - * Return Value: none - * - -*/ -void -VNTWIFIvUpdateNodeTxCounter( - void *pMgmtHandle, - unsigned char *pbyDestAddress, - bool bTxOk, - unsigned short wRate, - unsigned char *pbyTxFailCount -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - unsigned int uNodeIndex = 0; - unsigned int ii; - - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) || - (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { - if (BSSDBbIsSTAInNodeDB(pMgmt, pbyDestAddress, &uNodeIndex) == false) - return; - } - - pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts++; - if (bTxOk) { - /* transmit success, TxAttempts at least plus one */ - pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++; - pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wRate]++; - } else { - pMgmt->sNodeDBTable[uNodeIndex].uTxFailures++; - } - pMgmt->sNodeDBTable[uNodeIndex].uTxRetry += pbyTxFailCount[MAX_RATE]; - for (ii = 0; ii < MAX_RATE; ii++) - pMgmt->sNodeDBTable[uNodeIndex].uTxFail[ii] += pbyTxFailCount[ii]; -} - -void -VNTWIFIvGetTxRate( - void *pMgmtHandle, - unsigned char *pbyDestAddress, - unsigned short *pwTxDataRate, - unsigned char *pbyACKRate, - unsigned char *pbyCCKBasicRate, - unsigned char *pbyOFDMBasicRate -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - unsigned int uNodeIndex = 0; - unsigned short wTxDataRate = RATE_1M; - unsigned char byACKRate = RATE_1M; - unsigned char byCCKBasicRate = RATE_1M; - unsigned char byOFDMBasicRate = RATE_24M; - PWLAN_IE_SUPP_RATES pSupportRateIEs = NULL; - PWLAN_IE_SUPP_RATES pExtSupportRateIEs = NULL; - - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) || - (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { - /* Adhoc Tx rate decided from node DB */ - if (BSSDBbIsSTAInNodeDB(pMgmt, pbyDestAddress, &uNodeIndex)) { - wTxDataRate = (pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate); - pSupportRateIEs = (PWLAN_IE_SUPP_RATES) (pMgmt->sNodeDBTable[uNodeIndex].abyCurrSuppRates); - pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) (pMgmt->sNodeDBTable[uNodeIndex].abyCurrExtSuppRates); - } else { - if (pMgmt->eCurrentPHYMode != PHY_TYPE_11A) - wTxDataRate = RATE_2M; - else - wTxDataRate = RATE_24M; - - pSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrSuppRates; - pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrExtSuppRates; - } - } else { /* Infrastructure: rate decided from AP Node, index = 0 */ - - wTxDataRate = (pMgmt->sNodeDBTable[0].wTxDataRate); - - pSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrSuppRates; - pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrExtSuppRates; - } - byACKRate = VNTWIFIbyGetACKTxRate((unsigned char) wTxDataRate, - pSupportRateIEs, - pExtSupportRateIEs -); - if (byACKRate > (unsigned char) wTxDataRate) - byACKRate = (unsigned char) wTxDataRate; - - byCCKBasicRate = VNTWIFIbyGetACKTxRate(RATE_11M, - pSupportRateIEs, - pExtSupportRateIEs -); - byOFDMBasicRate = VNTWIFIbyGetACKTxRate(RATE_54M, - pSupportRateIEs, - pExtSupportRateIEs -); - *pwTxDataRate = wTxDataRate; - *pbyACKRate = byACKRate; - *pbyCCKBasicRate = byCCKBasicRate; - *pbyOFDMBasicRate = byOFDMBasicRate; -} - -unsigned char -VNTWIFIbyGetKeyCypher( - void *pMgmtHandle, - bool bGroupKey -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - if (bGroupKey) - return pMgmt->byCSSGK; - else - return pMgmt->byCSSPK; -} - -bool -VNTWIFIbSetPMKIDCache( - void *pMgmtObject, - unsigned long ulCount, - void *pPMKIDInfo -) -{ - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; - - if (ulCount > MAX_PMKID_CACHE) - return false; - - pMgmt->gsPMKIDCache.BSSIDInfoCount = ulCount; - memcpy(pMgmt->gsPMKIDCache.BSSIDInfo, pPMKIDInfo, (ulCount*sizeof(PMKIDInfo))); - return true; -} - -unsigned short -VNTWIFIwGetMaxSupportRate( - void *pMgmtObject -) -{ - unsigned short wRate = RATE_54M; - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; - - for (wRate = RATE_54M; wRate > RATE_1M; wRate--) { - if (pMgmt->sNodeDBTable[0].wSuppRate & (1<<wRate)) - return wRate; - } - - if (pMgmt->eCurrentPHYMode == PHY_TYPE_11A) - return RATE_6M; - else - return RATE_1M; -} - -void -VNTWIFIvSet11h( - void *pMgmtObject, - bool b11hEnable -) -{ - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; - - pMgmt->b11hEnable = b11hEnable; -} - -bool -VNTWIFIbMeasureReport( - void *pMgmtObject, - bool bEndOfReport, - void *pvMeasureEID, - unsigned char byReportMode, - unsigned char byBasicMap, - unsigned char byCCAFraction, - unsigned char *pbyRPIs -) -{ - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; - unsigned char *pbyCurrentEID = (unsigned char *)(pMgmt->pCurrMeasureEIDRep); - - if ((pvMeasureEID != NULL) && - (pMgmt->uLengthOfRepEIDs < (WLAN_A3FR_MAXLEN - sizeof(MEASEURE_REP) - sizeof(WLAN_80211HDR_A3) - 3)) -) { - pMgmt->pCurrMeasureEIDRep->byElementID = WLAN_EID_MEASURE_REP; - pMgmt->pCurrMeasureEIDRep->len = 3; - pMgmt->pCurrMeasureEIDRep->byToken = ((PWLAN_IE_MEASURE_REQ)pvMeasureEID)->byToken; - pMgmt->pCurrMeasureEIDRep->byMode = byReportMode; - pMgmt->pCurrMeasureEIDRep->byType = ((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->byType; - switch (pMgmt->pCurrMeasureEIDRep->byType) { - case MEASURE_TYPE_BASIC: - pMgmt->pCurrMeasureEIDRep->len += sizeof(MEASEURE_REP_BASIC); - memcpy(&(pMgmt->pCurrMeasureEIDRep->sRep.sBasic), - &(((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->sReq), - sizeof(MEASEURE_REQ)); - pMgmt->pCurrMeasureEIDRep->sRep.sBasic.byMap = byBasicMap; - break; - case MEASURE_TYPE_CCA: - pMgmt->pCurrMeasureEIDRep->len += sizeof(MEASEURE_REP_CCA); - memcpy(&(pMgmt->pCurrMeasureEIDRep->sRep.sCCA), - &(((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->sReq), - sizeof(MEASEURE_REQ)); - pMgmt->pCurrMeasureEIDRep->sRep.sCCA.byCCABusyFraction = byCCAFraction; - break; - case MEASURE_TYPE_RPI: - pMgmt->pCurrMeasureEIDRep->len += sizeof(MEASEURE_REP_RPI); - memcpy(&(pMgmt->pCurrMeasureEIDRep->sRep.sRPI), - &(((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->sReq), - sizeof(MEASEURE_REQ)); - memcpy(pMgmt->pCurrMeasureEIDRep->sRep.sRPI.abyRPIdensity, pbyRPIs, 8); - break; - default: - break; - } - pbyCurrentEID += (2 + pMgmt->pCurrMeasureEIDRep->len); - pMgmt->uLengthOfRepEIDs += (2 + pMgmt->pCurrMeasureEIDRep->len); - pMgmt->pCurrMeasureEIDRep = (PWLAN_IE_MEASURE_REP) pbyCurrentEID; - } - if (bEndOfReport) - IEEE11hbMSRRepTx(pMgmt); - - return true; -} - -bool -VNTWIFIbChannelSwitch( - void *pMgmtObject, - unsigned char byNewChannel -) -{ - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; - - pMgmt->uCurrChannel = byNewChannel; - pMgmt->bSwitchChannel = false; - return true; -} diff --git a/drivers/staging/vt6655/vntwifi.h b/drivers/staging/vt6655/vntwifi.h deleted file mode 100644 index 880b8ab109be..000000000000 --- a/drivers/staging/vt6655/vntwifi.h +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: vntwifi.h - * - * Purpose: export VNT Host WiFi library function - * - * Author: Yiching Chen - * - * Date: Jan 7, 2004 - * - */ - -#ifndef __VNTWIFI_H__ -#define __VNTWIFI_H__ - -#include "ttype.h" -#include "80211mgr.h" -#include "card.h" -#include "wpa2.h" - -/*--------------------- Export Definitions -------------------------*/ -#define RATE_1M 0 -#define RATE_2M 1 -#define RATE_5M 2 -#define RATE_11M 3 -#define RATE_6M 4 -#define RATE_9M 5 -#define RATE_12M 6 -#define RATE_18M 7 -#define RATE_24M 8 -#define RATE_36M 9 -#define RATE_48M 10 -#define RATE_54M 11 -#define RATE_AUTO 12 -#define MAX_RATE 12 - -// key CipherSuite -#define KEY_CTL_WEP 0x00 -#define KEY_CTL_NONE 0x01 -#define KEY_CTL_TKIP 0x02 -#define KEY_CTL_CCMP 0x03 -#define KEY_CTL_INVALID 0xFF - -#define CHANNEL_MAX_24G 14 - -#define MAX_BSS_NUM 42 - -// Pre-configured Authenticaiton Mode (from XP) -typedef enum tagWMAC_AUTHENTICATION_MODE { - WMAC_AUTH_OPEN, - WMAC_AUTH_SHAREKEY, - WMAC_AUTH_AUTO, - WMAC_AUTH_WPA, - WMAC_AUTH_WPAPSK, - WMAC_AUTH_WPANONE, - WMAC_AUTH_WPA2, - WMAC_AUTH_WPA2PSK, - WMAC_AUTH_MAX // Not a real mode, defined as upper bound -} WMAC_AUTHENTICATION_MODE, *PWMAC_AUTHENTICATION_MODE; - -typedef enum tagWMAC_ENCRYPTION_MODE { - WMAC_ENCRYPTION_WEPEnabled, - WMAC_ENCRYPTION_WEPDisabled, - WMAC_ENCRYPTION_WEPKeyAbsent, - WMAC_ENCRYPTION_WEPNotSupported, - WMAC_ENCRYPTION_TKIPEnabled, - WMAC_ENCRYPTION_TKIPKeyAbsent, - WMAC_ENCRYPTION_AESEnabled, - WMAC_ENCRYPTION_AESKeyAbsent -} WMAC_ENCRYPTION_MODE, *PWMAC_ENCRYPTION_MODE; - -// Pre-configured Mode (from XP) - -typedef enum tagWMAC_CONFIG_MODE { - WMAC_CONFIG_ESS_STA = 0, - WMAC_CONFIG_IBSS_STA, - WMAC_CONFIG_AUTO, - WMAC_CONFIG_AP -} WMAC_CONFIG_MODE, *PWMAC_CONFIG_MODE; - -typedef enum tagWMAC_POWER_MODE { - WMAC_POWER_CAM, - WMAC_POWER_FAST, - WMAC_POWER_MAX -} WMAC_POWER_MODE, *PWMAC_POWER_MODE; - -#define VNTWIFIbIsShortSlotTime(wCapInfo) \ - WLAN_GET_CAP_INFO_SHORTSLOTTIME(wCapInfo) \ - -#define VNTWIFIbIsProtectMode(byERP) \ - ((byERP & WLAN_EID_ERP_USE_PROTECTION) != 0) \ - -#define VNTWIFIbIsBarkerMode(byERP) \ - ((byERP & WLAN_EID_ERP_BARKER_MODE) != 0) \ - -#define VNTWIFIbIsShortPreamble(wCapInfo) \ - WLAN_GET_CAP_INFO_SHORTPREAMBLE(wCapInfo) \ - -#define VNTWIFIbIsEncryption(wCapInfo) \ - WLAN_GET_CAP_INFO_PRIVACY(wCapInfo) \ - -#define VNTWIFIbIsESS(wCapInfo) \ - WLAN_GET_CAP_INFO_ESS(wCapInfo) \ - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Types ------------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -void -VNTWIFIvSetIBSSParameter( - void *pMgmtHandle, - unsigned short wBeaconPeriod, - unsigned short wATIMWindow, - unsigned int uChannel -); - -void -VNTWIFIvSetOPMode( - void *pMgmtHandle, - WMAC_CONFIG_MODE eOPMode -); - -PWLAN_IE_SSID -VNTWIFIpGetCurrentSSID( - void *pMgmtHandle -); - -unsigned int -VNTWIFIpGetCurrentChannel( - void *pMgmtHandle -); - -unsigned short -VNTWIFIwGetAssocID( - void *pMgmtHandle -); - -unsigned char -VNTWIFIbyGetMaxSupportRate( - PWLAN_IE_SUPP_RATES pSupportRateIEs, - PWLAN_IE_SUPP_RATES pExtSupportRateIEs -); - -unsigned char -VNTWIFIbyGetACKTxRate( - unsigned char byRxDataRate, - PWLAN_IE_SUPP_RATES pSupportRateIEs, - PWLAN_IE_SUPP_RATES pExtSupportRateIEs -); - -void -VNTWIFIvSetAuthenticationMode( - void *pMgmtHandle, - WMAC_AUTHENTICATION_MODE eAuthMode -); - -void -VNTWIFIvSetEncryptionMode( - void *pMgmtHandle, - WMAC_ENCRYPTION_MODE eEncryptionMode -); - -bool -VNTWIFIbConfigPhyMode( - void *pMgmtHandle, - CARD_PHY_TYPE ePhyType -); - -void -VNTWIFIbGetConfigPhyMode( - void *pMgmtHandle, - void *pePhyType -); - -void -VNTWIFIvQueryBSSList(void *pMgmtHandle, unsigned int *puBSSCount, - void **pvFirstBSS); - -void -VNTWIFIvGetNextBSS( - void *pMgmtHandle, - void *pvCurrentBSS, - void **pvNextBSS -); - -void -VNTWIFIvUpdateNodeTxCounter( - void *pMgmtHandle, - unsigned char *pbyDestAddress, - bool bTxOk, - unsigned short wRate, - unsigned char *pbyTxFailCount -); - -void -VNTWIFIvGetTxRate( - void *pMgmtHandle, - unsigned char *pbyDestAddress, - unsigned short *pwTxDataRate, - unsigned char *pbyACKRate, - unsigned char *pbyCCKBasicRate, - unsigned char *pbyOFDMBasicRate -); - -unsigned char -VNTWIFIbyGetKeyCypher( - void *pMgmtHandle, - bool bGroupKey -); - -bool -VNTWIFIbSetPMKIDCache( - void *pMgmtObject, - unsigned long ulCount, - void *pPMKIDInfo -); - -bool -VNTWIFIbCommandRunning( - void *pMgmtObject -); - -unsigned short -VNTWIFIwGetMaxSupportRate( - void *pMgmtObject -); - -// for 802.11h -void -VNTWIFIvSet11h( - void *pMgmtObject, - bool b11hEnable -); - -bool -VNTWIFIbMeasureReport( - void *pMgmtObject, - bool bEndOfReport, - void *pvMeasureEID, - unsigned char byReportMode, - unsigned char byBasicMap, - unsigned char byCCAFraction, - unsigned char *pbyRPIs -); - -bool -VNTWIFIbChannelSwitch( - void *pMgmtObject, - unsigned char byNewChannel -); - -#endif //__VNTWIFI_H__ diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c deleted file mode 100644 index 985e1b99362d..000000000000 --- a/drivers/staging/vt6655/wcmd.c +++ /dev/null @@ -1,1023 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: wcmd.c - * - * Purpose: Handles the management command interface functions - * - * Author: Lyndon Chen - * - * Date: May 8, 2003 - * - * Functions: - * s_vProbeChannel - Active scan channel - * s_MgrMakeProbeRequest - Make ProbeRequest packet - * CommandTimer - Timer function to handle command - * s_bCommandComplete - Command Complete function - * bScheduleCommand - Push Command and wait Command Scheduler to do - * vCommandTimer- Command call back functions - * vCommandTimerWait- Call back timer - * bClearBSSID_SCAN- Clear BSSID_SCAN cmd in CMD Queue - * - * Revision History: - * - */ - -#include "ttype.h" -#include "tmacro.h" -#include "device.h" -#include "mac.h" -#include "card.h" -#include "80211hdr.h" -#include "wcmd.h" -#include "wmgr.h" -#include "power.h" -#include "wctl.h" -#include "baseband.h" -#include "rxtx.h" -#include "rf.h" -#include "iowpa.h" -#include "channel.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -static -void -s_vProbeChannel( - struct vnt_private *pDevice -); - -static -PSTxMgmtPacket -s_MgrMakeProbeRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned char *pScanBSSID, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pCurrRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -); - -static -bool -s_bCommandComplete( - struct vnt_private *pDevice -); - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -/* - * Description: - * Stop AdHoc beacon during scan process - * - * Parameters: - * In: - * pDevice - Pointer to the adapter - * Out: - * none - * - * Return Value: none - * - */ -static -void -vAdHocBeaconStop(struct vnt_private *pDevice) -{ - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - bool bStop; - - /* - * temporarily stop Beacon packet for AdHoc Server - * if all of the following conditions are met: - * (1) STA is in AdHoc mode - * (2) VT3253 is programmed as automatic Beacon Transmitting - * (3) One of the following conditions is met - * (3.1) AdHoc channel is in B/G band and the - * current scan channel is in A band - * or - * (3.2) AdHoc channel is in A mode - */ - bStop = false; - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && - (pMgmt->eCurrState >= WMAC_STATE_STARTED)) { - if ((pMgmt->uIBSSChannel <= CB_MAX_CHANNEL_24G) && - (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G)) { - bStop = true; - } - if (pMgmt->uIBSSChannel > CB_MAX_CHANNEL_24G) - bStop = true; - - } - - if (bStop) - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); -} /* vAdHocBeaconStop */ - -/* - * Description: - * Restart AdHoc beacon after scan process complete - * - * Parameters: - * In: - * pDevice - Pointer to the adapter - * Out: - * none - * - * Return Value: none - * - */ -static -void -vAdHocBeaconRestart(struct vnt_private *pDevice) -{ - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - - /* - * Restart Beacon packet for AdHoc Server - * if all of the following coditions are met: - * (1) STA is in AdHoc mode - * (2) VT3253 is programmed as automatic Beacon Transmitting - */ - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && - (pMgmt->eCurrState >= WMAC_STATE_STARTED)) { - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); - } -} - -/*+ - * - * Routine Description: - * Prepare and send probe request management frames. - * - * - * Return Value: - * none. - * - -*/ - -static -void -s_vProbeChannel( - struct vnt_private *pDevice -) -{ - //1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M - unsigned char abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C}; - unsigned char abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60}; - //6M, 9M, 12M, 48M - unsigned char abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; - unsigned char abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16}; - unsigned char *pbyRate; - PSTxMgmtPacket pTxPacket; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int ii; - - if (pDevice->eCurrentPHYType == PHY_TYPE_11A) - pbyRate = &abyCurrSuppRatesA[0]; - else if (pDevice->eCurrentPHYType == PHY_TYPE_11B) - pbyRate = &abyCurrSuppRatesB[0]; - else - pbyRate = &abyCurrSuppRatesG[0]; - - // build an assocreq frame and send it - pTxPacket = s_MgrMakeProbeRequest - ( - pDevice, - pMgmt, - pMgmt->abyScanBSSID, - (PWLAN_IE_SSID)pMgmt->abyScanSSID, - (PWLAN_IE_SUPP_RATES)pbyRate, - (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRatesG - ); - - if (pTxPacket != NULL) { - for (ii = 0; ii < 2; ii++) { - if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) - pr_debug("Probe request sending fail..\n"); - else - pr_debug("Probe request is sending..\n"); - } - } -} - -/*+ - * - * Routine Description: - * Constructs an probe request frame - * - * - * Return Value: - * A ptr to Tx frame or NULL on allocation failure - * - -*/ - -static PSTxMgmtPacket -s_MgrMakeProbeRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned char *pScanBSSID, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pCurrRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates - -) -{ - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_PROBEREQ sFrame; - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBEREQ_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_PROBEREQ_FR_MAXLEN; - vMgrEncodeProbeRequest(&sFrame); - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBEREQ) -)); - memcpy(sFrame.pHdr->sA3.abyAddr1, pScanBSSID, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pScanBSSID, WLAN_BSSID_LEN); - // Copy the SSID, pSSID->len=0 indicate broadcast SSID - sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); - sFrame.len += pSSID->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSSID, pSSID, pSSID->len + WLAN_IEHDR_LEN); - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); - // Copy the extension rate set - if (pDevice->eCurrentPHYType == PHY_TYPE_11G) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN); - } - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - return pTxPacket; -} - -void -vCommandTimerWait( - void *hDeviceContext, - unsigned int MSecond -) -{ - struct vnt_private *pDevice = hDeviceContext; - - init_timer(&pDevice->sTimerCommand); - pDevice->sTimerCommand.data = (unsigned long) pDevice; - pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer; - // RUN_AT :1 msec ~= (HZ/1024) - pDevice->sTimerCommand.expires = (unsigned int)RUN_AT((MSecond * HZ) >> 10); - add_timer(&pDevice->sTimerCommand); -} - -void -vCommandTimer( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - PWLAN_IE_SSID pItemSSID; - PWLAN_IE_SSID pItemSSIDCurr; - CMD_STATUS Status; - unsigned int ii; - unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; - struct sk_buff *skb; - - if (pDevice->dwDiagRefCount != 0) - return; - if (!pDevice->bCmdRunning) - return; - - spin_lock_irq(&pDevice->lock); - - switch (pDevice->eCommandState) { - case WLAN_CMD_SCAN_START: - - pDevice->byReAssocCount = 0; - if (pDevice->bRadioOff) { - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - s_bCommandComplete(pDevice); - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_AP); - spin_unlock_irq(&pDevice->lock); - return; - } - - pr_debug("eCommandState= WLAN_CMD_SCAN_START\n"); - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyScanSSID; - // wait all Data TD complete - if (pDevice->iTDUsed[TYPE_AC0DMA] != 0) { - spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((void *)pDevice, 10); - return; - } - - if (pMgmt->uScanChannel == 0) { - pMgmt->uScanChannel = pDevice->byMinChannel; - // Set Baseband to be more sensitive. - - } - if (pMgmt->uScanChannel > pDevice->byMaxChannel) { - pMgmt->eScanState = WMAC_NO_SCANNING; - - // Set Baseband's sensitivity back. - // Set channel back - set_channel(pMgmt->pAdapter, pMgmt->uCurrChannel); - pr_debug("Scanning, set back to channel: [%d]\n", - pMgmt->uCurrChannel); - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_ADHOC); - else - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_STATION); - - vAdHocBeaconRestart(pDevice); - s_bCommandComplete(pDevice); - - } else { -//2008-8-4 <add> by chester - if (!is_channel_valid(pMgmt->uScanChannel)) { - pr_debug("Invalid channel pMgmt->uScanChannel = %d\n", - pMgmt->uScanChannel); - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } - if (pMgmt->uScanChannel == pDevice->byMinChannel) { - pMgmt->abyScanBSSID[0] = 0xFF; - pMgmt->abyScanBSSID[1] = 0xFF; - pMgmt->abyScanBSSID[2] = 0xFF; - pMgmt->abyScanBSSID[3] = 0xFF; - pMgmt->abyScanBSSID[4] = 0xFF; - pMgmt->abyScanBSSID[5] = 0xFF; - pItemSSID->byElementID = WLAN_EID_SSID; - pMgmt->eScanState = WMAC_IS_SCANNING; - - } - - vAdHocBeaconStop(pDevice); - - if (set_channel(pMgmt->pAdapter, pMgmt->uScanChannel)) - pr_debug("SCAN Channel: %d\n", - pMgmt->uScanChannel); - else - pr_debug("SET SCAN Channel Fail: %d\n", - pMgmt->uScanChannel); - - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_UNSPECIFIED); - pMgmt->uScanChannel++; -//2008-8-4 <modify> by chester - if (!is_channel_valid(pMgmt->uScanChannel) && - pMgmt->uScanChannel <= pDevice->byMaxChannel) { - pMgmt->uScanChannel = pDevice->byMaxChannel + 1; - pMgmt->eCommandState = WLAN_CMD_SCAN_END; - - } - - if (!pMgmt->b11hEnable || - (pMgmt->uScanChannel < CB_MAX_CHANNEL_24G)) { - s_vProbeChannel(pDevice); - spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((void *)pDevice, WCMD_ACTIVE_SCAN_TIME); - return; - } else { - spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((void *)pDevice, WCMD_PASSIVE_SCAN_TIME); - return; - } - - } - - break; - - case WLAN_CMD_SCAN_END: - - // Set Baseband's sensitivity back. - // Set channel back - set_channel(pMgmt->pAdapter, pMgmt->uCurrChannel); - pr_debug("Scanning, set back to channel: [%d]\n", - pMgmt->uCurrChannel); - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_ADHOC); - else - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_STATION); - - pMgmt->eScanState = WMAC_NO_SCANNING; - vAdHocBeaconRestart(pDevice); -//2008-0409-07, <Add> by Einsn Liu -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - if (pMgmt->eScanType == WMAC_SCAN_PASSIVE) { - //send scan event to wpa_Supplicant - union iwreq_data wrqu; - - memset(&wrqu, 0, sizeof(wrqu)); - wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL); - } -#endif - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_DISASSOCIATE_START: - pDevice->byReAssocCount = 0; - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pMgmt->eCurrState != WMAC_STATE_ASSOC)) { - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } else { - pr_debug("Send Disassociation Packet..\n"); - // reason = 8 : disassoc because sta has left - vMgrDisassocBeginSta((void *)pDevice, pMgmt, pMgmt->abyCurrBSSID, (8), &Status); - pDevice->bLinkPass = false; - // unlock command busy - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - pItemSSID->len = 0; - memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN); - pMgmt->eCurrState = WMAC_STATE_IDLE; - pMgmt->sNodeDBTable[0].bActive = false; - } - netif_stop_queue(pDevice->dev); - pDevice->eCommandState = WLAN_DISASSOCIATE_WAIT; - // wait all Control TD complete - if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) { - vCommandTimerWait((void *)pDevice, 10); - spin_unlock_irq(&pDevice->lock); - return; - } - pr_debug(" CARDbRadioPowerOff\n"); - //2008-09-02 <mark> by chester - s_bCommandComplete(pDevice); - break; - - case WLAN_DISASSOCIATE_WAIT: - // wait all Control TD complete - if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) { - vCommandTimerWait((void *)pDevice, 10); - spin_unlock_irq(&pDevice->lock); - return; - } -//2008-09-02 <mark> by chester - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_SSID_START: - pDevice->byReAssocCount = 0; - if (pDevice->bRadioOff) { - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } - pr_debug("chester-abyDesireSSID=%s\n", ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID); - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; - pItemSSIDCurr = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - pr_debug(" cmd: desire ssid = %s\n", pItemSSID->abySSID); - pr_debug(" cmd: curr ssid = %s\n", pItemSSIDCurr->abySSID); - - if (pMgmt->eCurrState == WMAC_STATE_ASSOC) { - pr_debug(" Cmd pMgmt->eCurrState == WMAC_STATE_ASSOC\n"); - pr_debug(" pItemSSID->len =%d\n", pItemSSID->len); - pr_debug(" pItemSSIDCurr->len = %d\n", - pItemSSIDCurr->len); - pr_debug(" desire ssid = %s\n", pItemSSID->abySSID); - pr_debug(" curr ssid = %s\n", pItemSSIDCurr->abySSID); - } - - if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) || - ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) { - if (pItemSSID->len == pItemSSIDCurr->len) { - if (memcmp(pItemSSID->abySSID, pItemSSIDCurr->abySSID, pItemSSID->len) == 0) { - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } - } - - netif_stop_queue(pDevice->dev); - pDevice->bLinkPass = false; - } - // set initial state - pMgmt->eCurrState = WMAC_STATE_IDLE; - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - PSvDisablePowerSaving((void *)pDevice); - BSSvClearNodeDBTable(pDevice, 0); - - vMgrJoinBSSBegin((void *)pDevice, &Status); - // if Infra mode - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED)) { - // Call mgr to begin the deauthentication - // reason = (3) because sta has left ESS - if (pMgmt->eCurrState >= WMAC_STATE_AUTH) - vMgrDeAuthenBeginSta((void *)pDevice, pMgmt, pMgmt->abyCurrBSSID, (3), &Status); - - // Call mgr to begin the authentication - vMgrAuthenBeginSta((void *)pDevice, pMgmt, &Status); - if (Status == CMD_STATUS_SUCCESS) { - pDevice->byLinkWaitCount = 0; - pDevice->eCommandState = WLAN_AUTHENTICATE_WAIT; - vCommandTimerWait((void *)pDevice, AUTHENTICATE_TIMEOUT); - spin_unlock_irq(&pDevice->lock); - pr_debug(" Set eCommandState = WLAN_AUTHENTICATE_WAIT\n"); - return; - } - } - // if Adhoc mode - else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - if (pMgmt->eCurrState == WMAC_STATE_JOINTED) { - if (netif_queue_stopped(pDevice->dev)) - netif_wake_queue(pDevice->dev); - - pDevice->bLinkPass = true; - - pMgmt->sNodeDBTable[0].bActive = true; - pMgmt->sNodeDBTable[0].uInActiveCount = 0; - bClearBSSID_SCAN(pDevice); - } else { - // start own IBSS - vMgrCreateOwnIBSS((void *)pDevice, &Status); - if (Status != CMD_STATUS_SUCCESS) - pr_debug(" WLAN_CMD_IBSS_CREATE fail !\n"); - - BSSvAddMulticastNode(pDevice); - } - } - // if SSID not found - else if (pMgmt->eCurrMode == WMAC_MODE_STANDBY) { - if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA || - pMgmt->eConfigMode == WMAC_CONFIG_AUTO) { - // start own IBSS - vMgrCreateOwnIBSS((void *)pDevice, &Status); - if (Status != CMD_STATUS_SUCCESS) - pr_debug(" WLAN_CMD_IBSS_CREATE fail !\n"); - - BSSvAddMulticastNode(pDevice); - if (netif_queue_stopped(pDevice->dev)) - netif_wake_queue(pDevice->dev); - - pDevice->bLinkPass = true; - } else { - pr_debug("Disconnect SSID none\n"); -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - { - union iwreq_data wrqu; - - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - pr_debug("wireless_send_event--->SIOCGIWAP(disassociated:vMgrJoinBSSBegin Fail !!)\n"); - wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); - } -#endif - - } - } - s_bCommandComplete(pDevice); - break; - - case WLAN_AUTHENTICATE_WAIT: - pr_debug("eCommandState == WLAN_AUTHENTICATE_WAIT\n"); - if (pMgmt->eCurrState == WMAC_STATE_AUTH) { - // Call mgr to begin the association - pDevice->byLinkWaitCount = 0; - pr_debug("eCurrState == WMAC_STATE_AUTH\n"); - vMgrAssocBeginSta((void *)pDevice, pMgmt, &Status); - if (Status == CMD_STATUS_SUCCESS) { - pDevice->byLinkWaitCount = 0; - pr_debug("eCommandState = WLAN_ASSOCIATE_WAIT\n"); - pDevice->eCommandState = WLAN_ASSOCIATE_WAIT; - vCommandTimerWait((void *)pDevice, ASSOCIATE_TIMEOUT); - spin_unlock_irq(&pDevice->lock); - return; - } - } - - else if (pMgmt->eCurrState < WMAC_STATE_AUTHPENDING) { - pr_debug("WLAN_AUTHENTICATE_WAIT:Authen Fail???\n"); - } else if (pDevice->byLinkWaitCount <= 4) { //mike add:wait another 2 sec if authenticated_frame delay! - pDevice->byLinkWaitCount++; - pr_debug("WLAN_AUTHENTICATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount); - spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((void *)pDevice, AUTHENTICATE_TIMEOUT/2); - return; - } - pDevice->byLinkWaitCount = 0; - s_bCommandComplete(pDevice); - break; - - case WLAN_ASSOCIATE_WAIT: - if (pMgmt->eCurrState == WMAC_STATE_ASSOC) { - pr_debug("eCurrState == WMAC_STATE_ASSOC\n"); - if (pDevice->ePSMode != WMAC_POWER_CAM) - PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); - - if (pMgmt->eAuthenMode >= WMAC_AUTH_WPA) - KeybRemoveAllKey(&(pDevice->sKey), pDevice->abyBSSID, pDevice->PortOffset); - - pDevice->bLinkPass = true; - pDevice->byLinkWaitCount = 0; - pDevice->byReAssocCount = 0; - bClearBSSID_SCAN(pDevice); - if (pDevice->byFOETuning) { - BBvSetFOE(pDevice->PortOffset); - PSbSendNullPacket(pDevice); - } - if (netif_queue_stopped(pDevice->dev)) - netif_wake_queue(pDevice->dev); - - if (pDevice->IsTxDataTrigger) { //TxDataTimer is not triggered at the first time - del_timer(&pDevice->sTimerTxData); - init_timer(&pDevice->sTimerTxData); - pDevice->sTimerTxData.data = (unsigned long) pDevice; - pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData; - pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback - pDevice->fTxDataInSleep = false; - pDevice->nTxDataTimeCout = 0; - } - - pDevice->IsTxDataTrigger = true; - add_timer(&pDevice->sTimerTxData); - - } else if (pMgmt->eCurrState < WMAC_STATE_ASSOCPENDING) { - printk("WLAN_ASSOCIATE_WAIT:Association Fail???\n"); - } else if (pDevice->byLinkWaitCount <= 4) { //mike add:wait another 2 sec if associated_frame delay! - pDevice->byLinkWaitCount++; - pr_debug("WLAN_ASSOCIATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount); - spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((void *)pDevice, ASSOCIATE_TIMEOUT/2); - return; - } - pDevice->byLinkWaitCount = 0; - - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_AP_MODE_START: - pr_debug("eCommandState == WLAN_CMD_AP_MODE_START\n"); - - if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { - del_timer(&pMgmt->sTimerSecondCallback); - pMgmt->eCurrState = WMAC_STATE_IDLE; - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - pDevice->bLinkPass = false; - if (pDevice->bEnableHostWEP) - BSSvClearNodeDBTable(pDevice, 1); - else - BSSvClearNodeDBTable(pDevice, 0); - pDevice->uAssocCount = 0; - pMgmt->eCurrState = WMAC_STATE_IDLE; - pDevice->bFixRate = false; - - vMgrCreateOwnIBSS((void *)pDevice, &Status); - if (Status != CMD_STATUS_SUCCESS) - pr_debug(" vMgrCreateOwnIBSS fail !\n"); - - // alway turn off unicast bit - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_UNICAST); - pDevice->byRxMode &= ~RCR_UNICAST; - pr_debug("wcmd: rx_mode = %x\n", pDevice->byRxMode); - BSSvAddMulticastNode(pDevice); - if (netif_queue_stopped(pDevice->dev)) - netif_wake_queue(pDevice->dev); - - pDevice->bLinkPass = true; - add_timer(&pMgmt->sTimerSecondCallback); - } - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_TX_PSPACKET_START: - // DTIM Multicast tx - if (pMgmt->sNodeDBTable[0].bRxPSPoll) { - while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[0].sTxPSQueue)) != NULL) { - if (skb_queue_empty(&pMgmt->sNodeDBTable[0].sTxPSQueue)) { - pMgmt->abyPSTxMap[0] &= ~byMask[0]; - pDevice->bMoreData = false; - } else { - pDevice->bMoreData = true; - } - if (!device_dma0_xmit(pDevice, skb, 0)) - pr_debug("Multicast ps tx fail\n"); - - pMgmt->sNodeDBTable[0].wEnQueueCnt--; - } - } - - // PS nodes tx - for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) { - if (pMgmt->sNodeDBTable[ii].bActive && - pMgmt->sNodeDBTable[ii].bRxPSPoll) { - pr_debug("Index=%d Enqueu Cnt= %d\n", - ii, - pMgmt->sNodeDBTable[ii].wEnQueueCnt); - while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) { - if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) { - // clear tx map - pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &= - ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7]; - pDevice->bMoreData = false; - } else { - pDevice->bMoreData = true; - } - if (!device_dma0_xmit(pDevice, skb, ii)) - pr_debug("sta ps tx fail\n"); - - pMgmt->sNodeDBTable[ii].wEnQueueCnt--; - // check if sta ps enabled, and wait next pspoll. - // if sta ps disable, then send all pending buffers. - if (pMgmt->sNodeDBTable[ii].bPSEnable) - break; - } - if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) { - // clear tx map - pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &= - ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7]; - pr_debug("Index=%d PS queue clear\n", - ii); - } - pMgmt->sNodeDBTable[ii].bRxPSPoll = false; - } - } - - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_RADIO_START: - pr_debug("eCommandState == WLAN_CMD_RADIO_START\n"); - if (pDevice->bRadioCmd) - CARDbRadioPowerOn(pDevice); - else - CARDbRadioPowerOff(pDevice); - - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE: - // wait all TD complete - if (pDevice->iTDUsed[TYPE_AC0DMA] != 0) { - vCommandTimerWait((void *)pDevice, 10); - spin_unlock_irq(&pDevice->lock); - return; - } - if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) { - vCommandTimerWait((void *)pDevice, 10); - spin_unlock_irq(&pDevice->lock); - return; - } - pDevice->byBBVGACurrent = pDevice->byBBVGANew; - BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent); - pr_debug("SetVGAGainOffset %02X\n", pDevice->byBBVGACurrent); - s_bCommandComplete(pDevice); - break; - - default: - s_bCommandComplete(pDevice); - break; - - } //switch - spin_unlock_irq(&pDevice->lock); -} - -static -bool -s_bCommandComplete( - struct vnt_private *pDevice -) -{ - PWLAN_IE_SSID pSSID; - bool bRadioCmd = false; - bool bForceSCAN = true; - PSMgmtObject pMgmt = pDevice->pMgmt; - - pDevice->eCommandState = WLAN_CMD_IDLE; - if (pDevice->cbFreeCmdQueue == CMD_Q_SIZE) { - //Command Queue Empty - pDevice->bCmdRunning = false; - return true; - } else { - pDevice->eCommand = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].eCmd; - pSSID = (PWLAN_IE_SSID)pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].abyCmdDesireSSID; - bRadioCmd = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bRadioCmd; - bForceSCAN = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bForceSCAN; - ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdDequeueIdx, CMD_Q_SIZE); - pDevice->cbFreeCmdQueue++; - pDevice->bCmdRunning = true; - switch (pDevice->eCommand) { - case WLAN_CMD_BSSID_SCAN: - pr_debug("eCommandState= WLAN_CMD_BSSID_SCAN\n"); - pDevice->eCommandState = WLAN_CMD_SCAN_START; - pMgmt->uScanChannel = 0; - if (pSSID->len != 0) - memcpy(pMgmt->abyScanSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - else - memset(pMgmt->abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - - break; - case WLAN_CMD_SSID: - pDevice->eCommandState = WLAN_CMD_SSID_START; - if (pSSID->len > WLAN_SSID_MAXLEN) - pSSID->len = WLAN_SSID_MAXLEN; - if (pSSID->len != 0) - memcpy(pDevice->pMgmt->abyDesireSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - pr_debug("eCommandState= WLAN_CMD_SSID_START\n"); - break; - case WLAN_CMD_DISASSOCIATE: - pDevice->eCommandState = WLAN_CMD_DISASSOCIATE_START; - break; - case WLAN_CMD_RX_PSPOLL: - pDevice->eCommandState = WLAN_CMD_TX_PSPACKET_START; - break; - case WLAN_CMD_RUN_AP: - pDevice->eCommandState = WLAN_CMD_AP_MODE_START; - break; - case WLAN_CMD_RADIO: - pDevice->eCommandState = WLAN_CMD_RADIO_START; - pDevice->bRadioCmd = bRadioCmd; - break; - case WLAN_CMD_CHANGE_BBSENSITIVITY: - pDevice->eCommandState = WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE; - break; - - default: - break; - - } - - vCommandTimerWait((void *)pDevice, 0); - } - - return true; -} - -bool bScheduleCommand( - void *hDeviceContext, - CMD_CODE eCommand, - unsigned char *pbyItem0 -) -{ - struct vnt_private *pDevice = hDeviceContext; - - if (pDevice->cbFreeCmdQueue == 0) - return false; - - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].eCmd = eCommand; - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = true; - memset(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, 0 , WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - - if (pbyItem0 != NULL) { - switch (eCommand) { - case WLAN_CMD_BSSID_SCAN: - memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, - pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = false; - break; - - case WLAN_CMD_SSID: - memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, - pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - break; - - case WLAN_CMD_DISASSOCIATE: - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bNeedRadioOFF = *((int *)pbyItem0); - break; - - case WLAN_CMD_RX_PSPOLL: - break; - - case WLAN_CMD_RADIO: - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bRadioCmd = *((int *)pbyItem0); - break; - - case WLAN_CMD_CHANGE_BBSENSITIVITY: - pDevice->eCommandState = WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE; - break; - - default: - break; - } - } - - ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdEnqueueIdx, CMD_Q_SIZE); - pDevice->cbFreeCmdQueue--; - - if (!pDevice->bCmdRunning) - s_bCommandComplete(pDevice); - - return true; -} - -/* - * Description: - * Clear BSSID_SCAN cmd in CMD Queue - * - * Parameters: - * In: - * hDeviceContext - Pointer to the adapter - * eCommand - Command - * Out: - * none - * - * Return Value: true if success; otherwise false - * - */ -bool bClearBSSID_SCAN( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - unsigned int uCmdDequeueIdx = pDevice->uCmdDequeueIdx; - unsigned int ii; - - if ((pDevice->cbFreeCmdQueue < CMD_Q_SIZE) && (uCmdDequeueIdx != pDevice->uCmdEnqueueIdx)) { - for (ii = 0; ii < (CMD_Q_SIZE - pDevice->cbFreeCmdQueue); ii++) { - if (pDevice->eCmdQueue[uCmdDequeueIdx].eCmd == WLAN_CMD_BSSID_SCAN) - pDevice->eCmdQueue[uCmdDequeueIdx].eCmd = WLAN_CMD_IDLE; - ADD_ONE_WITH_WRAP_AROUND(uCmdDequeueIdx, CMD_Q_SIZE); - if (uCmdDequeueIdx == pDevice->uCmdEnqueueIdx) - break; - } - } - return true; -} - -//mike add:reset command timer -void -vResetCommandTimer( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - - //delete timer - del_timer(&pDevice->sTimerCommand); - //init timer - init_timer(&pDevice->sTimerCommand); - pDevice->sTimerCommand.data = (unsigned long) pDevice; - pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer; - pDevice->sTimerCommand.expires = RUN_AT(HZ); - pDevice->cbFreeCmdQueue = CMD_Q_SIZE; - pDevice->uCmdDequeueIdx = 0; - pDevice->uCmdEnqueueIdx = 0; - pDevice->eCommandState = WLAN_CMD_IDLE; - pDevice->bCmdRunning = false; - pDevice->bCmdClear = false; -} - -void -BSSvSecondTxData( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - - pDevice->nTxDataTimeCout++; - - if (pDevice->nTxDataTimeCout < 4) //don't tx data if timer less than 40s - { - pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback - add_timer(&pDevice->sTimerTxData); - return; - } - - spin_lock_irq(&pDevice->lock); - - /* open && sharekey linking */ - if ((pDevice->bLinkPass && (pMgmt->eAuthenMode < WMAC_AUTH_WPA)) || - pDevice->fWPA_Authened) { /* wpa linking */ - pDevice->fTxDataInSleep = true; - PSbSendNullPacket(pDevice); /* send null packet */ - pDevice->fTxDataInSleep = false; - } - - spin_unlock_irq(&pDevice->lock); - - pDevice->sTimerTxData.expires = RUN_AT(10*HZ); /* 10s callback */ - add_timer(&pDevice->sTimerTxData); -} diff --git a/drivers/staging/vt6655/wcmd.h b/drivers/staging/vt6655/wcmd.h deleted file mode 100644 index 6ef04de69f37..000000000000 --- a/drivers/staging/vt6655/wcmd.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: wcmd.h - * - * Purpose: Handles the management command interface functions - * - * Author: Lyndon Chen - * - * Date: May 8, 2002 - * - */ - -#ifndef __WCMD_H__ -#define __WCMD_H__ - -#include "ttype.h" -#include "80211hdr.h" -#include "80211mgr.h" - -#define AUTHENTICATE_TIMEOUT 1000 -#define ASSOCIATE_TIMEOUT 1000 - -typedef enum tagCMD_CODE { - WLAN_CMD_BSSID_SCAN, - WLAN_CMD_SSID, - WLAN_CMD_DISASSOCIATE, - WLAN_CMD_DEAUTH, - WLAN_CMD_RX_PSPOLL, - WLAN_CMD_RADIO, - WLAN_CMD_CHANGE_BBSENSITIVITY, - WLAN_CMD_SETPOWER, - WLAN_CMD_TBTT_WAKEUP, - WLAN_CMD_BECON_SEND, - WLAN_CMD_CHANGE_ANTENNA, - WLAN_CMD_REMOVE_ALLKEY, - WLAN_CMD_MAC_DISPOWERSAVING, - WLAN_CMD_11H_CHSW, - WLAN_CMD_RUN_AP -} CMD_CODE, *PCMD_CODE; - -#define CMD_Q_SIZE 32 - -typedef enum tagCMD_STATUS { - CMD_STATUS_SUCCESS = 0, - CMD_STATUS_FAILURE, - CMD_STATUS_RESOURCES, - CMD_STATUS_TIMEOUT, - CMD_STATUS_PENDING -} CMD_STATUS, *PCMD_STATUS; - -typedef struct tagCMD_ITEM { - CMD_CODE eCmd; - unsigned char abyCmdDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - bool bNeedRadioOFF; - unsigned short wDeAuthenReason; - bool bRadioCmd; - bool bForceSCAN; -} CMD_ITEM, *PCMD_ITEM; - -typedef enum tagCMD_STATE { - WLAN_CMD_SCAN_START, - WLAN_CMD_SCAN_END, - WLAN_CMD_DISASSOCIATE_START, - WLAN_CMD_SSID_START, - WLAN_AUTHENTICATE_WAIT, - WLAN_ASSOCIATE_WAIT, - WLAN_DISASSOCIATE_WAIT, - WLAN_CMD_TX_PSPACKET_START, - WLAN_CMD_AP_MODE_START, - WLAN_CMD_RADIO_START, - WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE, - WLAN_CMD_IDLE -} CMD_STATE, *PCMD_STATE; - -void -vResetCommandTimer( - void *hDeviceContext -); - -void -vCommandTimer( - void *hDeviceContext -); - -bool bClearBSSID_SCAN( - void *hDeviceContext -); - -bool -bScheduleCommand( - void *hDeviceContext, - CMD_CODE eCommand, - unsigned char *pbyItem0 -); - -void -vCommandTimerWait( - void *hDeviceContext, - unsigned int MSecond -); - -void -BSSvSecondTxData( - void *hDeviceContext -); - -#endif //__WCMD_H__ diff --git a/drivers/staging/vt6655/wctl.c b/drivers/staging/vt6655/wctl.c deleted file mode 100644 index 5a54d98d985a..000000000000 --- a/drivers/staging/vt6655/wctl.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: wctl.c - * - * Purpose: handle WMAC duplicate filter & defragment - * - * Author: Jerry Chen - * - * Date: Jun. 27, 2002 - * - * Functions: - * WCTLbIsDuplicate - Test if duplicate packet - * WCTLuSearchDFCB - Search DeFragment Control Database - * WCTLuInsertDFCB - Insert DeFragment Control Database - * WCTLbHandleFragment - Handle received fragment packet - * - * Revision History: - * - */ - -#include "wctl.h" -#include "device.h" -#include "card.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/* - * Description: - * Scan Rx cache. Return true if packet is duplicate, else - * inserts in receive cache and returns false. - * - * Parameters: - * In: - * pCache - Receive packets history - * pMACHeader - 802.11 MAC Header of received packet - * Out: - * none - * - * Return Value: true if packet duplicate; otherwise false - * - */ - -bool WCTLbIsDuplicate(PSCache pCache, PS802_11Header pMACHeader) -{ - unsigned int uIndex; - unsigned int ii; - PSCacheEntry pCacheEntry; - - if (IS_FC_RETRY(pMACHeader)) { - uIndex = pCache->uInPtr; - for (ii = 0; ii < DUPLICATE_RX_CACHE_LENGTH; ii++) { - pCacheEntry = &(pCache->asCacheEntry[uIndex]); - if ((pCacheEntry->wFmSequence == pMACHeader->wSeqCtl) && - ether_addr_equal(pCacheEntry->abyAddr2, - pMACHeader->abyAddr2)) { - /* Duplicate match */ - return true; - } - ADD_ONE_WITH_WRAP_AROUND(uIndex, DUPLICATE_RX_CACHE_LENGTH); - } - } - /* Not fount in cache - insert */ - pCacheEntry = &pCache->asCacheEntry[pCache->uInPtr]; - pCacheEntry->wFmSequence = pMACHeader->wSeqCtl; - memcpy(&(pCacheEntry->abyAddr2[0]), &(pMACHeader->abyAddr2[0]), ETH_ALEN); - ADD_ONE_WITH_WRAP_AROUND(pCache->uInPtr, DUPLICATE_RX_CACHE_LENGTH); - return false; -} - -/* - * Description: - * Found if sequence number of received fragment packet in Defragment Database - * - * Parameters: - * In: - * pDevice - Pointer to adapter - * pMACHeader - 802.11 MAC Header of received packet - * Out: - * none - * - * Return Value: index number in Defragment Database - * - */ -unsigned int WCTLuSearchDFCB(struct vnt_private *pDevice, - PS802_11Header pMACHeader) -{ - unsigned int ii; - - for (ii = 0; ii < pDevice->cbDFCB; ii++) { - if (pDevice->sRxDFCB[ii].bInUse && - ether_addr_equal(pDevice->sRxDFCB[ii].abyAddr2, - pMACHeader->abyAddr2)) { - return ii; - } - } - return pDevice->cbDFCB; -} - -/* - * Description: - * Insert received fragment packet in Defragment Database - * - * Parameters: - * In: - * pDevice - Pointer to adapter - * pMACHeader - 802.11 MAC Header of received packet - * Out: - * none - * - * Return Value: index number in Defragment Database - * - */ -unsigned int WCTLuInsertDFCB(struct vnt_private *pDevice, PS802_11Header pMACHeader) -{ - unsigned int ii; - - if (pDevice->cbFreeDFCB == 0) - return pDevice->cbDFCB; - for (ii = 0; ii < pDevice->cbDFCB; ii++) { - if (!pDevice->sRxDFCB[ii].bInUse) { - pDevice->cbFreeDFCB--; - pDevice->sRxDFCB[ii].uLifetime = pDevice->dwMaxReceiveLifetime; - pDevice->sRxDFCB[ii].bInUse = true; - pDevice->sRxDFCB[ii].wSequence = (pMACHeader->wSeqCtl >> 4); - pDevice->sRxDFCB[ii].wFragNum = (pMACHeader->wSeqCtl & 0x000F); - memcpy(&(pDevice->sRxDFCB[ii].abyAddr2[0]), &(pMACHeader->abyAddr2[0]), ETH_ALEN); - return ii; - } - } - return pDevice->cbDFCB; -} - -/* - * Description: - * Handle received fragment packet - * - * Parameters: - * In: - * pDevice - Pointer to adapter - * pMACHeader - 802.11 MAC Header of received packet - * cbFrameLength - Frame length - * bWEP - is WEP packet - * Out: - * none - * - * Return Value: true if it is valid fragment packet and we have resource to defragment; otherwise false - * - */ -bool WCTLbHandleFragment(struct vnt_private *pDevice, PS802_11Header pMACHeader, - unsigned int cbFrameLength, bool bWEP, bool bExtIV) -{ - unsigned int uHeaderSize; - - if (bWEP) { - uHeaderSize = 28; - if (bExtIV) - // ExtIV - uHeaderSize += 4; - } else { - uHeaderSize = 24; - } - - if (IS_FIRST_FRAGMENT_PKT(pMACHeader)) { - pDevice->uCurrentDFCBIdx = WCTLuSearchDFCB(pDevice, pMACHeader); - if (pDevice->uCurrentDFCBIdx < pDevice->cbDFCB) { - // duplicate, we must flush previous DCB - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].uLifetime = pDevice->dwMaxReceiveLifetime; - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wSequence = (pMACHeader->wSeqCtl >> 4); - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum = (pMACHeader->wSeqCtl & 0x000F); - } else { - pDevice->uCurrentDFCBIdx = WCTLuInsertDFCB(pDevice, pMACHeader); - if (pDevice->uCurrentDFCBIdx == pDevice->cbDFCB) - return false; - } - // reserve 4 byte to match MAC RX Buffer - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (unsigned char *)(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb->data + 4); - memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, pMACHeader, cbFrameLength); - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength = cbFrameLength; - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += cbFrameLength; - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++; - return false; - } else { - pDevice->uCurrentDFCBIdx = WCTLuSearchDFCB(pDevice, pMACHeader); - if (pDevice->uCurrentDFCBIdx != pDevice->cbDFCB) { - if ((pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wSequence == (pMACHeader->wSeqCtl >> 4)) && - (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum == (pMACHeader->wSeqCtl & 0x000F)) && - ((pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength + cbFrameLength - uHeaderSize) < 2346)) { - memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, ((unsigned char *)(pMACHeader) + uHeaderSize), (cbFrameLength - uHeaderSize)); - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength += (cbFrameLength - uHeaderSize); - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += (cbFrameLength - uHeaderSize); - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++; - } else { - // seq error or frag # error flush DFCB - pDevice->cbFreeDFCB++; - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].bInUse = false; - return false; - } - } else { - return false; - } - if (IS_LAST_FRAGMENT_PKT(pMACHeader)) { - //enq defragcontrolblock - pDevice->cbFreeDFCB++; - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].bInUse = false; - return true; - } - return false; - } -} diff --git a/drivers/staging/vt6655/wctl.h b/drivers/staging/vt6655/wctl.h deleted file mode 100644 index f0995d86f71f..000000000000 --- a/drivers/staging/vt6655/wctl.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: wctl.h - * - * Purpose: - * - * Author: Jerry Chen - * - * Date: Jun. 27, 2002 - * - */ - -#ifndef __WCTL_H__ -#define __WCTL_H__ - -#include "ttype.h" -#include "tether.h" -#include "device.h" - -/*--------------------- Export Definitions -------------------------*/ - -#define IS_TYPE_DATA(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_802_11_MASK) == TYPE_802_11_DATA) - -#define IS_TYPE_MGMT(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_802_11_MASK) == TYPE_802_11_MGMT) - -#define IS_TYPE_CONTROL(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_802_11_MASK) == TYPE_802_11_CTL) - -#define IS_FC_MOREDATA(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREDATA) == FC_MOREDATA) - -#define IS_FC_POWERMGT(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_POWERMGT) == FC_POWERMGT) - -#define IS_FC_RETRY(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_RETRY) == FC_RETRY) - -#define IS_FC_WEP(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_WEP) == FC_WEP) - -#ifdef __BIG_ENDIAN - -#define IS_FRAGMENT_PKT(pMACHeader) \ - (((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREFRAG) != 0) | \ - ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x0F00) != 0)) - -#define IS_FIRST_FRAGMENT_PKT(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x0F00) == 0) - -#else - -#define IS_FRAGMENT_PKT(pMACHeader) \ - (((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREFRAG) != 0) | \ - ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x000F) != 0)) - -#define IS_FIRST_FRAGMENT_PKT(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x000F) == 0) - -#endif//#ifdef __BIG_ENDIAN - -#define IS_LAST_FRAGMENT_PKT(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREFRAG) == 0) - -#define IS_CTL_PSPOLL(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) - -#define ADD_ONE_WITH_WRAP_AROUND(uVar, uModulo) \ -do { \ - if ((uVar) >= ((uModulo) - 1)) \ - (uVar) = 0; \ - else \ - (uVar)++; \ -} while (0) - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -bool WCTLbIsDuplicate(PSCache pCache, PS802_11Header pMACHeader); -bool WCTLbHandleFragment(struct vnt_private *, PS802_11Header pMACHeader, - unsigned int cbFrameLength, bool bWEP, bool bExtIV); -unsigned int WCTLuSearchDFCB(struct vnt_private *, PS802_11Header pMACHeader); -unsigned int WCTLuInsertDFCB(struct vnt_private *, PS802_11Header pMACHeader); - -#endif // __WCTL_H__ diff --git a/drivers/staging/vt6655/wmgr.c b/drivers/staging/vt6655/wmgr.c deleted file mode 100644 index c73c39d7adfd..000000000000 --- a/drivers/staging/vt6655/wmgr.c +++ /dev/null @@ -1,4602 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: wmgr.c - * - * Purpose: Handles the 802.11 management functions - * - * Author: Lyndon Chen - * - * Date: May 8, 2002 - * - * Functions: - * nsMgrObjectInitial - Initialize Management Object data structure - * vMgrObjectReset - Reset Management Object data structure - * vMgrAssocBeginSta - Start associate function - * vMgrReAssocBeginSta - Start reassociate function - * vMgrDisassocBeginSta - Start disassociate function - * s_vMgrRxAssocRequest - Handle Rcv associate_request - * s_vMgrRxAssocResponse - Handle Rcv associate_response - * vMrgAuthenBeginSta - Start authentication function - * vMgrDeAuthenDeginSta - Start deauthentication function - * s_vMgrRxAuthentication - Handle Rcv authentication - * s_vMgrRxAuthenSequence_1 - Handle Rcv authentication sequence 1 - * s_vMgrRxAuthenSequence_2 - Handle Rcv authentication sequence 2 - * s_vMgrRxAuthenSequence_3 - Handle Rcv authentication sequence 3 - * s_vMgrRxAuthenSequence_4 - Handle Rcv authentication sequence 4 - * s_vMgrRxDisassociation - Handle Rcv disassociation - * s_vMgrRxBeacon - Handle Rcv Beacon - * vMgrCreateOwnIBSS - Create ad_hoc IBSS or AP BSS - * vMgrJoinBSSBegin - Join BSS function - * s_vMgrSynchBSS - Synch & adopt BSS parameters - * s_MgrMakeBeacon - Create Baecon frame - * s_MgrMakeProbeResponse - Create Probe Response frame - * s_MgrMakeAssocRequest - Create Associate Request frame - * s_MgrMakeReAssocRequest - Create ReAssociate Request frame - * s_vMgrRxProbeResponse - Handle Rcv probe_response - * s_vMrgRxProbeRequest - Handle Rcv probe_request - * bMgrPrepareBeaconToSend - Prepare Beacon frame - * s_vMgrLogStatus - Log 802.11 Status - * vMgrRxManagePacket - Rcv management frame dispatch function - * s_vMgrFormatTIM- Assembler TIM field of beacon - * vMgrTimerInit- Initial 1-sec and command call back funtions - * - * Revision History: - * - */ - -#include "tmacro.h" -#include "desc.h" -#include "device.h" -#include "card.h" -#include "channel.h" -#include "80211hdr.h" -#include "80211mgr.h" -#include "wmgr.h" -#include "wcmd.h" -#include "mac.h" -#include "bssdb.h" -#include "power.h" -#include "datarate.h" -#include "baseband.h" -#include "rxtx.h" -#include "wpa.h" -#include "rf.h" -#include "iowpa.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Functions --------------------------*/ -//2008-8-4 <add> by chester -static bool ChannelExceedZoneType( - struct vnt_private *pDevice, - unsigned char byCurrChannel -); - -// Association/diassociation functions -static -PSTxMgmtPacket -s_MgrMakeAssocRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned char *pDAddr, - unsigned short wCurrCapInfo, - unsigned short wListenInterval, - PWLAN_IE_SSID pCurrSSID, - PWLAN_IE_SUPP_RATES pCurrRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -); - -static -void -s_vMgrRxAssocRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket, - unsigned int uNodeIndex -); - -static -PSTxMgmtPacket -s_MgrMakeReAssocRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned char *pDAddr, - unsigned short wCurrCapInfo, - unsigned short wListenInterval, - PWLAN_IE_SSID pCurrSSID, - PWLAN_IE_SUPP_RATES pCurrRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -); - -static -void -s_vMgrRxAssocResponse( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket, - bool bReAssocType -); - -static -void -s_vMgrRxDisassociation( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -); - -// Authentication/deauthen functions -static -void -s_vMgrRxAuthenSequence_1( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame -); - -static -void -s_vMgrRxAuthenSequence_2( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame -); - -static -void -s_vMgrRxAuthenSequence_3( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame -); - -static -void -s_vMgrRxAuthenSequence_4( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame -); - -static -void -s_vMgrRxAuthentication( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -); - -static -void -s_vMgrRxDeauthentication( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -); - -// Scan functions -// probe request/response functions -static -void -s_vMgrRxProbeRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -); - -static -void -s_vMgrRxProbeResponse( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -); - -// beacon functions -static -void -s_vMgrRxBeacon( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket, - bool bInScan -); - -static -void -s_vMgrFormatTIM( - PSMgmtObject pMgmt, - PWLAN_IE_TIM pTIM -); - -static -PSTxMgmtPacket -s_MgrMakeBeacon( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wCurrBeaconPeriod, - unsigned int uCurrChannel, - unsigned short wCurrATIMWinodw, - PWLAN_IE_SSID pCurrSSID, - unsigned char *pCurrBSSID, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -); - -// Association response -static -PSTxMgmtPacket -s_MgrMakeAssocResponse( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wAssocStatus, - unsigned short wAssocAID, - unsigned char *pDstAddr, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -); - -// ReAssociation response -static -PSTxMgmtPacket -s_MgrMakeReAssocResponse( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wAssocStatus, - unsigned short wAssocAID, - unsigned char *pDstAddr, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -); - -// Probe response -static -PSTxMgmtPacket -s_MgrMakeProbeResponse( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wCurrBeaconPeriod, - unsigned int uCurrChannel, - unsigned short wCurrATIMWinodw, - unsigned char *pDstAddr, - PWLAN_IE_SSID pCurrSSID, - unsigned char *pCurrBSSID, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates, - unsigned char byPHYType -); - -// received status -static -void -s_vMgrLogStatus( - PSMgmtObject pMgmt, - unsigned short wStatus -); - -static -void -s_vMgrSynchBSS( - struct vnt_private *pDevice, - unsigned int uBSSMode, - PKnownBSS pCurr, - PCMD_STATUS pStatus -); - -static bool -s_bCipherMatch( - PKnownBSS pBSSNode, - NDIS_802_11_ENCRYPTION_STATUS EncStatus, - unsigned char *pbyCCSPK, - unsigned char *pbyCCSGK -); - -static void Encyption_Rebuild( - struct vnt_private *pDevice, - PKnownBSS pCurr -); - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -/*+ - * - * Routine Description: - * Allocates and initializes the Management object. - * - * Return Value: - * Ndis_staus. - * - -*/ - -void -vMgrObjectInit( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - int ii; - - pMgmt->pbyPSPacketPool = &pMgmt->byPSPacketPool[0]; - pMgmt->pbyMgmtPacketPool = &pMgmt->byMgmtPacketPool[0]; - pMgmt->uCurrChannel = pDevice->uChannel; - for (ii = 0; ii < WLAN_BSSID_LEN; ii++) - pMgmt->abyDesireBSSID[ii] = 0xFF; - - pMgmt->sAssocInfo.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); - pMgmt->byCSSPK = KEY_CTL_NONE; - pMgmt->byCSSGK = KEY_CTL_NONE; - pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI; - BSSvClearBSSList((void *)pDevice, false); -} - -/*+ - * - * Routine Description: - * Initializes timer object - * - * Return Value: - * Ndis_staus. - * - -*/ - -void -vMgrTimerInit( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - - init_timer(&pMgmt->sTimerSecondCallback); - pMgmt->sTimerSecondCallback.data = (unsigned long) pDevice; - pMgmt->sTimerSecondCallback.function = (TimerFunction)BSSvSecondCallBack; - pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ); - - init_timer(&pDevice->sTimerCommand); - pDevice->sTimerCommand.data = (unsigned long) pDevice; - pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer; - pDevice->sTimerCommand.expires = RUN_AT(HZ); - - init_timer(&pDevice->sTimerTxData); - pDevice->sTimerTxData.data = (unsigned long) pDevice; - pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData; - pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback - pDevice->fTxDataInSleep = false; - pDevice->IsTxDataTrigger = false; - pDevice->nTxDataTimeCout = 0; - - pDevice->cbFreeCmdQueue = CMD_Q_SIZE; - pDevice->uCmdDequeueIdx = 0; - pDevice->uCmdEnqueueIdx = 0; -} - -/*+ - * - * Routine Description: - * Reset the management object structure. - * - * Return Value: - * None. - * - -*/ - -void -vMgrObjectReset( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - pMgmt->eCurrState = WMAC_STATE_IDLE; - pDevice->bEnablePSMode = false; - // TODO: timer -} - -/*+ - * - * Routine Description: - * Start the station association procedure. Namely, send an - * association request frame to the AP. - * - * Return Value: - * None. - * - -*/ - -void -vMgrAssocBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSTxMgmtPacket pTxPacket; - - pMgmt->wCurrCapInfo = 0; - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1); - if (pDevice->bEncryptionEnable) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1); - - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - if (pMgmt->wListenInterval == 0) - pMgmt->wListenInterval = 1; // at least one. - - // ERP Phy (802.11g) should support short preamble. - if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - if (CARDbIsShorSlotTime(pMgmt->pAdapter)) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1); - } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) { - if (CARDbIsShortPreamble(pMgmt->pAdapter)) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - } - if (pMgmt->b11hEnable) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1); - - /* build an assocreq frame and send it */ - pTxPacket = s_MgrMakeAssocRequest - ( - pDevice, - pMgmt, - pMgmt->abyCurrBSSID, - pMgmt->wCurrCapInfo, - pMgmt->wListenInterval, - (PWLAN_IE_SSID)pMgmt->abyCurrSSID, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates -); - - if (pTxPacket != NULL) { - /* send the frame */ - *pStatus = csMgmt_xmit(pDevice, pTxPacket); - if (*pStatus == CMD_STATUS_PENDING) { - pMgmt->eCurrState = WMAC_STATE_ASSOCPENDING; - *pStatus = CMD_STATUS_SUCCESS; - } - } else { - *pStatus = CMD_STATUS_RESOURCES; - } -} - -/*+ - * - * Routine Description: - * Start the station re-association procedure. - * - * Return Value: - * None. - * - -*/ - -void -vMgrReAssocBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSTxMgmtPacket pTxPacket; - - pMgmt->wCurrCapInfo = 0; - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1); - if (pDevice->bEncryptionEnable) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1); - - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - - if (pMgmt->wListenInterval == 0) - pMgmt->wListenInterval = 1; // at least one. - - // ERP Phy (802.11g) should support short preamble. - if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - if (CARDbIsShorSlotTime(pMgmt->pAdapter)) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1); - } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) { - if (CARDbIsShortPreamble(pMgmt->pAdapter)) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - } - - if (pMgmt->b11hEnable) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1); - - pTxPacket = s_MgrMakeReAssocRequest - ( - pDevice, - pMgmt, - pMgmt->abyCurrBSSID, - pMgmt->wCurrCapInfo, - pMgmt->wListenInterval, - (PWLAN_IE_SSID)pMgmt->abyCurrSSID, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates -); - - if (pTxPacket != NULL) { - /* send the frame */ - *pStatus = csMgmt_xmit(pDevice, pTxPacket); - if (*pStatus != CMD_STATUS_PENDING) - pr_debug("Mgt:Reassociation tx failed\n"); - else - pr_debug("Mgt:Reassociation tx sending\n"); - } -} - -/*+ - * - * Routine Description: - * Send an dis-association request frame to the AP. - * - * Return Value: - * None. - * - -*/ - -void -vMgrDisassocBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - unsigned char *abyDestAddress, - unsigned short wReason, - PCMD_STATUS pStatus -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_DISASSOC sFrame; - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_DISASSOC_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - - // Setup the sFrame structure - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_DISASSOC_FR_MAXLEN; - - // format fixed field frame structure - vMgrEncodeDisassociation(&sFrame); - - // Setup the header - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DISASSOC) -)); - - memcpy(sFrame.pHdr->sA3.abyAddr1, abyDestAddress, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - // Set reason code - *(sFrame.pwReason) = cpu_to_le16(wReason); - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - // send the frame - *pStatus = csMgmt_xmit(pDevice, pTxPacket); - if (*pStatus == CMD_STATUS_PENDING) { - pMgmt->eCurrState = WMAC_STATE_IDLE; - *pStatus = CMD_STATUS_SUCCESS; - } -} - -/*+ - * - * Routine Description:(AP function) - * Handle incoming station association request frames. - * - * Return Value: - * None. - * - -*/ - -static -void -s_vMgrRxAssocRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket, - unsigned int uNodeIndex -) -{ - WLAN_FR_ASSOCREQ sFrame; - CMD_STATUS Status; - PSTxMgmtPacket pTxPacket; - unsigned short wAssocStatus = 0; - unsigned short wAssocAID = 0; - unsigned int uRateLen = WLAN_RATES_MAXLEN; - unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - - if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) - return; - // node index not found - if (!uNodeIndex) - return; - - //check if node is authenticated - //decode the frame - memset(&sFrame, 0, sizeof(WLAN_FR_ASSOCREQ)); - memset(abyCurrSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); - memset(abyCurrExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - - vMgrDecodeAssocRequest(&sFrame); - - if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) { - pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC; - pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval); - pMgmt->sNodeDBTable[uNodeIndex].bPSEnable = - WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? true : false; - // Todo: check sta basic rate, if ap can't support, set status code - if (pDevice->eCurrentPHYType == PHY_TYPE_11B) - uRateLen = WLAN_RATES_MAXLEN_11B; - - abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES; - abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, - (PWLAN_IE_SUPP_RATES)abyCurrSuppRates, - uRateLen); - abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES; - if (pDevice->eCurrentPHYType == PHY_TYPE_11G) - abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates, - (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates, - uRateLen); - else - abyCurrExtSuppRates[1] = 0; - - RATEvParseMaxRate((void *)pDevice, - (PWLAN_IE_SUPP_RATES)abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates, - false, // do not change our basic rate - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate) -); - - // set max tx rate - pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = - pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate; - - pr_debug("RxAssocRequest:wTxDataRate is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate); - - // Todo: check sta preamble, if ap can't support, set status code - pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = - WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = - WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)uNodeIndex; - wAssocStatus = WLAN_MGMT_STATUS_SUCCESS; - wAssocAID = (unsigned short)uNodeIndex; - // check if ERP support - if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M) - pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true; - - if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) { - // B only STA join - pDevice->bProtectMode = true; - pDevice->bNonERPPresent = true; - } - if (!pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) - pDevice->bBarkerPreambleMd = true; - - pr_info("Associate AID= %d\n", wAssocAID); - pr_info("MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", - sFrame.pHdr->sA3.abyAddr2[0], - sFrame.pHdr->sA3.abyAddr2[1], - sFrame.pHdr->sA3.abyAddr2[2], - sFrame.pHdr->sA3.abyAddr2[3], - sFrame.pHdr->sA3.abyAddr2[4], - sFrame.pHdr->sA3.abyAddr2[5] - ); - pr_info("Max Support rate = %d\n", - pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate); - } else { - /* TODO: received STA under state1 handle */ - return; - } - - // assoc response reply.. - pTxPacket = s_MgrMakeAssocResponse - ( - pDevice, - pMgmt, - pMgmt->wCurrCapInfo, - wAssocStatus, - wAssocAID, - sFrame.pHdr->sA3.abyAddr2, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates -); - if (pTxPacket != NULL) { - if (pDevice->bEnableHostapd) - return; - - /* send the frame */ - Status = csMgmt_xmit(pDevice, pTxPacket); - if (Status != CMD_STATUS_PENDING) - pr_debug("Mgt:Assoc response tx failed\n"); - else - pr_debug("Mgt:Assoc response tx sending..\n"); - } -} - -/*+ - * - * Description:(AP function) - * Handle incoming station re-association request frames. - * - * Parameters: - * In: - * pMgmt - Management Object structure - * pRxPacket - Received Packet - * Out: - * none - * - * Return Value: None. - * - -*/ - -static -void -s_vMgrRxReAssocRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket, - unsigned int uNodeIndex -) -{ - WLAN_FR_REASSOCREQ sFrame; - CMD_STATUS Status; - PSTxMgmtPacket pTxPacket; - unsigned short wAssocStatus = 0; - unsigned short wAssocAID = 0; - unsigned int uRateLen = WLAN_RATES_MAXLEN; - unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - - if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) - return; - // node index not found - if (!uNodeIndex) - return; - //check if node is authenticated - //decode the frame - memset(&sFrame, 0, sizeof(WLAN_FR_REASSOCREQ)); - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - vMgrDecodeReassocRequest(&sFrame); - - if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) { - pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC; - pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval); - pMgmt->sNodeDBTable[uNodeIndex].bPSEnable = - WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? true : false; - // Todo: check sta basic rate, if ap can't support, set status code - - if (pDevice->eCurrentPHYType == PHY_TYPE_11B) - uRateLen = WLAN_RATES_MAXLEN_11B; - - abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES; - abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, - (PWLAN_IE_SUPP_RATES)abyCurrSuppRates, - uRateLen); - abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES; - if (pDevice->eCurrentPHYType == PHY_TYPE_11G) { - abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates, - (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates, - uRateLen); - } else { - abyCurrExtSuppRates[1] = 0; - } - - RATEvParseMaxRate((void *)pDevice, - (PWLAN_IE_SUPP_RATES)abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates, - false, // do not change our basic rate - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate) -); - - // set max tx rate - pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = - pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate; - - pr_debug("RxReAssocRequest:TxDataRate is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate); - - // Todo: check sta preamble, if ap can't support, set status code - pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = - WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = - WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)uNodeIndex; - wAssocStatus = WLAN_MGMT_STATUS_SUCCESS; - wAssocAID = (unsigned short)uNodeIndex; - - // if suppurt ERP - if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M) - pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true; - - if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) { - // B only STA join - pDevice->bProtectMode = true; - pDevice->bNonERPPresent = true; - } - if (!pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) - pDevice->bBarkerPreambleMd = true; - - pr_info("Rx ReAssociate AID= %d\n", wAssocAID); - pr_info("MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", - sFrame.pHdr->sA3.abyAddr2[0], - sFrame.pHdr->sA3.abyAddr2[1], - sFrame.pHdr->sA3.abyAddr2[2], - sFrame.pHdr->sA3.abyAddr2[3], - sFrame.pHdr->sA3.abyAddr2[4], - sFrame.pHdr->sA3.abyAddr2[5] - ); - pr_info("Max Support rate = %d\n", - pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate); - - } - - // assoc response reply.. - pTxPacket = s_MgrMakeReAssocResponse - ( - pDevice, - pMgmt, - pMgmt->wCurrCapInfo, - wAssocStatus, - wAssocAID, - sFrame.pHdr->sA3.abyAddr2, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates - ); - - if (pTxPacket != NULL) { - /* send the frame */ - if (pDevice->bEnableHostapd) - return; - - Status = csMgmt_xmit(pDevice, pTxPacket); - if (Status != CMD_STATUS_PENDING) - pr_debug("Mgt:ReAssoc response tx failed\n"); - else - pr_debug("Mgt:ReAssoc response tx sending..\n"); - } -} - -/*+ - * - * Routine Description: - * Handle incoming association response frames. - * - * Return Value: - * None. - * - -*/ - -static -void -s_vMgrRxAssocResponse( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket, - bool bReAssocType -) -{ - WLAN_FR_ASSOCRESP sFrame; - PWLAN_IE_SSID pItemSSID; - unsigned char *pbyIEs; - viawget_wpa_header *wpahdr; - - if (pMgmt->eCurrState == WMAC_STATE_ASSOCPENDING || - pMgmt->eCurrState == WMAC_STATE_ASSOC) { - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - // decode the frame - vMgrDecodeAssocResponse(&sFrame); - if ((sFrame.pwCapInfo == NULL) || - (sFrame.pwStatus == NULL) || - (sFrame.pwAid == NULL) || - (sFrame.pSuppRates == NULL)) { - DBG_PORT80(0xCC); - return; - } - - pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.Capabilities = *(sFrame.pwCapInfo); - pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.StatusCode = *(sFrame.pwStatus); - pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.AssociationId = *(sFrame.pwAid); - pMgmt->sAssocInfo.AssocInfo.AvailableResponseFixedIEs |= 0x07; - - pMgmt->sAssocInfo.AssocInfo.ResponseIELength = sFrame.len - 24 - 6; - pMgmt->sAssocInfo.AssocInfo.OffsetResponseIEs = pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs + pMgmt->sAssocInfo.AssocInfo.RequestIELength; - pbyIEs = pMgmt->sAssocInfo.abyIEs; - pbyIEs += pMgmt->sAssocInfo.AssocInfo.RequestIELength; - memcpy(pbyIEs, (sFrame.pBuf + 24 + 6), pMgmt->sAssocInfo.AssocInfo.ResponseIELength); - - // save values and set current BSS state - if (cpu_to_le16((*(sFrame.pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) { - // set AID - pMgmt->wCurrAID = cpu_to_le16((*(sFrame.pwAid))); - if ((pMgmt->wCurrAID >> 14) != (BIT0 | BIT1)) - pr_debug("AID from AP, has two msb clear\n"); - - pr_info("Association Successful, AID=%d\n", - pMgmt->wCurrAID & ~(BIT14 | BIT15)); - pMgmt->eCurrState = WMAC_STATE_ASSOC; - BSSvUpdateAPNode((void *)pDevice, sFrame.pwCapInfo, sFrame.pSuppRates, sFrame.pExtSuppRates); - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - pr_info("Link with AP(SSID): %s\n", pItemSSID->abySSID); - pDevice->bLinkPass = true; - pDevice->uBBVGADiffCount = 0; - if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { - if (skb_tailroom(pDevice->skb) < (sizeof(viawget_wpa_header) + pMgmt->sAssocInfo.AssocInfo.ResponseIELength + - pMgmt->sAssocInfo.AssocInfo.RequestIELength)) { //data room not enough - dev_kfree_skb(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - } - wpahdr = (viawget_wpa_header *)pDevice->skb->data; - wpahdr->type = VIAWGET_ASSOC_MSG; - wpahdr->resp_ie_len = pMgmt->sAssocInfo.AssocInfo.ResponseIELength; - wpahdr->req_ie_len = pMgmt->sAssocInfo.AssocInfo.RequestIELength; - memcpy(pDevice->skb->data + sizeof(viawget_wpa_header), pMgmt->sAssocInfo.abyIEs, wpahdr->req_ie_len); - memcpy(pDevice->skb->data + sizeof(viawget_wpa_header) + wpahdr->req_ie_len, - pbyIEs, - wpahdr->resp_ie_len -); - skb_put(pDevice->skb, sizeof(viawget_wpa_header) + wpahdr->resp_ie_len + wpahdr->req_ie_len); - pDevice->skb->dev = pDevice->wpadev; - skb_reset_mac_header(pDevice->skb); - pDevice->skb->pkt_type = PACKET_HOST; - pDevice->skb->protocol = htons(ETH_P_802_2); - memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); - netif_rx(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - } - -//2008-0409-07, <Add> by Einsn Liu -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - { - unsigned char buf[512]; - size_t len; - union iwreq_data wrqu; - int we_event; - - memset(buf, 0, 512); - - len = pMgmt->sAssocInfo.AssocInfo.RequestIELength; - if (len) { - memcpy(buf, pMgmt->sAssocInfo.abyIEs, len); - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = len; - we_event = IWEVASSOCREQIE; - wireless_send_event(pDevice->dev, we_event, &wrqu, buf); - } - - memset(buf, 0, 512); - len = pMgmt->sAssocInfo.AssocInfo.ResponseIELength; - - if (len) { - memcpy(buf, pbyIEs, len); - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = len; - we_event = IWEVASSOCRESPIE; - wireless_send_event(pDevice->dev, we_event, &wrqu, buf); - } - - memset(&wrqu, 0, sizeof(wrqu)); - memcpy(wrqu.ap_addr.sa_data, &pMgmt->abyCurrBSSID[0], ETH_ALEN); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); - } -#endif //#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -//End Add -- //2008-0409-07, <Add> by Einsn Liu - } else { - if (bReAssocType) { - pMgmt->eCurrState = WMAC_STATE_IDLE; - } else { - // jump back to the auth state and indicate the error - pMgmt->eCurrState = WMAC_STATE_AUTH; - } - s_vMgrLogStatus(pMgmt, cpu_to_le16((*(sFrame.pwStatus)))); - } - - } - -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -//need clear flags related to Networkmanager - - pDevice->bwextcount = 0; - pDevice->bWPASuppWextEnabled = false; -#endif - - if (pMgmt->eCurrState == WMAC_STATE_ASSOC) - timer_expire(pDevice->sTimerCommand, 0); -} - -/*+ - * - * Routine Description: - * Start the station authentication procedure. Namely, send an - * authentication frame to the AP. - * - * Return Value: - * None. - * - -*/ - -void -vMgrAuthenBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus -) -{ - struct vnt_private *pDevice = hDeviceContext; - WLAN_FR_AUTHEN sFrame; - PSTxMgmtPacket pTxPacket = NULL; - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_AUTHEN_FR_MAXLEN; - vMgrEncodeAuthen(&sFrame); - /* insert values */ - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN) -)); - memcpy(sFrame.pHdr->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - if (pMgmt->bShareKeyAlgorithm) - *(sFrame.pwAuthAlgorithm) = cpu_to_le16(WLAN_AUTH_ALG_SHAREDKEY); - else - *(sFrame.pwAuthAlgorithm) = cpu_to_le16(WLAN_AUTH_ALG_OPENSYSTEM); - - *(sFrame.pwAuthSequence) = cpu_to_le16(1); - /* Adjust the length fields */ - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - *pStatus = csMgmt_xmit(pDevice, pTxPacket); - if (*pStatus == CMD_STATUS_PENDING) { - pMgmt->eCurrState = WMAC_STATE_AUTHPENDING; - *pStatus = CMD_STATUS_SUCCESS; - } -} - -/*+ - * - * Routine Description: - * Start the station(AP) deauthentication procedure. Namely, send an - * deauthentication frame to the AP or Sta. - * - * Return Value: - * None. - * - -*/ - -void -vMgrDeAuthenBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - unsigned char *abyDestAddress, - unsigned short wReason, - PCMD_STATUS pStatus -) -{ - struct vnt_private *pDevice = hDeviceContext; - WLAN_FR_DEAUTHEN sFrame; - PSTxMgmtPacket pTxPacket = NULL; - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_DEAUTHEN_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_DEAUTHEN_FR_MAXLEN; - vMgrEncodeDeauthen(&sFrame); - /* insert values */ - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DEAUTHEN) -)); - - memcpy(sFrame.pHdr->sA3.abyAddr1, abyDestAddress, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - *(sFrame.pwReason) = cpu_to_le16(wReason); // deauthen. bcs left BSS - /* Adjust the length fields */ - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - *pStatus = csMgmt_xmit(pDevice, pTxPacket); - if (*pStatus == CMD_STATUS_PENDING) - *pStatus = CMD_STATUS_SUCCESS; -} - -/*+ - * - * Routine Description: - * Handle incoming authentication frames. - * - * Return Value: - * None. - * - -*/ - -static -void -s_vMgrRxAuthentication( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -) -{ - WLAN_FR_AUTHEN sFrame; - - // we better be an AP or a STA in AUTHPENDING otherwise ignore - if (!(pMgmt->eCurrMode == WMAC_MODE_ESS_AP || - pMgmt->eCurrState == WMAC_STATE_AUTHPENDING)) { - return; - } - - // decode the frame - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - vMgrDecodeAuthen(&sFrame); - switch (cpu_to_le16((*(sFrame.pwAuthSequence)))) { - case 1: - //AP function - s_vMgrRxAuthenSequence_1(pDevice, pMgmt, &sFrame); - break; - case 2: - s_vMgrRxAuthenSequence_2(pDevice, pMgmt, &sFrame); - break; - case 3: - //AP function - s_vMgrRxAuthenSequence_3(pDevice, pMgmt, &sFrame); - break; - case 4: - s_vMgrRxAuthenSequence_4(pDevice, pMgmt, &sFrame); - break; - default: - pr_debug("Auth Sequence error, seq = %d\n", - cpu_to_le16((*(sFrame.pwAuthSequence)))); - break; - } -} - -/*+ - * - * Routine Description: - * Handles incoming authen frames with sequence 1. Currently - * assumes we're an AP. So far, no one appears to use authentication - * in Ad-Hoc mode. - * - * Return Value: - * None. - * - -*/ - -static -void -s_vMgrRxAuthenSequence_1( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame -) -{ - PSTxMgmtPacket pTxPacket = NULL; - unsigned int uNodeIndex; - WLAN_FR_AUTHEN sFrame; - PSKeyItem pTransmitKey; - - // Insert a Node entry - if (!BSSDBbIsSTAInNodeDB(pMgmt, pFrame->pHdr->sA3.abyAddr2, &uNodeIndex)) { - BSSvCreateOneNode(pDevice, &uNodeIndex); - memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, pFrame->pHdr->sA3.abyAddr2, - WLAN_ADDR_LEN); - } - - if (pMgmt->bShareKeyAlgorithm) { - pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_KNOWN; - pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 1; - } else { - pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_AUTH; - } - - // send auth reply - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_AUTHEN_FR_MAXLEN; - // format buffer structure - vMgrEncodeAuthen(&sFrame); - // insert values - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)| - WLAN_SET_FC_ISWEP(0) -)); - memcpy(sFrame.pHdr->sA3.abyAddr1, pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm); - *(sFrame.pwAuthSequence) = cpu_to_le16(2); - - if (cpu_to_le16(*(pFrame->pwAuthAlgorithm)) == WLAN_AUTH_ALG_SHAREDKEY) { - if (pMgmt->bShareKeyAlgorithm) - *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS); - else - *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG); - } else { - if (pMgmt->bShareKeyAlgorithm) - *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG); - else - *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS); - } - - if (pMgmt->bShareKeyAlgorithm && - (cpu_to_le16(*(sFrame.pwStatus)) == WLAN_MGMT_STATUS_SUCCESS)) { - sFrame.pChallenge = (PWLAN_IE_CHALLENGE)(sFrame.pBuf + sFrame.len); - sFrame.len += WLAN_CHALLENGE_IE_LEN; - sFrame.pChallenge->byElementID = WLAN_EID_CHALLENGE; - sFrame.pChallenge->len = WLAN_CHALLENGE_LEN; - memset(pMgmt->abyChallenge, 0, WLAN_CHALLENGE_LEN); - // get group key - if (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, GROUP_KEY, &pTransmitKey) == true) { - rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength+3); - rc4_encrypt(&pDevice->SBox, pMgmt->abyChallenge, pMgmt->abyChallenge, WLAN_CHALLENGE_LEN); - } - memcpy(sFrame.pChallenge->abyChallenge, pMgmt->abyChallenge , WLAN_CHALLENGE_LEN); - } - - /* Adjust the length fields */ - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - // send the frame - if (pDevice->bEnableHostapd) - return; - - pr_debug("Mgt:Authreq_reply sequence_1 tx..\n"); - if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) - pr_debug("Mgt:Authreq_reply sequence_1 tx failed\n"); -} - -/*+ - * - * Routine Description: - * Handles incoming auth frames with sequence number 2. Currently - * assumes we're a station. - * - * - * Return Value: - * None. - * - -*/ - -static -void -s_vMgrRxAuthenSequence_2( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame -) -{ - WLAN_FR_AUTHEN sFrame; - PSTxMgmtPacket pTxPacket = NULL; - - switch (cpu_to_le16((*(pFrame->pwAuthAlgorithm)))) { - case WLAN_AUTH_ALG_OPENSYSTEM: - if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) { - pr_info("802.11 Authen (OPEN) Successful\n"); - pMgmt->eCurrState = WMAC_STATE_AUTH; - timer_expire(pDevice->sTimerCommand, 0); - } else { - pr_info("802.11 Authen (OPEN) Failed\n"); - s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus)))); - pMgmt->eCurrState = WMAC_STATE_IDLE; - } - - break; - - case WLAN_AUTH_ALG_SHAREDKEY: - - if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) { - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_AUTHEN_FR_MAXLEN; - // format buffer structure - vMgrEncodeAuthen(&sFrame); - // insert values - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)| - WLAN_SET_FC_ISWEP(1) -)); - memcpy(sFrame.pHdr->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm); - *(sFrame.pwAuthSequence) = cpu_to_le16(3); - *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS); - sFrame.pChallenge = (PWLAN_IE_CHALLENGE)(sFrame.pBuf + sFrame.len); - sFrame.len += WLAN_CHALLENGE_IE_LEN; - sFrame.pChallenge->byElementID = WLAN_EID_CHALLENGE; - sFrame.pChallenge->len = WLAN_CHALLENGE_LEN; - memcpy(sFrame.pChallenge->abyChallenge, pFrame->pChallenge->abyChallenge, WLAN_CHALLENGE_LEN); - // Adjust the length fields - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - // send the frame - if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) - pr_debug("Mgt:Auth_reply sequence_2 tx failed\n"); - - pr_debug("Mgt:Auth_reply sequence_2 tx ...\n"); - } else { - pr_debug("Mgt:rx Auth_reply sequence_2 status error ...\n"); - s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus)))); - } - break; - default: - pr_debug("Mgt: rx auth.seq = 2 unknown AuthAlgorithm=%d\n", - cpu_to_le16((*(pFrame->pwAuthAlgorithm)))); - break; - } -} - -/*+ - * - * Routine Description: - * Handles incoming authen frames with sequence 3. Currently - * assumes we're an AP. This function assumes the frame has - * already been successfully decrypted. - * - * - * Return Value: - * None. - * - -*/ - -static -void -s_vMgrRxAuthenSequence_3( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame -) -{ - PSTxMgmtPacket pTxPacket = NULL; - unsigned int uStatusCode = 0; - unsigned int uNodeIndex = 0; - WLAN_FR_AUTHEN sFrame; - - if (!WLAN_GET_FC_ISWEP(pFrame->pHdr->sA3.wFrameCtl)) { - uStatusCode = WLAN_MGMT_STATUS_CHALLENGE_FAIL; - goto reply; - } - if (BSSDBbIsSTAInNodeDB(pMgmt, pFrame->pHdr->sA3.abyAddr2, &uNodeIndex)) { - if (pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence != 1) { - uStatusCode = WLAN_MGMT_STATUS_RX_AUTH_NOSEQ; - goto reply; - } - if (memcmp(pMgmt->abyChallenge, pFrame->pChallenge->abyChallenge, WLAN_CHALLENGE_LEN) != 0) { - uStatusCode = WLAN_MGMT_STATUS_CHALLENGE_FAIL; - goto reply; - } - } else { - uStatusCode = WLAN_MGMT_STATUS_UNSPEC_FAILURE; - goto reply; - } - - if (uNodeIndex) { - pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_AUTH; - pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 0; - } - uStatusCode = WLAN_MGMT_STATUS_SUCCESS; - pr_debug("Challenge text check ok..\n"); - -reply: - // send auth reply - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_AUTHEN_FR_MAXLEN; - // format buffer structure - vMgrEncodeAuthen(&sFrame); - /* insert values */ - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)| - WLAN_SET_FC_ISWEP(0) -)); - memcpy(sFrame.pHdr->sA3.abyAddr1, pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm); - *(sFrame.pwAuthSequence) = cpu_to_le16(4); - *(sFrame.pwStatus) = cpu_to_le16(uStatusCode); - - /* Adjust the length fields */ - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - // send the frame - if (pDevice->bEnableHostapd) - return; - - if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) - pr_debug("Mgt:Authreq_reply sequence_4 tx failed\n"); -} - -/*+ - * - * Routine Description: - * Handles incoming authen frames with sequence 4 - * - * - * Return Value: - * None. - * - -*/ -static -void -s_vMgrRxAuthenSequence_4( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame -) -{ - if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) { - pr_info("802.11 Authen (SHAREDKEY) Successful\n"); - pMgmt->eCurrState = WMAC_STATE_AUTH; - timer_expire(pDevice->sTimerCommand, 0); - } else{ - pr_info("802.11 Authen (SHAREDKEY) Failed\n"); - s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus)))); - pMgmt->eCurrState = WMAC_STATE_IDLE; - } -} - -/*+ - * - * Routine Description: - * Handles incoming disassociation frames - * - * - * Return Value: - * None. - * - -*/ - -static -void -s_vMgrRxDisassociation( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -) -{ - WLAN_FR_DISASSOC sFrame; - unsigned int uNodeIndex = 0; - viawget_wpa_header *wpahdr; - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - // if is acting an AP.. - // a STA is leaving this BSS.. - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) - BSSvRemoveOneNode(pDevice, uNodeIndex); - else - pr_debug("Rx disassoc, sta not found\n"); - - } else if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) { - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - vMgrDecodeDisassociation(&sFrame); - pr_info("AP disassociated me, reason=%d\n", - cpu_to_le16(*(sFrame.pwReason))); - //TODO: do something let upper layer know or - //try to send associate packet again because of inactivity timeout - if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { - wpahdr = (viawget_wpa_header *)pDevice->skb->data; - wpahdr->type = VIAWGET_DISASSOC_MSG; - wpahdr->resp_ie_len = 0; - wpahdr->req_ie_len = 0; - skb_put(pDevice->skb, sizeof(viawget_wpa_header)); - pDevice->skb->dev = pDevice->wpadev; - skb_reset_mac_header(pDevice->skb); - - pDevice->skb->pkt_type = PACKET_HOST; - pDevice->skb->protocol = htons(ETH_P_802_2); - memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); - netif_rx(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - } - -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - { - union iwreq_data wrqu; - - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - pr_debug("wireless_send_event--->SIOCGIWAP(disassociated)\n"); - wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); - } -#endif - } - /* else, ignore it */ -} - -/*+ - * - * Routine Description: - * Handles incoming deauthentication frames - * - * - * Return Value: - * None. - * - -*/ - -static -void -s_vMgrRxDeauthentication( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -) -{ - WLAN_FR_DEAUTHEN sFrame; - unsigned int uNodeIndex = 0; - viawget_wpa_header *wpahdr; - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - //Todo: - // if is acting an AP.. - // a STA is leaving this BSS.. - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) - BSSvRemoveOneNode(pDevice, uNodeIndex); - else - pr_info("Rx deauth, sta not found\n"); - } else { - if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) { - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - vMgrDecodeDeauthen(&sFrame); - pr_info("AP deauthed me, reason=%d\n", - cpu_to_le16((*(sFrame.pwReason)))); - // TODO: update BSS list for specific BSSID if pre-authentication case - if (ether_addr_equal(sFrame.pHdr->sA3.abyAddr3, - pMgmt->abyCurrBSSID)) { - if (pMgmt->eCurrState >= WMAC_STATE_AUTHPENDING) { - pMgmt->sNodeDBTable[0].bActive = false; - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - pMgmt->eCurrState = WMAC_STATE_IDLE; - netif_stop_queue(pDevice->dev); - pDevice->bLinkPass = false; - } - } - - if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { - wpahdr = (viawget_wpa_header *)pDevice->skb->data; - wpahdr->type = VIAWGET_DISASSOC_MSG; - wpahdr->resp_ie_len = 0; - wpahdr->req_ie_len = 0; - skb_put(pDevice->skb, sizeof(viawget_wpa_header)); - pDevice->skb->dev = pDevice->wpadev; - skb_reset_mac_header(pDevice->skb); - pDevice->skb->pkt_type = PACKET_HOST; - pDevice->skb->protocol = htons(ETH_P_802_2); - memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); - netif_rx(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - } - -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - { - union iwreq_data wrqu; - - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - PRINT_K("wireless_send_event--->SIOCGIWAP(disauthen)\n"); - wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); - } -#endif - - } - /* else, ignore it. TODO: IBSS authentication service - would be implemented here */ - } -} - -//2008-8-4 <add> by chester -/*+ - * - * Routine Description: - * check if current channel is match ZoneType. - *for USA:1~11; - * Japan:1~13; - * Europe:1~13 - * Return Value: - * True:exceed; - * False:normal case - -*/ -static bool -ChannelExceedZoneType( - struct vnt_private *pDevice, - unsigned char byCurrChannel -) -{ - bool exceed = false; - - switch (pDevice->byZoneType) { - case 0x00: //USA:1~11 - if ((byCurrChannel < 1) || (byCurrChannel > 11)) - exceed = true; - break; - case 0x01: //Japan:1~13 - case 0x02: //Europe:1~13 - if ((byCurrChannel < 1) || (byCurrChannel > 13)) - exceed = true; - break; - default: //reserve for other zonetype - break; - } - - return exceed; -} - -/*+ - * - * Routine Description: - * Handles and analysis incoming beacon frames. - * - * - * Return Value: - * None. - * - -*/ - -static -void -s_vMgrRxBeacon( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket, - bool bInScan -) -{ - PKnownBSS pBSSList; - WLAN_FR_BEACON sFrame; - u64 qwTSFOffset; - bool bIsBSSIDEqual = false; - bool bIsSSIDEqual = false; - bool bTSFLargeDiff = false; - bool bTSFOffsetPostive = false; - bool bUpdateTSF = false; - bool bIsAPBeacon = false; - bool bIsChannelEqual = false; - unsigned int uLocateByteIndex; - unsigned char byTIMBitOn = 0; - unsigned short wAIDNumber = 0; - unsigned int uNodeIndex; - u64 qwTimestamp, qwLocalTSF; - u64 qwCurrTSF; - unsigned short wStartIndex = 0; - unsigned short wAIDIndex = 0; - unsigned char byCurrChannel = pRxPacket->byRxChannel; - ERPObject sERP; - unsigned int uRateLen = WLAN_RATES_MAXLEN; - bool bChannelHit = false; - bool bUpdatePhyParameter = false; - unsigned char byIEChannel = 0; - - memset(&sFrame, 0, sizeof(WLAN_FR_BEACON)); - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - - // decode the beacon frame - vMgrDecodeBeacon(&sFrame); - - if ((sFrame.pwBeaconInterval == NULL) || - (sFrame.pwCapInfo == NULL) || - (sFrame.pSSID == NULL) || - (sFrame.pSuppRates == NULL)) { - pr_debug("Rx beacon frame error\n"); - return; - } - - if (sFrame.pDSParms != NULL) { - if (byCurrChannel > CB_MAX_CHANNEL_24G) { - // channel remapping to - byIEChannel = get_channel_mapping(pDevice, sFrame.pDSParms->byCurrChannel, PHY_TYPE_11A); - } else { - byIEChannel = sFrame.pDSParms->byCurrChannel; - } - if (byCurrChannel != byIEChannel) { - // adjust channel info. bcs we rcv adjacent channel packets - bChannelHit = false; - byCurrChannel = byIEChannel; - } - } else { - // no DS channel info - bChannelHit = true; - } -//2008-0730-01<Add>by MikeLiu - if (ChannelExceedZoneType(pDevice, byCurrChannel)) - return; - - if (sFrame.pERP != NULL) { - sERP.byERP = sFrame.pERP->byContext; - sERP.bERPExist = true; - - } else { - sERP.bERPExist = false; - sERP.byERP = 0; - } - - pBSSList = BSSpAddrIsInBSSList((void *)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID); - if (pBSSList == NULL) { - pr_debug("Beacon/insert: RxChannel = : %d\n", byCurrChannel); - BSSbInsertToBSSList((void *)pDevice, - sFrame.pHdr->sA3.abyAddr3, - *sFrame.pqwTimestamp, - *sFrame.pwBeaconInterval, - *sFrame.pwCapInfo, - byCurrChannel, - sFrame.pSSID, - sFrame.pSuppRates, - sFrame.pExtSuppRates, - &sERP, - sFrame.pRSN, - sFrame.pRSNWPA, - sFrame.pIE_Country, - sFrame.pIE_Quiet, - sFrame.len - WLAN_HDR_ADDR3_LEN, - sFrame.pHdr->sA4.abyAddr4, // payload of beacon - (void *)pRxPacket -); - } else { - BSSbUpdateToBSSList((void *)pDevice, - *sFrame.pqwTimestamp, - *sFrame.pwBeaconInterval, - *sFrame.pwCapInfo, - byCurrChannel, - bChannelHit, - sFrame.pSSID, - sFrame.pSuppRates, - sFrame.pExtSuppRates, - &sERP, - sFrame.pRSN, - sFrame.pRSNWPA, - sFrame.pIE_Country, - sFrame.pIE_Quiet, - pBSSList, - sFrame.len - WLAN_HDR_ADDR3_LEN, - sFrame.pHdr->sA4.abyAddr4, // payload of probresponse - (void *)pRxPacket -); - - } - - if (bInScan) - return; - - if (byCurrChannel == (unsigned char)pMgmt->uCurrChannel) - bIsChannelEqual = true; - - if (bIsChannelEqual && (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { - // if rx beacon without ERP field - if (sERP.bERPExist) { - if (WLAN_GET_ERP_USE_PROTECTION(sERP.byERP)) { - pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1); - pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD; - } - } else { - pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1); - pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD; - } - - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - if (!WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo)) - pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1); - if (!sERP.bERPExist) - pDevice->byERPFlag |= WLAN_SET_ERP_NONERP_PRESENT(1); - } - - // set to MAC&BBP - if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)) { - if (!pDevice->bProtectMode) { - MACvEnableProtectMD(pDevice->PortOffset); - pDevice->bProtectMode = true; - } - } - } - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) - return; - - // check if BSSID the same - if (memcmp(sFrame.pHdr->sA3.abyAddr3, - pMgmt->abyCurrBSSID, - WLAN_BSSID_LEN) == 0) { - bIsBSSIDEqual = true; - -// 2008-05-21 <add> by Richardtai - pDevice->uCurrRSSI = pRxPacket->uRSSI; - pDevice->byCurrSQ = pRxPacket->bySQ; - - if (pMgmt->sNodeDBTable[0].uInActiveCount != 0) - pMgmt->sNodeDBTable[0].uInActiveCount = 0; - } - // check if SSID the same - if (sFrame.pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) { - if (memcmp(sFrame.pSSID->abySSID, - ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, - sFrame.pSSID->len -) == 0) { - bIsSSIDEqual = true; - } - } - - if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo) && - bIsBSSIDEqual && - bIsSSIDEqual && - (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - // add state check to prevent reconnect fail since we'll receive Beacon - - bIsAPBeacon = true; - - if (pBSSList != NULL) { - // Compare PHY parameter setting - if (pMgmt->wCurrCapInfo != pBSSList->wCapInfo) { - bUpdatePhyParameter = true; - pMgmt->wCurrCapInfo = pBSSList->wCapInfo; - } - if (sFrame.pERP != NULL) { - if ((sFrame.pERP->byElementID == WLAN_EID_ERP) && - (pMgmt->byERPContext != sFrame.pERP->byContext)) { - bUpdatePhyParameter = true; - pMgmt->byERPContext = sFrame.pERP->byContext; - } - } - // - // Basic Rate Set may change dynamically - // - if (pBSSList->eNetworkTypeInUse == PHY_TYPE_11B) - uRateLen = WLAN_RATES_MAXLEN_11B; - - pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abySuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - uRateLen); - pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abyExtSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, - uRateLen); - RATEvParseMaxRate((void *)pDevice, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, - true, - &(pMgmt->sNodeDBTable[0].wMaxBasicRate), - &(pMgmt->sNodeDBTable[0].wMaxSuppRate), - &(pMgmt->sNodeDBTable[0].wSuppRate), - &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate), - &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate) - ); - if (bUpdatePhyParameter) { - CARDbSetPhyParameter(pMgmt->pAdapter, - pMgmt->eCurrentPHYMode, - pMgmt->wCurrCapInfo, - pMgmt->byERPContext, - pMgmt->abyCurrSuppRates, - pMgmt->abyCurrExtSuppRates - ); - } - if (sFrame.pIE_PowerConstraint != NULL) { - CARDvSetPowerConstraint(pMgmt->pAdapter, - (unsigned char) pBSSList->uChannel, - sFrame.pIE_PowerConstraint->byPower -); - } - if (sFrame.pIE_CHSW != NULL) { - CARDbChannelSwitch(pMgmt->pAdapter, - sFrame.pIE_CHSW->byMode, - get_channel_mapping(pMgmt->pAdapter, sFrame.pIE_CHSW->byMode, pMgmt->eCurrentPHYMode), - sFrame.pIE_CHSW->byCount - ); - - } else if (!bIsChannelEqual) { - set_channel(pMgmt->pAdapter, pBSSList->uChannel); - } - } - } - -// pr_debug("Beacon 2\n"); - // check if CF field exists - if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)) { - if (sFrame.pCFParms->wCFPDurRemaining > 0) { - // TODO: deal with CFP period to set NAV - } - } - - qwTimestamp = le64_to_cpu(*sFrame.pqwTimestamp); - qwLocalTSF = pRxPacket->qwLocalTSF; - - // check if beacon TSF larger or small than our local TSF - if (qwTimestamp >= qwLocalTSF) - bTSFOffsetPostive = true; - else - bTSFOffsetPostive = false; - - if (bTSFOffsetPostive) - qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwTimestamp), (qwLocalTSF)); - else - qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwLocalTSF), (qwTimestamp)); - - if (qwTSFOffset > TRIVIAL_SYNC_DIFFERENCE) - bTSFLargeDiff = true; - - // if infra mode - if (bIsAPBeacon) { - // Infra mode: Local TSF always follow AP's TSF if Difference huge. - if (bTSFLargeDiff) - bUpdateTSF = true; - - if (pDevice->bEnablePSMode && (sFrame.pTIM != NULL)) { - // deal with DTIM, analysis TIM - pMgmt->bMulticastTIM = WLAN_MGMT_IS_MULTICAST_TIM(sFrame.pTIM->byBitMapCtl) ? true : false; - pMgmt->byDTIMCount = sFrame.pTIM->byDTIMCount; - pMgmt->byDTIMPeriod = sFrame.pTIM->byDTIMPeriod; - wAIDNumber = pMgmt->wCurrAID & ~(BIT14|BIT15); - - // check if AID in TIM field bit on - // wStartIndex = N1 - wStartIndex = WLAN_MGMT_GET_TIM_OFFSET(sFrame.pTIM->byBitMapCtl) << 1; - // AIDIndex = N2 - wAIDIndex = (wAIDNumber >> 3); - if ((wAIDNumber > 0) && (wAIDIndex >= wStartIndex)) { - uLocateByteIndex = wAIDIndex - wStartIndex; - // len = byDTIMCount + byDTIMPeriod + byDTIMPeriod + byVirtBitMap[0~250] - if (sFrame.pTIM->len >= (uLocateByteIndex + 4)) { - byTIMBitOn = (0x01) << ((wAIDNumber) % 8); - pMgmt->bInTIM = sFrame.pTIM->byVirtBitMap[uLocateByteIndex] & byTIMBitOn ? true : false; - } else { - pMgmt->bInTIM = false; - } - } else { - pMgmt->bInTIM = false; - } - - if (pMgmt->bInTIM || - (pMgmt->bMulticastTIM && (pMgmt->byDTIMCount == 0))) { - pMgmt->bInTIMWake = true; - // send out ps-poll packet - - if (pMgmt->bInTIM) - PSvSendPSPOLL(pDevice); - - } else { - pMgmt->bInTIMWake = false; - pr_debug("BCN: Not In TIM..\n"); - if (!pDevice->bPWBitOn) { - pr_debug("BCN: Send Null Packet\n"); - if (PSbSendNullPacket(pDevice)) - pDevice->bPWBitOn = true; - } - if (PSbConsiderPowerDown(pDevice, false, false)) - pr_debug("BCN: Power down now...\n"); - } - - } - - } - // if adhoc mode - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && !bIsAPBeacon && bIsChannelEqual) { - if (bIsBSSIDEqual) { - // Use sNodeDBTable[0].uInActiveCount as IBSS beacons received count. - if (pMgmt->sNodeDBTable[0].uInActiveCount != 0) - pMgmt->sNodeDBTable[0].uInActiveCount = 0; - - // adhoc mode:TSF updated only when beacon larger than local TSF - if (bTSFLargeDiff && bTSFOffsetPostive && - (pMgmt->eCurrState == WMAC_STATE_JOINTED)) - bUpdateTSF = true; - - // During dpc, already in spinlocked. - if (BSSDBbIsSTAInNodeDB(pMgmt, sFrame.pHdr->sA3.abyAddr2, &uNodeIndex)) { - // Update the STA, (Technically the Beacons of all the IBSS nodes - // should be identical, but that's not happening in practice. - pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - WLAN_RATES_MAXLEN_11B); - RATEvParseMaxRate((void *)pDevice, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - NULL, - true, - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate) - ); - pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].uInActiveCount = 0; - } else { - // Todo, initial Node content - BSSvCreateOneNode(pDevice, &uNodeIndex); - - pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - WLAN_RATES_MAXLEN_11B); - RATEvParseMaxRate((void *)pDevice, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - NULL, - true, - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate) - ); - - memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, sFrame.pHdr->sA3.abyAddr2, WLAN_ADDR_LEN); - pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate; - { - pr_debug("s_vMgrRxBeacon:TxDataRate is %d,Index is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate, uNodeIndex); - } - } - - // if other stations joined, indicate connection to upper layer.. - if (pMgmt->eCurrState == WMAC_STATE_STARTED) { - pr_debug("Current IBSS State: [Started]........to: [Jointed]\n"); - pMgmt->eCurrState = WMAC_STATE_JOINTED; - pDevice->bLinkPass = true; - if (netif_queue_stopped(pDevice->dev)) - netif_wake_queue(pDevice->dev); - - pMgmt->sNodeDBTable[0].bActive = true; - pMgmt->sNodeDBTable[0].uInActiveCount = 0; - - } - } else if (bIsSSIDEqual) { - // See other adhoc sta with the same SSID but BSSID is different. - // adpot this vars only when TSF larger then us. - if (bTSFLargeDiff && bTSFOffsetPostive) { - // we don't support ATIM under adhoc mode - // if (sFrame.pIBSSParms->wATIMWindow == 0) { - // adpot this vars - // TODO: check sFrame cap if privacy on, and support rate syn - memcpy(pMgmt->abyCurrBSSID, sFrame.pHdr->sA3.abyAddr3, WLAN_BSSID_LEN); - memcpy(pDevice->abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - pMgmt->wCurrATIMWindow = cpu_to_le16(sFrame.pIBSSParms->wATIMWindow); - pMgmt->wCurrBeaconPeriod = cpu_to_le16(*sFrame.pwBeaconInterval); - pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - WLAN_RATES_MAXLEN_11B); - // set HW beacon interval and re-synchronizing.... - pr_debug("Rejoining to Other Adhoc group with same SSID........\n"); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_BI, pMgmt->wCurrBeaconPeriod); - CARDbUpdateTSF(pDevice, pRxPacket->byRxRate, qwTimestamp, qwLocalTSF); - CARDvUpdateNextTBTT(pDevice->PortOffset, qwTimestamp, pMgmt->wCurrBeaconPeriod); - // Turn off bssid filter to avoid filter others adhoc station which bssid is different. - MACvWriteBSSIDAddress(pDevice->PortOffset, pMgmt->abyCurrBSSID); - - CARDbSetPhyParameter(pMgmt->pAdapter, - pMgmt->eCurrentPHYMode, - pMgmt->wCurrCapInfo, - pMgmt->byERPContext, - pMgmt->abyCurrSuppRates, - pMgmt->abyCurrExtSuppRates); - - // Prepare beacon frame - bMgrPrepareBeaconToSend((void *)pDevice, pMgmt); - } - } - } - // endian issue ??? - // Update TSF -if (bUpdateTSF) { - CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF); - CARDbUpdateTSF(pDevice, pRxPacket->byRxRate, qwTimestamp, pRxPacket->qwLocalTSF); - CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF); - CARDvUpdateNextTBTT(pDevice->PortOffset, qwTimestamp, pMgmt->wCurrBeaconPeriod); - } -} - -/*+ - * - * Routine Description: - * Instructs the hw to create a bss using the supplied - * attributes. Note that this implementation only supports Ad-Hoc - * BSS creation. - * - * - * Return Value: - * CMD_STATUS - * - -*/ -void -vMgrCreateOwnIBSS( - void *hDeviceContext, - PCMD_STATUS pStatus -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned short wMaxBasicRate; - unsigned short wMaxSuppRate; - unsigned char byTopCCKBasicRate; - unsigned char byTopOFDMBasicRate; - u64 qwCurrTSF; - unsigned int ii; - unsigned char abyRATE[] = {0x82, 0x84, 0x8B, 0x96, 0x24, 0x30, 0x48, 0x6C, 0x0C, 0x12, 0x18, 0x60}; - unsigned char abyCCK_RATE[] = {0x82, 0x84, 0x8B, 0x96}; - unsigned char abyOFDM_RATE[] = {0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; - unsigned short wSuppRate; - - pr_debug("Create Basic Service Set .......\n"); - - if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) { - if ((pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) && - (pDevice->eEncryptionStatus != Ndis802_11Encryption2Enabled) && - (pDevice->eEncryptionStatus != Ndis802_11Encryption3Enabled)) { - // encryption mode error - *pStatus = CMD_STATUS_FAILURE; - return; - } - } - - pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES; - pMgmt->abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES; - - if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { - pMgmt->eCurrentPHYMode = pMgmt->byAPBBType; - } else { - if (pDevice->byBBType == BB_TYPE_11G) - pMgmt->eCurrentPHYMode = PHY_TYPE_11G; - if (pDevice->byBBType == BB_TYPE_11B) - pMgmt->eCurrentPHYMode = PHY_TYPE_11B; - if (pDevice->byBBType == BB_TYPE_11A) - pMgmt->eCurrentPHYMode = PHY_TYPE_11A; - } - - if (pMgmt->eCurrentPHYMode != PHY_TYPE_11A) { - pMgmt->abyCurrSuppRates[1] = WLAN_RATES_MAXLEN_11B; - pMgmt->abyCurrExtSuppRates[1] = 0; - for (ii = 0; ii < 4; ii++) - pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii]; - } else { - pMgmt->abyCurrSuppRates[1] = 8; - pMgmt->abyCurrExtSuppRates[1] = 0; - for (ii = 0; ii < 8; ii++) - pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii]; - } - - if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) { - pMgmt->abyCurrSuppRates[1] = 8; - pMgmt->abyCurrExtSuppRates[1] = 4; - for (ii = 0; ii < 4; ii++) - pMgmt->abyCurrSuppRates[2+ii] = abyCCK_RATE[ii]; - for (ii = 4; ii < 8; ii++) - pMgmt->abyCurrSuppRates[2+ii] = abyOFDM_RATE[ii-4]; - for (ii = 0; ii < 4; ii++) - pMgmt->abyCurrExtSuppRates[2+ii] = abyOFDM_RATE[ii+4]; - } - - // Disable Protect Mode - pDevice->bProtectMode = false; - MACvDisableProtectMD(pDevice->PortOffset); - - pDevice->bBarkerPreambleMd = false; - MACvDisableBarkerPreambleMd(pDevice->PortOffset); - - // Kyle Test 2003.11.04 - - // set HW beacon interval - if (pMgmt->wIBSSBeaconPeriod == 0) - pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI; - - CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF); - // clear TSF counter - VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); - // enable TSF counter - VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); - - // set Next TBTT - CARDvSetFirstNextTBTT(pDevice->PortOffset, pMgmt->wIBSSBeaconPeriod); - - pMgmt->uIBSSChannel = pDevice->uChannel; - - if (pMgmt->uIBSSChannel == 0) - pMgmt->uIBSSChannel = DEFAULT_IBSS_CHANNEL; - - // set basic rate - - RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, true, - &wMaxBasicRate, &wMaxSuppRate, &wSuppRate, - &byTopCCKBasicRate, &byTopOFDMBasicRate); - - if (pMgmt->eConfigMode == WMAC_CONFIG_AP) - pMgmt->eCurrMode = WMAC_MODE_ESS_AP; - - if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) { - memcpy(pMgmt->abyIBSSDFSOwner, pDevice->abyCurrentNetAddr, 6); - pMgmt->byIBSSDFSRecovery = 10; - pMgmt->eCurrMode = WMAC_MODE_IBSS_STA; - } - - // Adopt pre-configured IBSS vars to current vars - pMgmt->eCurrState = WMAC_STATE_STARTED; - pMgmt->wCurrBeaconPeriod = pMgmt->wIBSSBeaconPeriod; - pMgmt->uCurrChannel = pMgmt->uIBSSChannel; - pMgmt->wCurrATIMWindow = pMgmt->wIBSSATIMWindow; - MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow); - pDevice->uCurrRSSI = 0; - pDevice->byCurrSQ = 0; - memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - memcpy(pMgmt->abyCurrSSID, - pMgmt->abyDesireSSID, - ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN -); - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - // AP mode BSSID = MAC addr - memcpy(pMgmt->abyCurrBSSID, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - pr_info("AP beacon created BSSID:%pM\n", - pMgmt->abyCurrBSSID); - } - - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - // BSSID selected must be randomized as spec 11.1.3 - pMgmt->abyCurrBSSID[5] = (u8) (qwCurrTSF & 0x000000ff); - pMgmt->abyCurrBSSID[4] = (u8) ((qwCurrTSF & 0x0000ff00) >> 8); - pMgmt->abyCurrBSSID[3] = (u8) ((qwCurrTSF & 0x00ff0000) >> 16); - pMgmt->abyCurrBSSID[2] = (u8) ((qwCurrTSF & 0x00000ff0) >> 4); - pMgmt->abyCurrBSSID[1] = (u8) ((qwCurrTSF & 0x000ff000) >> 12); - pMgmt->abyCurrBSSID[0] = (u8) ((qwCurrTSF & 0x0ff00000) >> 20); - pMgmt->abyCurrBSSID[5] ^= pMgmt->abyMACAddr[0]; - pMgmt->abyCurrBSSID[4] ^= pMgmt->abyMACAddr[1]; - pMgmt->abyCurrBSSID[3] ^= pMgmt->abyMACAddr[2]; - pMgmt->abyCurrBSSID[2] ^= pMgmt->abyMACAddr[3]; - pMgmt->abyCurrBSSID[1] ^= pMgmt->abyMACAddr[4]; - pMgmt->abyCurrBSSID[0] ^= pMgmt->abyMACAddr[5]; - pMgmt->abyCurrBSSID[0] &= ~IEEE_ADDR_GROUP; - pMgmt->abyCurrBSSID[0] |= IEEE_ADDR_UNIVERSAL; - - pr_info("Adhoc beacon created bssid:%pM\n", - pMgmt->abyCurrBSSID); - } - - // Set Capability Info - pMgmt->wCurrCapInfo = 0; - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1); - pMgmt->byDTIMPeriod = DEFAULT_DTIM_PERIOD; - pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1; - } - - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_IBSS(1); - - if (pDevice->bEncryptionEnable) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1); - if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - pMgmt->byCSSPK = KEY_CTL_CCMP; - pMgmt->byCSSGK = KEY_CTL_CCMP; - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { - pMgmt->byCSSPK = KEY_CTL_TKIP; - pMgmt->byCSSGK = KEY_CTL_TKIP; - } else { - pMgmt->byCSSPK = KEY_CTL_NONE; - pMgmt->byCSSGK = KEY_CTL_WEP; - } - } else { - pMgmt->byCSSPK = KEY_CTL_WEP; - pMgmt->byCSSGK = KEY_CTL_WEP; - } - } - - pMgmt->byERPContext = 0; - - if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_AP); - } else { - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_ADHOC); - } - - CARDbSetPhyParameter(pMgmt->pAdapter, - pMgmt->eCurrentPHYMode, - pMgmt->wCurrCapInfo, - pMgmt->byERPContext, - pMgmt->abyCurrSuppRates, - pMgmt->abyCurrExtSuppRates - ); - - CARDbSetBeaconPeriod(pMgmt->pAdapter, pMgmt->wIBSSBeaconPeriod); - // set channel and clear NAV - set_channel(pMgmt->pAdapter, pMgmt->uIBSSChannel); - pMgmt->uCurrChannel = pMgmt->uIBSSChannel; - - if (CARDbIsShortPreamble(pMgmt->pAdapter)) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - else - pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SHORTPREAMBLE(1)); - - if (pMgmt->b11hEnable && - (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1); - } else { - pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SPECTRUMMNG(1)); - } - - pMgmt->eCurrState = WMAC_STATE_STARTED; - // Prepare beacon to send - if (bMgrPrepareBeaconToSend((void *)pDevice, pMgmt)) - *pStatus = CMD_STATUS_SUCCESS; -} - -/*+ - * - * Routine Description: - * Instructs wmac to join a bss using the supplied attributes. - * The arguments may the BSSID or SSID and the rest of the - * attributes are obtained from the scan result of known bss list. - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrJoinBSSBegin( - void *hDeviceContext, - PCMD_STATUS pStatus -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - PKnownBSS pCurr = NULL; - unsigned int ii, uu; - PWLAN_IE_SUPP_RATES pItemRates = NULL; - PWLAN_IE_SUPP_RATES pItemExtRates = NULL; - PWLAN_IE_SSID pItemSSID; - unsigned int uRateLen = WLAN_RATES_MAXLEN; - unsigned short wMaxBasicRate = RATE_1M; - unsigned short wMaxSuppRate = RATE_1M; - unsigned short wSuppRate; - unsigned char byTopCCKBasicRate = RATE_1M; - unsigned char byTopOFDMBasicRate = RATE_1M; - - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - if (pMgmt->sBSSList[ii].bActive) - break; - } - - if (ii == MAX_BSS_NUM) { - *pStatus = CMD_STATUS_RESOURCES; - pr_info("BSS finding:BSS list is empty\n"); - return; - } - - // Search known BSS list for prefer BSSID or SSID - - pCurr = BSSpSearchBSSList(pDevice, - pMgmt->abyDesireBSSID, - pMgmt->abyDesireSSID, - pMgmt->eConfigPHYMode -); - - if (pCurr == NULL) { - *pStatus = CMD_STATUS_RESOURCES; - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; - pr_info("Scanning [%s] not found, disconnected !\n", - pItemSSID->abySSID); - return; - } - - pr_info("AP(BSS) finding:Found a AP(BSS)..\n"); - if (WLAN_GET_CAP_INFO_ESS(cpu_to_le16(pCurr->wCapInfo))) { - if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) { - // patch for CISCO migration mode - } - -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - Encyption_Rebuild(pDevice, pCurr); -#endif - // Infrastructure BSS - s_vMgrSynchBSS(pDevice, - WMAC_MODE_ESS_STA, - pCurr, - pStatus -); - - if (*pStatus == CMD_STATUS_SUCCESS) { - // Adopt this BSS state vars in Mgmt Object - pMgmt->uCurrChannel = pCurr->uChannel; - - memset(pMgmt->abyCurrSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); - memset(pMgmt->abyCurrExtSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); - - if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) - uRateLen = WLAN_RATES_MAXLEN_11B; - - pItemRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates; - pItemExtRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates; - - // Parse Support Rate IE - pItemRates->byElementID = WLAN_EID_SUPP_RATES; - pItemRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates, - pItemRates, - uRateLen); - - // Parse Extension Support Rate IE - pItemExtRates->byElementID = WLAN_EID_EXTSUPP_RATES; - pItemExtRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abyExtSuppRates, - pItemExtRates, - uRateLen); - // Stuffing Rate IE - if ((pItemExtRates->len > 0) && (pItemRates->len < 8)) { - for (ii = 0; ii < (unsigned int)(8 - pItemRates->len);) { - pItemRates->abyRates[pItemRates->len + ii] = pItemExtRates->abyRates[ii]; - ii++; - if (pItemExtRates->len <= ii) - break; - } - pItemRates->len += (unsigned char)ii; - if (pItemExtRates->len - ii > 0) { - pItemExtRates->len -= (unsigned char)ii; - for (uu = 0; uu < pItemExtRates->len; uu++) - pItemExtRates->abyRates[uu] = pItemExtRates->abyRates[uu + ii]; - } else { - pItemExtRates->len = 0; - } - } - - RATEvParseMaxRate((void *)pDevice, pItemRates, pItemExtRates, true, - &wMaxBasicRate, &wMaxSuppRate, &wSuppRate, - &byTopCCKBasicRate, &byTopOFDMBasicRate); - - // TODO: deal with if wCapInfo the privacy is on, but station WEP is off - // TODO: deal with if wCapInfo the PS-Pollable is on. - pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval; - memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN); - memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - - pMgmt->eCurrMode = WMAC_MODE_ESS_STA; - - pMgmt->eCurrState = WMAC_STATE_JOINTED; - - // Add current BSS to Candidate list - // This should only works for WPA2 BSS, and WPA2 BSS check must be done before. - if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) { - bool bResult = bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj); - - pr_debug("bAdd_PMKID_Candidate: 1(%d)\n", - bResult); - if (!bResult) { - vFlush_PMKID_Candidate((void *)pDevice); - pr_debug("vFlush_PMKID_Candidate: 4\n"); - bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj); - } - } - - // Preamble type auto-switch: if AP can receive short-preamble cap, - // we can turn on too. - - pr_debug("Join ESS\n"); - - pr_debug("End of Join AP -- A/B/G Action\n"); - } else { - pMgmt->eCurrState = WMAC_STATE_IDLE; - } - - } else { - // ad-hoc mode BSS - if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { - if (!WPA_SearchRSN(0, WPA_TKIP, pCurr)) { - // encryption mode error - pMgmt->eCurrState = WMAC_STATE_IDLE; - return; - } - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - if (!WPA_SearchRSN(0, WPA_AESCCMP, pCurr)) { - // encryption mode error - pMgmt->eCurrState = WMAC_STATE_IDLE; - return; - } - } else { - // encryption mode error - pMgmt->eCurrState = WMAC_STATE_IDLE; - return; - } - } - - s_vMgrSynchBSS(pDevice, - WMAC_MODE_IBSS_STA, - pCurr, - pStatus -); - - if (*pStatus == CMD_STATUS_SUCCESS) { - // Adopt this BSS state vars in Mgmt Object - // TODO: check if CapInfo privacy on, but we don't.. - pMgmt->uCurrChannel = pCurr->uChannel; - - // Parse Support Rate IE - pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES; - pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - WLAN_RATES_MAXLEN_11B); - // set basic rate - RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - NULL, true, &wMaxBasicRate, &wMaxSuppRate, &wSuppRate, - &byTopCCKBasicRate, &byTopOFDMBasicRate); - - pMgmt->wCurrCapInfo = pCurr->wCapInfo; - pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval; - memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN); - memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN); - memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN); - MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow); - pMgmt->eCurrMode = WMAC_MODE_IBSS_STA; - - pMgmt->eCurrState = WMAC_STATE_STARTED; - - pr_debug("Join IBSS ok:%pM\n", - pMgmt->abyCurrBSSID); - // Preamble type auto-switch: if AP can receive short-preamble cap, - // and if registry setting is short preamble we can turn on too. - - // Prepare beacon - bMgrPrepareBeaconToSend((void *)pDevice, pMgmt); - } else { - pMgmt->eCurrState = WMAC_STATE_IDLE; - } - } -} - -/*+ - * - * Routine Description: - * Set HW to synchronize a specific BSS from known BSS list. - * - * - * Return Value: - * PCM_STATUS - * - -*/ -static -void -s_vMgrSynchBSS( - struct vnt_private *pDevice, - unsigned int uBSSMode, - PKnownBSS pCurr, - PCMD_STATUS pStatus -) -{ - CARD_PHY_TYPE ePhyType = PHY_TYPE_11B; - PSMgmtObject pMgmt = pDevice->pMgmt; - - //1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M - unsigned char abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C}; - unsigned char abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60}; - //6M, 9M, 12M, 48M - unsigned char abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; - unsigned char abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16}; - - *pStatus = CMD_STATUS_FAILURE; - - if (!s_bCipherMatch(pCurr, - pDevice->eEncryptionStatus, - &(pMgmt->byCSSPK), - &(pMgmt->byCSSGK))) { - pr_debug("s_bCipherMatch Fail .......\n"); - return; - } - - pMgmt->pCurrBSS = pCurr; - - // if previous mode is IBSS. - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_BCNDMACTL, BEACON_READY); - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); - } - - // Init the BSS informations - pDevice->bProtectMode = false; - MACvDisableProtectMD(pDevice->PortOffset); - pDevice->bBarkerPreambleMd = false; - MACvDisableBarkerPreambleMd(pDevice->PortOffset); - pDevice->bNonERPPresent = false; - pDevice->byPreambleType = 0; - pDevice->wBasicRate = 0; - // Set Basic Rate - CARDbAddBasicRate((void *)pDevice, RATE_1M); - // calculate TSF offset - // TSF Offset = Received Timestamp TSF - Marked Local's TSF - CARDbUpdateTSF(pDevice, pCurr->byRxRate, pCurr->qwBSSTimestamp, pCurr->qwLocalTSF); - - CARDbSetBeaconPeriod(pDevice, pCurr->wBeaconInterval); - - // set Next TBTT - // Next TBTT = ((local_current_TSF / beacon_interval) + 1) * beacon_interval - CARDvSetFirstNextTBTT(pDevice->PortOffset, pCurr->wBeaconInterval); - - // set BSSID - MACvWriteBSSIDAddress(pDevice->PortOffset, pCurr->abyBSSID); - - MACvReadBSSIDAddress(pDevice->PortOffset, pMgmt->abyCurrBSSID); - - pr_debug("Sync:set CurrBSSID address = %pM\n", pMgmt->abyCurrBSSID); - - if (pCurr->eNetworkTypeInUse == PHY_TYPE_11A) { - if ((pMgmt->eConfigPHYMode == PHY_TYPE_11A) || - (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) { - ePhyType = PHY_TYPE_11A; - } else { - return; - } - } else if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) { - if ((pMgmt->eConfigPHYMode == PHY_TYPE_11B) || - (pMgmt->eConfigPHYMode == PHY_TYPE_11G) || - (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) { - ePhyType = PHY_TYPE_11B; - } else { - return; - } - } else { - if ((pMgmt->eConfigPHYMode == PHY_TYPE_11G) || - (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) { - ePhyType = PHY_TYPE_11G; - } else if (pMgmt->eConfigPHYMode == PHY_TYPE_11B) { - ePhyType = PHY_TYPE_11B; - } else { - return; - } - } - - if (ePhyType == PHY_TYPE_11A) { - memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesA[0], sizeof(abyCurrSuppRatesA)); - pMgmt->abyCurrExtSuppRates[1] = 0; - } else if (ePhyType == PHY_TYPE_11B) { - memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesB[0], sizeof(abyCurrSuppRatesB)); - pMgmt->abyCurrExtSuppRates[1] = 0; - } else { - memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesG[0], sizeof(abyCurrSuppRatesG)); - memcpy(pMgmt->abyCurrExtSuppRates, &abyCurrExtSuppRatesG[0], sizeof(abyCurrExtSuppRatesG)); - } - - if (WLAN_GET_CAP_INFO_ESS(pCurr->wCapInfo)) { - CARDbSetBSSID(pMgmt->pAdapter, pCurr->abyBSSID, NL80211_IFTYPE_STATION); - // Add current BSS to Candidate list - // This should only works for WPA2 BSS, and WPA2 BSS check must be done before. - if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) - CARDbAdd_PMKID_Candidate(pMgmt->pAdapter, pMgmt->abyCurrBSSID, pCurr->sRSNCapObj.bRSNCapExist, pCurr->sRSNCapObj.wRSNCap); - } else { - CARDbSetBSSID(pMgmt->pAdapter, pCurr->abyBSSID, NL80211_IFTYPE_ADHOC); - } - - if (!CARDbSetPhyParameter(pMgmt->pAdapter, - ePhyType, - pCurr->wCapInfo, - pCurr->sERP.byERP, - pMgmt->abyCurrSuppRates, - pMgmt->abyCurrExtSuppRates)) { - pr_debug("<----s_bSynchBSS Set Phy Mode Fail [%d]\n", ePhyType); - return; - } - // set channel and clear NAV - if (!set_channel(pMgmt->pAdapter, pCurr->uChannel)) { - pr_debug("<----s_bSynchBSS Set Channel [%d]\n", - pCurr->uChannel); - return; - } - - pMgmt->uCurrChannel = pCurr->uChannel; - pMgmt->eCurrentPHYMode = ePhyType; - pMgmt->byERPContext = pCurr->sERP.byERP; - pr_debug("Sync:Set to channel = [%d]\n", (int)pCurr->uChannel); - - *pStatus = CMD_STATUS_SUCCESS; - - return; -}; - -//mike add: fix NetworkManager 0.7.0 hidden ssid mode in WPA encryption -// ,need reset eAuthenMode and eEncryptionStatus -static void Encyption_Rebuild( - struct vnt_private *pDevice, - PKnownBSS pCurr -) -{ - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - - if ((pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || //networkmanager 0.7.0 does not give the pairwise-key selection, - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { // so we need re-select it according to real pairwise-key info. - if (pCurr->bWPAValid) { //WPA-PSK - pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK; - if (pCurr->abyPKType[0] == WPA_TKIP) { - pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; //TKIP - PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-TKIP]\n"); - } else if (pCurr->abyPKType[0] == WPA_AESCCMP) { - pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; //AES - PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-AES]\n"); - } - } else if (pCurr->bWPA2Valid) { //WPA2-PSK - pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK; - if (pCurr->abyCSSPK[0] == WLAN_11i_CSS_TKIP) { - pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; //TKIP - PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-TKIP]\n"); - } else if (pCurr->abyCSSPK[0] == WLAN_11i_CSS_CCMP) { - pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; //AES - PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-AES]\n"); - } - } - } -} - -/*+ - * - * Routine Description: - * Format TIM field - * - * - * Return Value: - * void - * - -*/ - -static -void -s_vMgrFormatTIM( - PSMgmtObject pMgmt, - PWLAN_IE_TIM pTIM -) -{ - unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; - unsigned char byMap; - unsigned int ii, jj; - bool bStartFound = false; - bool bMulticast = false; - unsigned short wStartIndex = 0; - unsigned short wEndIndex = 0; - - // Find size of partial virtual bitmap - for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) { - byMap = pMgmt->abyPSTxMap[ii]; - if (!ii) { - // Mask out the broadcast bit which is indicated separately. - bMulticast = (byMap & byMask[0]) != 0; - if (bMulticast) - pMgmt->sNodeDBTable[0].bRxPSPoll = true; - - byMap = 0; - } - if (byMap) { - if (!bStartFound) { - bStartFound = true; - wStartIndex = ii; - } - wEndIndex = ii; - } - } - - // Round start index down to nearest even number - wStartIndex &= ~BIT0; - - // Round end index up to nearest even number - wEndIndex = ((wEndIndex + 1) & ~BIT0); - - // Size of element payload - - pTIM->len = 3 + (wEndIndex - wStartIndex) + 1; - - // Fill in the Fixed parts of the TIM - pTIM->byDTIMCount = pMgmt->byDTIMCount; - pTIM->byDTIMPeriod = pMgmt->byDTIMPeriod; - pTIM->byBitMapCtl = (bMulticast ? TIM_MULTICAST_MASK : 0) | - (((wStartIndex >> 1) << 1) & TIM_BITMAPOFFSET_MASK); - - // Append variable part of TIM - - for (ii = wStartIndex, jj = 0; ii <= wEndIndex; ii++, jj++) - pTIM->byVirtBitMap[jj] = pMgmt->abyPSTxMap[ii]; - - // Aid = 0 don't used. - pTIM->byVirtBitMap[0] &= ~BIT0; -} - -/*+ - * - * Routine Description: - * Constructs an Beacon frame(Ad-hoc mode) - * - * - * Return Value: - * PTR to frame; or NULL on allocation failure - * - -*/ - -static -PSTxMgmtPacket -s_MgrMakeBeacon( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wCurrBeaconPeriod, - unsigned int uCurrChannel, - unsigned short wCurrATIMWinodw, - PWLAN_IE_SSID pCurrSSID, - unsigned char *pCurrBSSID, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -) -{ - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_BEACON sFrame; - unsigned char abyBroadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - unsigned char *pbyBuffer; - unsigned int uLength = 0; - PWLAN_IE_IBSS_DFS pIBSSDFS = NULL; - unsigned int ii; - - // prepare beacon frame - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_BEACON_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - // Setup the sFrame structure. - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_BEACON_FR_MAXLEN; - vMgrEncodeBeacon(&sFrame); - // Setup the header - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_BEACON) -)); - - if (pDevice->bEnablePSMode) - sFrame.pHdr->sA3.wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_PWRMGT(1)); - - memcpy(sFrame.pHdr->sA3.abyAddr1, abyBroadcastAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN); - *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod); - *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo); - // Copy SSID - sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSSID, - pCurrSSID, - ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN -); - // Copy the rate set - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, - pCurrSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN -); - // DS parameter - if (pDevice->eCurrentPHYType != PHY_TYPE_11A) { - sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len); - sFrame.len += (1) + WLAN_IEHDR_LEN; - sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS; - sFrame.pDSParms->len = 1; - sFrame.pDSParms->byCurrChannel = (unsigned char)uCurrChannel; - } - // TIM field - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - sFrame.pTIM = (PWLAN_IE_TIM)(sFrame.pBuf + sFrame.len); - sFrame.pTIM->byElementID = WLAN_EID_TIM; - s_vMgrFormatTIM(pMgmt, sFrame.pTIM); - sFrame.len += (WLAN_IEHDR_LEN + sFrame.pTIM->len); - } - - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - // IBSS parameter - sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len); - sFrame.len += (2) + WLAN_IEHDR_LEN; - sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS; - sFrame.pIBSSParms->len = 2; - sFrame.pIBSSParms->wATIMWindow = wCurrATIMWinodw; - if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - /* RSN parameter */ - sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len); - sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA; - sFrame.pRSNWPA->len = 12; - sFrame.pRSNWPA->abyOUI[0] = 0x00; - sFrame.pRSNWPA->abyOUI[1] = 0x50; - sFrame.pRSNWPA->abyOUI[2] = 0xf2; - sFrame.pRSNWPA->abyOUI[3] = 0x01; - sFrame.pRSNWPA->wVersion = 1; - sFrame.pRSNWPA->abyMulticast[0] = 0x00; - sFrame.pRSNWPA->abyMulticast[1] = 0x50; - sFrame.pRSNWPA->abyMulticast[2] = 0xf2; - if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) - sFrame.pRSNWPA->abyMulticast[3] = 0x04;//AES - else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) - sFrame.pRSNWPA->abyMulticast[3] = 0x02;//TKIP - else if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) - sFrame.pRSNWPA->abyMulticast[3] = 0x01;//WEP40 - else - sFrame.pRSNWPA->abyMulticast[3] = 0x00;//NONE - - // Pairwise Key Cipher Suite - sFrame.pRSNWPA->wPKCount = 0; - // Auth Key Management Suite - *((unsigned short *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len)) = 0; - sFrame.pRSNWPA->len += 2; - - // RSN Capabilities - *((unsigned short *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len)) = 0; - sFrame.pRSNWPA->len += 2; - sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; - } - } - - if (pMgmt->b11hEnable && (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) { - // Country IE - pbyBuffer = (unsigned char *)(sFrame.pBuf + sFrame.len); - set_country_IE(pMgmt->pAdapter, pbyBuffer); - set_country_info(pMgmt->pAdapter, PHY_TYPE_11A, pbyBuffer); - uLength += ((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN; - pbyBuffer += (((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN); - // Power Constrain IE - ((PWLAN_IE_PW_CONST) pbyBuffer)->byElementID = WLAN_EID_PWR_CONSTRAINT; - ((PWLAN_IE_PW_CONST) pbyBuffer)->len = 1; - ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0; - pbyBuffer += (1) + WLAN_IEHDR_LEN; - uLength += (1) + WLAN_IEHDR_LEN; - if (pMgmt->bSwitchChannel) { - // Channel Switch IE - ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH; - ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3; - ((PWLAN_IE_CH_SW) pbyBuffer)->byMode = 1; - ((PWLAN_IE_CH_SW) pbyBuffer)->byChannel = get_channel_number(pMgmt->pAdapter, pMgmt->byNewChannel); - ((PWLAN_IE_CH_SW) pbyBuffer)->byCount = 0; - pbyBuffer += (3) + WLAN_IEHDR_LEN; - uLength += (3) + WLAN_IEHDR_LEN; - } - // TPC report - ((PWLAN_IE_TPC_REP) pbyBuffer)->byElementID = WLAN_EID_TPC_REP; - ((PWLAN_IE_TPC_REP) pbyBuffer)->len = 2; - ((PWLAN_IE_TPC_REP) pbyBuffer)->byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter); - ((PWLAN_IE_TPC_REP) pbyBuffer)->byLinkMargin = 0; - pbyBuffer += (2) + WLAN_IEHDR_LEN; - uLength += (2) + WLAN_IEHDR_LEN; - // IBSS DFS - if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) { - pIBSSDFS = (PWLAN_IE_IBSS_DFS) pbyBuffer; - pIBSSDFS->byElementID = WLAN_EID_IBSS_DFS; - pIBSSDFS->len = 7; - memcpy(pIBSSDFS->abyDFSOwner, - pMgmt->abyIBSSDFSOwner, - 6); - pIBSSDFS->byDFSRecovery = pMgmt->byIBSSDFSRecovery; - pbyBuffer += (7) + WLAN_IEHDR_LEN; - uLength += (7) + WLAN_IEHDR_LEN; - for (ii = CB_MAX_CHANNEL_24G+1; ii <= CB_MAX_CHANNEL; ii++) { - if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1)) { - pbyBuffer += 2; - uLength += 2; - pIBSSDFS->len += 2; - } - } - } - sFrame.len += uLength; - } - - if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) { - sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len); - sFrame.len += 1 + WLAN_IEHDR_LEN; - sFrame.pERP->byElementID = WLAN_EID_ERP; - sFrame.pERP->len = 1; - sFrame.pERP->byContext = 0; - if (pDevice->bProtectMode) - sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION; - if (pDevice->bNonERPPresent) - sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT; - if (pDevice->bBarkerPreambleMd) - sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE; - } - if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, - pCurrExtSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN -); - } - // hostapd wpa/wpa2 IE - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && pDevice->bEnableHostapd) { - if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - if (pMgmt->wWPAIELen != 0) { - sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len); - memcpy(sFrame.pRSN, pMgmt->abyWPAIE, pMgmt->wWPAIELen); - sFrame.len += pMgmt->wWPAIELen; - } - } - } - - /* Adjust the length fields */ - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - return pTxPacket; -} - -/*+ - * - * Routine Description: - * Constructs an Prob-response frame - * - * - * Return Value: - * PTR to frame; or NULL on allocation failure - * - -*/ - -static PSTxMgmtPacket -s_MgrMakeProbeResponse( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wCurrBeaconPeriod, - unsigned int uCurrChannel, - unsigned short wCurrATIMWinodw, - unsigned char *pDstAddr, - PWLAN_IE_SSID pCurrSSID, - unsigned char *pCurrBSSID, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates, - unsigned char byPHYType -) -{ - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_PROBERESP sFrame; - unsigned char *pbyBuffer; - unsigned int uLength = 0; - PWLAN_IE_IBSS_DFS pIBSSDFS = NULL; - unsigned int ii; - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBERESP_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - // Setup the sFrame structure. - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_PROBERESP_FR_MAXLEN; - vMgrEncodeProbeResponse(&sFrame); - // Setup the header - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBERESP) -)); - memcpy(sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN); - *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod); - *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo); - - if (byPHYType == BB_TYPE_11B) - *sFrame.pwCapInfo &= cpu_to_le16((unsigned short)~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1))); - - // Copy SSID - sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSSID, - pCurrSSID, - ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN -); - // Copy the rate set - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, - pCurrSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN -); - - // DS parameter - if (pDevice->eCurrentPHYType != PHY_TYPE_11A) { - sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len); - sFrame.len += (1) + WLAN_IEHDR_LEN; - sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS; - sFrame.pDSParms->len = 1; - sFrame.pDSParms->byCurrChannel = (unsigned char)uCurrChannel; - } - - if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) { - // IBSS parameter - sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len); - sFrame.len += (2) + WLAN_IEHDR_LEN; - sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS; - sFrame.pIBSSParms->len = 2; - sFrame.pIBSSParms->wATIMWindow = 0; - } - if (pDevice->eCurrentPHYType == PHY_TYPE_11G) { - sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len); - sFrame.len += 1 + WLAN_IEHDR_LEN; - sFrame.pERP->byElementID = WLAN_EID_ERP; - sFrame.pERP->len = 1; - sFrame.pERP->byContext = 0; - if (pDevice->bProtectMode) - sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION; - if (pDevice->bNonERPPresent) - sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT; - if (pDevice->bBarkerPreambleMd) - sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE; - } - - if (pMgmt->b11hEnable && (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) { - // Country IE - pbyBuffer = (unsigned char *)(sFrame.pBuf + sFrame.len); - set_country_IE(pMgmt->pAdapter, pbyBuffer); - set_country_info(pMgmt->pAdapter, PHY_TYPE_11A, pbyBuffer); - uLength += ((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN; - pbyBuffer += (((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN); - // Power Constrain IE - ((PWLAN_IE_PW_CONST) pbyBuffer)->byElementID = WLAN_EID_PWR_CONSTRAINT; - ((PWLAN_IE_PW_CONST) pbyBuffer)->len = 1; - ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0; - pbyBuffer += (1) + WLAN_IEHDR_LEN; - uLength += (1) + WLAN_IEHDR_LEN; - if (pMgmt->bSwitchChannel) { - // Channel Switch IE - ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH; - ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3; - ((PWLAN_IE_CH_SW) pbyBuffer)->byMode = 1; - ((PWLAN_IE_CH_SW) pbyBuffer)->byChannel = get_channel_number(pMgmt->pAdapter, pMgmt->byNewChannel); - ((PWLAN_IE_CH_SW) pbyBuffer)->byCount = 0; - pbyBuffer += (3) + WLAN_IEHDR_LEN; - uLength += (3) + WLAN_IEHDR_LEN; - } - // TPC report - ((PWLAN_IE_TPC_REP) pbyBuffer)->byElementID = WLAN_EID_TPC_REP; - ((PWLAN_IE_TPC_REP) pbyBuffer)->len = 2; - ((PWLAN_IE_TPC_REP) pbyBuffer)->byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter); - ((PWLAN_IE_TPC_REP) pbyBuffer)->byLinkMargin = 0; - pbyBuffer += (2) + WLAN_IEHDR_LEN; - uLength += (2) + WLAN_IEHDR_LEN; - // IBSS DFS - if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) { - pIBSSDFS = (PWLAN_IE_IBSS_DFS) pbyBuffer; - pIBSSDFS->byElementID = WLAN_EID_IBSS_DFS; - pIBSSDFS->len = 7; - memcpy(pIBSSDFS->abyDFSOwner, - pMgmt->abyIBSSDFSOwner, - 6); - pIBSSDFS->byDFSRecovery = pMgmt->byIBSSDFSRecovery; - pbyBuffer += (7) + WLAN_IEHDR_LEN; - uLength += (7) + WLAN_IEHDR_LEN; - for (ii = CB_MAX_CHANNEL_24G + 1; ii <= CB_MAX_CHANNEL; ii++) { - if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1)) { - pbyBuffer += 2; - uLength += 2; - pIBSSDFS->len += 2; - } - } - } - sFrame.len += uLength; - } - - if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, - pCurrExtSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN -); - } - - // hostapd wpa/wpa2 IE - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && pDevice->bEnableHostapd) { - if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - if (pMgmt->wWPAIELen != 0) { - sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len); - memcpy(sFrame.pRSN, pMgmt->abyWPAIE, pMgmt->wWPAIELen); - sFrame.len += pMgmt->wWPAIELen; - } - } - } - - // Adjust the length fields - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - return pTxPacket; -} - -/*+ - * - * Routine Description: - * Constructs an association request frame - * - * - * Return Value: - * A ptr to frame or NULL on allocation failure - * - -*/ - -static PSTxMgmtPacket -s_MgrMakeAssocRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned char *pDAddr, - unsigned short wCurrCapInfo, - unsigned short wListenInterval, - PWLAN_IE_SSID pCurrSSID, - PWLAN_IE_SUPP_RATES pCurrRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -) -{ - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_ASSOCREQ sFrame; - unsigned char *pbyIEs; - unsigned char *pbyRSN; - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - // Setup the sFrame structure. - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_ASSOCREQ_FR_MAXLEN; - // format fixed field frame structure - vMgrEncodeAssocRequest(&sFrame); - // Setup the header - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCREQ) -)); - memcpy(sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - // Set the capability and listen interval - *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo); - *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval); - - // sFrame.len point to end of fixed field - sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN); - - pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN; - pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); - pbyIEs = pMgmt->sAssocInfo.abyIEs; - memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN); - pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN; - - // Copy the rate set - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - if ((pDevice->eCurrentPHYType == PHY_TYPE_11B) && (pCurrRates->len > 4)) - sFrame.len += 4 + WLAN_IEHDR_LEN; - else - sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); - - // Copy the extension rate set - if ((pDevice->eCurrentPHYType == PHY_TYPE_11G) && (pCurrExtSuppRates->len > 0)) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN); - } - - pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN; - memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); - pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN; - - // for 802.11h - if (pMgmt->b11hEnable) { - if (sFrame.pCurrPowerCap == NULL) { - sFrame.pCurrPowerCap = (PWLAN_IE_PW_CAP)(sFrame.pBuf + sFrame.len); - sFrame.len += (2 + WLAN_IEHDR_LEN); - sFrame.pCurrPowerCap->byElementID = WLAN_EID_PWR_CAPABILITY; - sFrame.pCurrPowerCap->len = 2; - CARDvGetPowerCapability(pMgmt->pAdapter, - &(sFrame.pCurrPowerCap->byMinPower), - &(sFrame.pCurrPowerCap->byMaxPower) -); - } - if (sFrame.pCurrSuppCh == NULL) { - sFrame.pCurrSuppCh = (PWLAN_IE_SUPP_CH)(sFrame.pBuf + sFrame.len); - sFrame.len += set_support_channels(pMgmt->pAdapter, (unsigned char *)sFrame.pCurrSuppCh); - } - } - - if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) && - (pMgmt->pCurrBSS != NULL)) { - /* WPA IE */ - sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len); - sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA; - sFrame.pRSNWPA->len = 16; - sFrame.pRSNWPA->abyOUI[0] = 0x00; - sFrame.pRSNWPA->abyOUI[1] = 0x50; - sFrame.pRSNWPA->abyOUI[2] = 0xf2; - sFrame.pRSNWPA->abyOUI[3] = 0x01; - sFrame.pRSNWPA->wVersion = 1; - //Group Key Cipher Suite - sFrame.pRSNWPA->abyMulticast[0] = 0x00; - sFrame.pRSNWPA->abyMulticast[1] = 0x50; - sFrame.pRSNWPA->abyMulticast[2] = 0xf2; - if (pMgmt->byCSSGK == KEY_CTL_WEP) - sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType; - else if (pMgmt->byCSSGK == KEY_CTL_TKIP) - sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP; - else if (pMgmt->byCSSGK == KEY_CTL_CCMP) - sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP; - else - sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE; - - // Pairwise Key Cipher Suite - sFrame.pRSNWPA->wPKCount = 1; - sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00; - sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50; - sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2; - if (pMgmt->byCSSPK == KEY_CTL_TKIP) - sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP; - else if (pMgmt->byCSSPK == KEY_CTL_CCMP) - sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP; - else - sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE; - - // Auth Key Management Suite - pbyRSN = (unsigned char *)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len); - *pbyRSN++ = 0x01; - *pbyRSN++ = 0x00; - *pbyRSN++ = 0x00; - - *pbyRSN++ = 0x50; - *pbyRSN++ = 0xf2; - if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) - *pbyRSN++ = WPA_AUTH_PSK; - else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA) - *pbyRSN++ = WPA_AUTH_IEEE802_1X; - else - *pbyRSN++ = WPA_NONE; - - sFrame.pRSNWPA->len += 6; - - // RSN Capabilities - - *pbyRSN++ = 0x00; - *pbyRSN++ = 0x00; - sFrame.pRSNWPA->len += 2; - - sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; - // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION - pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; - memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN); - pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; - - } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) && - (pMgmt->pCurrBSS != NULL)) { - unsigned int ii; - unsigned short *pwPMKID; - - // WPA IE - sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len); - sFrame.pRSN->byElementID = WLAN_EID_RSN; - sFrame.pRSN->len = 6; //Version(2)+GK(4) - sFrame.pRSN->wVersion = 1; - //Group Key Cipher Suite - sFrame.pRSN->abyRSN[0] = 0x00; - sFrame.pRSN->abyRSN[1] = 0x0F; - sFrame.pRSN->abyRSN[2] = 0xAC; - if (pMgmt->byCSSGK == KEY_CTL_WEP) - sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK; - else if (pMgmt->byCSSGK == KEY_CTL_TKIP) - sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP; - else if (pMgmt->byCSSGK == KEY_CTL_CCMP) - sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP; - else - sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN; - - // Pairwise Key Cipher Suite - sFrame.pRSN->abyRSN[4] = 1; - sFrame.pRSN->abyRSN[5] = 0; - sFrame.pRSN->abyRSN[6] = 0x00; - sFrame.pRSN->abyRSN[7] = 0x0F; - sFrame.pRSN->abyRSN[8] = 0xAC; - if (pMgmt->byCSSPK == KEY_CTL_TKIP) - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP; - else if (pMgmt->byCSSPK == KEY_CTL_CCMP) - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP; - else if (pMgmt->byCSSPK == KEY_CTL_NONE) - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP; - else - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN; - - sFrame.pRSN->len += 6; - - // Auth Key Management Suite - sFrame.pRSN->abyRSN[10] = 1; - sFrame.pRSN->abyRSN[11] = 0; - sFrame.pRSN->abyRSN[12] = 0x00; - sFrame.pRSN->abyRSN[13] = 0x0F; - sFrame.pRSN->abyRSN[14] = 0xAC; - if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) - sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK; - else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) - sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X; - else - sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN; - - sFrame.pRSN->len += 6; - - // RSN Capabilities - if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist) { - memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2); - } else { - sFrame.pRSN->abyRSN[16] = 0; - sFrame.pRSN->abyRSN[17] = 0; - } - sFrame.pRSN->len += 2; - - if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && pDevice->bRoaming && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) { - // RSN PMKID - pbyRSN = &sFrame.pRSN->abyRSN[18]; - pwPMKID = (unsigned short *)pbyRSN; // Point to PMKID count - *pwPMKID = 0; // Initialize PMKID count - pbyRSN += 2; // Point to PMKID list - for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) { - if (!memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, ETH_ALEN)) { - (*pwPMKID)++; - memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16); - pbyRSN += 16; - } - } - if (*pwPMKID != 0) - sFrame.pRSN->len += (2 + (*pwPMKID)*16); - } - - sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN; - // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION - pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN; - memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN); - pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN; - } - - // Adjust the length fields - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - return pTxPacket; -} - -/*+ - * - * Routine Description: - * Constructs an re-association request frame - * - * - * Return Value: - * A ptr to frame or NULL on allocation failure - * - -*/ - -static PSTxMgmtPacket -s_MgrMakeReAssocRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned char *pDAddr, - unsigned short wCurrCapInfo, - unsigned short wListenInterval, - PWLAN_IE_SSID pCurrSSID, - PWLAN_IE_SUPP_RATES pCurrRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -) -{ - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_REASSOCREQ sFrame; - unsigned char *pbyIEs; - unsigned char *pbyRSN; - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_REASSOCREQ_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - /* Setup the sFrame structure. */ - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_REASSOCREQ_FR_MAXLEN; - - // format fixed field frame structure - vMgrEncodeReassocRequest(&sFrame); - - /* Setup the header */ - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCREQ) -)); - memcpy(sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - /* Set the capability and listen interval */ - *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo); - *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval); - - memcpy(sFrame.pAddrCurrAP, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - /* Copy the SSID */ - /* sFrame.len point to end of fixed field */ - sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN); - - pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN; - pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); - pbyIEs = pMgmt->sAssocInfo.abyIEs; - memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN); - pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN; - - /* Copy the rate set */ - /* sFrame.len point to end of SSID */ - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); - - // Copy the extension rate set - if ((pMgmt->eCurrentPHYMode == PHY_TYPE_11G) && (pCurrExtSuppRates->len > 0)) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN); - } - - pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN; - memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); - pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN; - - if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) && - (pMgmt->pCurrBSS != NULL)) { - /* WPA IE */ - sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len); - sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA; - sFrame.pRSNWPA->len = 16; - sFrame.pRSNWPA->abyOUI[0] = 0x00; - sFrame.pRSNWPA->abyOUI[1] = 0x50; - sFrame.pRSNWPA->abyOUI[2] = 0xf2; - sFrame.pRSNWPA->abyOUI[3] = 0x01; - sFrame.pRSNWPA->wVersion = 1; - //Group Key Cipher Suite - sFrame.pRSNWPA->abyMulticast[0] = 0x00; - sFrame.pRSNWPA->abyMulticast[1] = 0x50; - sFrame.pRSNWPA->abyMulticast[2] = 0xf2; - if (pMgmt->byCSSGK == KEY_CTL_WEP) - sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType; - else if (pMgmt->byCSSGK == KEY_CTL_TKIP) - sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP; - else if (pMgmt->byCSSGK == KEY_CTL_CCMP) - sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP; - else - sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE; - - // Pairwise Key Cipher Suite - sFrame.pRSNWPA->wPKCount = 1; - sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00; - sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50; - sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2; - if (pMgmt->byCSSPK == KEY_CTL_TKIP) - sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP; - else if (pMgmt->byCSSPK == KEY_CTL_CCMP) - sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP; - else - sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE; - - // Auth Key Management Suite - pbyRSN = (unsigned char *)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len); - *pbyRSN++ = 0x01; - *pbyRSN++ = 0x00; - *pbyRSN++ = 0x00; - - *pbyRSN++ = 0x50; - *pbyRSN++ = 0xf2; - if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) - *pbyRSN++ = WPA_AUTH_PSK; - else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA) - *pbyRSN++ = WPA_AUTH_IEEE802_1X; - else - *pbyRSN++ = WPA_NONE; - - sFrame.pRSNWPA->len += 6; - - // RSN Capabilities - *pbyRSN++ = 0x00; - *pbyRSN++ = 0x00; - sFrame.pRSNWPA->len += 2; - - sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; - // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION - pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; - memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN); - pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; - - } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) && - (pMgmt->pCurrBSS != NULL)) { - unsigned int ii; - unsigned short *pwPMKID; - - /* WPA IE */ - sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len); - sFrame.pRSN->byElementID = WLAN_EID_RSN; - sFrame.pRSN->len = 6; //Version(2)+GK(4) - sFrame.pRSN->wVersion = 1; - //Group Key Cipher Suite - sFrame.pRSN->abyRSN[0] = 0x00; - sFrame.pRSN->abyRSN[1] = 0x0F; - sFrame.pRSN->abyRSN[2] = 0xAC; - if (pMgmt->byCSSGK == KEY_CTL_WEP) - sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK; - else if (pMgmt->byCSSGK == KEY_CTL_TKIP) - sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP; - else if (pMgmt->byCSSGK == KEY_CTL_CCMP) - sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP; - else - sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN; - - // Pairwise Key Cipher Suite - sFrame.pRSN->abyRSN[4] = 1; - sFrame.pRSN->abyRSN[5] = 0; - sFrame.pRSN->abyRSN[6] = 0x00; - sFrame.pRSN->abyRSN[7] = 0x0F; - sFrame.pRSN->abyRSN[8] = 0xAC; - if (pMgmt->byCSSPK == KEY_CTL_TKIP) - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP; - else if (pMgmt->byCSSPK == KEY_CTL_CCMP) - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP; - else if (pMgmt->byCSSPK == KEY_CTL_NONE) - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP; - else - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN; - - sFrame.pRSN->len += 6; - - // Auth Key Management Suite - sFrame.pRSN->abyRSN[10] = 1; - sFrame.pRSN->abyRSN[11] = 0; - sFrame.pRSN->abyRSN[12] = 0x00; - sFrame.pRSN->abyRSN[13] = 0x0F; - sFrame.pRSN->abyRSN[14] = 0xAC; - if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) - sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK; - else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) - sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X; - else - sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN; - - sFrame.pRSN->len += 6; - - // RSN Capabilities - if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist) { - memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2); - } else { - sFrame.pRSN->abyRSN[16] = 0; - sFrame.pRSN->abyRSN[17] = 0; - } - sFrame.pRSN->len += 2; - - if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && pDevice->bRoaming && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) { - // RSN PMKID - pbyRSN = &sFrame.pRSN->abyRSN[18]; - pwPMKID = (unsigned short *)pbyRSN; // Point to PMKID count - *pwPMKID = 0; // Initialize PMKID count - pbyRSN += 2; // Point to PMKID list - for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) { - if (!memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, ETH_ALEN)) { - (*pwPMKID)++; - memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16); - pbyRSN += 16; - } - } - - if (*pwPMKID != 0) - sFrame.pRSN->len += (2 + (*pwPMKID) * 16); - } - - sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN; - // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION - pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN; - memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN); - pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN; - } - - /* Adjust the length fields */ - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - return pTxPacket; -} - -/*+ - * - * Routine Description: - * Constructs an assoc-response frame - * - * - * Return Value: - * PTR to frame; or NULL on allocation failure - * - -*/ - -static PSTxMgmtPacket -s_MgrMakeAssocResponse( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wAssocStatus, - unsigned short wAssocAID, - unsigned char *pDstAddr, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -) -{ - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_ASSOCRESP sFrame; - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - // Setup the sFrame structure - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN; - vMgrEncodeAssocResponse(&sFrame); - // Setup the header - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCRESP) -)); - memcpy(sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo); - *sFrame.pwStatus = cpu_to_le16(wAssocStatus); - *sFrame.pwAid = cpu_to_le16((unsigned short)(wAssocAID | BIT14 | BIT15)); - - // Copy the rate set - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, - pCurrSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN -); - - if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, - pCurrExtSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN -); - } - - // Adjust the length fields - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - return pTxPacket; -} - -/*+ - * - * Routine Description: - * Constructs an reassoc-response frame - * - * - * Return Value: - * PTR to frame; or NULL on allocation failure - * - -*/ - -static PSTxMgmtPacket -s_MgrMakeReAssocResponse( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wAssocStatus, - unsigned short wAssocAID, - unsigned char *pDstAddr, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -) -{ - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_REASSOCRESP sFrame; - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - // Setup the sFrame structure - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN; - vMgrEncodeReassocResponse(&sFrame); - // Setup the header - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCRESP) -)); - memcpy(sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo); - *sFrame.pwStatus = cpu_to_le16(wAssocStatus); - *sFrame.pwAid = cpu_to_le16((unsigned short)(wAssocAID | BIT14 | BIT15)); - - // Copy the rate set - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, - pCurrSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN -); - - if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, - pCurrExtSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN -); - } - - // Adjust the length fields - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - return pTxPacket; -} - -/*+ - * - * Routine Description: - * Handles probe response management frames. - * - * - * Return Value: - * none. - * - -*/ - -static -void -s_vMgrRxProbeResponse( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -) -{ - PKnownBSS pBSSList = NULL; - WLAN_FR_PROBERESP sFrame; - unsigned char byCurrChannel = pRxPacket->byRxChannel; - ERPObject sERP; - unsigned char byIEChannel = 0; - bool bChannelHit = true; - - memset(&sFrame, 0, sizeof(WLAN_FR_PROBERESP)); - // decode the frame - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - vMgrDecodeProbeResponse(&sFrame); - - if ((sFrame.pqwTimestamp == NULL) || - (sFrame.pwBeaconInterval == NULL) || - (sFrame.pwCapInfo == NULL) || - (sFrame.pSSID == NULL) || - (sFrame.pSuppRates == NULL)) { - pr_debug("Probe resp:Fail addr:[%p]\n", - pRxPacket->p80211Header); - DBG_PORT80(0xCC); - return; - } - - if (sFrame.pSSID->len == 0) - pr_debug("Rx Probe resp: SSID len = 0\n"); - - if (sFrame.pDSParms != NULL) { - if (byCurrChannel > CB_MAX_CHANNEL_24G) { - // channel remapping to - byIEChannel = get_channel_mapping(pMgmt->pAdapter, sFrame.pDSParms->byCurrChannel, PHY_TYPE_11A); - } else { - byIEChannel = sFrame.pDSParms->byCurrChannel; - } - if (byCurrChannel != byIEChannel) { - // adjust channel info. bcs we rcv adjacent channel packets - bChannelHit = false; - byCurrChannel = byIEChannel; - } - } else { - // no DS channel info - bChannelHit = true; - } - -//2008-0730-01<Add>by MikeLiu - if (ChannelExceedZoneType(pDevice, byCurrChannel)) - return; - - if (sFrame.pERP != NULL) { - sERP.byERP = sFrame.pERP->byContext; - sERP.bERPExist = true; - } else { - sERP.bERPExist = false; - sERP.byERP = 0; - } - - // update or insert the bss - pBSSList = BSSpAddrIsInBSSList((void *)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID); - if (pBSSList) { - BSSbUpdateToBSSList((void *)pDevice, - *sFrame.pqwTimestamp, - *sFrame.pwBeaconInterval, - *sFrame.pwCapInfo, - byCurrChannel, - bChannelHit, - sFrame.pSSID, - sFrame.pSuppRates, - sFrame.pExtSuppRates, - &sERP, - sFrame.pRSN, - sFrame.pRSNWPA, - sFrame.pIE_Country, - sFrame.pIE_Quiet, - pBSSList, - sFrame.len - WLAN_HDR_ADDR3_LEN, - sFrame.pHdr->sA4.abyAddr4, // payload of probresponse - (void *)pRxPacket -); - } else { - pr_debug("Probe resp/insert: RxChannel = : %d\n", - byCurrChannel); - BSSbInsertToBSSList((void *)pDevice, - sFrame.pHdr->sA3.abyAddr3, - *sFrame.pqwTimestamp, - *sFrame.pwBeaconInterval, - *sFrame.pwCapInfo, - byCurrChannel, - sFrame.pSSID, - sFrame.pSuppRates, - sFrame.pExtSuppRates, - &sERP, - sFrame.pRSN, - sFrame.pRSNWPA, - sFrame.pIE_Country, - sFrame.pIE_Quiet, - sFrame.len - WLAN_HDR_ADDR3_LEN, - sFrame.pHdr->sA4.abyAddr4, // payload of beacon - (void *)pRxPacket -); - } -} - -/*+ - * - * Routine Description:(AP)or(Ad-hoc STA) - * Handles probe request management frames. - * - * - * Return Value: - * none. - * - -*/ - -static -void -s_vMgrRxProbeRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -) -{ - WLAN_FR_PROBEREQ sFrame; - CMD_STATUS Status; - PSTxMgmtPacket pTxPacket; - unsigned char byPHYType = BB_TYPE_11B; - - // STA in Ad-hoc mode: when latest TBTT beacon transmit success, - // STA have to response this request. - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || - ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && pDevice->bBeaconSent)) { - memset(&sFrame, 0, sizeof(WLAN_FR_PROBEREQ)); - // decode the frame - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - vMgrDecodeProbeRequest(&sFrame); - - if (sFrame.pSSID->len != 0) { - if (sFrame.pSSID->len != ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) - return; - if (memcmp(sFrame.pSSID->abySSID, - ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, - ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) != 0) { - return; - } - } - - if ((sFrame.pSuppRates->len > 4) || (sFrame.pExtSuppRates != NULL)) - byPHYType = BB_TYPE_11G; - - // Probe response reply.. - pTxPacket = s_MgrMakeProbeResponse - ( - pDevice, - pMgmt, - pMgmt->wCurrCapInfo, - pMgmt->wCurrBeaconPeriod, - pMgmt->uCurrChannel, - 0, - sFrame.pHdr->sA3.abyAddr2, - (PWLAN_IE_SSID)pMgmt->abyCurrSSID, - (unsigned char *)pMgmt->abyCurrBSSID, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, - byPHYType -); - if (pTxPacket != NULL) { - /* send the frame */ - Status = csMgmt_xmit(pDevice, pTxPacket); - if (Status != CMD_STATUS_PENDING) - pr_debug("Mgt:Probe response tx failed\n"); - } - } -} - -/*+ - * - * Routine Description: - * - * Entry point for the reception and handling of 802.11 management - * frames. Makes a determination of the frame type and then calls - * the appropriate function. - * - * - * Return Value: - * none. - * - -*/ - -void -vMgrRxManagePacket( - void *hDeviceContext, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -) -{ - struct vnt_private *pDevice = hDeviceContext; - bool bInScan = false; - unsigned int uNodeIndex = 0; - NODE_STATE eNodeState = 0; - CMD_STATUS Status; - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) - eNodeState = pMgmt->sNodeDBTable[uNodeIndex].eNodeState; - } - - switch (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl))) { - case WLAN_FSTYPE_ASSOCREQ: - // Frame Clase = 2 - pr_debug("rx assocreq\n"); - if (eNodeState < NODE_AUTH) { - // send deauth notification - // reason = (6) class 2 received from nonauth sta - vMgrDeAuthenBeginSta(pDevice, - pMgmt, - pRxPacket->p80211Header->sA3.abyAddr2, - (6), - &Status -); - pr_debug("wmgr: send vMgrDeAuthenBeginSta 1\n"); - } else { - s_vMgrRxAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex); - } - break; - - case WLAN_FSTYPE_ASSOCRESP: - // Frame Clase = 2 - pr_debug("rx assocresp1\n"); - s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, false); - pr_debug("rx assocresp2\n"); - break; - - case WLAN_FSTYPE_REASSOCREQ: - // Frame Clase = 2 - pr_debug("rx reassocreq\n"); - // Todo: reassoc - if (eNodeState < NODE_AUTH) { - // send deauth notification - // reason = (6) class 2 received from nonauth sta - vMgrDeAuthenBeginSta(pDevice, - pMgmt, - pRxPacket->p80211Header->sA3.abyAddr2, - (6), - &Status -); - pr_debug("wmgr: send vMgrDeAuthenBeginSta 2\n"); - - } - s_vMgrRxReAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex); - break; - - case WLAN_FSTYPE_REASSOCRESP: - // Frame Clase = 2 - pr_debug("rx reassocresp\n"); - s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, true); - break; - - case WLAN_FSTYPE_PROBEREQ: - // Frame Clase = 0 - s_vMgrRxProbeRequest(pDevice, pMgmt, pRxPacket); - break; - - case WLAN_FSTYPE_PROBERESP: - // Frame Clase = 0 - pr_debug("rx proberesp\n"); - - s_vMgrRxProbeResponse(pDevice, pMgmt, pRxPacket); - break; - - case WLAN_FSTYPE_BEACON: - // Frame Clase = 0 - if (pMgmt->eScanState != WMAC_NO_SCANNING) - bInScan = true; - - s_vMgrRxBeacon(pDevice, pMgmt, pRxPacket, bInScan); - break; - - case WLAN_FSTYPE_ATIM: - // Frame Clase = 1 - pr_debug("rx atim\n"); - break; - - case WLAN_FSTYPE_DISASSOC: - // Frame Clase = 2 - pr_debug("rx disassoc\n"); - if (eNodeState < NODE_AUTH) { - // send deauth notification - // reason = (6) class 2 received from nonauth sta - vMgrDeAuthenBeginSta(pDevice, - pMgmt, - pRxPacket->p80211Header->sA3.abyAddr2, - (6), - &Status -); - pr_debug("wmgr: send vMgrDeAuthenBeginSta 3\n"); - } - s_vMgrRxDisassociation(pDevice, pMgmt, pRxPacket); - break; - - case WLAN_FSTYPE_AUTHEN: - // Frame Clase = 1 - pr_debug("rx authen\n"); - s_vMgrRxAuthentication(pDevice, pMgmt, pRxPacket); - break; - - case WLAN_FSTYPE_DEAUTHEN: - // Frame Clase = 1 - pr_debug("rx deauthen\n"); - s_vMgrRxDeauthentication(pDevice, pMgmt, pRxPacket); - break; - - default: - pr_debug("rx unknown mgmt\n"); - } -} - -/*+ - * - * Routine Description: - * - * - * Prepare beacon to send - * - * Return Value: - * true if success; false if failed. - * - -*/ -bool -bMgrPrepareBeaconToSend( - void *hDeviceContext, - PSMgmtObject pMgmt -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSTxMgmtPacket pTxPacket; - - if (pDevice->bEncryptionEnable || pDevice->bEnable8021x) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1); - else - pMgmt->wCurrCapInfo &= ~WLAN_SET_CAP_INFO_PRIVACY(1); - - pTxPacket = s_MgrMakeBeacon - ( - pDevice, - pMgmt, - pMgmt->wCurrCapInfo, - pMgmt->wCurrBeaconPeriod, - pMgmt->uCurrChannel, - pMgmt->wCurrATIMWindow, - (PWLAN_IE_SSID)pMgmt->abyCurrSSID, - (unsigned char *)pMgmt->abyCurrBSSID, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates -); - - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && - (pMgmt->abyCurrBSSID[0] == 0)) - return false; - - csBeacon_xmit(pDevice, pTxPacket); - - return true; -} - -/*+ - * - * Routine Description: - * - * Log a warning message based on the contents of the Status - * Code field of an 802.11 management frame. Defines are - * derived from 802.11-1997 SPEC. - * - * Return Value: - * none. - * - -*/ -static -void -s_vMgrLogStatus( - PSMgmtObject pMgmt, - unsigned short wStatus -) -{ - switch (wStatus) { - case WLAN_MGMT_STATUS_UNSPEC_FAILURE: - pr_info("Status code == Unspecified error\n"); - break; - case WLAN_MGMT_STATUS_CAPS_UNSUPPORTED: - pr_info("Status code == Can't support all requested capabilities\n"); - break; - case WLAN_MGMT_STATUS_REASSOC_NO_ASSOC: - pr_info("Status code == Reassoc denied, can't confirm original Association\n"); - break; - case WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC: - pr_info("Status code == Assoc denied, undefine in spec\n"); - break; - case WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG: - pr_info("Status code == Peer doesn't support authen algorithm\n"); - break; - case WLAN_MGMT_STATUS_RX_AUTH_NOSEQ: - pr_info("Status code == Authen frame received out of sequence\n"); - break; - case WLAN_MGMT_STATUS_CHALLENGE_FAIL: - pr_info("Status code == Authen rejected, challenge failure\n"); - break; - case WLAN_MGMT_STATUS_AUTH_TIMEOUT: - pr_info("Status code == Authen rejected, timeout waiting for next frame\n"); - break; - case WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY: - pr_info("Status code == Assoc denied, AP too busy\n"); - break; - case WLAN_MGMT_STATUS_ASSOC_DENIED_RATES: - pr_info("Status code == Assoc denied, we haven't enough basic rates\n"); - break; - case WLAN_MGMT_STATUS_ASSOC_DENIED_SHORTPREAMBLE: - pr_info("Status code == Assoc denied, we do not support short preamble\n"); - break; - case WLAN_MGMT_STATUS_ASSOC_DENIED_PBCC: - pr_info("Status code == Assoc denied, we do not support PBCC\n"); - break; - case WLAN_MGMT_STATUS_ASSOC_DENIED_AGILITY: - pr_info("Status code == Assoc denied, we do not support channel agility\n"); - break; - default: - pr_info("Unknown status code %d\n", wStatus); - break; - } -} - -/* - * - * Description: - * Add BSSID in PMKID Candidate list. - * - * Parameters: - * In: - * hDeviceContext - device structure point - * pbyBSSID - BSSID address for adding - * wRSNCap - BSS's RSN capability - * Out: - * none - * - * Return Value: none. - * - -*/ -bool -bAdd_PMKID_Candidate( - void *hDeviceContext, - unsigned char *pbyBSSID, - PSRSNCapObject psRSNCapObj -) -{ - struct vnt_private *pDevice = hDeviceContext; - struct pmkid_candidate *pCandidateList; - unsigned int ii = 0; - - pr_debug("bAdd_PMKID_Candidate START: (%d)\n", - (int)pDevice->gsPMKIDCandidate.NumCandidates); - - if ((pDevice == NULL) || (pbyBSSID == NULL) || (psRSNCapObj == NULL)) - return false; - - if (pDevice->gsPMKIDCandidate.NumCandidates >= MAX_PMKIDLIST) - return false; - - // Update Old Candidate - for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) { - pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii]; - if (!memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) { - if (psRSNCapObj->bRSNCapExist && (psRSNCapObj->wRSNCap & BIT0)) - pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; - else - pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); - - return true; - } - } - - // New Candidate - pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates]; - if (psRSNCapObj->bRSNCapExist && (psRSNCapObj->wRSNCap & BIT0)) - pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; - else - pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); - - memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN); - pDevice->gsPMKIDCandidate.NumCandidates++; - pr_debug("NumCandidates:%d\n", - (int)pDevice->gsPMKIDCandidate.NumCandidates); - return true; -} - -/* - * - * Description: - * Flush PMKID Candidate list. - * - * Parameters: - * In: - * hDeviceContext - device structure point - * Out: - * none - * - * Return Value: none. - * - -*/ -void -vFlush_PMKID_Candidate( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - - if (pDevice == NULL) - return; - - memset(&pDevice->gsPMKIDCandidate, 0, sizeof(SPMKIDCandidateEvent)); -} - -static bool -s_bCipherMatch( - PKnownBSS pBSSNode, - NDIS_802_11_ENCRYPTION_STATUS EncStatus, - unsigned char *pbyCCSPK, - unsigned char *pbyCCSGK -) -{ - unsigned char byMulticastCipher = KEY_CTL_INVALID; - unsigned char byCipherMask = 0x00; - int i; - - if (pBSSNode == NULL) - return false; - - // check cap. of BSS - if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) && - (EncStatus == Ndis802_11Encryption1Enabled)) { - // default is WEP only - byMulticastCipher = KEY_CTL_WEP; - } - - if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) && - pBSSNode->bWPA2Valid && - //20080123-01,<Add> by Einsn Liu - ((EncStatus == Ndis802_11Encryption3Enabled) || (EncStatus == Ndis802_11Encryption2Enabled))) { - //WPA2 - // check Group Key Cipher - if ((pBSSNode->byCSSGK == WLAN_11i_CSS_WEP40) || - (pBSSNode->byCSSGK == WLAN_11i_CSS_WEP104)) { - byMulticastCipher = KEY_CTL_WEP; - } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_TKIP) { - byMulticastCipher = KEY_CTL_TKIP; - } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_CCMP) { - byMulticastCipher = KEY_CTL_CCMP; - } else { - byMulticastCipher = KEY_CTL_INVALID; - } - - // check Pairwise Key Cipher - for (i = 0; i < pBSSNode->wCSSPKCount; i++) { - if ((pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP40) || - (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP104)) { - // this should not happen as defined 802.11i - byCipherMask |= 0x01; - } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_TKIP) { - byCipherMask |= 0x02; - } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_CCMP) { - byCipherMask |= 0x04; - } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_USE_GROUP) { - // use group key only ignore all others - byCipherMask = 0; - i = pBSSNode->wCSSPKCount; - } - } - - } else if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) && - pBSSNode->bWPAValid && - ((EncStatus == Ndis802_11Encryption3Enabled) || (EncStatus == Ndis802_11Encryption2Enabled))) { - //WPA - // check Group Key Cipher - if ((pBSSNode->byGKType == WPA_WEP40) || - (pBSSNode->byGKType == WPA_WEP104)) { - byMulticastCipher = KEY_CTL_WEP; - } else if (pBSSNode->byGKType == WPA_TKIP) { - byMulticastCipher = KEY_CTL_TKIP; - } else if (pBSSNode->byGKType == WPA_AESCCMP) { - byMulticastCipher = KEY_CTL_CCMP; - } else { - byMulticastCipher = KEY_CTL_INVALID; - } - - // check Pairwise Key Cipher - for (i = 0; i < pBSSNode->wPKCount; i++) { - if (pBSSNode->abyPKType[i] == WPA_TKIP) { - byCipherMask |= 0x02; - } else if (pBSSNode->abyPKType[i] == WPA_AESCCMP) { - byCipherMask |= 0x04; - } else if (pBSSNode->abyPKType[i] == WPA_NONE) { - // use group key only ignore all others - byCipherMask = 0; - i = pBSSNode->wPKCount; - } - } - } - - pr_debug("%d, %d, %d, %d, EncStatus:%d\n", - byMulticastCipher, byCipherMask, - pBSSNode->bWPAValid, pBSSNode->bWPA2Valid, EncStatus); - - // mask our cap. with BSS - if (EncStatus == Ndis802_11Encryption1Enabled) { - // For supporting Cisco migration mode, don't care pairwise key cipher - if ((byMulticastCipher == KEY_CTL_WEP) && - (byCipherMask == 0)) { - *pbyCCSGK = KEY_CTL_WEP; - *pbyCCSPK = KEY_CTL_NONE; - return true; - } else { - return false; - } - - } else if (EncStatus == Ndis802_11Encryption2Enabled) { - if ((byMulticastCipher == KEY_CTL_TKIP) && - (byCipherMask == 0)) { - *pbyCCSGK = KEY_CTL_TKIP; - *pbyCCSPK = KEY_CTL_NONE; - return true; - } else if ((byMulticastCipher == KEY_CTL_WEP) && - ((byCipherMask & 0x02) != 0)) { - *pbyCCSGK = KEY_CTL_WEP; - *pbyCCSPK = KEY_CTL_TKIP; - return true; - } else if ((byMulticastCipher == KEY_CTL_TKIP) && - ((byCipherMask & 0x02) != 0)) { - *pbyCCSGK = KEY_CTL_TKIP; - *pbyCCSPK = KEY_CTL_TKIP; - return true; - } else { - return false; - } - } else if (EncStatus == Ndis802_11Encryption3Enabled) { - if ((byMulticastCipher == KEY_CTL_CCMP) && - (byCipherMask == 0)) { - // When CCMP is enable, "Use group cipher suite" shall not be a valid option. - return false; - } else if ((byMulticastCipher == KEY_CTL_WEP) && - ((byCipherMask & 0x04) != 0)) { - *pbyCCSGK = KEY_CTL_WEP; - *pbyCCSPK = KEY_CTL_CCMP; - return true; - } else if ((byMulticastCipher == KEY_CTL_TKIP) && - ((byCipherMask & 0x04) != 0)) { - *pbyCCSGK = KEY_CTL_TKIP; - *pbyCCSPK = KEY_CTL_CCMP; - return true; - } else if ((byMulticastCipher == KEY_CTL_CCMP) && - ((byCipherMask & 0x04) != 0)) { - *pbyCCSGK = KEY_CTL_CCMP; - *pbyCCSPK = KEY_CTL_CCMP; - return true; - } else { - return false; - } - } - return true; -} diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h deleted file mode 100644 index ce939b30ac2a..000000000000 --- a/drivers/staging/vt6655/wmgr.h +++ /dev/null @@ -1,420 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: wmgr.h - * - * Purpose: - * - * Author: lyndon chen - * - * Date: Jan 2, 2003 - * - * Functions: - * - * Revision History: - * - */ - -#ifndef __WMGR_H__ -#define __WMGR_H__ - -#include "ttype.h" -#include "80211mgr.h" -#include "80211hdr.h" -#include "wcmd.h" -#include "bssdb.h" -#include "wpa2.h" -#include "vntwifi.h" -#include "card.h" - -/*--------------------- Export Definitions -------------------------*/ - -// Scan time -#define PROBE_DELAY 100 // (us) -#define SWITCH_CHANNEL_DELAY 200 // (us) -#define WLAN_SCAN_MINITIME 25 // (ms) -#define WLAN_SCAN_MAXTIME 100 // (ms) -#define TRIVIAL_SYNC_DIFFERENCE 0 // (us) -#define DEFAULT_IBSS_BI 100 // (ms) - -#define WCMD_ACTIVE_SCAN_TIME 50 //(ms) -#define WCMD_PASSIVE_SCAN_TIME 100 //(ms) - -#define DEFAULT_MSDU_LIFETIME 512 // ms -#define DEFAULT_MSDU_LIFETIME_RES_64us 8000 // 64us - -#define DEFAULT_MGN_LIFETIME 8 // ms -#define DEFAULT_MGN_LIFETIME_RES_64us 125 // 64us - -#define MAKE_BEACON_RESERVED 10 //(us) - -#define TIM_MULTICAST_MASK 0x01 -#define TIM_BITMAPOFFSET_MASK 0xFE -#define DEFAULT_DTIM_PERIOD 1 - -#define AP_LONG_RETRY_LIMIT 4 - -#define DEFAULT_IBSS_CHANNEL 6 //2.4G - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Types ------------------------------*/ -#define timer_expire(timer, next_tick) mod_timer(&timer, RUN_AT(next_tick)) -typedef void (*TimerFunction)(unsigned long); - -//+++ NDIS related - -typedef unsigned char NDIS_802_11_MAC_ADDRESS[6]; -typedef struct _NDIS_802_11_AI_REQFI { - unsigned short Capabilities; - unsigned short ListenInterval; - NDIS_802_11_MAC_ADDRESS CurrentAPAddress; -} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI; - -typedef struct _NDIS_802_11_AI_RESFI { - unsigned short Capabilities; - unsigned short StatusCode; - unsigned short AssociationId; -} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI; - -typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION { - unsigned long Length; - unsigned short AvailableRequestFixedIEs; - NDIS_802_11_AI_REQFI RequestFixedIEs; - unsigned long RequestIELength; - unsigned long OffsetRequestIEs; - unsigned short AvailableResponseFixedIEs; - NDIS_802_11_AI_RESFI ResponseFixedIEs; - unsigned long ResponseIELength; - unsigned long OffsetResponseIEs; -} NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION; - -typedef struct tagSAssocInfo { - NDIS_802_11_ASSOCIATION_INFORMATION AssocInfo; - unsigned char abyIEs[WLAN_BEACON_FR_MAXLEN+WLAN_BEACON_FR_MAXLEN]; - // store ReqIEs set by OID_802_11_ASSOCIATION_INFORMATION - unsigned long RequestIELength; - unsigned char abyReqIEs[WLAN_BEACON_FR_MAXLEN]; -} SAssocInfo, *PSAssocInfo; -//--- - -typedef enum tagWMAC_SCAN_TYPE { - WMAC_SCAN_ACTIVE, - WMAC_SCAN_PASSIVE, - WMAC_SCAN_HYBRID -} WMAC_SCAN_TYPE, *PWMAC_SCAN_TYPE; - -typedef enum tagWMAC_SCAN_STATE { - WMAC_NO_SCANNING, - WMAC_IS_SCANNING, - WMAC_IS_PROBEPENDING -} WMAC_SCAN_STATE, *PWMAC_SCAN_STATE; - -// Notes: -// Basic Service Set state explained as following: -// WMAC_STATE_IDLE : no BSS is selected (Adhoc or Infra) -// WMAC_STATE_STARTED : no BSS is selected, start own IBSS (Adhoc only) -// WMAC_STATE_JOINTED : BSS is selected and synchronized (Adhoc or Infra) -// WMAC_STATE_AUTHPENDING : Authentication pending (Infra) -// WMAC_STATE_AUTH : Authenticated (Infra) -// WMAC_STATE_ASSOCPENDING : Association pending (Infra) -// WMAC_STATE_ASSOC : Associated (Infra) - -typedef enum tagWMAC_BSS_STATE { - WMAC_STATE_IDLE, - WMAC_STATE_STARTED, - WMAC_STATE_JOINTED, - WMAC_STATE_AUTHPENDING, - WMAC_STATE_AUTH, - WMAC_STATE_ASSOCPENDING, - WMAC_STATE_ASSOC -} WMAC_BSS_STATE, *PWMAC_BSS_STATE; - -// WMAC selected running mode -typedef enum tagWMAC_CURRENT_MODE { - WMAC_MODE_STANDBY, - WMAC_MODE_ESS_STA, - WMAC_MODE_IBSS_STA, - WMAC_MODE_ESS_AP -} WMAC_CURRENT_MODE, *PWMAC_CURRENT_MODE; - -/* - typedef enum tagWMAC_POWER_MODE { - WMAC_POWER_CAM, - WMAC_POWER_FAST, - WMAC_POWER_MAX - - } WMAC_POWER_MODE, *PWMAC_POWER_MODE; -*/ - -// Tx Management Packet descriptor -typedef struct tagSTxMgmtPacket { - PUWLAN_80211HDR p80211Header; - unsigned int cbMPDULen; - unsigned int cbPayloadLen; -} STxMgmtPacket, *PSTxMgmtPacket; - -// Rx Management Packet descriptor -typedef struct tagSRxMgmtPacket { - PUWLAN_80211HDR p80211Header; - u64 qwLocalTSF; - unsigned int cbMPDULen; - unsigned int cbPayloadLen; - unsigned int uRSSI; - unsigned char bySQ; - unsigned char byRxRate; - unsigned char byRxChannel; -} SRxMgmtPacket, *PSRxMgmtPacket; - -typedef struct tagSMgmtObject { - void *pAdapter; - // MAC address - unsigned char abyMACAddr[WLAN_ADDR_LEN]; - - // Configuration Mode - WMAC_CONFIG_MODE eConfigMode; // MAC pre-configed mode - CARD_PHY_TYPE eCurrentPHYMode; - CARD_PHY_TYPE eConfigPHYMode; - - // Operation state variables - WMAC_CURRENT_MODE eCurrMode; // MAC current connection mode - WMAC_BSS_STATE eCurrState; // MAC current BSS state - - PKnownBSS pCurrBSS; - unsigned char byCSSGK; - unsigned char byCSSPK; - - // Current state vars - unsigned int uCurrChannel; - unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - unsigned char abyCurrSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - unsigned char abyCurrBSSID[WLAN_BSSID_LEN]; - unsigned short wCurrCapInfo; - unsigned short wCurrAID; - unsigned short wCurrATIMWindow; - unsigned short wCurrBeaconPeriod; - bool bIsDS; - unsigned char byERPContext; - - CMD_STATE eCommandState; - unsigned int uScanChannel; - - // Desire joining BSS vars - unsigned char abyDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - unsigned char abyDesireBSSID[WLAN_BSSID_LEN]; - - // Adhoc or AP configuration vars - unsigned short wIBSSBeaconPeriod; - unsigned short wIBSSATIMWindow; - unsigned int uIBSSChannel; - unsigned char abyIBSSSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - unsigned char byAPBBType; - unsigned char abyWPAIE[MAX_WPA_IE_LEN]; - unsigned short wWPAIELen; - - unsigned int uAssocCount; - bool bMoreData; - - // Scan state vars - WMAC_SCAN_STATE eScanState; - WMAC_SCAN_TYPE eScanType; - unsigned int uScanStartCh; - unsigned int uScanEndCh; - unsigned short wScanSteps; - unsigned int uScanBSSType; - // Desire scanning vars - unsigned char abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - unsigned char abyScanBSSID[WLAN_BSSID_LEN]; - - // Privacy - WMAC_AUTHENTICATION_MODE eAuthenMode; - WMAC_ENCRYPTION_MODE eEncryptionMode; - bool bShareKeyAlgorithm; - unsigned char abyChallenge[WLAN_CHALLENGE_LEN]; - bool bPrivacyInvoked; - - // Received beacon state vars - bool bInTIM; - bool bMulticastTIM; - unsigned char byDTIMCount; - unsigned char byDTIMPeriod; - - // Power saving state vars - WMAC_POWER_MODE ePSMode; - unsigned short wListenInterval; - unsigned short wCountToWakeUp; - bool bInTIMWake; - unsigned char *pbyPSPacketPool; - unsigned char byPSPacketPool[sizeof(STxMgmtPacket) + WLAN_NULLDATA_FR_MAXLEN]; - bool bRxBeaconInTBTTWake; - unsigned char abyPSTxMap[MAX_NODE_NUM + 1]; - - // management command related - unsigned int uCmdBusy; - unsigned int uCmdHostAPBusy; - - // management packet pool - unsigned char *pbyMgmtPacketPool; - unsigned char byMgmtPacketPool[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN]; - - // One second callback timer - struct timer_list sTimerSecondCallback; - - // Temporarily Rx Mgmt Packet Descriptor - SRxMgmtPacket sRxPacket; - - // link list of known bss's (scan results) - KnownBSS sBSSList[MAX_BSS_NUM]; - - // table list of known node - // sNodeDBList[0] is reserved for AP under Infra mode - // sNodeDBList[0] is reserved for Multicast under adhoc/AP mode - KnownNodeDB sNodeDBTable[MAX_NODE_NUM + 1]; - - // WPA2 PMKID Cache - SPMKIDCache gsPMKIDCache; - bool bRoaming; - - // rate fall back vars - - // associate info - SAssocInfo sAssocInfo; - - // for 802.11h - bool b11hEnable; - bool bSwitchChannel; - unsigned char byNewChannel; - PWLAN_IE_MEASURE_REP pCurrMeasureEIDRep; - unsigned int uLengthOfRepEIDs; - unsigned char abyCurrentMSRReq[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN]; - unsigned char abyCurrentMSRRep[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN]; - unsigned char abyIECountry[WLAN_A3FR_MAXLEN]; - unsigned char abyIBSSDFSOwner[6]; - unsigned char byIBSSDFSRecovery; - - struct sk_buff skb; -} SMgmtObject, *PSMgmtObject; - -/*--------------------- Export Macros ------------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -void -vMgrObjectInit( - void *hDeviceContext -); - -void -vMgrTimerInit( - void *hDeviceContext -); - -void -vMgrObjectReset( - void *hDeviceContext -); - -void -vMgrAssocBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus -); - -void -vMgrReAssocBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus -); - -void -vMgrDisassocBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - unsigned char *abyDestAddress, - unsigned short wReason, - PCMD_STATUS pStatus -); - -void -vMgrAuthenBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus -); - -void -vMgrCreateOwnIBSS( - void *hDeviceContext, - PCMD_STATUS pStatus -); - -void -vMgrJoinBSSBegin( - void *hDeviceContext, - PCMD_STATUS pStatus -); - -void -vMgrRxManagePacket( - void *hDeviceContext, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -); - -/* - void - vMgrScanBegin( - void *hDeviceContext, - PCMD_STATUS pStatus -); -*/ - -void -vMgrDeAuthenBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - unsigned char *abyDestAddress, - unsigned short wReason, - PCMD_STATUS pStatus -); - -bool -bMgrPrepareBeaconToSend( - void *hDeviceContext, - PSMgmtObject pMgmt -); - -bool -bAdd_PMKID_Candidate( - void *hDeviceContext, - unsigned char *pbyBSSID, - PSRSNCapObject psRSNCapObj -); - -void -vFlush_PMKID_Candidate( - void *hDeviceContext -); - -#endif // __WMGR_H__ diff --git a/drivers/staging/vt6655/wpa.c b/drivers/staging/vt6655/wpa.c deleted file mode 100644 index 5d4eca8512af..000000000000 --- a/drivers/staging/vt6655/wpa.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: wpa.c - * - * Purpose: Handles the Basic Service Set & Node Database functions - * - * Functions: - * WPA_ParseRSN - Parse RSN IE. - * - * Revision History: - * - * Author: Kyle Hsu - * - * Date: July 14, 2003 - * - */ - -#include "ttype.h" -#include "tmacro.h" -#include "tether.h" -#include "device.h" -#include "80211hdr.h" -#include "bssdb.h" -#include "wmgr.h" -#include "wpa.h" -#include "80211mgr.h" - -/*--------------------- Static Variables --------------------------*/ -static const unsigned char abyOUI00[4] = { 0x00, 0x50, 0xf2, 0x00 }; -static const unsigned char abyOUI01[4] = { 0x00, 0x50, 0xf2, 0x01 }; -static const unsigned char abyOUI02[4] = { 0x00, 0x50, 0xf2, 0x02 }; -static const unsigned char abyOUI03[4] = { 0x00, 0x50, 0xf2, 0x03 }; -static const unsigned char abyOUI04[4] = { 0x00, 0x50, 0xf2, 0x04 }; -static const unsigned char abyOUI05[4] = { 0x00, 0x50, 0xf2, 0x05 }; - -/*+ - * - * Description: - * Clear RSN information in BSSList. - * - * Parameters: - * In: - * pBSSList - BSS list. - * Out: - * none - * - * Return Value: none. - * - -*/ - -void -WPA_ClearRSN( - PKnownBSS pBSSList -) -{ - int ii; - - pBSSList->byGKType = WPA_TKIP; - for (ii = 0; ii < 4; ii++) - pBSSList->abyPKType[ii] = WPA_TKIP; - pBSSList->wPKCount = 0; - for (ii = 0; ii < 4; ii++) - pBSSList->abyAuthType[ii] = WPA_AUTH_IEEE802_1X; - pBSSList->wAuthCount = 0; - pBSSList->byDefaultK_as_PK = 0; - pBSSList->byReplayIdx = 0; - pBSSList->sRSNCapObj.bRSNCapExist = false; - pBSSList->sRSNCapObj.wRSNCap = 0; - pBSSList->bWPAValid = false; -} - -/*+ - * - * Description: - * Parse RSN IE. - * - * Parameters: - * In: - * pBSSList - BSS list. - * pRSN - Pointer to the RSN IE. - * Out: - * none - * - * Return Value: none. - * - -*/ -void -WPA_ParseRSN( - PKnownBSS pBSSList, - PWLAN_IE_RSN_EXT pRSN -) -{ - PWLAN_IE_RSN_AUTH pIE_RSN_Auth = NULL; - int i, j, m, n = 0; - unsigned char *pbyCaps; - - WPA_ClearRSN(pBSSList); - - pr_debug("WPA_ParseRSN: [%d]\n", pRSN->len); - - // information element header makes sense - if ((pRSN->len >= 6) // oui1(4)+ver(2) - && (pRSN->byElementID == WLAN_EID_RSN_WPA) && !memcmp(pRSN->abyOUI, abyOUI01, 4) - && (pRSN->wVersion == 1)) { - pr_debug("Legal RSN\n"); - // update each variable if pRSN is long enough to contain the variable - if (pRSN->len >= 10) { - //OUI1(4)+ver(2)+GKSuite(4) - if (!memcmp(pRSN->abyMulticast, abyOUI01, 4)) - pBSSList->byGKType = WPA_WEP40; - else if (!memcmp(pRSN->abyMulticast, abyOUI02, 4)) - pBSSList->byGKType = WPA_TKIP; - else if (!memcmp(pRSN->abyMulticast, abyOUI03, 4)) - pBSSList->byGKType = WPA_AESWRAP; - else if (!memcmp(pRSN->abyMulticast, abyOUI04, 4)) - pBSSList->byGKType = WPA_AESCCMP; - else if (!memcmp(pRSN->abyMulticast, abyOUI05, 4)) - pBSSList->byGKType = WPA_WEP104; - else - // any vendor checks here - pBSSList->byGKType = WPA_NONE; - - pr_debug("byGKType: %x\n", pBSSList->byGKType); - } - - if (pRSN->len >= 12) { - //oui1(4)+ver(2)+GKS(4)+PKSCnt(2) - j = 0; - pr_debug("wPKCount: %d, sizeof(pBSSList->abyPKType): %zu\n", - pRSN->wPKCount, sizeof(pBSSList->abyPKType)); - for (i = 0; (i < pRSN->wPKCount) && (j < ARRAY_SIZE(pBSSList->abyPKType)); i++) { - if (pRSN->len >= 12+i*4+4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*i) - if (!memcmp(pRSN->PKSList[i].abyOUI, abyOUI00, 4)) - pBSSList->abyPKType[j++] = WPA_NONE; - else if (!memcmp(pRSN->PKSList[i].abyOUI, abyOUI02, 4)) - pBSSList->abyPKType[j++] = WPA_TKIP; - else if (!memcmp(pRSN->PKSList[i].abyOUI, abyOUI03, 4)) - pBSSList->abyPKType[j++] = WPA_AESWRAP; - else if (!memcmp(pRSN->PKSList[i].abyOUI, abyOUI04, 4)) - pBSSList->abyPKType[j++] = WPA_AESCCMP; - else - // any vendor checks here - ; - } else - break; - } - pBSSList->wPKCount = (unsigned short)j; - pr_debug("wPKCount: %d\n", pBSSList->wPKCount); - } - - m = pRSN->wPKCount; - pr_debug("m: %d\n", m); - pr_debug("14+m*4: %d\n", 14+m*4); - - if (pRSN->len >= 14+m*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2) - // overlay IE_RSN_Auth structure into correct place - pIE_RSN_Auth = (PWLAN_IE_RSN_AUTH) pRSN->PKSList[m].abyOUI; - j = 0; - pr_debug("wAuthCount: %d, sizeof(pBSSList->abyAuthType): %zu\n", - pIE_RSN_Auth->wAuthCount, - sizeof(pBSSList->abyAuthType)); - for (i = 0; (i < pIE_RSN_Auth->wAuthCount) && (j < ARRAY_SIZE(pBSSList->abyAuthType)); i++) { - if (pRSN->len >= 14+4+(m+i)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*i) - if (!memcmp(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI01, 4)) - pBSSList->abyAuthType[j++] = WPA_AUTH_IEEE802_1X; - else if (!memcmp(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI02, 4)) - pBSSList->abyAuthType[j++] = WPA_AUTH_PSK; - else - // any vendor checks here - ; - } else - break; - - } - if (j > 0) - pBSSList->wAuthCount = (unsigned short)j; - pr_debug("wAuthCount: %d\n", pBSSList->wAuthCount); - } - - if (pIE_RSN_Auth != NULL) { - n = pIE_RSN_Auth->wAuthCount; - - pr_debug("n: %d\n", n); - pr_debug("14+4+(m+n)*4: %d\n", 14+4+(m+n)*4); - - if (pRSN->len+2 >= 14+4+(m+n)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*n)+Cap(2) - pbyCaps = (unsigned char *)pIE_RSN_Auth->AuthKSList[n].abyOUI; - pBSSList->byDefaultK_as_PK = (*pbyCaps) & WPA_GROUPFLAG; - pBSSList->byReplayIdx = 2 << ((*pbyCaps >> WPA_REPLAYBITSSHIFT) & WPA_REPLAYBITS); - pBSSList->sRSNCapObj.bRSNCapExist = true; - pBSSList->sRSNCapObj.wRSNCap = *(unsigned short *)pbyCaps; - } - } - pBSSList->bWPAValid = true; - } -} - -/*+ - * - * Description: - * Search RSN information in BSSList. - * - * Parameters: - * In: - * byCmd - Search type - * byEncrypt- Encrypt Type - * pBSSList - BSS list - * Out: - * none - * - * Return Value: none. - * - -*/ -bool -WPA_SearchRSN( - unsigned char byCmd, - unsigned char byEncrypt, - PKnownBSS pBSSList -) -{ - int ii; - unsigned char byPKType = WPA_NONE; - - if (!pBSSList->bWPAValid) - return false; - - switch (byCmd) { - case 0: - - if (byEncrypt != pBSSList->byGKType) - return false; - - if (pBSSList->wPKCount > 0) { - for (ii = 0; ii < pBSSList->wPKCount; ii++) { - if (pBSSList->abyPKType[ii] == WPA_AESCCMP) - byPKType = WPA_AESCCMP; - else if ((pBSSList->abyPKType[ii] == WPA_TKIP) && (byPKType != WPA_AESCCMP)) - byPKType = WPA_TKIP; - else if ((pBSSList->abyPKType[ii] == WPA_WEP40) && (byPKType != WPA_AESCCMP) && (byPKType != WPA_TKIP)) - byPKType = WPA_WEP40; - else if ((pBSSList->abyPKType[ii] == WPA_WEP104) && (byPKType != WPA_AESCCMP) && (byPKType != WPA_TKIP)) - byPKType = WPA_WEP104; - } - if (byEncrypt != byPKType) - return false; - } - return true; - - default: - break; - } - return false; -} - -/*+ - * - * Description: - * Check if RSN IE makes sense. - * - * Parameters: - * In: - * pRSN - Pointer to the RSN IE. - * Out: - * none - * - * Return Value: none. - * - -*/ -bool -WPAb_Is_RSN( - PWLAN_IE_RSN_EXT pRSN -) -{ - if (pRSN == NULL) - return false; - - if ((pRSN->len >= 6) && // oui1(4)+ver(2) - (pRSN->byElementID == WLAN_EID_RSN_WPA) && !memcmp(pRSN->abyOUI, abyOUI01, 4) && - (pRSN->wVersion == 1)) { - return true; - } else - return false; -} diff --git a/drivers/staging/vt6655/wpa.h b/drivers/staging/vt6655/wpa.h deleted file mode 100644 index 1d1918a12641..000000000000 --- a/drivers/staging/vt6655/wpa.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: wpa.h - * - * Purpose: Defines the macros, types, and functions for dealing - * with WPA informations. - * - * Author: Kyle Hsu - * - * Date: Jul 14, 2003 - * - */ - -#ifndef __WPA_H__ -#define __WPA_H__ - -#include "ttype.h" -#include "80211hdr.h" - -/*--------------------- Export Definitions -------------------------*/ - -#define WPA_NONE 0 -#define WPA_WEP40 1 -#define WPA_TKIP 2 -#define WPA_AESWRAP 3 -#define WPA_AESCCMP 4 -#define WPA_WEP104 5 -#define WPA_AUTH_IEEE802_1X 1 -#define WPA_AUTH_PSK 2 - -#define WPA_GROUPFLAG 0x02 -#define WPA_REPLAYBITSSHIFT 2 -#define WPA_REPLAYBITS 0x03 - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Types ------------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -void -WPA_ClearRSN( - PKnownBSS pBSSList -); - -void -WPA_ParseRSN( - PKnownBSS pBSSList, - PWLAN_IE_RSN_EXT pRSN -); - -bool -WPA_SearchRSN( - unsigned char byCmd, - unsigned char byEncrypt, - PKnownBSS pBSSList -); - -bool -WPAb_Is_RSN( - PWLAN_IE_RSN_EXT pRSN -); - -#endif // __WPA_H__ diff --git a/drivers/staging/vt6655/wpa2.c b/drivers/staging/vt6655/wpa2.c deleted file mode 100644 index bb335ef51172..000000000000 --- a/drivers/staging/vt6655/wpa2.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: wpa2.c - * - * Purpose: Handles the Basic Service Set & Node Database functions - * - * Functions: - * - * Revision History: - * - * Author: Yiching Chen - * - * Date: Oct. 4, 2004 - * - */ - -#include "wpa2.h" -#include "device.h" -#include "wmgr.h" - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -static const unsigned char abyOUIGK[4] = { 0x00, 0x0F, 0xAC, 0x00 }; -static const unsigned char abyOUIWEP40[4] = { 0x00, 0x0F, 0xAC, 0x01 }; -static const unsigned char abyOUIWEP104[4] = { 0x00, 0x0F, 0xAC, 0x05 }; -static const unsigned char abyOUITKIP[4] = { 0x00, 0x0F, 0xAC, 0x02 }; -static const unsigned char abyOUICCMP[4] = { 0x00, 0x0F, 0xAC, 0x04 }; - -static const unsigned char abyOUI8021X[4] = { 0x00, 0x0F, 0xAC, 0x01 }; -static const unsigned char abyOUIPSK[4] = { 0x00, 0x0F, 0xAC, 0x02 }; - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -/*+ - * - * Description: - * Clear RSN information in BSSList. - * - * Parameters: - * In: - * pBSSNode - BSS list. - * Out: - * none - * - * Return Value: none. - * - -*/ -void -WPA2_ClearRSN( - PKnownBSS pBSSNode -) -{ - int ii; - - pBSSNode->bWPA2Valid = false; - - pBSSNode->byCSSGK = WLAN_11i_CSS_CCMP; - for (ii = 0; ii < 4; ii++) - pBSSNode->abyCSSPK[ii] = WLAN_11i_CSS_CCMP; - pBSSNode->wCSSPKCount = 1; - for (ii = 0; ii < 4; ii++) - pBSSNode->abyAKMSSAuthType[ii] = WLAN_11i_AKMSS_802_1X; - pBSSNode->wAKMSSAuthCount = 1; - pBSSNode->sRSNCapObj.bRSNCapExist = false; - pBSSNode->sRSNCapObj.wRSNCap = 0; -} - -/*+ - * - * Description: - * Parse RSN IE. - * - * Parameters: - * In: - * pBSSNode - BSS list. - * pRSN - Pointer to the RSN IE. - * Out: - * none - * - * Return Value: none. - * - -*/ -void -WPA2vParseRSN( - PKnownBSS pBSSNode, - PWLAN_IE_RSN pRSN -) -{ - int i, j; - unsigned short m = 0, n = 0; - unsigned char *pbyOUI; - bool bUseGK = false; - - pr_debug("WPA2_ParseRSN: [%d]\n", pRSN->len); - - WPA2_ClearRSN(pBSSNode); - - if (pRSN->len == 2) { // ver(2) - if ((pRSN->byElementID == WLAN_EID_RSN) && (pRSN->wVersion == 1)) - pBSSNode->bWPA2Valid = true; - - return; - } - - if (pRSN->len < 6) { // ver(2) + GK(4) - // invalid CSS, P802.11i/D10.0, p31 - return; - } - - // information element header makes sense - if ((pRSN->byElementID == WLAN_EID_RSN) && - (pRSN->wVersion == 1)) { - pr_debug("Legal 802.11i RSN\n"); - - pbyOUI = &(pRSN->abyRSN[0]); - if (!memcmp(pbyOUI, abyOUIWEP40, 4)) - pBSSNode->byCSSGK = WLAN_11i_CSS_WEP40; - else if (!memcmp(pbyOUI, abyOUITKIP, 4)) - pBSSNode->byCSSGK = WLAN_11i_CSS_TKIP; - else if (!memcmp(pbyOUI, abyOUICCMP, 4)) - pBSSNode->byCSSGK = WLAN_11i_CSS_CCMP; - else if (!memcmp(pbyOUI, abyOUIWEP104, 4)) - pBSSNode->byCSSGK = WLAN_11i_CSS_WEP104; - else if (!memcmp(pbyOUI, abyOUIGK, 4)) { - // invalid CSS, P802.11i/D10.0, p32 - return; - } else - // any vendor checks here - pBSSNode->byCSSGK = WLAN_11i_CSS_UNKNOWN; - - pr_debug("802.11i CSS: %X\n", pBSSNode->byCSSGK); - - if (pRSN->len == 6) { - pBSSNode->bWPA2Valid = true; - return; - } - - if (pRSN->len >= 8) { // ver(2) + GK(4) + PK count(2) - pBSSNode->wCSSPKCount = *((unsigned short *)&(pRSN->abyRSN[4])); - j = 0; - pbyOUI = &(pRSN->abyRSN[6]); - - for (i = 0; (i < pBSSNode->wCSSPKCount) && (j < sizeof(pBSSNode->abyCSSPK)/sizeof(unsigned char)); i++) { - if (pRSN->len >= 8+i*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*i) - if (!memcmp(pbyOUI, abyOUIGK, 4)) { - pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_USE_GROUP; - bUseGK = true; - } else if (!memcmp(pbyOUI, abyOUIWEP40, 4)) { - // Invalid CSS, continue to parsing - } else if (!memcmp(pbyOUI, abyOUITKIP, 4)) { - if (pBSSNode->byCSSGK != WLAN_11i_CSS_CCMP) - pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_TKIP; - else - ; // Invalid CSS, continue to parsing - } else if (!memcmp(pbyOUI, abyOUICCMP, 4)) { - pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_CCMP; - } else if (!memcmp(pbyOUI, abyOUIWEP104, 4)) { - // Invalid CSS, continue to parsing - } else { - // any vendor checks here - pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_UNKNOWN; - } - pbyOUI += 4; - pr_debug("abyCSSPK[%d]: %X\n", - j-1, pBSSNode->abyCSSPK[j-1]); - } else - break; - } //for - - if (bUseGK) { - if (j != 1) { - // invalid CSS, This should be only PK CSS. - return; - } - if (pBSSNode->byCSSGK == WLAN_11i_CSS_CCMP) { - // invalid CSS, If CCMP is enable , PK can't be CSSGK. - return; - } - } - if ((pBSSNode->wCSSPKCount != 0) && (j == 0)) { - // invalid CSS, No valid PK. - return; - } - pBSSNode->wCSSPKCount = (unsigned short)j; - pr_debug("wCSSPKCount: %d\n", pBSSNode->wCSSPKCount); - } - - m = *((unsigned short *)&(pRSN->abyRSN[4])); - - if (pRSN->len >= 10+m*4) { // ver(2) + GK(4) + PK count(2) + PKS(4*m) + AKMSS count(2) - pBSSNode->wAKMSSAuthCount = *((unsigned short *)&(pRSN->abyRSN[6+4*m])); - j = 0; - pbyOUI = &(pRSN->abyRSN[8+4*m]); - for (i = 0; (i < pBSSNode->wAKMSSAuthCount) && (j < sizeof(pBSSNode->abyAKMSSAuthType)/sizeof(unsigned char)); i++) { - if (pRSN->len >= 10+(m+i)*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSS(2)+AKS(4*i) - if (!memcmp(pbyOUI, abyOUI8021X, 4)) - pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_802_1X; - else if (!memcmp(pbyOUI, abyOUIPSK, 4)) - pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_PSK; - else - // any vendor checks here - pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_UNKNOWN; - pr_debug("abyAKMSSAuthType[%d]: %X\n", - j-1, - pBSSNode->abyAKMSSAuthType[j-1]); - } else - break; - } - pBSSNode->wAKMSSAuthCount = (unsigned short)j; - pr_debug("wAKMSSAuthCount: %d\n", - pBSSNode->wAKMSSAuthCount); - - n = *((unsigned short *)&(pRSN->abyRSN[6+4*m])); - if (pRSN->len >= 12 + 4 * m + 4 * n) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSSCnt(2)+AKMSS(4*n)+Cap(2) - pBSSNode->sRSNCapObj.bRSNCapExist = true; - pBSSNode->sRSNCapObj.wRSNCap = *((unsigned short *)&(pRSN->abyRSN[8+4*m+4*n])); - } - } - //ignore PMKID lists bcs only (Re)Assocrequest has this field - pBSSNode->bWPA2Valid = true; - } -} - -/*+ - * - * Description: - * Set WPA IEs - * - * Parameters: - * In: - * pMgmtHandle - Pointer to management object - * Out: - * pRSNIEs - Pointer to the RSN IE to set. - * - * Return Value: length of IEs. - * - -*/ -unsigned int -WPA2uSetIEs( - void *pMgmtHandle, - PWLAN_IE_RSN pRSNIEs -) -{ - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; - unsigned char *pbyBuffer = NULL; - unsigned int ii = 0; - unsigned short *pwPMKID = NULL; - - if (pRSNIEs == NULL) - return 0; - - if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) && - (pMgmt->pCurrBSS != NULL)) { - /* WPA2 IE */ - pbyBuffer = (unsigned char *)pRSNIEs; - pRSNIEs->byElementID = WLAN_EID_RSN; - pRSNIEs->len = 6; //Version(2)+GK(4) - pRSNIEs->wVersion = 1; - //Group Key Cipher Suite - pRSNIEs->abyRSN[0] = 0x00; - pRSNIEs->abyRSN[1] = 0x0F; - pRSNIEs->abyRSN[2] = 0xAC; - if (pMgmt->byCSSGK == KEY_CTL_WEP) - pRSNIEs->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK; - else if (pMgmt->byCSSGK == KEY_CTL_TKIP) - pRSNIEs->abyRSN[3] = WLAN_11i_CSS_TKIP; - else if (pMgmt->byCSSGK == KEY_CTL_CCMP) - pRSNIEs->abyRSN[3] = WLAN_11i_CSS_CCMP; - else - pRSNIEs->abyRSN[3] = WLAN_11i_CSS_UNKNOWN; - - // Pairwise Key Cipher Suite - pRSNIEs->abyRSN[4] = 1; - pRSNIEs->abyRSN[5] = 0; - pRSNIEs->abyRSN[6] = 0x00; - pRSNIEs->abyRSN[7] = 0x0F; - pRSNIEs->abyRSN[8] = 0xAC; - if (pMgmt->byCSSPK == KEY_CTL_TKIP) - pRSNIEs->abyRSN[9] = WLAN_11i_CSS_TKIP; - else if (pMgmt->byCSSPK == KEY_CTL_CCMP) - pRSNIEs->abyRSN[9] = WLAN_11i_CSS_CCMP; - else if (pMgmt->byCSSPK == KEY_CTL_NONE) - pRSNIEs->abyRSN[9] = WLAN_11i_CSS_USE_GROUP; - else - pRSNIEs->abyRSN[9] = WLAN_11i_CSS_UNKNOWN; - - pRSNIEs->len += 6; - - // Auth Key Management Suite - pRSNIEs->abyRSN[10] = 1; - pRSNIEs->abyRSN[11] = 0; - pRSNIEs->abyRSN[12] = 0x00; - pRSNIEs->abyRSN[13] = 0x0F; - pRSNIEs->abyRSN[14] = 0xAC; - if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) - pRSNIEs->abyRSN[15] = WLAN_11i_AKMSS_PSK; - else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) - pRSNIEs->abyRSN[15] = WLAN_11i_AKMSS_802_1X; - else - pRSNIEs->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN; - - pRSNIEs->len += 6; - - // RSN Capabilities - if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) { - memcpy(&pRSNIEs->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2); - } else { - pRSNIEs->abyRSN[16] = 0; - pRSNIEs->abyRSN[17] = 0; - } - pRSNIEs->len += 2; - - if ((pMgmt->gsPMKIDCache.BSSIDInfoCount > 0) && - pMgmt->bRoaming && - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) { - // RSN PMKID - pwPMKID = (unsigned short *)(&pRSNIEs->abyRSN[18]); // Point to PMKID count - *pwPMKID = 0; // Initialize PMKID count - pbyBuffer = &pRSNIEs->abyRSN[20]; // Point to PMKID list - for (ii = 0; ii < pMgmt->gsPMKIDCache.BSSIDInfoCount; ii++) { - if (!memcmp(&pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyBSSID[0], pMgmt->abyCurrBSSID, ETH_ALEN)) { - (*pwPMKID)++; - memcpy(pbyBuffer, pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyPMKID, 16); - pbyBuffer += 16; - } - } - if (*pwPMKID != 0) - pRSNIEs->len += (2 + (*pwPMKID)*16); - else - pbyBuffer = &pRSNIEs->abyRSN[18]; - } - return pRSNIEs->len + WLAN_IEHDR_LEN; - } - return 0; -} diff --git a/drivers/staging/vt6655/wpa2.h b/drivers/staging/vt6655/wpa2.h deleted file mode 100644 index 2d0bd2e515f3..000000000000 --- a/drivers/staging/vt6655/wpa2.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: wpa2.h - * - * Purpose: Defines the macros, types, and functions for dealing - * with WPA2 informations. - * - * Author: Yiching Chen - * - * Date: Oct. 4, 2004 - * - */ - -#ifndef __WPA2_H__ -#define __WPA2_H__ - -#include "ttype.h" -#include "80211mgr.h" -#include "80211hdr.h" -#include "bssdb.h" - -/*--------------------- Export Definitions -------------------------*/ -#define MAX_PMKID_CACHE 16 - -typedef struct tagsPMKIDInfo { - unsigned char abyBSSID[6]; - unsigned char abyPMKID[16]; -} PMKIDInfo, *PPMKIDInfo; - -typedef struct tagSPMKIDCache { - unsigned long BSSIDInfoCount; - PMKIDInfo BSSIDInfo[MAX_PMKID_CACHE]; -} SPMKIDCache, *PSPMKIDCache; - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Types ------------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -void -WPA2_ClearRSN( - PKnownBSS pBSSNode -); - -void -WPA2vParseRSN( - PKnownBSS pBSSNode, - PWLAN_IE_RSN pRSN -); - -unsigned int -WPA2uSetIEs( - void *pMgmtHandle, - PWLAN_IE_RSN pRSNIEs -); - -#endif // __WPA2_H__ diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c deleted file mode 100644 index dab1e8078652..000000000000 --- a/drivers/staging/vt6655/wpactl.c +++ /dev/null @@ -1,896 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: wpactl.c - * - * Purpose: handle wpa supplicant ioctl input/out functions - * - * Author: Lyndon Chen - * - * Date: Oct. 20, 2003 - * - * Functions: - * - * Revision History: - * - */ - -#include "wpactl.h" -#include "key.h" -#include "mac.h" -#include "device.h" -#include "wmgr.h" -#include "iocmd.h" -#include "iowpa.h" -#include "rf.h" - -/*--------------------- Static Definitions -------------------------*/ - -#define VIAWGET_WPA_MAX_BUF_SIZE 1024 - -static const int frequency_list[] = { - 2412, 2417, 2422, 2427, 2432, 2437, 2442, - 2447, 2452, 2457, 2462, 2467, 2472, 2484 -}; -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ -static void wpadev_setup(struct net_device *dev) -{ - dev->type = ARPHRD_IEEE80211; - dev->hard_header_len = ETH_HLEN; - dev->mtu = 2048; - dev->addr_len = ETH_ALEN; - dev->tx_queue_len = 1000; - - memset(dev->broadcast, 0xFF, ETH_ALEN); - - dev->flags = IFF_BROADCAST|IFF_MULTICAST; -} - -/* - * Description: - * register netdev for wpa supplicant daemon - * - * Parameters: - * In: - * pDevice - - * enable - - * Out: - * - * Return Value: - * - */ - -static int wpa_init_wpadev(struct vnt_private *pDevice) -{ - struct vnt_private *wpadev_priv; - struct net_device *dev = pDevice->dev; - int ret = 0; - - pDevice->wpadev = alloc_netdev(sizeof(*wpadev_priv), "vntwpa", - NET_NAME_UNKNOWN, wpadev_setup); - if (pDevice->wpadev == NULL) - return -ENOMEM; - - wpadev_priv = netdev_priv(pDevice->wpadev); - *wpadev_priv = *pDevice; - eth_hw_addr_inherit(pDevice->wpadev, dev); - pDevice->wpadev->base_addr = dev->base_addr; - pDevice->wpadev->irq = dev->irq; - pDevice->wpadev->mem_start = dev->mem_start; - pDevice->wpadev->mem_end = dev->mem_end; - ret = register_netdev(pDevice->wpadev); - if (ret) { - pr_debug("%s: register_netdev(WPA) failed!\n", dev->name); - free_netdev(pDevice->wpadev); - return -1; - } - - if (pDevice->skb == NULL) { - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - if (pDevice->skb == NULL) - return -ENOMEM; - } - - pr_debug("%s: Registered netdev %s for WPA management\n", - dev->name, pDevice->wpadev->name); - - return 0; -} - -/* - * Description: - * unregister net_device (wpadev) - * - * Parameters: - * In: - * pDevice - - * Out: - * - * Return Value: - * - */ - -static int wpa_release_wpadev(struct vnt_private *pDevice) -{ - if (pDevice->skb) { - dev_kfree_skb(pDevice->skb); - pDevice->skb = NULL; - } - - if (pDevice->wpadev) { - pr_debug("%s: Netdevice %s unregistered\n", - pDevice->dev->name, pDevice->wpadev->name); - unregister_netdev(pDevice->wpadev); - free_netdev(pDevice->wpadev); - pDevice->wpadev = NULL; - } - - return 0; -} - -/* - * Description: - * Set enable/disable dev for wpa supplicant daemon - * - * Parameters: - * In: - * pDevice - - * val - - * Out: - * - * Return Value: - * - */ - -int wpa_set_wpadev(struct vnt_private *pDevice, int val) -{ - if (val) - return wpa_init_wpadev(pDevice); - else - return wpa_release_wpadev(pDevice); -} - -/* - * Description: - * Set WPA algorithm & keys - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ - -int wpa_set_keys(struct vnt_private *pDevice, void *ctx, - bool fcpfkernel) __must_hold(&pDevice->lock) -{ - struct viawget_wpa_param *param = ctx; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned long dwKeyIndex = 0; - unsigned char abyKey[MAX_KEY_LEN]; - unsigned char abySeq[MAX_KEY_LEN]; - u64 KeyRSC; - unsigned char byKeyDecMode = KEY_CTL_WEP; - int ret = 0; - int uu, ii; - - if (param->u.wpa_key.alg_name > WPA_ALG_CCMP || - param->u.wpa_key.key_len > MAX_KEY_LEN || - param->u.wpa_key.seq_len > MAX_KEY_LEN) - return -EINVAL; - - pr_debug("param->u.wpa_key.alg_name = %d\n", param->u.wpa_key.alg_name); - if (param->u.wpa_key.alg_name == WPA_ALG_NONE) { - pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - pDevice->bEncryptionEnable = false; - pDevice->byKeyIndex = 0; - pDevice->bTransmitKey = false; - KeyvRemoveAllWEPKey(&(pDevice->sKey), pDevice->PortOffset); - for (uu = 0; uu < MAX_KEY_TABLE; uu++) - MACvDisableKeyEntry(pDevice->PortOffset, uu); - - return ret; - } - - if (param->u.wpa_key.key && fcpfkernel) { - memcpy(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len); - } else { - spin_unlock_irq(&pDevice->lock); - if (param->u.wpa_key.key && - copy_from_user(&abyKey[0], - (void __user *)param->u.wpa_key.key, - param->u.wpa_key.key_len)) { - spin_lock_irq(&pDevice->lock); - return -EINVAL; - } - spin_lock_irq(&pDevice->lock); - } - - dwKeyIndex = (unsigned long)(param->u.wpa_key.key_index); - - if (param->u.wpa_key.alg_name == WPA_ALG_WEP) { - if (dwKeyIndex > 3) { - return -EINVAL; - } else { - if (param->u.wpa_key.set_tx) { - pDevice->byKeyIndex = (unsigned char)dwKeyIndex; - pDevice->bTransmitKey = true; - dwKeyIndex |= (1 << 31); - } - KeybSetDefaultKey(&(pDevice->sKey), - dwKeyIndex & ~(BIT30 | USE_KEYRSC), - param->u.wpa_key.key_len, - NULL, - abyKey, - KEY_CTL_WEP, - pDevice->PortOffset, - pDevice->byLocalID); - - } - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - pDevice->bEncryptionEnable = true; - return ret; - } - - if (param->u.wpa_key.seq && fcpfkernel) { - memcpy(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len); - } else { - spin_unlock_irq(&pDevice->lock); - if (param->u.wpa_key.seq && - copy_from_user(&abySeq[0], - (void __user *)param->u.wpa_key.seq, - param->u.wpa_key.seq_len)) { - spin_lock_irq(&pDevice->lock); - return -EINVAL; - } - spin_lock_irq(&pDevice->lock); - } - - if (param->u.wpa_key.seq_len > 0) { - for (ii = 0; ii < param->u.wpa_key.seq_len; ii++) { - if (ii < 4) - KeyRSC |= (u64)(abySeq[ii] << (ii * 8)); - else - KeyRSC |= (u64)(abySeq[ii] << ((ii-4) * 8)); - } - dwKeyIndex |= 1 << 29; - } - - if (param->u.wpa_key.key_index >= MAX_GROUP_KEY) { - pr_debug("return dwKeyIndex > 3\n"); - return -EINVAL; - } - - if (param->u.wpa_key.alg_name == WPA_ALG_TKIP) - pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; - - if (param->u.wpa_key.alg_name == WPA_ALG_CCMP) - pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; - - if (param->u.wpa_key.set_tx) - dwKeyIndex |= (1 << 31); - - if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) - byKeyDecMode = KEY_CTL_CCMP; - else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) - byKeyDecMode = KEY_CTL_TKIP; - else - byKeyDecMode = KEY_CTL_WEP; - - /* Fix HCT test that set 256 bits KEY and Ndis802_11Encryption3Enabled */ - if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - if (param->u.wpa_key.key_len == MAX_KEY_LEN) - byKeyDecMode = KEY_CTL_TKIP; - else if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN) - byKeyDecMode = KEY_CTL_WEP; - else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN) - byKeyDecMode = KEY_CTL_WEP; - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { - if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN) - byKeyDecMode = KEY_CTL_WEP; - else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN) - byKeyDecMode = KEY_CTL_WEP; - } - - /* Check TKIP key length */ - if ((byKeyDecMode == KEY_CTL_TKIP) && - (param->u.wpa_key.key_len != MAX_KEY_LEN)) { - /* TKIP Key must be 256 bits */ - pr_debug("return- TKIP Key must be 256 bits!\n"); - return -EINVAL; - } - /* Check AES key length */ - if ((byKeyDecMode == KEY_CTL_CCMP) && - (param->u.wpa_key.key_len != AES_KEY_LEN)) { - /* AES Key must be 128 bits */ - return -EINVAL; - } - - /* spin_lock_irq(&pDevice->lock); */ - if (is_broadcast_ether_addr(¶m->addr[0]) || (param->addr == NULL)) { - /* If is_broadcast_ether_addr, set the key as every key entry's group key. */ - pr_debug("Groupe Key Assign\n"); - - if (KeybSetAllGroupKey(&(pDevice->sKey), - dwKeyIndex, - param->u.wpa_key.key_len, - (u64 *) &KeyRSC, - (unsigned char *)abyKey, - byKeyDecMode, - pDevice->PortOffset, - pDevice->byLocalID) && - KeybSetDefaultKey(&(pDevice->sKey), - dwKeyIndex, - param->u.wpa_key.key_len, - (u64 *) &KeyRSC, - (unsigned char *)abyKey, - byKeyDecMode, - pDevice->PortOffset, - pDevice->byLocalID)) { - pr_debug("GROUP Key Assign\n"); - - } else { - return -EINVAL; - } - - } else { - pr_debug("Pairwise Key Assign\n"); - /* BSSID not 0xffffffffffff */ - /* Pairwise Key can't be WEP */ - if (byKeyDecMode == KEY_CTL_WEP) { - pr_debug("Pairwise Key can't be WEP\n"); - return -EINVAL; - } - - dwKeyIndex |= (1 << 30); /* set pairwise key */ - if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) - return -EINVAL; - - if (KeybSetKey(&(pDevice->sKey), - ¶m->addr[0], - dwKeyIndex, - param->u.wpa_key.key_len, - (u64 *) &KeyRSC, - (unsigned char *)abyKey, - byKeyDecMode, - pDevice->PortOffset, - pDevice->byLocalID)) { - pr_debug("Pairwise Key Set\n"); - - } else { - /* Key Table Full */ - return -EINVAL; - } - } /* BSSID not 0xffffffffffff */ - if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) { - pDevice->byKeyIndex = (unsigned char)param->u.wpa_key.key_index; - pDevice->bTransmitKey = true; - } - pDevice->bEncryptionEnable = true; - - return ret; -} - -/* - * Description: - * enable wpa auth & mode - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ - -static int wpa_set_wpa(struct vnt_private *pDevice, - struct viawget_wpa_param *param) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - - pMgmt->eAuthenMode = WMAC_AUTH_OPEN; - pMgmt->bShareKeyAlgorithm = false; - - return 0; -} - -/* - * Description: - * set disassociate - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ - -static int wpa_set_disassociate(struct vnt_private *pDevice, - struct viawget_wpa_param *param) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - - spin_lock_irq(&pDevice->lock); - if (pDevice->bLinkPass) { - if (!memcmp(param->addr, pMgmt->abyCurrBSSID, 6)) - bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL); - } - spin_unlock_irq(&pDevice->lock); - - return 0; -} - -/* - * Description: - * enable scan process - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ - -static int wpa_set_scan(struct vnt_private *pDevice, - struct viawget_wpa_param *param) -{ - spin_lock_irq(&pDevice->lock); - BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); - spin_unlock_irq(&pDevice->lock); - - return 0; -} - -/* - * Description: - * get bssid - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ - -static int wpa_get_bssid(struct vnt_private *pDevice, - struct viawget_wpa_param *param) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - - memcpy(param->u.wpa_associate.bssid, pMgmt->abyCurrBSSID , 6); - - return 0; -} - -/* - * Description: - * get bssid - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ - -static int wpa_get_ssid(struct vnt_private *pDevice, - struct viawget_wpa_param *param) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - PWLAN_IE_SSID pItemSSID; - - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - - memcpy(param->u.wpa_associate.ssid, pItemSSID->abySSID , pItemSSID->len); - param->u.wpa_associate.ssid_len = pItemSSID->len; - - return 0; -} - -/* - * Description: - * get scan results - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ - -static int wpa_get_scan(struct vnt_private *pDevice, - struct viawget_wpa_param *param) -{ - struct viawget_scan_result *scan_buf; - PSMgmtObject pMgmt = pDevice->pMgmt; - PWLAN_IE_SSID pItemSSID; - PKnownBSS pBSS; - unsigned char *pBuf; - int ret = 0; - u16 count = 0; - u16 ii, jj; -#if 1 - - unsigned char *ptempBSS; - - ptempBSS = kmalloc(sizeof(KnownBSS), GFP_ATOMIC); - - if (ptempBSS == NULL) { - pr_err("bubble sort kmalloc memory fail@@@\n"); - - ret = -ENOMEM; - - return ret; - - } - - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - for (jj = 0; jj < MAX_BSS_NUM - ii - 1; jj++) { - if ((pMgmt->sBSSList[jj].bActive != true) || - - ((pMgmt->sBSSList[jj].uRSSI > pMgmt->sBSSList[jj + 1].uRSSI) && (pMgmt->sBSSList[jj + 1].bActive != false))) { - memcpy(ptempBSS, &pMgmt->sBSSList[jj], sizeof(KnownBSS)); - - memcpy(&pMgmt->sBSSList[jj], &pMgmt->sBSSList[jj + 1], sizeof(KnownBSS)); - - memcpy(&pMgmt->sBSSList[jj + 1], ptempBSS, sizeof(KnownBSS)); - - } - - } - - } - - kfree(ptempBSS); -#endif - -//******mike:bubble sort by stronger RSSI*****// - - count = 0; - pBSS = &(pMgmt->sBSSList[0]); - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - pBSS = &(pMgmt->sBSSList[ii]); - if (!pBSS->bActive) - continue; - count++; - } - - pBuf = kcalloc(count, sizeof(struct viawget_scan_result), GFP_ATOMIC); - - if (pBuf == NULL) { - ret = -ENOMEM; - return ret; - } - scan_buf = (struct viawget_scan_result *)pBuf; - pBSS = &(pMgmt->sBSSList[0]); - for (ii = 0, jj = 0; ii < MAX_BSS_NUM; ii++) { - pBSS = &(pMgmt->sBSSList[ii]); - if (pBSS->bActive) { - if (jj >= count) - break; - memcpy(scan_buf->bssid, pBSS->abyBSSID, WLAN_BSSID_LEN); - pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; - memcpy(scan_buf->ssid, pItemSSID->abySSID, pItemSSID->len); - scan_buf->ssid_len = pItemSSID->len; - scan_buf->freq = frequency_list[pBSS->uChannel-1]; - scan_buf->caps = pBSS->wCapInfo; - - if (pBSS->wWPALen != 0) { - scan_buf->wpa_ie_len = pBSS->wWPALen; - memcpy(scan_buf->wpa_ie, pBSS->byWPAIE, pBSS->wWPALen); - } - if (pBSS->wRSNLen != 0) { - scan_buf->rsn_ie_len = pBSS->wRSNLen; - memcpy(scan_buf->rsn_ie, pBSS->byRSNIE, pBSS->wRSNLen); - } - scan_buf = (struct viawget_scan_result *)((unsigned char *)scan_buf + sizeof(struct viawget_scan_result)); - jj++; - } - } - - if (jj < count) - count = jj; - - if (copy_to_user(param->u.scan_results.buf, pBuf, sizeof(struct viawget_scan_result) * count)) - ret = -EFAULT; - - param->u.scan_results.scan_count = count; - pr_debug(" param->u.scan_results.scan_count = %d\n", count); - - kfree(pBuf); - return ret; -} - -/* - * Description: - * set associate with AP - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ - -static int wpa_set_associate(struct vnt_private *pDevice, - struct viawget_wpa_param *param) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - PWLAN_IE_SSID pItemSSID; - unsigned char abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - unsigned char abyWPAIE[64]; - bool bWepEnabled = false; - - /* set key type & algorithm */ - pr_debug("pairwise_suite = %d\n", - param->u.wpa_associate.pairwise_suite); - pr_debug("group_suite = %d\n", param->u.wpa_associate.group_suite); - pr_debug("key_mgmt_suite = %d\n", - param->u.wpa_associate.key_mgmt_suite); - pr_debug("auth_alg = %d\n", param->u.wpa_associate.auth_alg); - pr_debug("mode = %d\n", param->u.wpa_associate.mode); - pr_debug("wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len); - - if (param->u.wpa_associate.wpa_ie_len) { - if (!param->u.wpa_associate.wpa_ie) - return -EINVAL; - if (param->u.wpa_associate.wpa_ie_len > sizeof(abyWPAIE)) - return -EINVAL; - if (copy_from_user(&abyWPAIE[0], param->u.wpa_associate.wpa_ie, param->u.wpa_associate.wpa_ie_len)) - return -EFAULT; - } - - if (param->u.wpa_associate.mode == 1) - pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; - else - pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; - /* set ssid */ - memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; - pItemSSID->byElementID = WLAN_EID_SSID; - pItemSSID->len = param->u.wpa_associate.ssid_len; - memcpy(pItemSSID->abySSID, param->u.wpa_associate.ssid, pItemSSID->len); - /* set bssid */ - if (memcmp(param->u.wpa_associate.bssid, &abyNullAddr[0], 6) != 0) - memcpy(pMgmt->abyDesireBSSID, param->u.wpa_associate.bssid, 6); - else - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pItemSSID->abySSID); - - if (param->u.wpa_associate.wpa_ie_len == 0) { - if (param->u.wpa_associate.auth_alg & AUTH_ALG_SHARED_KEY) - pMgmt->eAuthenMode = WMAC_AUTH_SHAREKEY; - else - pMgmt->eAuthenMode = WMAC_AUTH_OPEN; - } else if (abyWPAIE[0] == RSN_INFO_ELEM) { - if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK) - pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK; - else - pMgmt->eAuthenMode = WMAC_AUTH_WPA2; - } else { - if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_WPA_NONE) - pMgmt->eAuthenMode = WMAC_AUTH_WPANONE; - else if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK) - pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK; - else - pMgmt->eAuthenMode = WMAC_AUTH_WPA; - } - - switch (param->u.wpa_associate.pairwise_suite) { - case CIPHER_CCMP: - pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; - break; - case CIPHER_TKIP: - pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; - break; - case CIPHER_WEP40: - case CIPHER_WEP104: - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - bWepEnabled = true; - break; - case CIPHER_NONE: - if (param->u.wpa_associate.group_suite == CIPHER_CCMP) - pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; - else - pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; - break; - default: - pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - } - -//DavidWang add for WPA_supplicant support open/share mode - - if (pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) { - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - pMgmt->bShareKeyAlgorithm = true; - } else if (pMgmt->eAuthenMode == WMAC_AUTH_OPEN) { - if (!bWepEnabled) pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - else pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - } -//mike save old encryption status - pDevice->eOldEncryptionStatus = pDevice->eEncryptionStatus; - - if (pDevice->eEncryptionStatus != Ndis802_11EncryptionDisabled) - pDevice->bEncryptionEnable = true; - else - pDevice->bEncryptionEnable = false; - if (!((pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) || - ((pMgmt->eAuthenMode == WMAC_AUTH_OPEN) && bWepEnabled))) //DavidWang //20080717-06,<Modify> by chester//Not to initial WEP - KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); - spin_lock_irq(&pDevice->lock); - pDevice->bLinkPass = false; - memset(pMgmt->abyCurrBSSID, 0, 6); - pMgmt->eCurrState = WMAC_STATE_IDLE; - netif_stop_queue(pDevice->dev); - //20080701-02,<Add> by Mike Liu -/*******search if ap_scan=2 ,which is associating request in hidden ssid mode ****/ - { - PKnownBSS pCurr = NULL; - - pCurr = BSSpSearchBSSList(pDevice, - pMgmt->abyDesireBSSID, - pMgmt->abyDesireSSID, - pMgmt->eConfigPHYMode -); - - if (pCurr == NULL) { - pr_debug("wpa_set_associate---->hidden mode site survey before associate.......\n"); - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - } - } -/****************************************************************/ - bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); - spin_unlock_irq(&pDevice->lock); - - return 0; -} - -/* - * Description: - * wpa_ioctl main function supported for wpa supplicant - * - * Parameters: - * In: - * pDevice - - * iw_point - - * Out: - * - * Return Value: - * - */ - -int wpa_ioctl(struct vnt_private *pDevice, struct iw_point *p) -{ - struct viawget_wpa_param *param; - int ret = 0; - int wpa_ioctl = 0; - - if (p->length < sizeof(struct viawget_wpa_param) || - p->length > VIAWGET_WPA_MAX_BUF_SIZE || !p->pointer) - return -EINVAL; - - param = kmalloc((int)p->length, GFP_KERNEL); - if (param == NULL) - return -ENOMEM; - - if (copy_from_user(param, p->pointer, p->length)) { - ret = -EFAULT; - goto out; - } - - switch (param->cmd) { - case VIAWGET_SET_WPA: - ret = wpa_set_wpa(pDevice, param); - pr_debug("VIAWGET_SET_WPA\n"); - break; - - case VIAWGET_SET_KEY: - pr_debug("VIAWGET_SET_KEY\n"); - spin_lock_irq(&pDevice->lock); - ret = wpa_set_keys(pDevice, param, false); - spin_unlock_irq(&pDevice->lock); - break; - - case VIAWGET_SET_SCAN: - pr_debug("VIAWGET_SET_SCAN\n"); - ret = wpa_set_scan(pDevice, param); - break; - - case VIAWGET_GET_SCAN: - pr_debug("VIAWGET_GET_SCAN\n"); - ret = wpa_get_scan(pDevice, param); - wpa_ioctl = 1; - break; - - case VIAWGET_GET_SSID: - pr_debug("VIAWGET_GET_SSID\n"); - ret = wpa_get_ssid(pDevice, param); - wpa_ioctl = 1; - break; - - case VIAWGET_GET_BSSID: - pr_debug("VIAWGET_GET_BSSID\n"); - ret = wpa_get_bssid(pDevice, param); - wpa_ioctl = 1; - break; - - case VIAWGET_SET_ASSOCIATE: - pr_debug("VIAWGET_SET_ASSOCIATE\n"); - ret = wpa_set_associate(pDevice, param); - break; - - case VIAWGET_SET_DISASSOCIATE: - pr_debug("VIAWGET_SET_DISASSOCIATE\n"); - ret = wpa_set_disassociate(pDevice, param); - break; - - case VIAWGET_SET_DROP_UNENCRYPT: - pr_debug("VIAWGET_SET_DROP_UNENCRYPT\n"); - break; - - case VIAWGET_SET_DEAUTHENTICATE: - pr_debug("VIAWGET_SET_DEAUTHENTICATE\n"); - break; - - default: - pr_debug("wpa_ioctl: unknown cmd=%d\n", - param->cmd); - ret = -EOPNOTSUPP; - goto out; - } - - if ((ret == 0) && wpa_ioctl) { - if (copy_to_user(p->pointer, param, p->length)) { - ret = -EFAULT; - goto out; - } - } - -out: - kfree(param); - - return ret; -} diff --git a/drivers/staging/vt6655/wpactl.h b/drivers/staging/vt6655/wpactl.h deleted file mode 100644 index c1b4a7292061..000000000000 --- a/drivers/staging/vt6655/wpactl.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: wpactl.h - * - * Purpose: - * - * Author: Lyndon Chen - * - * Date: March 1, 2005 - * - */ - -#ifndef __WPACTL_H__ -#define __WPACTL_H__ - -#include "device.h" -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -#include "iowpa.h" -#endif - -/*--------------------- Export Definitions -------------------------*/ - -//WPA related - -enum wpa_alg { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP }; -enum wpa_cipher { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, - CIPHER_WEP104 }; -enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_CCKM, KEY_MGMT_PSK, KEY_MGMT_NONE, - KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE }; - -#define AUTH_ALG_OPEN_SYSTEM 0x01 -#define AUTH_ALG_SHARED_KEY 0x02 -#define AUTH_ALG_LEAP 0x04 - -#define GENERIC_INFO_ELEM 0xdd -#define RSN_INFO_ELEM 0x30 - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -int wpa_set_wpadev(struct vnt_private *, int val); -int wpa_ioctl(struct vnt_private *, struct iw_point *p); -int wpa_set_keys(struct vnt_private *, void *ctx, bool fcpfkernel); - -#endif // __WPACL_H__ diff --git a/drivers/staging/vt6655/wroute.c b/drivers/staging/vt6655/wroute.c deleted file mode 100644 index d1171fa3446e..000000000000 --- a/drivers/staging/vt6655/wroute.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: wroute.c - * - * Purpose: handle WMAC frame relay & filtering - * - * Author: Lyndon Chen - * - * Date: May 20, 2003 - * - * Functions: - * ROUTEbRelay - Relay packet - * - * Revision History: - * - */ - -#include "mac.h" -#include "tcrc.h" -#include "rxtx.h" -#include "wroute.h" -#include "card.h" -#include "baseband.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/* - * Description: - * Relay packet. Return true if packet is copy to DMA1 - * - * Parameters: - * In: - * pDevice - - * pbySkbData - rx packet skb data - * Out: - * true, false - * - * Return Value: true if packet duplicate; otherwise false - * - */ -bool ROUTEbRelay(struct vnt_private *pDevice, unsigned char *pbySkbData, - unsigned int uDataLen, unsigned int uNodeIndex) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - PSTxDesc pHeadTD, pLastTD; - unsigned int cbFrameBodySize; - unsigned int uMACfragNum; - unsigned char byPktType; - bool bNeedEncryption = false; - SKeyItem STempKey; - PSKeyItem pTransmitKey = NULL; - unsigned int cbHeaderSize; - unsigned int ii; - unsigned char *pbyBSSID; - - if (AVAIL_TD(pDevice, TYPE_AC0DMA) <= 0) { - pr_debug("Relay can't allocate TD1..\n"); - return false; - } - - pHeadTD = pDevice->apCurrTD[TYPE_AC0DMA]; - - pHeadTD->m_td1TD1.byTCR = (TCR_EDP | TCR_STP); - - memcpy(pDevice->sTxEthHeader.abyDstAddr, pbySkbData, ETH_HLEN); - - cbFrameBodySize = uDataLen - ETH_HLEN; - - if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN) - cbFrameBodySize += 8; - - if (pDevice->bEncryptionEnable == true) { - bNeedEncryption = true; - - // get group key - pbyBSSID = pDevice->abyBroadcastAddr; - if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, - GROUP_KEY, &pTransmitKey) == false) { - pTransmitKey = NULL; - pr_debug("KEY is NULL. [%d]\n", - pDevice->pMgmt->eCurrMode); - } else { - pr_debug("Get GTK\n"); - } - } - - if (pDevice->bEnableHostWEP) { - if (uNodeIndex < MAX_NODE_NUM + 1) { - pTransmitKey = &STempKey; - pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite; - pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex; - pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength; - pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16; - pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0; - memcpy(pTransmitKey->abyKey, - &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0], - pTransmitKey->uKeyLength); - } - } - - uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, - cbFrameBodySize, &pDevice->sTxEthHeader); - - if (uMACfragNum > AVAIL_TD(pDevice, TYPE_AC0DMA)) - return false; - - byPktType = pDevice->byPacketType; - - if (pDevice->bFixRate) { - if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { - if (pDevice->uConnectionRate >= RATE_11M) - pDevice->wCurrentRate = RATE_11M; - else - pDevice->wCurrentRate = pDevice->uConnectionRate; - } else { - if ((pDevice->eCurrentPHYType == PHY_TYPE_11A) && - (pDevice->uConnectionRate <= RATE_6M)) { - pDevice->wCurrentRate = RATE_6M; - } else { - if (pDevice->uConnectionRate >= RATE_54M) - pDevice->wCurrentRate = RATE_54M; - else - pDevice->wCurrentRate = pDevice->uConnectionRate; - } - } - } else { - pDevice->wCurrentRate = pDevice->pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate; - } - - if (pDevice->wCurrentRate <= RATE_11M) - byPktType = PK_TYPE_11B; - - vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, - bNeedEncryption, cbFrameBodySize, TYPE_AC0DMA, - pHeadTD, &pDevice->sTxEthHeader, pbySkbData, - pTransmitKey, uNodeIndex, &uMACfragNum, - &cbHeaderSize); - - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { - // Disable PS - MACbPSWakeup(pDevice->PortOffset); - } - - pDevice->bPWBitOn = false; - - pLastTD = pHeadTD; - for (ii = 0; ii < uMACfragNum; ii++) { - // Poll Transmit the adapter - wmb(); - pHeadTD->m_td0TD0.f1Owner = OWNED_BY_NIC; - wmb(); - if (ii == (uMACfragNum - 1)) - pLastTD = pHeadTD; - pHeadTD = pHeadTD->next; - } - - pLastTD->pTDInfo->skb = NULL; - pLastTD->pTDInfo->byFlags = 0; - - pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD; - - MACvTransmitAC0(pDevice->PortOffset); - - return true; -} diff --git a/drivers/staging/vt6655/wroute.h b/drivers/staging/vt6655/wroute.h deleted file mode 100644 index e59eec955cac..000000000000 --- a/drivers/staging/vt6655/wroute.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: wroute.h - * - * Purpose: - * - * Author: Lyndon Chen - * - * Date: May 21, 2003 - * - */ - -#ifndef __WROUTE_H__ -#define __WROUTE_H__ - -#include "device.h" - -/*--------------------- Export Definitions -------------------------*/ - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -bool ROUTEbRelay(struct vnt_private *pDevice, unsigned char *pbySkbData, - unsigned int uDataLen, unsigned int uNodeIndex); - -#endif /* __WROUTE_H__ */ diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index dbc311c3dc37..b95d5b1efcc7 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -431,11 +431,8 @@ static bool vnt_alloc_bufs(struct vnt_private *priv) for (ii = 0; ii < priv->num_tx_context; ii++) { tx_context = kmalloc(sizeof(struct vnt_usb_send_context), GFP_KERNEL); - if (tx_context == NULL) { - dev_err(&priv->usb->dev, - "allocate tx usb context failed\n"); + if (tx_context == NULL) goto free_tx; - } priv->tx_context[ii] = tx_context; tx_context->priv = priv; @@ -471,10 +468,8 @@ static bool vnt_alloc_bufs(struct vnt_private *priv) } rcb->skb = dev_alloc_skb(priv->rx_buf_sz); - if (rcb->skb == NULL) { - dev_err(&priv->usb->dev, "Failed to alloc rx skb\n"); + if (rcb->skb == NULL) goto free_rx_tx; - } rcb->in_use = false; @@ -491,7 +486,6 @@ static bool vnt_alloc_bufs(struct vnt_private *priv) priv->int_buf.data_buf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL); if (priv->int_buf.data_buf == NULL) { - dev_err(&priv->usb->dev, "Failed to alloc int buf\n"); usb_free_urb(priv->interrupt_urb); goto free_rx_tx; } diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h index 1f2c78cc0086..20d146b61ba7 100644 --- a/drivers/staging/wlan-ng/hfa384x.h +++ b/drivers/staging/wlan-ng/hfa384x.h @@ -1376,6 +1376,7 @@ int hfa384x_drvr_setconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len); static inline int hfa384x_drvr_getconfig16(hfa384x_t *hw, u16 rid, void *val) { int result = 0; + result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(u16)); if (result == 0) *((u16 *) val) = le16_to_cpu(*((u16 *) val)); @@ -1385,6 +1386,7 @@ static inline int hfa384x_drvr_getconfig16(hfa384x_t *hw, u16 rid, void *val) static inline int hfa384x_drvr_setconfig16(hfa384x_t *hw, u16 rid, u16 val) { u16 value = cpu_to_le16(val); + return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value)); } @@ -1402,6 +1404,7 @@ static inline int hfa384x_drvr_setconfig16_async(hfa384x_t *hw, u16 rid, u16 val) { u16 value = cpu_to_le16(val); + return hfa384x_drvr_setconfig_async(hw, rid, &value, sizeof(value), NULL, NULL); } diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c index 898bde73c59a..55d2f563e308 100644 --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ b/drivers/staging/wlan-ng/hfa384x_usb.c @@ -3583,12 +3583,8 @@ static void hfa384x_int_rxmonitor(wlandevice_t *wlandev, } skb = dev_alloc_skb(skblen); - if (skb == NULL) { - netdev_err(hw->wlandev->netdev, - "alloc_skb failed trying to allocate %d bytes\n", - skblen); + if (skb == NULL) return; - } /* only prepend the prism header if in the right mode */ if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) && diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c index 3b5468c64fde..7eaaf9a63503 100644 --- a/drivers/staging/wlan-ng/p80211conv.c +++ b/drivers/staging/wlan-ng/p80211conv.c @@ -107,7 +107,7 @@ int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv, struct p80211_metawep *p80211_wep) { - u16 fc; + __le16 fc; u16 proto; struct wlan_ethhdr e_hdr; struct wlan_llc *e_llc; diff --git a/drivers/staging/wlan-ng/p80211hdr.h b/drivers/staging/wlan-ng/p80211hdr.h index 66b5e201d418..79d9b20b364d 100644 --- a/drivers/staging/wlan-ng/p80211hdr.h +++ b/drivers/staging/wlan-ng/p80211hdr.h @@ -148,7 +148,7 @@ /* Generic 802.11 Header types */ struct p80211_hdr_a3 { - u16 fc; + __le16 fc; u16 dur; u8 a1[ETH_ALEN]; u8 a2[ETH_ALEN]; diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index 2dd9bf8a6e18..a9c1e0bafa62 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c @@ -358,7 +358,7 @@ static int p80211knetdev_hard_start_xmit(struct sk_buff *skb, * and return success . * TODO: we need a saner way to handle this */ - if (skb->protocol != ETH_P_80211_RAW) { + if (be16_to_cpu(skb->protocol) != ETH_P_80211_RAW) { netif_start_queue(wlandev->netdev); netdev_notice(netdev, "Tx attempt prior to association, frame dropped.\n"); netdev->stats.tx_dropped++; @@ -369,7 +369,7 @@ static int p80211knetdev_hard_start_xmit(struct sk_buff *skb, } /* Check for raw transmits */ - if (skb->protocol == ETH_P_80211_RAW) { + if (be16_to_cpu(skb->protocol) == ETH_P_80211_RAW) { if (!capable(CAP_NET_ADMIN)) { result = 1; goto failed; diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index 6c38f797d1ab..9408644cc8b8 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -238,7 +238,8 @@ static int prism2_fwtry(struct usb_device *udev, wlandevice_t *wlandev) * 0 - success * ~0 - failure ----------------------------------------------------------------*/ -static int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev) +static int prism2_fwapply(const struct ihex_binrec *rfptr, + wlandevice_t *wlandev) { signed int result = 0; struct p80211msg_dot11req_mibget getmsg; @@ -986,8 +987,8 @@ static int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk, u32 currlen; u32 currdaddr; - rstmsg = kmalloc(sizeof(*rstmsg), GFP_KERNEL); - rwrmsg = kmalloc(sizeof(*rwrmsg), GFP_KERNEL); + rstmsg = kzalloc(sizeof(*rstmsg), GFP_KERNEL); + rwrmsg = kzalloc(sizeof(*rwrmsg), GFP_KERNEL); if (!rstmsg || !rwrmsg) { kfree(rstmsg); kfree(rwrmsg); @@ -997,7 +998,6 @@ static int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk, } /* Initialize the messages */ - memset(rstmsg, 0, sizeof(*rstmsg)); strcpy(rstmsg->devname, wlandev->name); rstmsg->msgcode = DIDmsg_p2req_ramdl_state; rstmsg->msglen = sizeof(*rstmsg); @@ -1011,7 +1011,6 @@ static int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk, rstmsg->exeaddr.len = sizeof(u32); rstmsg->resultcode.len = sizeof(u32); - memset(rwrmsg, 0, sizeof(*rwrmsg)); strcpy(rwrmsg->devname, wlandev->name); rwrmsg->msgcode = DIDmsg_p2req_ramdl_write; rwrmsg->msglen = sizeof(*rwrmsg); diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index be7778b59118..709d49e7f3c9 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -2012,7 +2012,7 @@ static int xgifb_probe(struct pci_dev *pdev, XGIfb_get_fix(&fb_info->fix, -1, fb_info); fb_info->pseudo_palette = xgifb_info->pseudo_palette; - fb_alloc_cmap(&fb_info->cmap, 256 , 0); + fb_alloc_cmap(&fb_info->cmap, 256, 0); #ifdef CONFIG_MTRR xgifb_info->mtrr = mtrr_add(xgifb_info->video_base, diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index 481eb174fdf0..d9524a2e9ce4 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -7,7 +7,6 @@ #define SupportCRT2in301C 0x0100 /* for 301C */ #define SetCHTVOverScan 0x8000 -#define Panel_320x480 0x07 /*fstn*/ #define PanelResInfo 0x1F /* CR36 Panel Type/LCDResInfo */ #define Panel_1024x768x75 0x22 #define Panel_1280x1024x75 0x23 diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index d5f49d2a8db3..1f6f699e238c 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -4135,7 +4135,7 @@ static void XGI_SetGroup4(unsigned short ModeIdIndex, tempax -= 1; temp = (tempax & 0xFF00) >> 8; - temp = ((temp & 0x0003) << 4); + temp = (temp & 0x0003) << 4; xgifb_reg_set(pVBInfo->Part4Port, 0x1E, temp); temp = (tempax & 0x00FF); xgifb_reg_set(pVBInfo->Part4Port, 0x1D, temp); diff --git a/drivers/staging/xgifb/vb_util.c b/drivers/staging/xgifb/vb_util.c index 1b452f8b6274..be3437ca339e 100644 --- a/drivers/staging/xgifb/vb_util.c +++ b/drivers/staging/xgifb/vb_util.c @@ -9,11 +9,8 @@ void xgifb_reg_set(unsigned long port, u8 index, u8 data) u8 xgifb_reg_get(unsigned long port, u8 index) { - u8 data; - outb(index, port); - data = inb(port + 1); - return data; + return inb(port + 1); } void xgifb_reg_and_or(unsigned long port, u8 index, diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 73e58d22e325..aebde3289c50 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -609,6 +609,7 @@ static int __init iscsi_target_init_module(void) return ret; r2t_out: + iscsit_unregister_transport(&iscsi_target_transport); kmem_cache_destroy(lio_r2t_cache); ooo_out: kmem_cache_destroy(lio_ooo_cache); @@ -943,17 +944,17 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, */ if ((iscsi_task_attr == ISCSI_ATTR_UNTAGGED) || (iscsi_task_attr == ISCSI_ATTR_SIMPLE)) - sam_task_attr = MSG_SIMPLE_TAG; + sam_task_attr = TCM_SIMPLE_TAG; else if (iscsi_task_attr == ISCSI_ATTR_ORDERED) - sam_task_attr = MSG_ORDERED_TAG; + sam_task_attr = TCM_ORDERED_TAG; else if (iscsi_task_attr == ISCSI_ATTR_HEAD_OF_QUEUE) - sam_task_attr = MSG_HEAD_TAG; + sam_task_attr = TCM_HEAD_TAG; else if (iscsi_task_attr == ISCSI_ATTR_ACA) - sam_task_attr = MSG_ACA_TAG; + sam_task_attr = TCM_ACA_TAG; else { pr_debug("Unknown iSCSI Task Attribute: 0x%02x, using" - " MSG_SIMPLE_TAG\n", iscsi_task_attr); - sam_task_attr = MSG_SIMPLE_TAG; + " TCM_SIMPLE_TAG\n", iscsi_task_attr); + sam_task_attr = TCM_SIMPLE_TAG; } cmd->iscsi_opcode = ISCSI_OP_SCSI_CMD; @@ -1811,7 +1812,7 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, transport_init_se_cmd(&cmd->se_cmd, &lio_target_fabric_configfs->tf_ops, conn->sess->se_sess, 0, DMA_NONE, - MSG_SIMPLE_TAG, cmd->sense_buffer + 2); + TCM_SIMPLE_TAG, cmd->sense_buffer + 2); target_get_sess_cmd(conn->sess->se_sess, &cmd->se_cmd, true); sess_ref = true; @@ -2026,10 +2027,10 @@ iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, goto reject; } if (!strncmp("=All", text_ptr, 4)) { - cmd->cmd_flags |= IFC_SENDTARGETS_ALL; + cmd->cmd_flags |= ICF_SENDTARGETS_ALL; } else if (!strncmp("=iqn.", text_ptr, 5) || !strncmp("=eui.", text_ptr, 5)) { - cmd->cmd_flags |= IFC_SENDTARGETS_SINGLE; + cmd->cmd_flags |= ICF_SENDTARGETS_SINGLE; } else { pr_err("Unable to locate valid SendTargets=%s value\n", text_ptr); goto reject; @@ -3414,10 +3415,10 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd, return -ENOMEM; } /* - * Locate pointer to iqn./eui. string for IFC_SENDTARGETS_SINGLE + * Locate pointer to iqn./eui. string for ICF_SENDTARGETS_SINGLE * explicit case.. */ - if (cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) { + if (cmd->cmd_flags & ICF_SENDTARGETS_SINGLE) { text_ptr = strchr(text_in, '='); if (!text_ptr) { pr_err("Unable to locate '=' string in text_in:" @@ -3433,7 +3434,7 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd, spin_lock(&tiqn_lock); list_for_each_entry(tiqn, &g_tiqn_list, tiqn_list) { - if ((cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) && + if ((cmd->cmd_flags & ICF_SENDTARGETS_SINGLE) && strcmp(tiqn->tiqn, text_ptr)) { continue; } @@ -3511,7 +3512,7 @@ eob: if (end_of_buf) break; - if (cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) + if (cmd->cmd_flags & ICF_SENDTARGETS_SINGLE) break; } spin_unlock(&tiqn_lock); diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index 302eb3b78715..cbcff38ac9b7 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h @@ -135,8 +135,8 @@ enum cmd_flags_table { ICF_CONTIG_MEMORY = 0x00000020, ICF_ATTACHED_TO_RQUEUE = 0x00000040, ICF_OOO_CMDSN = 0x00000080, - IFC_SENDTARGETS_ALL = 0x00000100, - IFC_SENDTARGETS_SINGLE = 0x00000200, + ICF_SENDTARGETS_ALL = 0x00000100, + ICF_SENDTARGETS_SINGLE = 0x00000200, }; /* struct iscsi_cmd->i_state */ @@ -790,7 +790,6 @@ struct iscsi_np { void *np_context; struct iscsit_transport *np_transport; struct list_head np_list; - struct iscsi_tpg_np *tpg_np; } ____cacheline_aligned; struct iscsi_tpg_np { diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 480f2e0ecc11..713c0c1877ab 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -281,7 +281,6 @@ static int iscsi_login_zero_tsih_s1( { struct iscsi_session *sess = NULL; struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf; - enum target_prot_op sup_pro_ops; int ret; sess = kzalloc(sizeof(struct iscsi_session), GFP_KERNEL); @@ -343,9 +342,8 @@ static int iscsi_login_zero_tsih_s1( kfree(sess); return -ENOMEM; } - sup_pro_ops = conn->conn_transport->iscsit_get_sup_prot_ops(conn); - sess->se_sess = transport_init_session(sup_pro_ops); + sess->se_sess = transport_init_session(TARGET_PROT_NORMAL); if (IS_ERR(sess->se_sess)) { iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, ISCSI_LOGIN_STATUS_NO_RESOURCES); @@ -1161,6 +1159,7 @@ void iscsi_target_login_sess_out(struct iscsi_conn *conn, } kfree(conn->sess->sess_ops); kfree(conn->sess); + conn->sess = NULL; old_sess_out: iscsi_stop_login_thread_timer(np); @@ -1204,6 +1203,9 @@ old_sess_out: conn->sock = NULL; } + if (conn->conn_transport->iscsit_wait_conn) + conn->conn_transport->iscsit_wait_conn(conn); + if (conn->conn_transport->iscsit_free_conn) conn->conn_transport->iscsit_free_conn(conn); @@ -1364,6 +1366,9 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) } login->zero_tsih = zero_tsih; + conn->sess->se_sess->sup_prot_ops = + conn->conn_transport->iscsit_get_sup_prot_ops(conn); + tpg = conn->tpg; if (!tpg) { pr_err("Unable to locate struct iscsi_conn->tpg\n"); diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi/iscsi_target_tpg.c index c3cb5c15efda..9053a3c0c6e5 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.c +++ b/drivers/target/iscsi/iscsi_target_tpg.c @@ -501,7 +501,6 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal( init_completion(&tpg_np->tpg_np_comp); kref_init(&tpg_np->tpg_np_kref); tpg_np->tpg_np = np; - np->tpg_np = tpg_np; tpg_np->tpg = tpg; spin_lock(&tpg->tpg_np_lock); diff --git a/drivers/target/iscsi/iscsi_target_transport.c b/drivers/target/iscsi/iscsi_target_transport.c index 882728fac30c..08217d62fb0d 100644 --- a/drivers/target/iscsi/iscsi_target_transport.c +++ b/drivers/target/iscsi/iscsi_target_transport.c @@ -26,8 +26,7 @@ struct iscsit_transport *iscsit_get_transport(int type) void iscsit_put_transport(struct iscsit_transport *t) { - if (t->owner) - module_put(t->owner); + module_put(t->owner); } int iscsit_register_transport(struct iscsit_transport *t) diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 7c6a95bcb35e..bcd88ec99793 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -1356,15 +1356,15 @@ static int iscsit_do_tx_data( struct iscsi_conn *conn, struct iscsi_data_count *count) { - int data = count->data_length, total_tx = 0, tx_loop = 0, iov_len; + int ret, iov_len; struct kvec *iov_p; struct msghdr msg; if (!conn || !conn->sock || !conn->conn_ops) return -1; - if (data <= 0) { - pr_err("Data length is: %d\n", data); + if (count->data_length <= 0) { + pr_err("Data length is: %d\n", count->data_length); return -1; } @@ -1373,20 +1373,16 @@ static int iscsit_do_tx_data( iov_p = count->iov; iov_len = count->iov_count; - while (total_tx < data) { - tx_loop = kernel_sendmsg(conn->sock, &msg, iov_p, iov_len, - (data - total_tx)); - if (tx_loop <= 0) { - pr_debug("tx_loop: %d total_tx %d\n", - tx_loop, total_tx); - return tx_loop; - } - total_tx += tx_loop; - pr_debug("tx_loop: %d, total_tx: %d, data: %d\n", - tx_loop, total_tx, data); + ret = kernel_sendmsg(conn->sock, &msg, iov_p, iov_len, + count->data_length); + if (ret != count->data_length) { + pr_err("Unexpected ret: %d send data %d\n", + ret, count->data_length); + return -EPIPE; } + pr_debug("ret: %d, sent data: %d\n", ret, count->data_length); - return total_tx; + return ret; } int rx_data( diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 4d1b7224a7f2..6b3c32954689 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -138,7 +138,7 @@ static void tcm_loop_submission_work(struct work_struct *work) set_host_byte(sc, DID_TRANSPORT_DISRUPTED); goto out_done; } - tl_nexus = tl_hba->tl_nexus; + tl_nexus = tl_tpg->tl_nexus; if (!tl_nexus) { scmd_printk(KERN_ERR, sc, "TCM_Loop I_T Nexus" " does not exist\n"); @@ -168,7 +168,7 @@ static void tcm_loop_submission_work(struct work_struct *work) rc = target_submit_cmd_map_sgls(se_cmd, tl_nexus->se_sess, sc->cmnd, &tl_cmd->tl_sense_buf[0], tl_cmd->sc->device->lun, - transfer_length, MSG_SIMPLE_TAG, + transfer_length, TCM_SIMPLE_TAG, sc->sc_data_direction, 0, scsi_sglist(sc), scsi_sg_count(sc), sgl_bidi, sgl_bidi_count, @@ -218,16 +218,26 @@ static int tcm_loop_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc) * to struct scsi_device */ static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg, - struct tcm_loop_nexus *tl_nexus, int lun, int task, enum tcm_tmreq_table tmr) { struct se_cmd *se_cmd = NULL; struct se_session *se_sess; struct se_portal_group *se_tpg; + struct tcm_loop_nexus *tl_nexus; struct tcm_loop_cmd *tl_cmd = NULL; struct tcm_loop_tmr *tl_tmr = NULL; int ret = TMR_FUNCTION_FAILED, rc; + /* + * Locate the tl_nexus and se_sess pointers + */ + tl_nexus = tl_tpg->tl_nexus; + if (!tl_nexus) { + pr_err("Unable to perform device reset without" + " active I_T Nexus\n"); + return ret; + } + tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_KERNEL); if (!tl_cmd) { pr_err("Unable to allocate memory for tl_cmd\n"); @@ -243,12 +253,12 @@ static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg, se_cmd = &tl_cmd->tl_se_cmd; se_tpg = &tl_tpg->tl_se_tpg; - se_sess = tl_nexus->se_sess; + se_sess = tl_tpg->tl_nexus->se_sess; /* * Initialize struct se_cmd descriptor from target_core_mod infrastructure */ transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, 0, - DMA_NONE, MSG_SIMPLE_TAG, + DMA_NONE, TCM_SIMPLE_TAG, &tl_cmd->tl_sense_buf[0]); rc = core_tmr_alloc_req(se_cmd, tl_tmr, tmr, GFP_KERNEL); @@ -288,7 +298,6 @@ release: static int tcm_loop_abort_task(struct scsi_cmnd *sc) { struct tcm_loop_hba *tl_hba; - struct tcm_loop_nexus *tl_nexus; struct tcm_loop_tpg *tl_tpg; int ret = FAILED; @@ -296,21 +305,8 @@ static int tcm_loop_abort_task(struct scsi_cmnd *sc) * Locate the tcm_loop_hba_t pointer */ tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host); - /* - * Locate the tl_nexus and se_sess pointers - */ - tl_nexus = tl_hba->tl_nexus; - if (!tl_nexus) { - pr_err("Unable to perform device reset without" - " active I_T Nexus\n"); - return FAILED; - } - - /* - * Locate the tl_tpg pointer from TargetID in sc->device->id - */ tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id]; - ret = tcm_loop_issue_tmr(tl_tpg, tl_nexus, sc->device->lun, + ret = tcm_loop_issue_tmr(tl_tpg, sc->device->lun, sc->request->tag, TMR_ABORT_TASK); return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED; } @@ -322,7 +318,6 @@ static int tcm_loop_abort_task(struct scsi_cmnd *sc) static int tcm_loop_device_reset(struct scsi_cmnd *sc) { struct tcm_loop_hba *tl_hba; - struct tcm_loop_nexus *tl_nexus; struct tcm_loop_tpg *tl_tpg; int ret = FAILED; @@ -330,20 +325,9 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc) * Locate the tcm_loop_hba_t pointer */ tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host); - /* - * Locate the tl_nexus and se_sess pointers - */ - tl_nexus = tl_hba->tl_nexus; - if (!tl_nexus) { - pr_err("Unable to perform device reset without" - " active I_T Nexus\n"); - return FAILED; - } - /* - * Locate the tl_tpg pointer from TargetID in sc->device->id - */ tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id]; - ret = tcm_loop_issue_tmr(tl_tpg, tl_nexus, sc->device->lun, + + ret = tcm_loop_issue_tmr(tl_tpg, sc->device->lun, 0, TMR_LUN_RESET); return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED; } @@ -385,7 +369,6 @@ static struct scsi_host_template tcm_loop_driver_template = { .name = "TCM_Loopback", .queuecommand = tcm_loop_queuecommand, .change_queue_depth = scsi_change_queue_depth, - .change_queue_type = scsi_change_queue_type, .eh_abort_handler = tcm_loop_abort_task, .eh_device_reset_handler = tcm_loop_device_reset, .eh_target_reset_handler = tcm_loop_target_reset, @@ -940,8 +923,8 @@ static int tcm_loop_make_nexus( struct tcm_loop_nexus *tl_nexus; int ret = -ENOMEM; - if (tl_tpg->tl_hba->tl_nexus) { - pr_debug("tl_tpg->tl_hba->tl_nexus already exists\n"); + if (tl_tpg->tl_nexus) { + pr_debug("tl_tpg->tl_nexus already exists\n"); return -EEXIST; } se_tpg = &tl_tpg->tl_se_tpg; @@ -976,7 +959,7 @@ static int tcm_loop_make_nexus( */ __transport_register_session(se_tpg, tl_nexus->se_sess->se_node_acl, tl_nexus->se_sess, tl_nexus); - tl_tpg->tl_hba->tl_nexus = tl_nexus; + tl_tpg->tl_nexus = tl_nexus; pr_debug("TCM_Loop_ConfigFS: Established I_T Nexus to emulated" " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tl_hba), name); @@ -992,12 +975,8 @@ static int tcm_loop_drop_nexus( { struct se_session *se_sess; struct tcm_loop_nexus *tl_nexus; - struct tcm_loop_hba *tl_hba = tpg->tl_hba; - if (!tl_hba) - return -ENODEV; - - tl_nexus = tl_hba->tl_nexus; + tl_nexus = tpg->tl_nexus; if (!tl_nexus) return -ENODEV; @@ -1013,13 +992,13 @@ static int tcm_loop_drop_nexus( } pr_debug("TCM_Loop_ConfigFS: Removing I_T Nexus to emulated" - " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tl_hba), + " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tpg->tl_hba), tl_nexus->se_sess->se_node_acl->initiatorname); /* * Release the SCSI I_T Nexus to the emulated SAS Target Port */ transport_deregister_session(tl_nexus->se_sess); - tpg->tl_hba->tl_nexus = NULL; + tpg->tl_nexus = NULL; kfree(tl_nexus); return 0; } @@ -1035,7 +1014,7 @@ static ssize_t tcm_loop_tpg_show_nexus( struct tcm_loop_nexus *tl_nexus; ssize_t ret; - tl_nexus = tl_tpg->tl_hba->tl_nexus; + tl_nexus = tl_tpg->tl_nexus; if (!tl_nexus) return -ENODEV; diff --git a/drivers/target/loopback/tcm_loop.h b/drivers/target/loopback/tcm_loop.h index 54c59d0b6608..6ae49f272ba6 100644 --- a/drivers/target/loopback/tcm_loop.h +++ b/drivers/target/loopback/tcm_loop.h @@ -27,11 +27,6 @@ struct tcm_loop_tmr { }; struct tcm_loop_nexus { - int it_nexus_active; - /* - * Pointer to Linux/SCSI HBA from linux/include/scsi_host.h - */ - struct scsi_host *sh; /* * Pointer to TCM session for I_T Nexus */ @@ -51,6 +46,7 @@ struct tcm_loop_tpg { atomic_t tl_tpg_port_count; struct se_portal_group tl_se_tpg; struct tcm_loop_hba *tl_hba; + struct tcm_loop_nexus *tl_nexus; }; struct tcm_loop_hba { @@ -59,7 +55,6 @@ struct tcm_loop_hba { struct se_hba_s *se_hba; struct se_lun *tl_hba_lun; struct se_port *tl_hba_lun_sep; - struct tcm_loop_nexus *tl_nexus; struct device dev; struct Scsi_Host *sh; struct tcm_loop_tpg tl_hba_tpgs[TL_TPGS_PER_HBA]; diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index e7e93727553c..9512af6a8114 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -1237,7 +1237,7 @@ static void sbp_handle_command(struct sbp_target_request *req) if (target_submit_cmd(&req->se_cmd, sess->se_sess, req->cmd_buf, req->sense_buf, unpacked_lun, data_length, - MSG_SIMPLE_TAG, data_dir, 0)) + TCM_SIMPLE_TAG, data_dir, 0)) goto err; return; diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 79f9296a08ae..75d89adfccc0 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -50,6 +50,19 @@ #include "target_core_rd.h" #include "target_core_xcopy.h" +#define TB_CIT_SETUP(_name, _item_ops, _group_ops, _attrs) \ +static void target_core_setup_##_name##_cit(struct se_subsystem_api *sa) \ +{ \ + struct target_backend_cits *tbc = &sa->tb_cits; \ + struct config_item_type *cit = &tbc->tb_##_name##_cit; \ + \ + cit->ct_item_ops = _item_ops; \ + cit->ct_group_ops = _group_ops; \ + cit->ct_attrs = _attrs; \ + cit->ct_owner = sa->owner; \ + pr_debug("Setup generic %s\n", __stringify(_name)); \ +} + extern struct t10_alua_lu_gp *default_lu_gp; static LIST_HEAD(g_tf_list); @@ -126,48 +139,57 @@ static struct config_group *target_core_register_fabric( pr_debug("Target_Core_ConfigFS: REGISTER -> group: %p name:" " %s\n", group, name); - /* - * Below are some hardcoded request_module() calls to automatically - * local fabric modules when the following is called: - * - * mkdir -p /sys/kernel/config/target/$MODULE_NAME - * - * Note that this does not limit which TCM fabric module can be - * registered, but simply provids auto loading logic for modules with - * mkdir(2) system calls with known TCM fabric modules. - */ - if (!strncmp(name, "iscsi", 5)) { + + tf = target_core_get_fabric(name); + if (!tf) { + pr_err("target_core_register_fabric() trying autoload for %s\n", + name); + /* - * Automatically load the LIO Target fabric module when the - * following is called: + * Below are some hardcoded request_module() calls to automatically + * local fabric modules when the following is called: * - * mkdir -p $CONFIGFS/target/iscsi - */ - ret = request_module("iscsi_target_mod"); - if (ret < 0) { - pr_err("request_module() failed for" - " iscsi_target_mod.ko: %d\n", ret); - return ERR_PTR(-EINVAL); - } - } else if (!strncmp(name, "loopback", 8)) { - /* - * Automatically load the tcm_loop fabric module when the - * following is called: + * mkdir -p /sys/kernel/config/target/$MODULE_NAME * - * mkdir -p $CONFIGFS/target/loopback + * Note that this does not limit which TCM fabric module can be + * registered, but simply provids auto loading logic for modules with + * mkdir(2) system calls with known TCM fabric modules. */ - ret = request_module("tcm_loop"); - if (ret < 0) { - pr_err("request_module() failed for" - " tcm_loop.ko: %d\n", ret); - return ERR_PTR(-EINVAL); + + if (!strncmp(name, "iscsi", 5)) { + /* + * Automatically load the LIO Target fabric module when the + * following is called: + * + * mkdir -p $CONFIGFS/target/iscsi + */ + ret = request_module("iscsi_target_mod"); + if (ret < 0) { + pr_err("request_module() failed for" + " iscsi_target_mod.ko: %d\n", ret); + return ERR_PTR(-EINVAL); + } + } else if (!strncmp(name, "loopback", 8)) { + /* + * Automatically load the tcm_loop fabric module when the + * following is called: + * + * mkdir -p $CONFIGFS/target/loopback + */ + ret = request_module("tcm_loop"); + if (ret < 0) { + pr_err("request_module() failed for" + " tcm_loop.ko: %d\n", ret); + return ERR_PTR(-EINVAL); + } } + + tf = target_core_get_fabric(name); } - tf = target_core_get_fabric(name); if (!tf) { pr_err("target_core_get_fabric() failed for %s\n", - name); + name); return ERR_PTR(-EINVAL); } pr_debug("Target_Core_ConfigFS: REGISTER -> Located fabric:" @@ -562,198 +584,21 @@ EXPORT_SYMBOL(target_fabric_configfs_deregister); // Stop functions called by external Target Fabrics Modules //############################################################################*/ -/* Start functions for struct config_item_type target_core_dev_attrib_cit */ - -#define DEF_DEV_ATTRIB_SHOW(_name) \ -static ssize_t target_core_dev_show_attr_##_name( \ - struct se_dev_attrib *da, \ - char *page) \ -{ \ - return snprintf(page, PAGE_SIZE, "%u\n", \ - (u32)da->da_dev->dev_attrib._name); \ -} - -#define DEF_DEV_ATTRIB_STORE(_name) \ -static ssize_t target_core_dev_store_attr_##_name( \ - struct se_dev_attrib *da, \ - const char *page, \ - size_t count) \ -{ \ - unsigned long val; \ - int ret; \ - \ - ret = kstrtoul(page, 0, &val); \ - if (ret < 0) { \ - pr_err("kstrtoul() failed with" \ - " ret: %d\n", ret); \ - return -EINVAL; \ - } \ - ret = se_dev_set_##_name(da->da_dev, (u32)val); \ - \ - return (!ret) ? count : -EINVAL; \ -} - -#define DEF_DEV_ATTRIB(_name) \ -DEF_DEV_ATTRIB_SHOW(_name); \ -DEF_DEV_ATTRIB_STORE(_name); - -#define DEF_DEV_ATTRIB_RO(_name) \ -DEF_DEV_ATTRIB_SHOW(_name); +/* Start functions for struct config_item_type tb_dev_attrib_cit */ CONFIGFS_EATTR_STRUCT(target_core_dev_attrib, se_dev_attrib); -#define SE_DEV_ATTR(_name, _mode) \ -static struct target_core_dev_attrib_attribute \ - target_core_dev_attrib_##_name = \ - __CONFIGFS_EATTR(_name, _mode, \ - target_core_dev_show_attr_##_name, \ - target_core_dev_store_attr_##_name); - -#define SE_DEV_ATTR_RO(_name); \ -static struct target_core_dev_attrib_attribute \ - target_core_dev_attrib_##_name = \ - __CONFIGFS_EATTR_RO(_name, \ - target_core_dev_show_attr_##_name); - -DEF_DEV_ATTRIB(emulate_model_alias); -SE_DEV_ATTR(emulate_model_alias, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_dpo); -SE_DEV_ATTR(emulate_dpo, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_fua_write); -SE_DEV_ATTR(emulate_fua_write, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_fua_read); -SE_DEV_ATTR(emulate_fua_read, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_write_cache); -SE_DEV_ATTR(emulate_write_cache, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_ua_intlck_ctrl); -SE_DEV_ATTR(emulate_ua_intlck_ctrl, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_tas); -SE_DEV_ATTR(emulate_tas, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_tpu); -SE_DEV_ATTR(emulate_tpu, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_tpws); -SE_DEV_ATTR(emulate_tpws, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_caw); -SE_DEV_ATTR(emulate_caw, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_3pc); -SE_DEV_ATTR(emulate_3pc, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(pi_prot_type); -SE_DEV_ATTR(pi_prot_type, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB_RO(hw_pi_prot_type); -SE_DEV_ATTR_RO(hw_pi_prot_type); - -DEF_DEV_ATTRIB(pi_prot_format); -SE_DEV_ATTR(pi_prot_format, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(enforce_pr_isids); -SE_DEV_ATTR(enforce_pr_isids, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(is_nonrot); -SE_DEV_ATTR(is_nonrot, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_rest_reord); -SE_DEV_ATTR(emulate_rest_reord, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(force_pr_aptpl); -SE_DEV_ATTR(force_pr_aptpl, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB_RO(hw_block_size); -SE_DEV_ATTR_RO(hw_block_size); - -DEF_DEV_ATTRIB(block_size); -SE_DEV_ATTR(block_size, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB_RO(hw_max_sectors); -SE_DEV_ATTR_RO(hw_max_sectors); - -DEF_DEV_ATTRIB(fabric_max_sectors); -SE_DEV_ATTR(fabric_max_sectors, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(optimal_sectors); -SE_DEV_ATTR(optimal_sectors, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB_RO(hw_queue_depth); -SE_DEV_ATTR_RO(hw_queue_depth); - -DEF_DEV_ATTRIB(queue_depth); -SE_DEV_ATTR(queue_depth, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(max_unmap_lba_count); -SE_DEV_ATTR(max_unmap_lba_count, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(max_unmap_block_desc_count); -SE_DEV_ATTR(max_unmap_block_desc_count, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(unmap_granularity); -SE_DEV_ATTR(unmap_granularity, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(unmap_granularity_alignment); -SE_DEV_ATTR(unmap_granularity_alignment, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(max_write_same_len); -SE_DEV_ATTR(max_write_same_len, S_IRUGO | S_IWUSR); - CONFIGFS_EATTR_OPS(target_core_dev_attrib, se_dev_attrib, da_group); -static struct configfs_attribute *target_core_dev_attrib_attrs[] = { - &target_core_dev_attrib_emulate_model_alias.attr, - &target_core_dev_attrib_emulate_dpo.attr, - &target_core_dev_attrib_emulate_fua_write.attr, - &target_core_dev_attrib_emulate_fua_read.attr, - &target_core_dev_attrib_emulate_write_cache.attr, - &target_core_dev_attrib_emulate_ua_intlck_ctrl.attr, - &target_core_dev_attrib_emulate_tas.attr, - &target_core_dev_attrib_emulate_tpu.attr, - &target_core_dev_attrib_emulate_tpws.attr, - &target_core_dev_attrib_emulate_caw.attr, - &target_core_dev_attrib_emulate_3pc.attr, - &target_core_dev_attrib_pi_prot_type.attr, - &target_core_dev_attrib_hw_pi_prot_type.attr, - &target_core_dev_attrib_pi_prot_format.attr, - &target_core_dev_attrib_enforce_pr_isids.attr, - &target_core_dev_attrib_force_pr_aptpl.attr, - &target_core_dev_attrib_is_nonrot.attr, - &target_core_dev_attrib_emulate_rest_reord.attr, - &target_core_dev_attrib_hw_block_size.attr, - &target_core_dev_attrib_block_size.attr, - &target_core_dev_attrib_hw_max_sectors.attr, - &target_core_dev_attrib_fabric_max_sectors.attr, - &target_core_dev_attrib_optimal_sectors.attr, - &target_core_dev_attrib_hw_queue_depth.attr, - &target_core_dev_attrib_queue_depth.attr, - &target_core_dev_attrib_max_unmap_lba_count.attr, - &target_core_dev_attrib_max_unmap_block_desc_count.attr, - &target_core_dev_attrib_unmap_granularity.attr, - &target_core_dev_attrib_unmap_granularity_alignment.attr, - &target_core_dev_attrib_max_write_same_len.attr, - NULL, -}; - static struct configfs_item_operations target_core_dev_attrib_ops = { .show_attribute = target_core_dev_attrib_attr_show, .store_attribute = target_core_dev_attrib_attr_store, }; -static struct config_item_type target_core_dev_attrib_cit = { - .ct_item_ops = &target_core_dev_attrib_ops, - .ct_attrs = target_core_dev_attrib_attrs, - .ct_owner = THIS_MODULE, -}; +TB_CIT_SETUP(dev_attrib, &target_core_dev_attrib_ops, NULL, NULL); -/* End functions for struct config_item_type target_core_dev_attrib_cit */ +/* End functions for struct config_item_type tb_dev_attrib_cit */ -/* Start functions for struct config_item_type target_core_dev_wwn_cit */ +/* Start functions for struct config_item_type tb_dev_wwn_cit */ CONFIGFS_EATTR_STRUCT(target_core_dev_wwn, t10_wwn); #define SE_DEV_WWN_ATTR(_name, _mode) \ @@ -984,15 +829,11 @@ static struct configfs_item_operations target_core_dev_wwn_ops = { .store_attribute = target_core_dev_wwn_attr_store, }; -static struct config_item_type target_core_dev_wwn_cit = { - .ct_item_ops = &target_core_dev_wwn_ops, - .ct_attrs = target_core_dev_wwn_attrs, - .ct_owner = THIS_MODULE, -}; +TB_CIT_SETUP(dev_wwn, &target_core_dev_wwn_ops, NULL, target_core_dev_wwn_attrs); -/* End functions for struct config_item_type target_core_dev_wwn_cit */ +/* End functions for struct config_item_type tb_dev_wwn_cit */ -/* Start functions for struct config_item_type target_core_dev_pr_cit */ +/* Start functions for struct config_item_type tb_dev_pr_cit */ CONFIGFS_EATTR_STRUCT(target_core_dev_pr, se_device); #define SE_DEV_PR_ATTR(_name, _mode) \ @@ -1453,15 +1294,11 @@ static struct configfs_item_operations target_core_dev_pr_ops = { .store_attribute = target_core_dev_pr_attr_store, }; -static struct config_item_type target_core_dev_pr_cit = { - .ct_item_ops = &target_core_dev_pr_ops, - .ct_attrs = target_core_dev_pr_attrs, - .ct_owner = THIS_MODULE, -}; +TB_CIT_SETUP(dev_pr, &target_core_dev_pr_ops, NULL, target_core_dev_pr_attrs); -/* End functions for struct config_item_type target_core_dev_pr_cit */ +/* End functions for struct config_item_type tb_dev_pr_cit */ -/* Start functions for struct config_item_type target_core_dev_cit */ +/* Start functions for struct config_item_type tb_dev_cit */ static ssize_t target_core_show_dev_info(void *p, char *page) { @@ -1925,7 +1762,7 @@ static struct target_core_configfs_attribute target_core_attr_dev_lba_map = { .store = target_core_store_dev_lba_map, }; -static struct configfs_attribute *lio_core_dev_attrs[] = { +static struct configfs_attribute *target_core_dev_attrs[] = { &target_core_attr_dev_info.attr, &target_core_attr_dev_control.attr, &target_core_attr_dev_alias.attr, @@ -1984,13 +1821,9 @@ static struct configfs_item_operations target_core_dev_item_ops = { .store_attribute = target_core_dev_store, }; -static struct config_item_type target_core_dev_cit = { - .ct_item_ops = &target_core_dev_item_ops, - .ct_attrs = lio_core_dev_attrs, - .ct_owner = THIS_MODULE, -}; +TB_CIT_SETUP(dev, &target_core_dev_item_ops, NULL, target_core_dev_attrs); -/* End functions for struct config_item_type target_core_dev_cit */ +/* End functions for struct config_item_type tb_dev_cit */ /* Start functions for struct config_item_type target_core_alua_lu_gp_cit */ @@ -2670,7 +2503,7 @@ static struct config_item_type target_core_alua_tg_pt_gp_cit = { /* End functions for struct config_item_type target_core_alua_tg_pt_gp_cit */ -/* Start functions for struct config_item_type target_core_alua_tg_pt_gps_cit */ +/* Start functions for struct config_item_type tb_alua_tg_pt_gps_cit */ static struct config_group *target_core_alua_create_tg_pt_gp( struct config_group *group, @@ -2721,12 +2554,9 @@ static struct configfs_group_operations target_core_alua_tg_pt_gps_group_ops = { .drop_item = &target_core_alua_drop_tg_pt_gp, }; -static struct config_item_type target_core_alua_tg_pt_gps_cit = { - .ct_group_ops = &target_core_alua_tg_pt_gps_group_ops, - .ct_owner = THIS_MODULE, -}; +TB_CIT_SETUP(dev_alua_tg_pt_gps, NULL, &target_core_alua_tg_pt_gps_group_ops, NULL); -/* End functions for struct config_item_type target_core_alua_tg_pt_gps_cit */ +/* End functions for struct config_item_type tb_alua_tg_pt_gps_cit */ /* Start functions for struct config_item_type target_core_alua_cit */ @@ -2744,7 +2574,7 @@ static struct config_item_type target_core_alua_cit = { /* End functions for struct config_item_type target_core_alua_cit */ -/* Start functions for struct config_item_type target_core_stat_cit */ +/* Start functions for struct config_item_type tb_dev_stat_cit */ static struct config_group *target_core_stat_mkdir( struct config_group *group, @@ -2765,12 +2595,9 @@ static struct configfs_group_operations target_core_stat_group_ops = { .drop_item = &target_core_stat_rmdir, }; -static struct config_item_type target_core_stat_cit = { - .ct_group_ops = &target_core_stat_group_ops, - .ct_owner = THIS_MODULE, -}; +TB_CIT_SETUP(dev_stat, NULL, &target_core_stat_group_ops, NULL); -/* End functions for struct config_item_type target_core_stat_cit */ +/* End functions for struct config_item_type tb_dev_stat_cit */ /* Start functions for struct config_item_type target_core_hba_cit */ @@ -2806,17 +2633,17 @@ static struct config_group *target_core_make_subdev( if (!dev_cg->default_groups) goto out_free_device; - config_group_init_type_name(dev_cg, name, &target_core_dev_cit); + config_group_init_type_name(dev_cg, name, &t->tb_cits.tb_dev_cit); config_group_init_type_name(&dev->dev_attrib.da_group, "attrib", - &target_core_dev_attrib_cit); + &t->tb_cits.tb_dev_attrib_cit); config_group_init_type_name(&dev->dev_pr_group, "pr", - &target_core_dev_pr_cit); + &t->tb_cits.tb_dev_pr_cit); config_group_init_type_name(&dev->t10_wwn.t10_wwn_group, "wwn", - &target_core_dev_wwn_cit); + &t->tb_cits.tb_dev_wwn_cit); config_group_init_type_name(&dev->t10_alua.alua_tg_pt_gps_group, - "alua", &target_core_alua_tg_pt_gps_cit); + "alua", &t->tb_cits.tb_dev_alua_tg_pt_gps_cit); config_group_init_type_name(&dev->dev_stat_grps.stat_group, - "statistics", &target_core_stat_cit); + "statistics", &t->tb_cits.tb_dev_stat_cit); dev_cg->default_groups[0] = &dev->dev_attrib.da_group; dev_cg->default_groups[1] = &dev->dev_pr_group; @@ -3110,6 +2937,17 @@ static struct config_item_type target_core_cit = { /* Stop functions for struct config_item_type target_core_hba_cit */ +void target_core_setup_sub_cits(struct se_subsystem_api *sa) +{ + target_core_setup_dev_cit(sa); + target_core_setup_dev_attrib_cit(sa); + target_core_setup_dev_pr_cit(sa); + target_core_setup_dev_wwn_cit(sa); + target_core_setup_dev_alua_tg_pt_gps_cit(sa); + target_core_setup_dev_stat_cit(sa); +} +EXPORT_SYMBOL(target_core_setup_sub_cits); + static int __init target_core_init_configfs(void) { struct config_group *target_cg, *hba_cg = NULL, *alua_cg = NULL; diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index c45f9e907e44..58f49ff69b14 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -659,6 +659,7 @@ int se_dev_set_max_unmap_lba_count( dev, dev->dev_attrib.max_unmap_lba_count); return 0; } +EXPORT_SYMBOL(se_dev_set_max_unmap_lba_count); int se_dev_set_max_unmap_block_desc_count( struct se_device *dev, @@ -670,6 +671,7 @@ int se_dev_set_max_unmap_block_desc_count( dev, dev->dev_attrib.max_unmap_block_desc_count); return 0; } +EXPORT_SYMBOL(se_dev_set_max_unmap_block_desc_count); int se_dev_set_unmap_granularity( struct se_device *dev, @@ -680,6 +682,7 @@ int se_dev_set_unmap_granularity( dev, dev->dev_attrib.unmap_granularity); return 0; } +EXPORT_SYMBOL(se_dev_set_unmap_granularity); int se_dev_set_unmap_granularity_alignment( struct se_device *dev, @@ -690,6 +693,7 @@ int se_dev_set_unmap_granularity_alignment( dev, dev->dev_attrib.unmap_granularity_alignment); return 0; } +EXPORT_SYMBOL(se_dev_set_unmap_granularity_alignment); int se_dev_set_max_write_same_len( struct se_device *dev, @@ -700,6 +704,7 @@ int se_dev_set_max_write_same_len( dev, dev->dev_attrib.max_write_same_len); return 0; } +EXPORT_SYMBOL(se_dev_set_max_write_same_len); static void dev_set_t10_wwn_model_alias(struct se_device *dev) { @@ -738,6 +743,7 @@ int se_dev_set_emulate_model_alias(struct se_device *dev, int flag) return 0; } +EXPORT_SYMBOL(se_dev_set_emulate_model_alias); int se_dev_set_emulate_dpo(struct se_device *dev, int flag) { @@ -753,6 +759,7 @@ int se_dev_set_emulate_dpo(struct se_device *dev, int flag) return 0; } +EXPORT_SYMBOL(se_dev_set_emulate_dpo); int se_dev_set_emulate_fua_write(struct se_device *dev, int flag) { @@ -760,17 +767,12 @@ int se_dev_set_emulate_fua_write(struct se_device *dev, int flag) pr_err("Illegal value %d\n", flag); return -EINVAL; } - - if (flag && - dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { - pr_err("emulate_fua_write not supported for pSCSI\n"); - return -EINVAL; - } dev->dev_attrib.emulate_fua_write = flag; pr_debug("dev[%p]: SE Device Forced Unit Access WRITEs: %d\n", dev, dev->dev_attrib.emulate_fua_write); return 0; } +EXPORT_SYMBOL(se_dev_set_emulate_fua_write); int se_dev_set_emulate_fua_read(struct se_device *dev, int flag) { @@ -786,6 +788,7 @@ int se_dev_set_emulate_fua_read(struct se_device *dev, int flag) return 0; } +EXPORT_SYMBOL(se_dev_set_emulate_fua_read); int se_dev_set_emulate_write_cache(struct se_device *dev, int flag) { @@ -794,11 +797,6 @@ int se_dev_set_emulate_write_cache(struct se_device *dev, int flag) return -EINVAL; } if (flag && - dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { - pr_err("emulate_write_cache not supported for pSCSI\n"); - return -EINVAL; - } - if (flag && dev->transport->get_write_cache) { pr_err("emulate_write_cache not supported for this device\n"); return -EINVAL; @@ -809,6 +807,7 @@ int se_dev_set_emulate_write_cache(struct se_device *dev, int flag) dev, dev->dev_attrib.emulate_write_cache); return 0; } +EXPORT_SYMBOL(se_dev_set_emulate_write_cache); int se_dev_set_emulate_ua_intlck_ctrl(struct se_device *dev, int flag) { @@ -829,6 +828,7 @@ int se_dev_set_emulate_ua_intlck_ctrl(struct se_device *dev, int flag) return 0; } +EXPORT_SYMBOL(se_dev_set_emulate_ua_intlck_ctrl); int se_dev_set_emulate_tas(struct se_device *dev, int flag) { @@ -849,6 +849,7 @@ int se_dev_set_emulate_tas(struct se_device *dev, int flag) return 0; } +EXPORT_SYMBOL(se_dev_set_emulate_tas); int se_dev_set_emulate_tpu(struct se_device *dev, int flag) { @@ -870,6 +871,7 @@ int se_dev_set_emulate_tpu(struct se_device *dev, int flag) dev, flag); return 0; } +EXPORT_SYMBOL(se_dev_set_emulate_tpu); int se_dev_set_emulate_tpws(struct se_device *dev, int flag) { @@ -891,6 +893,7 @@ int se_dev_set_emulate_tpws(struct se_device *dev, int flag) dev, flag); return 0; } +EXPORT_SYMBOL(se_dev_set_emulate_tpws); int se_dev_set_emulate_caw(struct se_device *dev, int flag) { @@ -904,6 +907,7 @@ int se_dev_set_emulate_caw(struct se_device *dev, int flag) return 0; } +EXPORT_SYMBOL(se_dev_set_emulate_caw); int se_dev_set_emulate_3pc(struct se_device *dev, int flag) { @@ -917,6 +921,7 @@ int se_dev_set_emulate_3pc(struct se_device *dev, int flag) return 0; } +EXPORT_SYMBOL(se_dev_set_emulate_3pc); int se_dev_set_pi_prot_type(struct se_device *dev, int flag) { @@ -970,6 +975,7 @@ int se_dev_set_pi_prot_type(struct se_device *dev, int flag) return 0; } +EXPORT_SYMBOL(se_dev_set_pi_prot_type); int se_dev_set_pi_prot_format(struct se_device *dev, int flag) { @@ -1005,6 +1011,7 @@ int se_dev_set_pi_prot_format(struct se_device *dev, int flag) return 0; } +EXPORT_SYMBOL(se_dev_set_pi_prot_format); int se_dev_set_enforce_pr_isids(struct se_device *dev, int flag) { @@ -1017,6 +1024,7 @@ int se_dev_set_enforce_pr_isids(struct se_device *dev, int flag) (dev->dev_attrib.enforce_pr_isids) ? "Enabled" : "Disabled"); return 0; } +EXPORT_SYMBOL(se_dev_set_enforce_pr_isids); int se_dev_set_force_pr_aptpl(struct se_device *dev, int flag) { @@ -1034,6 +1042,7 @@ int se_dev_set_force_pr_aptpl(struct se_device *dev, int flag) pr_debug("dev[%p]: SE Device force_pr_aptpl: %d\n", dev, flag); return 0; } +EXPORT_SYMBOL(se_dev_set_force_pr_aptpl); int se_dev_set_is_nonrot(struct se_device *dev, int flag) { @@ -1046,6 +1055,7 @@ int se_dev_set_is_nonrot(struct se_device *dev, int flag) dev, flag); return 0; } +EXPORT_SYMBOL(se_dev_set_is_nonrot); int se_dev_set_emulate_rest_reord(struct se_device *dev, int flag) { @@ -1058,6 +1068,7 @@ int se_dev_set_emulate_rest_reord(struct se_device *dev, int flag) pr_debug("dev[%p]: SE Device emulate_rest_reord: %d\n", dev, flag); return 0; } +EXPORT_SYMBOL(se_dev_set_emulate_rest_reord); /* * Note, this can only be called on unexported SE Device Object. @@ -1076,85 +1087,21 @@ int se_dev_set_queue_depth(struct se_device *dev, u32 queue_depth) return -EINVAL; } - if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { + if (queue_depth > dev->dev_attrib.queue_depth) { if (queue_depth > dev->dev_attrib.hw_queue_depth) { - pr_err("dev[%p]: Passed queue_depth: %u" - " exceeds TCM/SE_Device TCQ: %u\n", - dev, queue_depth, + pr_err("dev[%p]: Passed queue_depth:" + " %u exceeds TCM/SE_Device MAX" + " TCQ: %u\n", dev, queue_depth, dev->dev_attrib.hw_queue_depth); return -EINVAL; } - } else { - if (queue_depth > dev->dev_attrib.queue_depth) { - if (queue_depth > dev->dev_attrib.hw_queue_depth) { - pr_err("dev[%p]: Passed queue_depth:" - " %u exceeds TCM/SE_Device MAX" - " TCQ: %u\n", dev, queue_depth, - dev->dev_attrib.hw_queue_depth); - return -EINVAL; - } - } } - dev->dev_attrib.queue_depth = dev->queue_depth = queue_depth; pr_debug("dev[%p]: SE Device TCQ Depth changed to: %u\n", dev, queue_depth); return 0; } - -int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors) -{ - int block_size = dev->dev_attrib.block_size; - - if (dev->export_count) { - pr_err("dev[%p]: Unable to change SE Device" - " fabric_max_sectors while export_count is %d\n", - dev, dev->export_count); - return -EINVAL; - } - if (!fabric_max_sectors) { - pr_err("dev[%p]: Illegal ZERO value for" - " fabric_max_sectors\n", dev); - return -EINVAL; - } - if (fabric_max_sectors < DA_STATUS_MAX_SECTORS_MIN) { - pr_err("dev[%p]: Passed fabric_max_sectors: %u less than" - " DA_STATUS_MAX_SECTORS_MIN: %u\n", dev, fabric_max_sectors, - DA_STATUS_MAX_SECTORS_MIN); - return -EINVAL; - } - if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { - if (fabric_max_sectors > dev->dev_attrib.hw_max_sectors) { - pr_err("dev[%p]: Passed fabric_max_sectors: %u" - " greater than TCM/SE_Device max_sectors:" - " %u\n", dev, fabric_max_sectors, - dev->dev_attrib.hw_max_sectors); - return -EINVAL; - } - } else { - if (fabric_max_sectors > DA_STATUS_MAX_SECTORS_MAX) { - pr_err("dev[%p]: Passed fabric_max_sectors: %u" - " greater than DA_STATUS_MAX_SECTORS_MAX:" - " %u\n", dev, fabric_max_sectors, - DA_STATUS_MAX_SECTORS_MAX); - return -EINVAL; - } - } - /* - * Align max_sectors down to PAGE_SIZE to follow transport_allocate_data_tasks() - */ - if (!block_size) { - block_size = 512; - pr_warn("Defaulting to 512 for zero block_size\n"); - } - fabric_max_sectors = se_dev_align_max_sectors(fabric_max_sectors, - block_size); - - dev->dev_attrib.fabric_max_sectors = fabric_max_sectors; - pr_debug("dev[%p]: SE Device max_sectors changed to %u\n", - dev, fabric_max_sectors); - return 0; -} +EXPORT_SYMBOL(se_dev_set_queue_depth); int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors) { @@ -1164,15 +1111,10 @@ int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors) dev, dev->export_count); return -EINVAL; } - if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { - pr_err("dev[%p]: Passed optimal_sectors cannot be" - " changed for TCM/pSCSI\n", dev); - return -EINVAL; - } - if (optimal_sectors > dev->dev_attrib.fabric_max_sectors) { + if (optimal_sectors > dev->dev_attrib.hw_max_sectors) { pr_err("dev[%p]: Passed optimal_sectors %u cannot be" - " greater than fabric_max_sectors: %u\n", dev, - optimal_sectors, dev->dev_attrib.fabric_max_sectors); + " greater than hw_max_sectors: %u\n", dev, + optimal_sectors, dev->dev_attrib.hw_max_sectors); return -EINVAL; } @@ -1181,6 +1123,7 @@ int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors) dev, optimal_sectors); return 0; } +EXPORT_SYMBOL(se_dev_set_optimal_sectors); int se_dev_set_block_size(struct se_device *dev, u32 block_size) { @@ -1201,13 +1144,6 @@ int se_dev_set_block_size(struct se_device *dev, u32 block_size) return -EINVAL; } - if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { - pr_err("dev[%p]: Not allowed to change block_size for" - " Physical Device, use for Linux/SCSI to change" - " block_size for underlying hardware\n", dev); - return -EINVAL; - } - dev->dev_attrib.block_size = block_size; pr_debug("dev[%p]: SE Device block_size changed to %u\n", dev, block_size); @@ -1218,6 +1154,7 @@ int se_dev_set_block_size(struct se_device *dev, u32 block_size) return 0; } +EXPORT_SYMBOL(se_dev_set_block_size); struct se_lun *core_dev_add_lun( struct se_portal_group *tpg, @@ -1571,8 +1508,6 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) dev->dev_attrib.unmap_granularity_alignment = DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT; dev->dev_attrib.max_write_same_len = DA_MAX_WRITE_SAME_LEN; - dev->dev_attrib.fabric_max_sectors = DA_FABRIC_MAX_SECTORS; - dev->dev_attrib.optimal_sectors = DA_FABRIC_MAX_SECTORS; xcopy_lun = &dev->xcopy_lun; xcopy_lun->lun_se_dev = dev; @@ -1613,6 +1548,7 @@ int target_configure_device(struct se_device *dev) dev->dev_attrib.hw_max_sectors = se_dev_align_max_sectors(dev->dev_attrib.hw_max_sectors, dev->dev_attrib.hw_block_size); + dev->dev_attrib.optimal_sectors = dev->dev_attrib.hw_max_sectors; dev->dev_index = scsi_get_new_index(SCSI_DEVICE_INDEX); dev->creation_time = get_jiffies_64(); diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 72c83d98662b..d836de200a03 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -37,6 +37,7 @@ #include <target/target_core_base.h> #include <target/target_core_backend.h> +#include <target/target_core_backend_configfs.h> #include "target_core_file.h" @@ -620,7 +621,16 @@ fd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, struct fd_prot fd_prot; sense_reason_t rc; int ret = 0; - + /* + * We are currently limited by the number of iovecs (2048) per + * single vfs_[writev,readv] call. + */ + if (cmd->data_length > FD_MAX_BYTES) { + pr_err("FILEIO: Not able to process I/O of %u bytes due to" + "FD_MAX_BYTES: %u iovec count limitiation\n", + cmd->data_length, FD_MAX_BYTES); + return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; + } /* * Call vectorized fileio functions to map struct scatterlist * physical memory addresses to struct iovec virtual memory. @@ -934,6 +944,41 @@ fd_parse_cdb(struct se_cmd *cmd) return sbc_parse_cdb(cmd, &fd_sbc_ops); } +DEF_TB_DEFAULT_ATTRIBS(fileio); + +static struct configfs_attribute *fileio_backend_dev_attrs[] = { + &fileio_dev_attrib_emulate_model_alias.attr, + &fileio_dev_attrib_emulate_dpo.attr, + &fileio_dev_attrib_emulate_fua_write.attr, + &fileio_dev_attrib_emulate_fua_read.attr, + &fileio_dev_attrib_emulate_write_cache.attr, + &fileio_dev_attrib_emulate_ua_intlck_ctrl.attr, + &fileio_dev_attrib_emulate_tas.attr, + &fileio_dev_attrib_emulate_tpu.attr, + &fileio_dev_attrib_emulate_tpws.attr, + &fileio_dev_attrib_emulate_caw.attr, + &fileio_dev_attrib_emulate_3pc.attr, + &fileio_dev_attrib_pi_prot_type.attr, + &fileio_dev_attrib_hw_pi_prot_type.attr, + &fileio_dev_attrib_pi_prot_format.attr, + &fileio_dev_attrib_enforce_pr_isids.attr, + &fileio_dev_attrib_is_nonrot.attr, + &fileio_dev_attrib_emulate_rest_reord.attr, + &fileio_dev_attrib_force_pr_aptpl.attr, + &fileio_dev_attrib_hw_block_size.attr, + &fileio_dev_attrib_block_size.attr, + &fileio_dev_attrib_hw_max_sectors.attr, + &fileio_dev_attrib_optimal_sectors.attr, + &fileio_dev_attrib_hw_queue_depth.attr, + &fileio_dev_attrib_queue_depth.attr, + &fileio_dev_attrib_max_unmap_lba_count.attr, + &fileio_dev_attrib_max_unmap_block_desc_count.attr, + &fileio_dev_attrib_unmap_granularity.attr, + &fileio_dev_attrib_unmap_granularity_alignment.attr, + &fileio_dev_attrib_max_write_same_len.attr, + NULL, +}; + static struct se_subsystem_api fileio_template = { .name = "fileio", .inquiry_prod = "FILEIO", @@ -957,6 +1002,11 @@ static struct se_subsystem_api fileio_template = { static int __init fileio_module_init(void) { + struct target_backend_cits *tbc = &fileio_template.tb_cits; + + target_core_setup_sub_cits(&fileio_template); + tbc->tb_dev_attrib_cit.ct_attrs = fileio_backend_dev_attrs; + return transport_subsystem_register(&fileio_template); } diff --git a/drivers/target/target_core_hba.c b/drivers/target/target_core_hba.c index a25051a37dd7..ff95f95dcd13 100644 --- a/drivers/target/target_core_hba.c +++ b/drivers/target/target_core_hba.c @@ -36,6 +36,7 @@ #include <target/target_core_base.h> #include <target/target_core_backend.h> #include <target/target_core_fabric.h> +#include <target/target_core_configfs.h> #include "target_core_internal.h" @@ -137,8 +138,7 @@ core_alloc_hba(const char *plugin_name, u32 plugin_dep_id, u32 hba_flags) return hba; out_module_put: - if (hba->transport->owner) - module_put(hba->transport->owner); + module_put(hba->transport->owner); hba->transport = NULL; out_free_hba: kfree(hba); @@ -159,8 +159,7 @@ core_delete_hba(struct se_hba *hba) pr_debug("CORE_HBA[%d] - Detached HBA from Generic Target" " Core\n", hba->hba_id); - if (hba->transport->owner) - module_put(hba->transport->owner); + module_put(hba->transport->owner); hba->transport = NULL; kfree(hba); diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 7e6b857c6b3f..78346b850968 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -41,6 +41,7 @@ #include <target/target_core_base.h> #include <target/target_core_backend.h> +#include <target/target_core_backend_configfs.h> #include "target_core_iblock.h" @@ -123,7 +124,7 @@ static int iblock_configure_device(struct se_device *dev) q = bdev_get_queue(bd); dev->dev_attrib.hw_block_size = bdev_logical_block_size(bd); - dev->dev_attrib.hw_max_sectors = UINT_MAX; + dev->dev_attrib.hw_max_sectors = queue_max_hw_sectors(q); dev->dev_attrib.hw_queue_depth = q->nr_requests; /* @@ -858,6 +859,41 @@ static bool iblock_get_write_cache(struct se_device *dev) return q->flush_flags & REQ_FLUSH; } +DEF_TB_DEFAULT_ATTRIBS(iblock); + +static struct configfs_attribute *iblock_backend_dev_attrs[] = { + &iblock_dev_attrib_emulate_model_alias.attr, + &iblock_dev_attrib_emulate_dpo.attr, + &iblock_dev_attrib_emulate_fua_write.attr, + &iblock_dev_attrib_emulate_fua_read.attr, + &iblock_dev_attrib_emulate_write_cache.attr, + &iblock_dev_attrib_emulate_ua_intlck_ctrl.attr, + &iblock_dev_attrib_emulate_tas.attr, + &iblock_dev_attrib_emulate_tpu.attr, + &iblock_dev_attrib_emulate_tpws.attr, + &iblock_dev_attrib_emulate_caw.attr, + &iblock_dev_attrib_emulate_3pc.attr, + &iblock_dev_attrib_pi_prot_type.attr, + &iblock_dev_attrib_hw_pi_prot_type.attr, + &iblock_dev_attrib_pi_prot_format.attr, + &iblock_dev_attrib_enforce_pr_isids.attr, + &iblock_dev_attrib_is_nonrot.attr, + &iblock_dev_attrib_emulate_rest_reord.attr, + &iblock_dev_attrib_force_pr_aptpl.attr, + &iblock_dev_attrib_hw_block_size.attr, + &iblock_dev_attrib_block_size.attr, + &iblock_dev_attrib_hw_max_sectors.attr, + &iblock_dev_attrib_optimal_sectors.attr, + &iblock_dev_attrib_hw_queue_depth.attr, + &iblock_dev_attrib_queue_depth.attr, + &iblock_dev_attrib_max_unmap_lba_count.attr, + &iblock_dev_attrib_max_unmap_block_desc_count.attr, + &iblock_dev_attrib_unmap_granularity.attr, + &iblock_dev_attrib_unmap_granularity_alignment.attr, + &iblock_dev_attrib_max_write_same_len.attr, + NULL, +}; + static struct se_subsystem_api iblock_template = { .name = "iblock", .inquiry_prod = "IBLOCK", @@ -883,6 +919,11 @@ static struct se_subsystem_api iblock_template = { static int __init iblock_module_init(void) { + struct target_backend_cits *tbc = &iblock_template.tb_cits; + + target_core_setup_sub_cits(&iblock_template); + tbc->tb_dev_attrib_cit.ct_attrs = iblock_backend_dev_attrs; + return transport_subsystem_register(&iblock_template); } diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index e31f42f369ff..60381db90026 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h @@ -18,34 +18,6 @@ int core_dev_export(struct se_device *, struct se_portal_group *, struct se_lun *); void core_dev_unexport(struct se_device *, struct se_portal_group *, struct se_lun *); -int se_dev_set_task_timeout(struct se_device *, u32); -int se_dev_set_max_unmap_lba_count(struct se_device *, u32); -int se_dev_set_max_unmap_block_desc_count(struct se_device *, u32); -int se_dev_set_unmap_granularity(struct se_device *, u32); -int se_dev_set_unmap_granularity_alignment(struct se_device *, u32); -int se_dev_set_max_write_same_len(struct se_device *, u32); -int se_dev_set_emulate_model_alias(struct se_device *, int); -int se_dev_set_emulate_dpo(struct se_device *, int); -int se_dev_set_emulate_fua_write(struct se_device *, int); -int se_dev_set_emulate_fua_read(struct se_device *, int); -int se_dev_set_emulate_write_cache(struct se_device *, int); -int se_dev_set_emulate_ua_intlck_ctrl(struct se_device *, int); -int se_dev_set_emulate_tas(struct se_device *, int); -int se_dev_set_emulate_tpu(struct se_device *, int); -int se_dev_set_emulate_tpws(struct se_device *, int); -int se_dev_set_emulate_caw(struct se_device *, int); -int se_dev_set_emulate_3pc(struct se_device *, int); -int se_dev_set_pi_prot_type(struct se_device *, int); -int se_dev_set_pi_prot_format(struct se_device *, int); -int se_dev_set_enforce_pr_isids(struct se_device *, int); -int se_dev_set_force_pr_aptpl(struct se_device *, int); -int se_dev_set_is_nonrot(struct se_device *, int); -int se_dev_set_emulate_rest_reord(struct se_device *dev, int); -int se_dev_set_queue_depth(struct se_device *, u32); -int se_dev_set_max_sectors(struct se_device *, u32); -int se_dev_set_fabric_max_sectors(struct se_device *, u32); -int se_dev_set_optimal_sectors(struct se_device *, u32); -int se_dev_set_block_size(struct se_device *, u32); struct se_lun *core_dev_add_lun(struct se_portal_group *, struct se_device *, u32); void core_dev_del_lun(struct se_portal_group *, struct se_lun *); struct se_lun *core_get_lun_from_tpg(struct se_portal_group *, u32); diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 4c261c33cf55..283cf786ef98 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -76,7 +76,7 @@ enum preempt_type { }; static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *, - struct t10_pr_registration *, int); + struct t10_pr_registration *, int, int); static sense_reason_t target_scsi2_reservation_check(struct se_cmd *cmd) @@ -528,6 +528,18 @@ static int core_scsi3_pr_seq_non_holder( return 0; } + } else if (we && registered_nexus) { + /* + * Reads are allowed for Write Exclusive locks + * from all registrants. + */ + if (cmd->data_direction == DMA_FROM_DEVICE) { + pr_debug("Allowing READ CDB: 0x%02x for %s" + " reservation\n", cdb[0], + core_scsi3_pr_dump_type(pr_reg_type)); + + return 0; + } } pr_debug("%s Conflict for %sregistered nexus %s CDB: 0x%2x" " for %s reservation\n", transport_dump_cmd_direction(cmd), @@ -1177,7 +1189,7 @@ static int core_scsi3_check_implicit_release( * service action with the SERVICE ACTION RESERVATION KEY * field set to zero (see 5.7.11.3). */ - __core_scsi3_complete_pro_release(dev, nacl, pr_reg, 0); + __core_scsi3_complete_pro_release(dev, nacl, pr_reg, 0, 1); ret = 1; /* * For 'All Registrants' reservation types, all existing @@ -1219,7 +1231,8 @@ static void __core_scsi3_free_registration( pr_reg->pr_reg_deve->def_pr_registered = 0; pr_reg->pr_reg_deve->pr_res_key = 0; - list_del(&pr_reg->pr_reg_list); + if (!list_empty(&pr_reg->pr_reg_list)) + list_del(&pr_reg->pr_reg_list); /* * Caller accessing *pr_reg using core_scsi3_locate_pr_reg(), * so call core_scsi3_put_pr_reg() to decrement our reference. @@ -1271,6 +1284,7 @@ void core_scsi3_free_pr_reg_from_nacl( { struct t10_reservation *pr_tmpl = &dev->t10_pr; struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_res_holder; + bool free_reg = false; /* * If the passed se_node_acl matches the reservation holder, * release the reservation. @@ -1278,13 +1292,18 @@ void core_scsi3_free_pr_reg_from_nacl( spin_lock(&dev->dev_reservation_lock); pr_res_holder = dev->dev_pr_res_holder; if ((pr_res_holder != NULL) && - (pr_res_holder->pr_reg_nacl == nacl)) - __core_scsi3_complete_pro_release(dev, nacl, pr_res_holder, 0); + (pr_res_holder->pr_reg_nacl == nacl)) { + __core_scsi3_complete_pro_release(dev, nacl, pr_res_holder, 0, 1); + free_reg = true; + } spin_unlock(&dev->dev_reservation_lock); /* * Release any registration associated with the struct se_node_acl. */ spin_lock(&pr_tmpl->registration_lock); + if (pr_res_holder && free_reg) + __core_scsi3_free_registration(dev, pr_res_holder, NULL, 0); + list_for_each_entry_safe(pr_reg, pr_reg_tmp, &pr_tmpl->registration_list, pr_reg_list) { @@ -1307,7 +1326,7 @@ void core_scsi3_free_all_registrations( if (pr_res_holder != NULL) { struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl; __core_scsi3_complete_pro_release(dev, pr_res_nacl, - pr_res_holder, 0); + pr_res_holder, 0, 0); } spin_unlock(&dev->dev_reservation_lock); @@ -1429,14 +1448,12 @@ core_scsi3_decode_spec_i_port( struct target_core_fabric_ops *tmp_tf_ops; unsigned char *buf; unsigned char *ptr, *i_str = NULL, proto_ident, tmp_proto_ident; - char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN]; + char *iport_ptr = NULL, i_buf[PR_REG_ISID_ID_LEN]; sense_reason_t ret; u32 tpdl, tid_len = 0; int dest_local_nexus; u32 dest_rtpi = 0; - memset(dest_iport, 0, 64); - local_se_deve = se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; /* * Allocate a struct pr_transport_id_holder and setup the @@ -2105,13 +2122,13 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, /* * sa_res_key=0 Unregister Reservation Key for registered I_T Nexus. */ - pr_holder = core_scsi3_check_implicit_release( - cmd->se_dev, pr_reg); + type = pr_reg->pr_res_type; + pr_holder = core_scsi3_check_implicit_release(cmd->se_dev, + pr_reg); if (pr_holder < 0) { ret = TCM_RESERVATION_CONFLICT; goto out; } - type = pr_reg->pr_res_type; spin_lock(&pr_tmpl->registration_lock); /* @@ -2269,6 +2286,7 @@ core_scsi3_pro_reserve(struct se_cmd *cmd, int type, int scope, u64 res_key) spin_lock(&dev->dev_reservation_lock); pr_res_holder = dev->dev_pr_res_holder; if (pr_res_holder) { + int pr_res_type = pr_res_holder->pr_res_type; /* * From spc4r17 Section 5.7.9: Reserving: * @@ -2279,7 +2297,9 @@ core_scsi3_pro_reserve(struct se_cmd *cmd, int type, int scope, u64 res_key) * the logical unit, then the command shall be completed with * RESERVATION CONFLICT status. */ - if (pr_res_holder != pr_reg) { + if ((pr_res_holder != pr_reg) && + (pr_res_type != PR_TYPE_WRITE_EXCLUSIVE_ALLREG) && + (pr_res_type != PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) { struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl; pr_err("SPC-3 PR: Attempted RESERVE from" " [%s]: %s while reservation already held by" @@ -2385,23 +2405,59 @@ static void __core_scsi3_complete_pro_release( struct se_device *dev, struct se_node_acl *se_nacl, struct t10_pr_registration *pr_reg, - int explicit) + int explicit, + int unreg) { struct target_core_fabric_ops *tfo = se_nacl->se_tpg->se_tpg_tfo; char i_buf[PR_REG_ISID_ID_LEN]; + int pr_res_type = 0, pr_res_scope = 0; memset(i_buf, 0, PR_REG_ISID_ID_LEN); core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN); /* * Go ahead and release the current PR reservation holder. + * If an All Registrants reservation is currently active and + * a unregister operation is requested, replace the current + * dev_pr_res_holder with another active registration. */ - dev->dev_pr_res_holder = NULL; + if (dev->dev_pr_res_holder) { + pr_res_type = dev->dev_pr_res_holder->pr_res_type; + pr_res_scope = dev->dev_pr_res_holder->pr_res_scope; + dev->dev_pr_res_holder->pr_res_type = 0; + dev->dev_pr_res_holder->pr_res_scope = 0; + dev->dev_pr_res_holder->pr_res_holder = 0; + dev->dev_pr_res_holder = NULL; + } + if (!unreg) + goto out; - pr_debug("SPC-3 PR [%s] Service Action: %s RELEASE cleared" - " reservation holder TYPE: %s ALL_TG_PT: %d\n", - tfo->get_fabric_name(), (explicit) ? "explicit" : "implicit", - core_scsi3_pr_dump_type(pr_reg->pr_res_type), - (pr_reg->pr_reg_all_tg_pt) ? 1 : 0); + spin_lock(&dev->t10_pr.registration_lock); + list_del_init(&pr_reg->pr_reg_list); + /* + * If the I_T nexus is a reservation holder, the persistent reservation + * is of an all registrants type, and the I_T nexus is the last remaining + * registered I_T nexus, then the device server shall also release the + * persistent reservation. + */ + if (!list_empty(&dev->t10_pr.registration_list) && + ((pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) || + (pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG))) { + dev->dev_pr_res_holder = + list_entry(dev->t10_pr.registration_list.next, + struct t10_pr_registration, pr_reg_list); + dev->dev_pr_res_holder->pr_res_type = pr_res_type; + dev->dev_pr_res_holder->pr_res_scope = pr_res_scope; + dev->dev_pr_res_holder->pr_res_holder = 1; + } + spin_unlock(&dev->t10_pr.registration_lock); +out: + if (!dev->dev_pr_res_holder) { + pr_debug("SPC-3 PR [%s] Service Action: %s RELEASE cleared" + " reservation holder TYPE: %s ALL_TG_PT: %d\n", + tfo->get_fabric_name(), (explicit) ? "explicit" : + "implicit", core_scsi3_pr_dump_type(pr_res_type), + (pr_reg->pr_reg_all_tg_pt) ? 1 : 0); + } pr_debug("SPC-3 PR [%s] RELEASE Node: %s%s\n", tfo->get_fabric_name(), se_nacl->initiatorname, i_buf); @@ -2532,7 +2588,7 @@ core_scsi3_emulate_pro_release(struct se_cmd *cmd, int type, int scope, * server shall not establish a unit attention condition. */ __core_scsi3_complete_pro_release(dev, se_sess->se_node_acl, - pr_reg, 1); + pr_reg, 1, 0); spin_unlock(&dev->dev_reservation_lock); @@ -2620,7 +2676,7 @@ core_scsi3_emulate_pro_clear(struct se_cmd *cmd, u64 res_key) if (pr_res_holder) { struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl; __core_scsi3_complete_pro_release(dev, pr_res_nacl, - pr_res_holder, 0); + pr_res_holder, 0, 0); } spin_unlock(&dev->dev_reservation_lock); /* @@ -2679,7 +2735,7 @@ static void __core_scsi3_complete_pro_preempt( */ if (dev->dev_pr_res_holder) __core_scsi3_complete_pro_release(dev, nacl, - dev->dev_pr_res_holder, 0); + dev->dev_pr_res_holder, 0, 0); dev->dev_pr_res_holder = pr_reg; pr_reg->pr_res_holder = 1; @@ -2924,8 +2980,8 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, */ if (pr_reg_n != pr_res_holder) __core_scsi3_complete_pro_release(dev, - pr_res_holder->pr_reg_nacl, - dev->dev_pr_res_holder, 0); + pr_res_holder->pr_reg_nacl, + dev->dev_pr_res_holder, 0, 0); /* * b) Remove the registrations for all I_T nexuses identified * by the SERVICE ACTION RESERVATION KEY field, except the @@ -3059,7 +3115,7 @@ core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key, struct t10_reservation *pr_tmpl = &dev->t10_pr; unsigned char *buf; unsigned char *initiator_str; - char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN]; + char *iport_ptr = NULL, i_buf[PR_REG_ISID_ID_LEN]; u32 tid_len, tmp_tid_len; int new_reg = 0, type, scope, matching_iname; sense_reason_t ret; @@ -3071,7 +3127,6 @@ core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key, return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; } - memset(dest_iport, 0, 64); memset(i_buf, 0, PR_REG_ISID_ID_LEN); se_tpg = se_sess->se_tpg; tf_ops = se_tpg->se_tpg_tfo; @@ -3389,7 +3444,7 @@ after_iport_check: * holder (i.e., the I_T nexus on which the */ __core_scsi3_complete_pro_release(dev, pr_res_nacl, - dev->dev_pr_res_holder, 0); + dev->dev_pr_res_holder, 0, 0); /* * g) Move the persistent reservation to the specified I_T nexus using * the same scope and type as the persistent reservation released in @@ -3837,7 +3892,8 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd) unsigned char *buf; u32 add_desc_len = 0, add_len = 0, desc_len, exp_desc_len; u32 off = 8; /* off into first Full Status descriptor */ - int format_code = 0; + int format_code = 0, pr_res_type = 0, pr_res_scope = 0; + bool all_reg = false; if (cmd->data_length < 8) { pr_err("PRIN SA READ_FULL_STATUS SCSI Data Length: %u" @@ -3854,6 +3910,19 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd) buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff); buf[3] = (dev->t10_pr.pr_generation & 0xff); + spin_lock(&dev->dev_reservation_lock); + if (dev->dev_pr_res_holder) { + struct t10_pr_registration *pr_holder = dev->dev_pr_res_holder; + + if (pr_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG || + pr_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG) { + all_reg = true; + pr_res_type = pr_holder->pr_res_type; + pr_res_scope = pr_holder->pr_res_scope; + } + } + spin_unlock(&dev->dev_reservation_lock); + spin_lock(&pr_tmpl->registration_lock); list_for_each_entry_safe(pr_reg, pr_reg_tmp, &pr_tmpl->registration_list, pr_reg_list) { @@ -3901,14 +3970,20 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd) * reservation holder for PR_HOLDER bit. * * Also, if this registration is the reservation - * holder, fill in SCOPE and TYPE in the next byte. + * holder or there is an All Registrants reservation + * active, fill in SCOPE and TYPE in the next byte. */ if (pr_reg->pr_res_holder) { buf[off++] |= 0x01; buf[off++] = (pr_reg->pr_res_scope & 0xf0) | (pr_reg->pr_res_type & 0x0f); - } else + } else if (all_reg) { + buf[off++] |= 0x01; + buf[off++] = (pr_res_scope & 0xf0) | + (pr_res_type & 0x0f); + } else { off += 2; + } off += 4; /* Skip over reserved area */ /* diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 7c8291f0bbbc..1045dcd7bf65 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -44,6 +44,7 @@ #include <target/target_core_base.h> #include <target/target_core_backend.h> +#include <target/target_core_backend_configfs.h> #include "target_core_alua.h" #include "target_core_pscsi.h" @@ -1094,7 +1095,7 @@ pscsi_execute_cmd(struct se_cmd *cmd) req->retries = PS_RETRY; blk_execute_rq_nowait(pdv->pdv_sd->request_queue, NULL, req, - (cmd->sam_task_attr == MSG_HEAD_TAG), + (cmd->sam_task_attr == TCM_HEAD_TAG), pscsi_req_done); return 0; @@ -1165,6 +1166,26 @@ static void pscsi_req_done(struct request *req, int uptodate) kfree(pt); } +DEF_TB_DEV_ATTRIB_RO(pscsi, hw_pi_prot_type); +TB_DEV_ATTR_RO(pscsi, hw_pi_prot_type); + +DEF_TB_DEV_ATTRIB_RO(pscsi, hw_block_size); +TB_DEV_ATTR_RO(pscsi, hw_block_size); + +DEF_TB_DEV_ATTRIB_RO(pscsi, hw_max_sectors); +TB_DEV_ATTR_RO(pscsi, hw_max_sectors); + +DEF_TB_DEV_ATTRIB_RO(pscsi, hw_queue_depth); +TB_DEV_ATTR_RO(pscsi, hw_queue_depth); + +static struct configfs_attribute *pscsi_backend_dev_attrs[] = { + &pscsi_dev_attrib_hw_pi_prot_type.attr, + &pscsi_dev_attrib_hw_block_size.attr, + &pscsi_dev_attrib_hw_max_sectors.attr, + &pscsi_dev_attrib_hw_queue_depth.attr, + NULL, +}; + static struct se_subsystem_api pscsi_template = { .name = "pscsi", .owner = THIS_MODULE, @@ -1185,6 +1206,11 @@ static struct se_subsystem_api pscsi_template = { static int __init pscsi_module_init(void) { + struct target_backend_cits *tbc = &pscsi_template.tb_cits; + + target_core_setup_sub_cits(&pscsi_template); + tbc->tb_dev_attrib_cit.ct_attrs = pscsi_backend_dev_attrs; + return transport_subsystem_register(&pscsi_template); } diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index b920db3388cd..98e83ac5661b 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c @@ -34,6 +34,7 @@ #include <target/target_core_base.h> #include <target/target_core_backend.h> +#include <target/target_core_backend_configfs.h> #include "target_core_rd.h" @@ -632,6 +633,41 @@ rd_parse_cdb(struct se_cmd *cmd) return sbc_parse_cdb(cmd, &rd_sbc_ops); } +DEF_TB_DEFAULT_ATTRIBS(rd_mcp); + +static struct configfs_attribute *rd_mcp_backend_dev_attrs[] = { + &rd_mcp_dev_attrib_emulate_model_alias.attr, + &rd_mcp_dev_attrib_emulate_dpo.attr, + &rd_mcp_dev_attrib_emulate_fua_write.attr, + &rd_mcp_dev_attrib_emulate_fua_read.attr, + &rd_mcp_dev_attrib_emulate_write_cache.attr, + &rd_mcp_dev_attrib_emulate_ua_intlck_ctrl.attr, + &rd_mcp_dev_attrib_emulate_tas.attr, + &rd_mcp_dev_attrib_emulate_tpu.attr, + &rd_mcp_dev_attrib_emulate_tpws.attr, + &rd_mcp_dev_attrib_emulate_caw.attr, + &rd_mcp_dev_attrib_emulate_3pc.attr, + &rd_mcp_dev_attrib_pi_prot_type.attr, + &rd_mcp_dev_attrib_hw_pi_prot_type.attr, + &rd_mcp_dev_attrib_pi_prot_format.attr, + &rd_mcp_dev_attrib_enforce_pr_isids.attr, + &rd_mcp_dev_attrib_is_nonrot.attr, + &rd_mcp_dev_attrib_emulate_rest_reord.attr, + &rd_mcp_dev_attrib_force_pr_aptpl.attr, + &rd_mcp_dev_attrib_hw_block_size.attr, + &rd_mcp_dev_attrib_block_size.attr, + &rd_mcp_dev_attrib_hw_max_sectors.attr, + &rd_mcp_dev_attrib_optimal_sectors.attr, + &rd_mcp_dev_attrib_hw_queue_depth.attr, + &rd_mcp_dev_attrib_queue_depth.attr, + &rd_mcp_dev_attrib_max_unmap_lba_count.attr, + &rd_mcp_dev_attrib_max_unmap_block_desc_count.attr, + &rd_mcp_dev_attrib_unmap_granularity.attr, + &rd_mcp_dev_attrib_unmap_granularity_alignment.attr, + &rd_mcp_dev_attrib_max_write_same_len.attr, + NULL, +}; + static struct se_subsystem_api rd_mcp_template = { .name = "rd_mcp", .inquiry_prod = "RAMDISK-MCP", @@ -653,8 +689,12 @@ static struct se_subsystem_api rd_mcp_template = { int __init rd_module_init(void) { + struct target_backend_cits *tbc = &rd_mcp_template.tb_cits; int ret; + target_core_setup_sub_cits(&rd_mcp_template); + tbc->tb_dev_attrib_cit.ct_attrs = rd_mcp_backend_dev_attrs; + ret = transport_subsystem_register(&rd_mcp_template); if (ret < 0) { return ret; diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 8d171ff77e75..cd4bed7b2757 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c @@ -485,7 +485,7 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd) cmd->t_data_nents_orig = cmd->t_data_nents; cmd->t_data_nents = 1; - cmd->sam_task_attr = MSG_HEAD_TAG; + cmd->sam_task_attr = TCM_HEAD_TAG; cmd->transport_complete_callback = compare_and_write_post; /* * Now reset ->execute_cmd() to the normal sbc_execute_rw() handler @@ -953,21 +953,6 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) if (cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) { unsigned long long end_lba; - - if (sectors > dev->dev_attrib.fabric_max_sectors) { - printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" - " big sectors %u exceeds fabric_max_sectors:" - " %u\n", cdb[0], sectors, - dev->dev_attrib.fabric_max_sectors); - return TCM_INVALID_CDB_FIELD; - } - if (sectors > dev->dev_attrib.hw_max_sectors) { - printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" - " big sectors %u exceeds backend hw_max_sectors:" - " %u\n", cdb[0], sectors, - dev->dev_attrib.hw_max_sectors); - return TCM_INVALID_CDB_FIELD; - } check_lba: end_lba = dev->transport->get_blocks(dev) + 1; if (cmd->t_task_lba + sectors > end_lba) { diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index bc286a67af7c..4c71657da56a 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -505,7 +505,6 @@ static sense_reason_t spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) { struct se_device *dev = cmd->se_dev; - u32 max_sectors; int have_tp = 0; int opt, min; @@ -539,9 +538,7 @@ spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) /* * Set MAXIMUM TRANSFER LENGTH */ - max_sectors = min(dev->dev_attrib.fabric_max_sectors, - dev->dev_attrib.hw_max_sectors); - put_unaligned_be32(max_sectors, &buf[8]); + put_unaligned_be32(dev->dev_attrib.hw_max_sectors, &buf[8]); /* * Set OPTIMAL TRANSFER LENGTH @@ -1357,7 +1354,7 @@ spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) * Do implicit HEAD_OF_QUEUE processing for INQUIRY. * See spc4r17 section 5.3 */ - cmd->sam_task_attr = MSG_HEAD_TAG; + cmd->sam_task_attr = TCM_HEAD_TAG; cmd->execute_cmd = spc_emulate_inquiry; break; case SECURITY_PROTOCOL_IN: @@ -1391,7 +1388,7 @@ spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) * Do implicit HEAD_OF_QUEUE processing for REPORT_LUNS * See spc4r17 section 5.3 */ - cmd->sam_task_attr = MSG_HEAD_TAG; + cmd->sam_task_attr = TCM_HEAD_TAG; break; case TEST_UNIT_READY: cmd->execute_cmd = spc_emulate_testunitready; diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index be877bf6f730..0adc0f650213 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1159,7 +1159,7 @@ transport_check_alloc_task_attr(struct se_cmd *cmd) if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) return 0; - if (cmd->sam_task_attr == MSG_ACA_TAG) { + if (cmd->sam_task_attr == TCM_ACA_TAG) { pr_debug("SAM Task Attribute ACA" " emulation is not supported\n"); return TCM_INVALID_CDB_FIELD; @@ -1531,7 +1531,7 @@ int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess, BUG_ON(!se_tpg); transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, - 0, DMA_NONE, MSG_SIMPLE_TAG, sense); + 0, DMA_NONE, TCM_SIMPLE_TAG, sense); /* * FIXME: Currently expect caller to handle se_cmd->se_tmr_req * allocation failure. @@ -1718,12 +1718,12 @@ static bool target_handle_task_attr(struct se_cmd *cmd) * to allow the passed struct se_cmd list of tasks to the front of the list. */ switch (cmd->sam_task_attr) { - case MSG_HEAD_TAG: + case TCM_HEAD_TAG: pr_debug("Added HEAD_OF_QUEUE for CDB: 0x%02x, " "se_ordered_id: %u\n", cmd->t_task_cdb[0], cmd->se_ordered_id); return false; - case MSG_ORDERED_TAG: + case TCM_ORDERED_TAG: atomic_inc_mb(&dev->dev_ordered_sync); pr_debug("Added ORDERED for CDB: 0x%02x to ordered list, " @@ -1828,7 +1828,7 @@ static void target_restart_delayed_cmds(struct se_device *dev) __target_execute_cmd(cmd); - if (cmd->sam_task_attr == MSG_ORDERED_TAG) + if (cmd->sam_task_attr == TCM_ORDERED_TAG) break; } } @@ -1844,18 +1844,18 @@ static void transport_complete_task_attr(struct se_cmd *cmd) if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) return; - if (cmd->sam_task_attr == MSG_SIMPLE_TAG) { + if (cmd->sam_task_attr == TCM_SIMPLE_TAG) { atomic_dec_mb(&dev->simple_cmds); dev->dev_cur_ordered_id++; pr_debug("Incremented dev->dev_cur_ordered_id: %u for" " SIMPLE: %u\n", dev->dev_cur_ordered_id, cmd->se_ordered_id); - } else if (cmd->sam_task_attr == MSG_HEAD_TAG) { + } else if (cmd->sam_task_attr == TCM_HEAD_TAG) { dev->dev_cur_ordered_id++; pr_debug("Incremented dev_cur_ordered_id: %u for" " HEAD_OF_QUEUE: %u\n", dev->dev_cur_ordered_id, cmd->se_ordered_id); - } else if (cmd->sam_task_attr == MSG_ORDERED_TAG) { + } else if (cmd->sam_task_attr == TCM_ORDERED_TAG) { atomic_dec_mb(&dev->dev_ordered_sync); dev->dev_cur_ordered_id++; diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index 9a1b314f6482..1157b559683b 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -28,6 +28,8 @@ #include <target/target_core_base.h> #include <target/target_core_fabric.h> #include <target/target_core_backend.h> +#include <target/target_core_backend_configfs.h> + #include <linux/target_core_user.h> /* @@ -1092,6 +1094,41 @@ tcmu_parse_cdb(struct se_cmd *cmd) return ret; } +DEF_TB_DEFAULT_ATTRIBS(tcmu); + +static struct configfs_attribute *tcmu_backend_dev_attrs[] = { + &tcmu_dev_attrib_emulate_model_alias.attr, + &tcmu_dev_attrib_emulate_dpo.attr, + &tcmu_dev_attrib_emulate_fua_write.attr, + &tcmu_dev_attrib_emulate_fua_read.attr, + &tcmu_dev_attrib_emulate_write_cache.attr, + &tcmu_dev_attrib_emulate_ua_intlck_ctrl.attr, + &tcmu_dev_attrib_emulate_tas.attr, + &tcmu_dev_attrib_emulate_tpu.attr, + &tcmu_dev_attrib_emulate_tpws.attr, + &tcmu_dev_attrib_emulate_caw.attr, + &tcmu_dev_attrib_emulate_3pc.attr, + &tcmu_dev_attrib_pi_prot_type.attr, + &tcmu_dev_attrib_hw_pi_prot_type.attr, + &tcmu_dev_attrib_pi_prot_format.attr, + &tcmu_dev_attrib_enforce_pr_isids.attr, + &tcmu_dev_attrib_is_nonrot.attr, + &tcmu_dev_attrib_emulate_rest_reord.attr, + &tcmu_dev_attrib_force_pr_aptpl.attr, + &tcmu_dev_attrib_hw_block_size.attr, + &tcmu_dev_attrib_block_size.attr, + &tcmu_dev_attrib_hw_max_sectors.attr, + &tcmu_dev_attrib_optimal_sectors.attr, + &tcmu_dev_attrib_hw_queue_depth.attr, + &tcmu_dev_attrib_queue_depth.attr, + &tcmu_dev_attrib_max_unmap_lba_count.attr, + &tcmu_dev_attrib_max_unmap_block_desc_count.attr, + &tcmu_dev_attrib_unmap_granularity.attr, + &tcmu_dev_attrib_unmap_granularity_alignment.attr, + &tcmu_dev_attrib_max_write_same_len.attr, + NULL, +}; + static struct se_subsystem_api tcmu_template = { .name = "user", .inquiry_prod = "USER", @@ -1112,6 +1149,7 @@ static struct se_subsystem_api tcmu_template = { static int __init tcmu_module_init(void) { + struct target_backend_cits *tbc = &tcmu_template.tb_cits; int ret; BUILD_BUG_ON((sizeof(struct tcmu_cmd_entry) % TCMU_OP_ALIGN_SIZE) != 0); @@ -1134,6 +1172,9 @@ static int __init tcmu_module_init(void) goto out_unreg_device; } + target_core_setup_sub_cits(&tcmu_template); + tbc->tb_dev_attrib_cit.ct_attrs = tcmu_backend_dev_attrs; + ret = transport_subsystem_register(&tcmu_template); if (ret) goto out_unreg_genl; diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index be0c0d08c56a..edcafa4490c0 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c @@ -554,17 +554,17 @@ static void ft_send_work(struct work_struct *work) */ switch (fcp->fc_pri_ta & FCP_PTA_MASK) { case FCP_PTA_HEADQ: - task_attr = MSG_HEAD_TAG; + task_attr = TCM_HEAD_TAG; break; case FCP_PTA_ORDERED: - task_attr = MSG_ORDERED_TAG; + task_attr = TCM_ORDERED_TAG; break; case FCP_PTA_ACA: - task_attr = MSG_ACA_TAG; + task_attr = TCM_ACA_TAG; break; case FCP_PTA_SIMPLE: /* Fallthrough */ default: - task_attr = MSG_SIMPLE_TAG; + task_attr = TCM_SIMPLE_TAG; } fc_seq_exch(cmd->seq)->lp->tt.seq_set_resp(cmd->seq, ft_recv_seq, cmd); diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index f554d25b4399..af40db0df58e 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -112,6 +112,18 @@ config CPU_THERMAL If you want this support, you should say Y here. +config CLOCK_THERMAL + bool "Generic clock cooling support" + depends on COMMON_CLK + depends on PM_OPP + help + This entry implements the generic clock cooling mechanism through + frequency clipping. Typically used to cool off co-processors. The + device that is configured to use this cooling mechanism will be + controlled to reduce clock frequency whenever temperature is high. + + If you want this support, you should say Y here. + config THERMAL_EMULATION bool "Thermal emulation mode support" help @@ -143,6 +155,16 @@ config SPEAR_THERMAL Enable this to plug the SPEAr thermal sensor driver into the Linux thermal framework. +config ROCKCHIP_THERMAL + tristate "Rockchip thermal driver" + depends on ARCH_ROCKCHIP + depends on RESET_CONTROLLER + help + Rockchip thermal driver provides support for Temperature sensor + ADC (TS-ADC) found on Rockchip SoCs. It supports one critical + trip point. Cpufreq is used as the cooling device and will throttle + CPUs when the Temperature crosses the passive trip point. + config RCAR_THERMAL tristate "Renesas R-Car thermal driver" depends on ARCH_SHMOBILE || COMPILE_TEST @@ -185,6 +207,16 @@ config ARMADA_THERMAL Enable this option if you want to have support for thermal management controller present in Armada 370 and Armada XP SoC. +config TEGRA_SOCTHERM + tristate "Tegra SOCTHERM thermal management" + depends on ARCH_TEGRA + help + Enable this option for integrated thermal management support on NVIDIA + Tegra124 systems-on-chip. The driver supports four thermal zones + (CPU, GPU, MEM, PLLX). Cooling devices can be bound to the thermal + zones to manage temperatures. This option is also required for the + emergency thermal reset (thermtrip) feature to function. + config DB8500_CPUFREQ_COOLING tristate "DB8500 cpufreq cooling" depends on ARCH_U8500 diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 39c4fe87da2f..fa0dc486790f 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -18,8 +18,12 @@ thermal_sys-$(CONFIG_THERMAL_GOV_USER_SPACE) += user_space.o # cpufreq cooling thermal_sys-$(CONFIG_CPU_THERMAL) += cpu_cooling.o +# clock cooling +thermal_sys-$(CONFIG_CLOCK_THERMAL) += clock_cooling.o + # platform thermal drivers obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o +obj-$(CONFIG_ROCKCHIP_THERMAL) += rockchip_thermal.o obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o obj-$(CONFIG_KIRKWOOD_THERMAL) += kirkwood_thermal.o obj-y += samsung/ @@ -34,3 +38,4 @@ obj-$(CONFIG_INTEL_SOC_DTS_THERMAL) += intel_soc_dts_thermal.o obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/ obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal/ obj-$(CONFIG_ST_THERMAL) += st/ +obj-$(CONFIG_TEGRA_SOCTHERM) += tegra_soctherm.o diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c index eaaf59c98ba2..c2556cf5186b 100644 --- a/drivers/thermal/armada_thermal.c +++ b/drivers/thermal/armada_thermal.c @@ -35,10 +35,6 @@ #define PMU_TDC0_OTF_CAL_MASK (0x1 << 30) #define PMU_TDC0_START_CAL_MASK (0x1 << 25) -#define A375_Z1_CAL_RESET_LSB 0x8011e214 -#define A375_Z1_CAL_RESET_MSB 0x30a88019 -#define A375_Z1_WORKAROUND_BIT BIT(9) - #define A375_UNIT_CONTROL_SHIFT 27 #define A375_UNIT_CONTROL_MASK 0x7 #define A375_READOUT_INVERT BIT(15) @@ -124,24 +120,12 @@ static void armada375_init_sensor(struct platform_device *pdev, struct armada_thermal_priv *priv) { unsigned long reg; - bool quirk_needed = - !!of_device_is_compatible(pdev->dev.of_node, - "marvell,armada375-z1-thermal"); - - if (quirk_needed) { - /* Ensure these registers have the default (reset) values */ - writel(A375_Z1_CAL_RESET_LSB, priv->control); - writel(A375_Z1_CAL_RESET_MSB, priv->control + 0x4); - } reg = readl(priv->control + 4); reg &= ~(A375_UNIT_CONTROL_MASK << A375_UNIT_CONTROL_SHIFT); reg &= ~A375_READOUT_INVERT; reg &= ~A375_HW_RESETn; - if (quirk_needed) - reg |= A375_Z1_WORKAROUND_BIT; - writel(reg, priv->control + 4); mdelay(20); @@ -260,10 +244,6 @@ static const struct of_device_id armada_thermal_id_table[] = { .data = &armada375_data, }, { - .compatible = "marvell,armada375-z1-thermal", - .data = &armada375_data, - }, - { .compatible = "marvell,armada380-thermal", .data = &armada380_data, }, diff --git a/drivers/thermal/clock_cooling.c b/drivers/thermal/clock_cooling.c new file mode 100644 index 000000000000..1b4ff0f4c716 --- /dev/null +++ b/drivers/thermal/clock_cooling.c @@ -0,0 +1,485 @@ +/* + * drivers/thermal/clock_cooling.c + * + * Copyright (C) 2014 Eduardo Valentin <edubezval@gmail.com> + * + * Copyright (C) 2013 Texas Instruments Inc. + * Contact: Eduardo Valentin <eduardo.valentin@ti.com> + * + * Highly based on cpu_cooling.c. + * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com) + * Copyright (C) 2012 Amit Daniel <amit.kachhap@linaro.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +#include <linux/clk.h> +#include <linux/cpufreq.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/idr.h> +#include <linux/mutex.h> +#include <linux/pm_opp.h> +#include <linux/slab.h> +#include <linux/thermal.h> +#include <linux/clock_cooling.h> + +/** + * struct clock_cooling_device - data for cooling device with clock + * @id: unique integer value corresponding to each clock_cooling_device + * registered. + * @dev: struct device pointer to the device being used to cool off using + * clock frequencies. + * @cdev: thermal_cooling_device pointer to keep track of the + * registered cooling device. + * @clk_rate_change_nb: reference to notifier block used to receive clock + * rate changes. + * @freq_table: frequency table used to keep track of available frequencies. + * @clock_state: integer value representing the current state of clock + * cooling devices. + * @clock_val: integer value representing the absolute value of the clipped + * frequency. + * @clk: struct clk reference used to enforce clock limits. + * @lock: mutex lock to protect this struct. + * + * This structure is required for keeping information of each + * clock_cooling_device registered. In order to prevent corruption of this a + * mutex @lock is used. + */ +struct clock_cooling_device { + int id; + struct device *dev; + struct thermal_cooling_device *cdev; + struct notifier_block clk_rate_change_nb; + struct cpufreq_frequency_table *freq_table; + unsigned long clock_state; + unsigned long clock_val; + struct clk *clk; + struct mutex lock; /* lock to protect the content of this struct */ +}; +#define to_clock_cooling_device(x) \ + container_of(x, struct clock_cooling_device, clk_rate_change_nb) +static DEFINE_IDR(clock_idr); +static DEFINE_MUTEX(cooling_clock_lock); + +/** + * clock_cooling_get_idr - function to get an unique id. + * @id: int * value generated by this function. + * + * This function will populate @id with an unique + * id, using the idr API. + * + * Return: 0 on success, an error code on failure. + */ +static int clock_cooling_get_idr(int *id) +{ + int ret; + + mutex_lock(&cooling_clock_lock); + ret = idr_alloc(&clock_idr, NULL, 0, 0, GFP_KERNEL); + mutex_unlock(&cooling_clock_lock); + if (unlikely(ret < 0)) + return ret; + *id = ret; + + return 0; +} + +/** + * release_idr - function to free the unique id. + * @id: int value representing the unique id. + */ +static void release_idr(int id) +{ + mutex_lock(&cooling_clock_lock); + idr_remove(&clock_idr, id); + mutex_unlock(&cooling_clock_lock); +} + +/* Below code defines functions to be used for clock as cooling device */ + +enum clock_cooling_property { + GET_LEVEL, + GET_FREQ, + GET_MAXL, +}; + +/** + * clock_cooling_get_property - fetch a property of interest for a give cpu. + * @ccdev: clock cooling device reference + * @input: query parameter + * @output: query return + * @property: type of query (frequency, level, max level) + * + * This is the common function to + * 1. get maximum clock cooling states + * 2. translate frequency to cooling state + * 3. translate cooling state to frequency + * Note that the code may be not in good shape + * but it is written in this way in order to: + * a) reduce duplicate code as most of the code can be shared. + * b) make sure the logic is consistent when translating between + * cooling states and frequencies. + * + * Return: 0 on success, -EINVAL when invalid parameters are passed. + */ +static int clock_cooling_get_property(struct clock_cooling_device *ccdev, + unsigned long input, + unsigned long *output, + enum clock_cooling_property property) +{ + int i; + unsigned long max_level = 0, level = 0; + unsigned int freq = CPUFREQ_ENTRY_INVALID; + int descend = -1; + struct cpufreq_frequency_table *pos, *table = ccdev->freq_table; + + if (!output) + return -EINVAL; + + if (!table) + return -EINVAL; + + cpufreq_for_each_valid_entry(pos, table) { + /* ignore duplicate entry */ + if (freq == pos->frequency) + continue; + + /* get the frequency order */ + if (freq != CPUFREQ_ENTRY_INVALID && descend == -1) + descend = freq > pos->frequency; + + freq = pos->frequency; + max_level++; + } + + /* No valid cpu frequency entry */ + if (max_level == 0) + return -EINVAL; + + /* max_level is an index, not a counter */ + max_level--; + + /* get max level */ + if (property == GET_MAXL) { + *output = max_level; + return 0; + } + + if (property == GET_FREQ) + level = descend ? input : (max_level - input); + + i = 0; + cpufreq_for_each_valid_entry(pos, table) { + /* ignore duplicate entry */ + if (freq == pos->frequency) + continue; + + /* now we have a valid frequency entry */ + freq = pos->frequency; + + if (property == GET_LEVEL && (unsigned int)input == freq) { + /* get level by frequency */ + *output = descend ? i : (max_level - i); + return 0; + } + if (property == GET_FREQ && level == i) { + /* get frequency by level */ + *output = freq; + return 0; + } + i++; + } + + return -EINVAL; +} + +/** + * clock_cooling_get_level - return the cooling level of given clock cooling. + * @cdev: reference of a thermal cooling device of used as clock cooling device + * @freq: the frequency of interest + * + * This function will match the cooling level corresponding to the + * requested @freq and return it. + * + * Return: The matched cooling level on success or THERMAL_CSTATE_INVALID + * otherwise. + */ +unsigned long clock_cooling_get_level(struct thermal_cooling_device *cdev, + unsigned long freq) +{ + struct clock_cooling_device *ccdev = cdev->devdata; + unsigned long val; + + if (clock_cooling_get_property(ccdev, (unsigned long)freq, &val, + GET_LEVEL)) + return THERMAL_CSTATE_INVALID; + + return val; +} +EXPORT_SYMBOL_GPL(clock_cooling_get_level); + +/** + * clock_cooling_get_frequency - get the absolute value of frequency from level. + * @ccdev: clock cooling device reference + * @level: cooling level + * + * This function matches cooling level with frequency. Based on a cooling level + * of frequency, equals cooling state of cpu cooling device, it will return + * the corresponding frequency. + * e.g level=0 --> 1st MAX FREQ, level=1 ---> 2nd MAX FREQ, .... etc + * + * Return: 0 on error, the corresponding frequency otherwise. + */ +static unsigned long +clock_cooling_get_frequency(struct clock_cooling_device *ccdev, + unsigned long level) +{ + int ret = 0; + unsigned long freq; + + ret = clock_cooling_get_property(ccdev, level, &freq, GET_FREQ); + if (ret) + return 0; + + return freq; +} + +/** + * clock_cooling_apply - function to apply frequency clipping. + * @ccdev: clock_cooling_device pointer containing frequency clipping data. + * @cooling_state: value of the cooling state. + * + * Function used to make sure the clock layer is aware of current thermal + * limits. The limits are applied by updating the clock rate in case it is + * higher than the corresponding frequency based on the requested cooling_state. + * + * Return: 0 on success, an error code otherwise (-EINVAL in case wrong + * cooling state). + */ +static int clock_cooling_apply(struct clock_cooling_device *ccdev, + unsigned long cooling_state) +{ + unsigned long clip_freq, cur_freq; + int ret = 0; + + /* Here we write the clipping */ + /* Check if the old cooling action is same as new cooling action */ + if (ccdev->clock_state == cooling_state) + return 0; + + clip_freq = clock_cooling_get_frequency(ccdev, cooling_state); + if (!clip_freq) + return -EINVAL; + + cur_freq = clk_get_rate(ccdev->clk); + + mutex_lock(&ccdev->lock); + ccdev->clock_state = cooling_state; + ccdev->clock_val = clip_freq; + /* enforce clock level */ + if (cur_freq > clip_freq) + ret = clk_set_rate(ccdev->clk, clip_freq); + mutex_unlock(&ccdev->lock); + + return ret; +} + +/** + * clock_cooling_clock_notifier - notifier callback on clock rate changes. + * @nb: struct notifier_block * with callback info. + * @event: value showing clock event for which this function invoked. + * @data: callback-specific data + * + * Callback to hijack the notification on clock transition. + * Every time there is a clock change, we intercept all pre change events + * and block the transition in case the new rate infringes thermal limits. + * + * Return: NOTIFY_DONE (success) or NOTIFY_BAD (new_rate > thermal limit). + */ +static int clock_cooling_clock_notifier(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct clk_notifier_data *ndata = data; + struct clock_cooling_device *ccdev = to_clock_cooling_device(nb); + + switch (event) { + case PRE_RATE_CHANGE: + /* + * checks on current state + * TODO: current method is not best we can find as it + * allows possibly voltage transitions, in case DVFS + * layer is also hijacking clock pre notifications. + */ + if (ndata->new_rate > ccdev->clock_val) + return NOTIFY_BAD; + /* fall through */ + case POST_RATE_CHANGE: + case ABORT_RATE_CHANGE: + default: + return NOTIFY_DONE; + } +} + +/* clock cooling device thermal callback functions are defined below */ + +/** + * clock_cooling_get_max_state - callback function to get the max cooling state. + * @cdev: thermal cooling device pointer. + * @state: fill this variable with the max cooling state. + * + * Callback for the thermal cooling device to return the clock + * max cooling state. + * + * Return: 0 on success, an error code otherwise. + */ +static int clock_cooling_get_max_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + struct clock_cooling_device *ccdev = cdev->devdata; + unsigned long count = 0; + int ret; + + ret = clock_cooling_get_property(ccdev, 0, &count, GET_MAXL); + if (!ret) + *state = count; + + return ret; +} + +/** + * clock_cooling_get_cur_state - function to get the current cooling state. + * @cdev: thermal cooling device pointer. + * @state: fill this variable with the current cooling state. + * + * Callback for the thermal cooling device to return the clock + * current cooling state. + * + * Return: 0 (success) + */ +static int clock_cooling_get_cur_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + struct clock_cooling_device *ccdev = cdev->devdata; + + *state = ccdev->clock_state; + + return 0; +} + +/** + * clock_cooling_set_cur_state - function to set the current cooling state. + * @cdev: thermal cooling device pointer. + * @state: set this variable to the current cooling state. + * + * Callback for the thermal cooling device to change the clock cooling + * current cooling state. + * + * Return: 0 on success, an error code otherwise. + */ +static int clock_cooling_set_cur_state(struct thermal_cooling_device *cdev, + unsigned long state) +{ + struct clock_cooling_device *clock_device = cdev->devdata; + + return clock_cooling_apply(clock_device, state); +} + +/* Bind clock callbacks to thermal cooling device ops */ +static struct thermal_cooling_device_ops const clock_cooling_ops = { + .get_max_state = clock_cooling_get_max_state, + .get_cur_state = clock_cooling_get_cur_state, + .set_cur_state = clock_cooling_set_cur_state, +}; + +/** + * clock_cooling_register - function to create clock cooling device. + * @dev: struct device pointer to the device used as clock cooling device. + * @clock_name: string containing the clock used as cooling mechanism. + * + * This interface function registers the clock cooling device with the name + * "thermal-clock-%x". The cooling device is based on clock frequencies. + * The struct device is assumed to be capable of DVFS transitions. + * The OPP layer is used to fetch and fill the available frequencies for + * the referred device. The ordered frequency table is used to control + * the clock cooling device cooling states and to limit clock transitions + * based on the cooling state requested by the thermal framework. + * + * Return: a valid struct thermal_cooling_device pointer on success, + * on failure, it returns a corresponding ERR_PTR(). + */ +struct thermal_cooling_device * +clock_cooling_register(struct device *dev, const char *clock_name) +{ + struct thermal_cooling_device *cdev; + struct clock_cooling_device *ccdev = NULL; + char dev_name[THERMAL_NAME_LENGTH]; + int ret = 0; + + ccdev = devm_kzalloc(dev, sizeof(*ccdev), GFP_KERNEL); + if (!ccdev) + return ERR_PTR(-ENOMEM); + + ccdev->dev = dev; + ccdev->clk = devm_clk_get(dev, clock_name); + if (IS_ERR(ccdev->clk)) + return ERR_CAST(ccdev->clk); + + ret = clock_cooling_get_idr(&ccdev->id); + if (ret) + return ERR_PTR(-EINVAL); + + snprintf(dev_name, sizeof(dev_name), "thermal-clock-%d", ccdev->id); + + cdev = thermal_cooling_device_register(dev_name, ccdev, + &clock_cooling_ops); + if (IS_ERR(cdev)) { + release_idr(ccdev->id); + return ERR_PTR(-EINVAL); + } + ccdev->cdev = cdev; + ccdev->clk_rate_change_nb.notifier_call = clock_cooling_clock_notifier; + + /* Assuming someone has already filled the opp table for this device */ + ret = dev_pm_opp_init_cpufreq_table(dev, &ccdev->freq_table); + if (ret) { + release_idr(ccdev->id); + return ERR_PTR(ret); + } + ccdev->clock_state = 0; + ccdev->clock_val = clock_cooling_get_frequency(ccdev, 0); + + clk_notifier_register(ccdev->clk, &ccdev->clk_rate_change_nb); + + return cdev; +} +EXPORT_SYMBOL_GPL(clock_cooling_register); + +/** + * clock_cooling_unregister - function to remove clock cooling device. + * @cdev: thermal cooling device pointer. + * + * This interface function unregisters the "thermal-clock-%x" cooling device. + */ +void clock_cooling_unregister(struct thermal_cooling_device *cdev) +{ + struct clock_cooling_device *ccdev; + + if (!cdev) + return; + + ccdev = cdev->devdata; + + clk_notifier_unregister(ccdev->clk, &ccdev->clk_rate_change_nb); + dev_pm_opp_free_cpufreq_table(ccdev->dev, &ccdev->freq_table); + + thermal_cooling_device_unregister(ccdev->cdev); + release_idr(ccdev->id); +} +EXPORT_SYMBOL_GPL(clock_cooling_unregister); diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index ad09e51ffae4..f65f0d109fc8 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c @@ -4,6 +4,8 @@ * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com) * Copyright (C) 2012 Amit Daniel <amit.kachhap@linaro.org> * + * Copyright (C) 2014 Viresh Kumar <viresh.kumar@linaro.org> + * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,6 +30,20 @@ #include <linux/cpu.h> #include <linux/cpu_cooling.h> +/* + * Cooling state <-> CPUFreq frequency + * + * Cooling states are translated to frequencies throughout this driver and this + * is the relation between them. + * + * Highest cooling state corresponds to lowest possible frequency. + * + * i.e. + * level 0 --> 1st Max Freq + * level 1 --> 2nd Max Freq + * ... + */ + /** * struct cpufreq_cooling_device - data for cooling device with cpufreq * @id: unique integer value corresponding to each cpufreq_cooling_device @@ -38,25 +54,27 @@ * cooling devices. * @cpufreq_val: integer value representing the absolute value of the clipped * frequency. + * @max_level: maximum cooling level. One less than total number of valid + * cpufreq frequencies. * @allowed_cpus: all the cpus involved for this cpufreq_cooling_device. + * @node: list_head to link all cpufreq_cooling_device together. * - * This structure is required for keeping information of each - * cpufreq_cooling_device registered. In order to prevent corruption of this a - * mutex lock cooling_cpufreq_lock is used. + * This structure is required for keeping information of each registered + * cpufreq_cooling_device. */ struct cpufreq_cooling_device { int id; struct thermal_cooling_device *cool_dev; unsigned int cpufreq_state; unsigned int cpufreq_val; + unsigned int max_level; + unsigned int *freq_table; /* In descending order */ struct cpumask allowed_cpus; struct list_head node; }; static DEFINE_IDR(cpufreq_idr); static DEFINE_MUTEX(cooling_cpufreq_lock); -static unsigned int cpufreq_dev_count; - static LIST_HEAD(cpufreq_dev_list); /** @@ -98,120 +116,30 @@ static void release_idr(struct idr *idr, int id) /* Below code defines functions to be used for cpufreq as cooling device */ /** - * is_cpufreq_valid - function to check frequency transitioning capability. - * @cpu: cpu for which check is needed. + * get_level: Find the level for a particular frequency + * @cpufreq_dev: cpufreq_dev for which the property is required + * @freq: Frequency * - * This function will check the current state of the system if - * it is capable of changing the frequency for a given @cpu. - * - * Return: 0 if the system is not currently capable of changing - * the frequency of given cpu. !0 in case the frequency is changeable. + * Return: level on success, THERMAL_CSTATE_INVALID on error. */ -static int is_cpufreq_valid(int cpu) +static unsigned long get_level(struct cpufreq_cooling_device *cpufreq_dev, + unsigned int freq) { - struct cpufreq_policy policy; - - return !cpufreq_get_policy(&policy, cpu); -} - -enum cpufreq_cooling_property { - GET_LEVEL, - GET_FREQ, - GET_MAXL, -}; - -/** - * get_property - fetch a property of interest for a give cpu. - * @cpu: cpu for which the property is required - * @input: query parameter - * @output: query return - * @property: type of query (frequency, level, max level) - * - * This is the common function to - * 1. get maximum cpu cooling states - * 2. translate frequency to cooling state - * 3. translate cooling state to frequency - * Note that the code may be not in good shape - * but it is written in this way in order to: - * a) reduce duplicate code as most of the code can be shared. - * b) make sure the logic is consistent when translating between - * cooling states and frequencies. - * - * Return: 0 on success, -EINVAL when invalid parameters are passed. - */ -static int get_property(unsigned int cpu, unsigned long input, - unsigned int *output, - enum cpufreq_cooling_property property) -{ - int i; - unsigned long max_level = 0, level = 0; - unsigned int freq = CPUFREQ_ENTRY_INVALID; - int descend = -1; - struct cpufreq_frequency_table *pos, *table = - cpufreq_frequency_get_table(cpu); - - if (!output) - return -EINVAL; - - if (!table) - return -EINVAL; - - cpufreq_for_each_valid_entry(pos, table) { - /* ignore duplicate entry */ - if (freq == pos->frequency) - continue; - - /* get the frequency order */ - if (freq != CPUFREQ_ENTRY_INVALID && descend == -1) - descend = freq > pos->frequency; - - freq = pos->frequency; - max_level++; - } - - /* No valid cpu frequency entry */ - if (max_level == 0) - return -EINVAL; + unsigned long level; - /* max_level is an index, not a counter */ - max_level--; + for (level = 0; level <= cpufreq_dev->max_level; level++) { + if (freq == cpufreq_dev->freq_table[level]) + return level; - /* get max level */ - if (property == GET_MAXL) { - *output = (unsigned int)max_level; - return 0; + if (freq > cpufreq_dev->freq_table[level]) + break; } - if (property == GET_FREQ) - level = descend ? input : (max_level - input); - - i = 0; - cpufreq_for_each_valid_entry(pos, table) { - /* ignore duplicate entry */ - if (freq == pos->frequency) - continue; - - /* now we have a valid frequency entry */ - freq = pos->frequency; - - if (property == GET_LEVEL && (unsigned int)input == freq) { - /* get level by frequency */ - *output = descend ? i : (max_level - i); - return 0; - } - if (property == GET_FREQ && level == i) { - /* get frequency by level */ - *output = freq; - return 0; - } - i++; - } - - return -EINVAL; + return THERMAL_CSTATE_INVALID; } /** - * cpufreq_cooling_get_level - for a give cpu, return the cooling level. + * cpufreq_cooling_get_level - for a given cpu, return the cooling level. * @cpu: cpu for which the level is required * @freq: the frequency of interest * @@ -223,77 +151,21 @@ static int get_property(unsigned int cpu, unsigned long input, */ unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq) { - unsigned int val; - - if (get_property(cpu, (unsigned long)freq, &val, GET_LEVEL)) - return THERMAL_CSTATE_INVALID; - - return (unsigned long)val; -} -EXPORT_SYMBOL_GPL(cpufreq_cooling_get_level); - -/** - * get_cpu_frequency - get the absolute value of frequency from level. - * @cpu: cpu for which frequency is fetched. - * @level: cooling level - * - * This function matches cooling level with frequency. Based on a cooling level - * of frequency, equals cooling state of cpu cooling device, it will return - * the corresponding frequency. - * e.g level=0 --> 1st MAX FREQ, level=1 ---> 2nd MAX FREQ, .... etc - * - * Return: 0 on error, the corresponding frequency otherwise. - */ -static unsigned int get_cpu_frequency(unsigned int cpu, unsigned long level) -{ - int ret = 0; - unsigned int freq; - - ret = get_property(cpu, level, &freq, GET_FREQ); - if (ret) - return 0; - - return freq; -} - -/** - * cpufreq_apply_cooling - function to apply frequency clipping. - * @cpufreq_device: cpufreq_cooling_device pointer containing frequency - * clipping data. - * @cooling_state: value of the cooling state. - * - * Function used to make sure the cpufreq layer is aware of current thermal - * limits. The limits are applied by updating the cpufreq policy. - * - * Return: 0 on success, an error code otherwise (-EINVAL in case wrong - * cooling state). - */ -static int cpufreq_apply_cooling(struct cpufreq_cooling_device *cpufreq_device, - unsigned long cooling_state) -{ - unsigned int cpuid, clip_freq; - struct cpumask *mask = &cpufreq_device->allowed_cpus; - unsigned int cpu = cpumask_any(mask); - - - /* Check if the old cooling action is same as new cooling action */ - if (cpufreq_device->cpufreq_state == cooling_state) - return 0; - - clip_freq = get_cpu_frequency(cpu, cooling_state); - if (!clip_freq) - return -EINVAL; - - cpufreq_device->cpufreq_state = cooling_state; - cpufreq_device->cpufreq_val = clip_freq; + struct cpufreq_cooling_device *cpufreq_dev; - for_each_cpu(cpuid, mask) { - if (is_cpufreq_valid(cpuid)) - cpufreq_update_policy(cpuid); + mutex_lock(&cooling_cpufreq_lock); + list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) { + if (cpumask_test_cpu(cpu, &cpufreq_dev->allowed_cpus)) { + mutex_unlock(&cooling_cpufreq_lock); + return get_level(cpufreq_dev, freq); + } } + mutex_unlock(&cooling_cpufreq_lock); - return 0; + pr_err("%s: cpu:%d not part of any cooling device\n", __func__, cpu); + return THERMAL_CSTATE_INVALID; } +EXPORT_SYMBOL_GPL(cpufreq_cooling_get_level); /** * cpufreq_thermal_notifier - notifier callback for cpufreq policy change. @@ -323,11 +195,6 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb, &cpufreq_dev->allowed_cpus)) continue; - if (!cpufreq_dev->cpufreq_val) - cpufreq_dev->cpufreq_val = get_cpu_frequency( - cpumask_any(&cpufreq_dev->allowed_cpus), - cpufreq_dev->cpufreq_state); - max_freq = cpufreq_dev->cpufreq_val; if (policy->max != max_freq) @@ -354,19 +221,9 @@ static int cpufreq_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state) { struct cpufreq_cooling_device *cpufreq_device = cdev->devdata; - struct cpumask *mask = &cpufreq_device->allowed_cpus; - unsigned int cpu; - unsigned int count = 0; - int ret; - - cpu = cpumask_any(mask); - - ret = get_property(cpu, 0, &count, GET_MAXL); - if (count > 0) - *state = count; - - return ret; + *state = cpufreq_device->max_level; + return 0; } /** @@ -403,8 +260,24 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) { struct cpufreq_cooling_device *cpufreq_device = cdev->devdata; + unsigned int cpu = cpumask_any(&cpufreq_device->allowed_cpus); + unsigned int clip_freq; + + /* Request state should be less than max_level */ + if (WARN_ON(state > cpufreq_device->max_level)) + return -EINVAL; + + /* Check if the old cooling action is same as new cooling action */ + if (cpufreq_device->cpufreq_state == state) + return 0; - return cpufreq_apply_cooling(cpufreq_device, state); + clip_freq = cpufreq_device->freq_table[state]; + cpufreq_device->cpufreq_state = state; + cpufreq_device->cpufreq_val = clip_freq; + + cpufreq_update_policy(cpu); + + return 0; } /* Bind cpufreq callbacks to thermal cooling device ops */ @@ -419,10 +292,25 @@ static struct notifier_block thermal_cpufreq_notifier_block = { .notifier_call = cpufreq_thermal_notifier, }; +static unsigned int find_next_max(struct cpufreq_frequency_table *table, + unsigned int prev_max) +{ + struct cpufreq_frequency_table *pos; + unsigned int max = 0; + + cpufreq_for_each_valid_entry(pos, table) { + if (pos->frequency > max && pos->frequency < prev_max) + max = pos->frequency; + } + + return max; +} + /** * __cpufreq_cooling_register - helper function to create cpufreq cooling device * @np: a valid struct device_node to the cooling device device tree node * @clip_cpus: cpumask of cpus where the frequency constraints will happen. + * Normally this should be same as cpufreq policy->related_cpus. * * This interface function registers the cpufreq cooling device with the name * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq @@ -437,37 +325,42 @@ __cpufreq_cooling_register(struct device_node *np, const struct cpumask *clip_cpus) { struct thermal_cooling_device *cool_dev; - struct cpufreq_cooling_device *cpufreq_dev = NULL; - unsigned int min = 0, max = 0; + struct cpufreq_cooling_device *cpufreq_dev; char dev_name[THERMAL_NAME_LENGTH]; - int ret = 0, i; - struct cpufreq_policy policy; + struct cpufreq_frequency_table *pos, *table; + unsigned int freq, i; + int ret; - /* Verify that all the clip cpus have same freq_min, freq_max limit */ - for_each_cpu(i, clip_cpus) { - /* continue if cpufreq policy not found and not return error */ - if (!cpufreq_get_policy(&policy, i)) - continue; - if (min == 0 && max == 0) { - min = policy.cpuinfo.min_freq; - max = policy.cpuinfo.max_freq; - } else { - if (min != policy.cpuinfo.min_freq || - max != policy.cpuinfo.max_freq) - return ERR_PTR(-EINVAL); - } + table = cpufreq_frequency_get_table(cpumask_first(clip_cpus)); + if (!table) { + pr_debug("%s: CPUFreq table not found\n", __func__); + return ERR_PTR(-EPROBE_DEFER); } - cpufreq_dev = kzalloc(sizeof(struct cpufreq_cooling_device), - GFP_KERNEL); + + cpufreq_dev = kzalloc(sizeof(*cpufreq_dev), GFP_KERNEL); if (!cpufreq_dev) return ERR_PTR(-ENOMEM); + /* Find max levels */ + cpufreq_for_each_valid_entry(pos, table) + cpufreq_dev->max_level++; + + cpufreq_dev->freq_table = kmalloc(sizeof(*cpufreq_dev->freq_table) * + cpufreq_dev->max_level, GFP_KERNEL); + if (!cpufreq_dev->freq_table) { + cool_dev = ERR_PTR(-ENOMEM); + goto free_cdev; + } + + /* max_level is an index, not a counter */ + cpufreq_dev->max_level--; + cpumask_copy(&cpufreq_dev->allowed_cpus, clip_cpus); ret = get_idr(&cpufreq_idr, &cpufreq_dev->id); if (ret) { - kfree(cpufreq_dev); - return ERR_PTR(-EINVAL); + cool_dev = ERR_PTR(ret); + goto free_table; } snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d", @@ -475,25 +368,44 @@ __cpufreq_cooling_register(struct device_node *np, cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev, &cpufreq_cooling_ops); - if (IS_ERR(cool_dev)) { - release_idr(&cpufreq_idr, cpufreq_dev->id); - kfree(cpufreq_dev); - return cool_dev; + if (IS_ERR(cool_dev)) + goto remove_idr; + + /* Fill freq-table in descending order of frequencies */ + for (i = 0, freq = -1; i <= cpufreq_dev->max_level; i++) { + freq = find_next_max(table, freq); + cpufreq_dev->freq_table[i] = freq; + + /* Warn for duplicate entries */ + if (!freq) + pr_warn("%s: table has duplicate entries\n", __func__); + else + pr_debug("%s: freq:%u KHz\n", __func__, freq); } + + cpufreq_dev->cpufreq_val = cpufreq_dev->freq_table[0]; cpufreq_dev->cool_dev = cool_dev; - cpufreq_dev->cpufreq_state = 0; + mutex_lock(&cooling_cpufreq_lock); /* Register the notifier for first cpufreq cooling device */ - if (cpufreq_dev_count == 0) + if (list_empty(&cpufreq_dev_list)) cpufreq_register_notifier(&thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER); - cpufreq_dev_count++; list_add(&cpufreq_dev->node, &cpufreq_dev_list); mutex_unlock(&cooling_cpufreq_lock); return cool_dev; + +remove_idr: + release_idr(&cpufreq_idr, cpufreq_dev->id); +free_table: + kfree(cpufreq_dev->freq_table); +free_cdev: + kfree(cpufreq_dev); + + return cool_dev; } /** @@ -554,16 +466,16 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) cpufreq_dev = cdev->devdata; mutex_lock(&cooling_cpufreq_lock); list_del(&cpufreq_dev->node); - cpufreq_dev_count--; /* Unregister the notifier for the last cpufreq cooling device */ - if (cpufreq_dev_count == 0) + if (list_empty(&cpufreq_dev_list)) cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER); mutex_unlock(&cooling_cpufreq_lock); thermal_cooling_device_unregister(cpufreq_dev->cool_dev); release_idr(&cpufreq_idr, cpufreq_dev->id); + kfree(cpufreq_dev->freq_table); kfree(cpufreq_dev); } EXPORT_SYMBOL_GPL(cpufreq_cooling_unregister); diff --git a/drivers/thermal/db8500_cpufreq_cooling.c b/drivers/thermal/db8500_cpufreq_cooling.c index 000d53e934a0..607b62c7e611 100644 --- a/drivers/thermal/db8500_cpufreq_cooling.c +++ b/drivers/thermal/db8500_cpufreq_cooling.c @@ -18,7 +18,6 @@ */ #include <linux/cpu_cooling.h> -#include <linux/cpufreq.h> #include <linux/err.h> #include <linux/module.h> #include <linux/of.h> @@ -28,18 +27,17 @@ static int db8500_cpufreq_cooling_probe(struct platform_device *pdev) { struct thermal_cooling_device *cdev; - struct cpumask mask_val; - - /* make sure cpufreq driver has been initialized */ - if (!cpufreq_frequency_get_table(0)) - return -EPROBE_DEFER; - - cpumask_set_cpu(0, &mask_val); - cdev = cpufreq_cooling_register(&mask_val); + cdev = cpufreq_cooling_register(cpu_present_mask); if (IS_ERR(cdev)) { - dev_err(&pdev->dev, "Failed to register cooling device\n"); - return PTR_ERR(cdev); + int ret = PTR_ERR(cdev); + + if (ret != -EPROBE_DEFER) + dev_err(&pdev->dev, + "Failed to register cooling device %d\n", + ret); + + return ret; } platform_set_drvdata(pdev, cdev); diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index 88b32f942dcf..2ccbc0788353 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -9,7 +9,6 @@ #include <linux/clk.h> #include <linux/cpu_cooling.h> -#include <linux/cpufreq.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/init.h> @@ -454,15 +453,10 @@ static int imx_thermal_probe(struct platform_device *pdev) const struct of_device_id *of_id = of_match_device(of_imx_thermal_match, &pdev->dev); struct imx_thermal_data *data; - struct cpumask clip_cpus; struct regmap *map; int measure_freq; int ret; - if (!cpufreq_get_current_driver()) { - dev_dbg(&pdev->dev, "no cpufreq driver!"); - return -EPROBE_DEFER; - } data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; @@ -516,12 +510,13 @@ static int imx_thermal_probe(struct platform_device *pdev) regmap_write(map, MISC0 + REG_SET, MISC0_REFTOP_SELBIASOFF); regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN); - cpumask_set_cpu(0, &clip_cpus); - data->cdev = cpufreq_cooling_register(&clip_cpus); + data->cdev = cpufreq_cooling_register(cpu_present_mask); if (IS_ERR(data->cdev)) { ret = PTR_ERR(data->cdev); - dev_err(&pdev->dev, - "failed to register cpufreq cooling device: %d\n", ret); + if (ret != -EPROBE_DEFER) + dev_err(&pdev->dev, + "failed to register cpufreq cooling device: %d\n", + ret); return ret; } @@ -613,6 +608,7 @@ static int imx_thermal_suspend(struct device *dev) regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP); regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN); data->mode = THERMAL_DEVICE_DISABLED; + clk_disable_unprepare(data->thermal_clk); return 0; } @@ -622,6 +618,7 @@ static int imx_thermal_resume(struct device *dev) struct imx_thermal_data *data = dev_get_drvdata(dev); struct regmap *map = data->tempmon; + clk_prepare_enable(data->thermal_clk); /* Enabled thermal sensor after resume */ regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN); regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP); diff --git a/drivers/thermal/int340x_thermal/Makefile b/drivers/thermal/int340x_thermal/Makefile index ffe40bffaf1a..d4413698a85f 100644 --- a/drivers/thermal/int340x_thermal/Makefile +++ b/drivers/thermal/int340x_thermal/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_INT340X_THERMAL) += int3400_thermal.o obj-$(CONFIG_INT340X_THERMAL) += int3402_thermal.o obj-$(CONFIG_INT340X_THERMAL) += int3403_thermal.o +obj-$(CONFIG_INT340X_THERMAL) += processor_thermal_device.o obj-$(CONFIG_ACPI_THERMAL_REL) += acpi_thermal_rel.o diff --git a/drivers/thermal/int340x_thermal/acpi_thermal_rel.c b/drivers/thermal/int340x_thermal/acpi_thermal_rel.c index 0d8db808f0ae..2c2ec7666eb1 100644 --- a/drivers/thermal/int340x_thermal/acpi_thermal_rel.c +++ b/drivers/thermal/int340x_thermal/acpi_thermal_rel.c @@ -82,7 +82,7 @@ int acpi_parse_trt(acpi_handle handle, int *trt_count, struct trt **trtp, struct acpi_buffer trt_format = { sizeof("RRNNNNNN"), "RRNNNNNN" }; if (!acpi_has_method(handle, "_TRT")) - return 0; + return -ENODEV; status = acpi_evaluate_object(handle, "_TRT", NULL, &buffer); if (ACPI_FAILURE(status)) @@ -119,18 +119,16 @@ int acpi_parse_trt(acpi_handle handle, int *trt_count, struct trt **trtp, continue; result = acpi_bus_get_device(trt->source, &adev); - if (!result) - acpi_create_platform_device(adev); - else + if (result) pr_warn("Failed to get source ACPI device\n"); result = acpi_bus_get_device(trt->target, &adev); - if (!result) - acpi_create_platform_device(adev); - else + if (result) pr_warn("Failed to get target ACPI device\n"); } + result = 0; + *trtp = trts; /* don't count bad entries */ *trt_count -= nr_bad_entries; @@ -165,7 +163,7 @@ int acpi_parse_art(acpi_handle handle, int *art_count, struct art **artp, sizeof("RRNNNNNNNNNNN"), "RRNNNNNNNNNNN" }; if (!acpi_has_method(handle, "_ART")) - return 0; + return -ENODEV; status = acpi_evaluate_object(handle, "_ART", NULL, &buffer); if (ACPI_FAILURE(status)) @@ -204,16 +202,12 @@ int acpi_parse_art(acpi_handle handle, int *art_count, struct art **artp, if (art->source) { result = acpi_bus_get_device(art->source, &adev); - if (!result) - acpi_create_platform_device(adev); - else + if (result) pr_warn("Failed to get source ACPI device\n"); } if (art->target) { result = acpi_bus_get_device(art->target, &adev); - if (!result) - acpi_create_platform_device(adev); - else + if (result) pr_warn("Failed to get source ACPI device\n"); } } @@ -317,21 +311,21 @@ static long acpi_thermal_rel_ioctl(struct file *f, unsigned int cmd, { int ret = 0; unsigned long length = 0; - unsigned long count = 0; + int count = 0; char __user *arg = (void __user *)__arg; - struct trt *trts; - struct art *arts; + struct trt *trts = NULL; + struct art *arts = NULL; switch (cmd) { case ACPI_THERMAL_GET_TRT_COUNT: - ret = acpi_parse_trt(acpi_thermal_rel_handle, (int *)&count, + ret = acpi_parse_trt(acpi_thermal_rel_handle, &count, &trts, false); kfree(trts); if (!ret) return put_user(count, (unsigned long __user *)__arg); return ret; case ACPI_THERMAL_GET_TRT_LEN: - ret = acpi_parse_trt(acpi_thermal_rel_handle, (int *)&count, + ret = acpi_parse_trt(acpi_thermal_rel_handle, &count, &trts, false); kfree(trts); length = count * sizeof(union trt_object); @@ -341,14 +335,14 @@ static long acpi_thermal_rel_ioctl(struct file *f, unsigned int cmd, case ACPI_THERMAL_GET_TRT: return fill_trt(arg); case ACPI_THERMAL_GET_ART_COUNT: - ret = acpi_parse_art(acpi_thermal_rel_handle, (int *)&count, + ret = acpi_parse_art(acpi_thermal_rel_handle, &count, &arts, false); kfree(arts); if (!ret) return put_user(count, (unsigned long __user *)__arg); return ret; case ACPI_THERMAL_GET_ART_LEN: - ret = acpi_parse_art(acpi_thermal_rel_handle, (int *)&count, + ret = acpi_parse_art(acpi_thermal_rel_handle, &count, &arts, false); kfree(arts); length = count * sizeof(union art_object); diff --git a/drivers/thermal/int340x_thermal/int3400_thermal.c b/drivers/thermal/int340x_thermal/int3400_thermal.c index edc1cce117ba..65a98a97df07 100644 --- a/drivers/thermal/int340x_thermal/int3400_thermal.c +++ b/drivers/thermal/int340x_thermal/int3400_thermal.c @@ -43,6 +43,74 @@ struct int3400_thermal_priv { struct trt *trts; u8 uuid_bitmap; int rel_misc_dev_res; + int current_uuid_index; +}; + +static ssize_t available_uuids_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct int3400_thermal_priv *priv = platform_get_drvdata(pdev); + int i; + int length = 0; + + for (i = 0; i < INT3400_THERMAL_MAXIMUM_UUID; i++) { + if (priv->uuid_bitmap & (1 << i)) + if (PAGE_SIZE - length > 0) + length += snprintf(&buf[length], + PAGE_SIZE - length, + "%s\n", + int3400_thermal_uuids[i]); + } + + return length; +} + +static ssize_t current_uuid_show(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct int3400_thermal_priv *priv = platform_get_drvdata(pdev); + + if (priv->uuid_bitmap & (1 << priv->current_uuid_index)) + return sprintf(buf, "%s\n", + int3400_thermal_uuids[priv->current_uuid_index]); + else + return sprintf(buf, "INVALID\n"); +} + +static ssize_t current_uuid_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct platform_device *pdev = to_platform_device(dev); + struct int3400_thermal_priv *priv = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < INT3400_THERMAL_MAXIMUM_UUID; ++i) { + if ((priv->uuid_bitmap & (1 << i)) && + !(strncmp(buf, int3400_thermal_uuids[i], + sizeof(int3400_thermal_uuids[i]) - 1))) { + priv->current_uuid_index = i; + return count; + } + } + + return -EINVAL; +} + +static DEVICE_ATTR(current_uuid, 0644, current_uuid_show, current_uuid_store); +static DEVICE_ATTR_RO(available_uuids); +static struct attribute *uuid_attrs[] = { + &dev_attr_available_uuids.attr, + &dev_attr_current_uuid.attr, + NULL +}; + +static struct attribute_group uuid_attribute_group = { + .attrs = uuid_attrs, + .name = "uuids" }; static int int3400_thermal_get_uuids(struct int3400_thermal_priv *priv) @@ -160,9 +228,9 @@ static int int3400_thermal_set_mode(struct thermal_zone_device *thermal, if (enable != priv->mode) { priv->mode = enable; - /* currently, only PASSIVE COOLING is supported */ result = int3400_thermal_run_osc(priv->adev->handle, - INT3400_THERMAL_PASSIVE_1, enable); + priv->current_uuid_index, + enable); } return result; } @@ -223,7 +291,14 @@ static int int3400_thermal_probe(struct platform_device *pdev) priv->rel_misc_dev_res = acpi_thermal_rel_misc_device_add( priv->adev->handle); + result = sysfs_create_group(&pdev->dev.kobj, &uuid_attribute_group); + if (result) + goto free_zone; + return 0; + +free_zone: + thermal_zone_device_unregister(priv->thermal); free_trt: kfree(priv->trts); free_art: @@ -240,6 +315,7 @@ static int int3400_thermal_remove(struct platform_device *pdev) if (!priv->rel_misc_dev_res) acpi_thermal_rel_misc_device_remove(priv->adev->handle); + sysfs_remove_group(&pdev->dev.kobj, &uuid_attribute_group); thermal_zone_device_unregister(priv->thermal); kfree(priv->trts); kfree(priv->arts); @@ -259,7 +335,6 @@ static struct platform_driver int3400_thermal_driver = { .remove = int3400_thermal_remove, .driver = { .name = "int3400 thermal", - .owner = THIS_MODULE, .acpi_match_table = ACPI_PTR(int3400_thermal_match), }, }; diff --git a/drivers/thermal/int340x_thermal/int3402_thermal.c b/drivers/thermal/int340x_thermal/int3402_thermal.c index a5d08c14ba24..c5cbc3af3a05 100644 --- a/drivers/thermal/int340x_thermal/int3402_thermal.c +++ b/drivers/thermal/int340x_thermal/int3402_thermal.c @@ -231,7 +231,6 @@ static struct platform_driver int3402_thermal_driver = { .remove = int3402_thermal_remove, .driver = { .name = "int3402 thermal", - .owner = THIS_MODULE, .acpi_match_table = int3402_thermal_match, }, }; diff --git a/drivers/thermal/int340x_thermal/int3403_thermal.c b/drivers/thermal/int340x_thermal/int3403_thermal.c index 6e9fb62eb817..0faf500d8a77 100644 --- a/drivers/thermal/int340x_thermal/int3403_thermal.c +++ b/drivers/thermal/int340x_thermal/int3403_thermal.c @@ -293,8 +293,7 @@ static int int3403_sensor_add(struct int3403_priv *priv) return 0; err_free_obj: - if (obj->tzone) - thermal_zone_device_unregister(obj->tzone); + thermal_zone_device_unregister(obj->tzone); return result; } @@ -302,6 +301,8 @@ static int int3403_sensor_remove(struct int3403_priv *priv) { struct int3403_sensor *obj = priv->priv; + acpi_remove_notify_handler(priv->adev->handle, + ACPI_DEVICE_NOTIFY, int3403_notify); thermal_zone_device_unregister(obj->tzone); return 0; } @@ -370,6 +371,7 @@ static int int3403_cdev_add(struct int3403_priv *priv) p = buf.pointer; if (!p || (p->type != ACPI_TYPE_PACKAGE)) { printk(KERN_WARNING "Invalid PPSS data\n"); + kfree(buf.pointer); return -EFAULT; } @@ -382,6 +384,7 @@ static int int3403_cdev_add(struct int3403_priv *priv) priv->priv = obj; + kfree(buf.pointer); /* TODO: add ACPI notification support */ return result; @@ -471,7 +474,6 @@ static struct platform_driver int3403_driver = { .remove = int3403_remove, .driver = { .name = "int3403 thermal", - .owner = THIS_MODULE, .acpi_match_table = int3403_device_ids, }, }; diff --git a/drivers/thermal/int340x_thermal/processor_thermal_device.c b/drivers/thermal/int340x_thermal/processor_thermal_device.c new file mode 100644 index 000000000000..0fe5dbbea968 --- /dev/null +++ b/drivers/thermal/int340x_thermal/processor_thermal_device.c @@ -0,0 +1,311 @@ +/* + * processor_thermal_device.c + * Copyright (c) 2014, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/platform_device.h> +#include <linux/acpi.h> + +/* Broadwell-U/HSB thermal reporting device */ +#define PCI_DEVICE_ID_PROC_BDW_THERMAL 0x1603 +#define PCI_DEVICE_ID_PROC_HSB_THERMAL 0x0A03 + +/* Braswell thermal reporting device */ +#define PCI_DEVICE_ID_PROC_BSW_THERMAL 0x22DC + +struct power_config { + u32 index; + u32 min_uw; + u32 max_uw; + u32 tmin_us; + u32 tmax_us; + u32 step_uw; +}; + +struct proc_thermal_device { + struct device *dev; + struct acpi_device *adev; + struct power_config power_limits[2]; +}; + +enum proc_thermal_emum_mode_type { + PROC_THERMAL_NONE, + PROC_THERMAL_PCI, + PROC_THERMAL_PLATFORM_DEV +}; + +/* + * We can have only one type of enumeration, PCI or Platform, + * not both. So we don't need instance specific data. + */ +static enum proc_thermal_emum_mode_type proc_thermal_emum_mode = + PROC_THERMAL_NONE; + +#define POWER_LIMIT_SHOW(index, suffix) \ +static ssize_t power_limit_##index##_##suffix##_show(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ +{ \ + struct pci_dev *pci_dev; \ + struct platform_device *pdev; \ + struct proc_thermal_device *proc_dev; \ +\ + if (proc_thermal_emum_mode == PROC_THERMAL_PLATFORM_DEV) { \ + pdev = to_platform_device(dev); \ + proc_dev = platform_get_drvdata(pdev); \ + } else { \ + pci_dev = to_pci_dev(dev); \ + proc_dev = pci_get_drvdata(pci_dev); \ + } \ + return sprintf(buf, "%lu\n",\ + (unsigned long)proc_dev->power_limits[index].suffix * 1000); \ +} + +POWER_LIMIT_SHOW(0, min_uw) +POWER_LIMIT_SHOW(0, max_uw) +POWER_LIMIT_SHOW(0, step_uw) +POWER_LIMIT_SHOW(0, tmin_us) +POWER_LIMIT_SHOW(0, tmax_us) + +POWER_LIMIT_SHOW(1, min_uw) +POWER_LIMIT_SHOW(1, max_uw) +POWER_LIMIT_SHOW(1, step_uw) +POWER_LIMIT_SHOW(1, tmin_us) +POWER_LIMIT_SHOW(1, tmax_us) + +static DEVICE_ATTR_RO(power_limit_0_min_uw); +static DEVICE_ATTR_RO(power_limit_0_max_uw); +static DEVICE_ATTR_RO(power_limit_0_step_uw); +static DEVICE_ATTR_RO(power_limit_0_tmin_us); +static DEVICE_ATTR_RO(power_limit_0_tmax_us); + +static DEVICE_ATTR_RO(power_limit_1_min_uw); +static DEVICE_ATTR_RO(power_limit_1_max_uw); +static DEVICE_ATTR_RO(power_limit_1_step_uw); +static DEVICE_ATTR_RO(power_limit_1_tmin_us); +static DEVICE_ATTR_RO(power_limit_1_tmax_us); + +static struct attribute *power_limit_attrs[] = { + &dev_attr_power_limit_0_min_uw.attr, + &dev_attr_power_limit_1_min_uw.attr, + &dev_attr_power_limit_0_max_uw.attr, + &dev_attr_power_limit_1_max_uw.attr, + &dev_attr_power_limit_0_step_uw.attr, + &dev_attr_power_limit_1_step_uw.attr, + &dev_attr_power_limit_0_tmin_us.attr, + &dev_attr_power_limit_1_tmin_us.attr, + &dev_attr_power_limit_0_tmax_us.attr, + &dev_attr_power_limit_1_tmax_us.attr, + NULL +}; + +static struct attribute_group power_limit_attribute_group = { + .attrs = power_limit_attrs, + .name = "power_limits" +}; + +static int proc_thermal_add(struct device *dev, + struct proc_thermal_device **priv) +{ + struct proc_thermal_device *proc_priv; + struct acpi_device *adev; + acpi_status status; + struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *elements, *ppcc; + union acpi_object *p; + int i; + int ret; + + adev = ACPI_COMPANION(dev); + if (!adev) + return -ENODEV; + + status = acpi_evaluate_object(adev->handle, "PPCC", NULL, &buf); + if (ACPI_FAILURE(status)) + return -ENODEV; + + p = buf.pointer; + if (!p || (p->type != ACPI_TYPE_PACKAGE)) { + dev_err(dev, "Invalid PPCC data\n"); + ret = -EFAULT; + goto free_buffer; + } + if (!p->package.count) { + dev_err(dev, "Invalid PPCC package size\n"); + ret = -EFAULT; + goto free_buffer; + } + + proc_priv = devm_kzalloc(dev, sizeof(*proc_priv), GFP_KERNEL); + if (!proc_priv) { + ret = -ENOMEM; + goto free_buffer; + } + + proc_priv->dev = dev; + proc_priv->adev = adev; + + for (i = 0; i < min((int)p->package.count - 1, 2); ++i) { + elements = &(p->package.elements[i+1]); + if (elements->type != ACPI_TYPE_PACKAGE || + elements->package.count != 6) { + ret = -EFAULT; + goto free_buffer; + } + ppcc = elements->package.elements; + proc_priv->power_limits[i].index = ppcc[0].integer.value; + proc_priv->power_limits[i].min_uw = ppcc[1].integer.value; + proc_priv->power_limits[i].max_uw = ppcc[2].integer.value; + proc_priv->power_limits[i].tmin_us = ppcc[3].integer.value; + proc_priv->power_limits[i].tmax_us = ppcc[4].integer.value; + proc_priv->power_limits[i].step_uw = ppcc[5].integer.value; + } + + *priv = proc_priv; + + ret = sysfs_create_group(&dev->kobj, + &power_limit_attribute_group); + +free_buffer: + kfree(buf.pointer); + + return ret; +} + +void proc_thermal_remove(struct proc_thermal_device *proc_priv) +{ + sysfs_remove_group(&proc_priv->dev->kobj, + &power_limit_attribute_group); +} + +static int int3401_add(struct platform_device *pdev) +{ + struct proc_thermal_device *proc_priv; + int ret; + + if (proc_thermal_emum_mode == PROC_THERMAL_PCI) { + dev_err(&pdev->dev, "error: enumerated as PCI dev\n"); + return -ENODEV; + } + + ret = proc_thermal_add(&pdev->dev, &proc_priv); + if (ret) + return ret; + + platform_set_drvdata(pdev, proc_priv); + proc_thermal_emum_mode = PROC_THERMAL_PLATFORM_DEV; + + return 0; +} + +static int int3401_remove(struct platform_device *pdev) +{ + proc_thermal_remove(platform_get_drvdata(pdev)); + + return 0; +} + +static int proc_thermal_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *unused) +{ + struct proc_thermal_device *proc_priv; + int ret; + + if (proc_thermal_emum_mode == PROC_THERMAL_PLATFORM_DEV) { + dev_err(&pdev->dev, "error: enumerated as platform dev\n"); + return -ENODEV; + } + + ret = pci_enable_device(pdev); + if (ret < 0) { + dev_err(&pdev->dev, "error: could not enable device\n"); + return ret; + } + + ret = proc_thermal_add(&pdev->dev, &proc_priv); + if (ret) { + pci_disable_device(pdev); + return ret; + } + + pci_set_drvdata(pdev, proc_priv); + proc_thermal_emum_mode = PROC_THERMAL_PCI; + + return 0; +} + +static void proc_thermal_pci_remove(struct pci_dev *pdev) +{ + proc_thermal_remove(pci_get_drvdata(pdev)); + pci_disable_device(pdev); +} + +static const struct pci_device_id proc_thermal_pci_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BDW_THERMAL)}, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_HSB_THERMAL)}, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BSW_THERMAL)}, + { 0, }, +}; + +MODULE_DEVICE_TABLE(pci, proc_thermal_pci_ids); + +static struct pci_driver proc_thermal_pci_driver = { + .name = "proc_thermal", + .probe = proc_thermal_pci_probe, + .remove = proc_thermal_pci_remove, + .id_table = proc_thermal_pci_ids, +}; + +static const struct acpi_device_id int3401_device_ids[] = { + {"INT3401", 0}, + {"", 0}, +}; +MODULE_DEVICE_TABLE(acpi, int3401_device_ids); + +static struct platform_driver int3401_driver = { + .probe = int3401_add, + .remove = int3401_remove, + .driver = { + .name = "int3401 thermal", + .acpi_match_table = int3401_device_ids, + }, +}; + +static int __init proc_thermal_init(void) +{ + int ret; + + ret = platform_driver_register(&int3401_driver); + if (ret) + return ret; + + ret = pci_register_driver(&proc_thermal_pci_driver); + + return ret; +} + +static void __exit proc_thermal_exit(void) +{ + platform_driver_unregister(&int3401_driver); + pci_unregister_driver(&proc_thermal_pci_driver); +} + +module_init(proc_thermal_init); +module_exit(proc_thermal_exit); + +MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>"); +MODULE_DESCRIPTION("Processor Thermal Reporting Device Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/thermal/intel_powerclamp.c b/drivers/thermal/intel_powerclamp.c index 95cb7fc20e17..6ceebd659dd4 100644 --- a/drivers/thermal/intel_powerclamp.c +++ b/drivers/thermal/intel_powerclamp.c @@ -435,7 +435,6 @@ static int clamp_thread(void *arg) * allowed. thus jiffies are updated properly. */ preempt_disable(); - tick_nohz_idle_enter(); /* mwait until target jiffies is reached */ while (time_before(jiffies, target_jiffies)) { unsigned long ecx = 1; @@ -451,7 +450,6 @@ static int clamp_thread(void *arg) start_critical_timings(); atomic_inc(&idle_wakeup_counter); } - tick_nohz_idle_exit(); preempt_enable(); } del_timer_sync(&wakeup_timer); @@ -689,6 +687,8 @@ static const struct x86_cpu_id intel_powerclamp_ids[] = { { X86_VENDOR_INTEL, 6, 0x3f}, { X86_VENDOR_INTEL, 6, 0x45}, { X86_VENDOR_INTEL, 6, 0x46}, + { X86_VENDOR_INTEL, 6, 0x4c}, + { X86_VENDOR_INTEL, 6, 0x56}, {} }; MODULE_DEVICE_TABLE(x86cpu, intel_powerclamp_ids); diff --git a/drivers/thermal/intel_soc_dts_thermal.c b/drivers/thermal/intel_soc_dts_thermal.c index a6a0a18ec0aa..5580f5b24eb9 100644 --- a/drivers/thermal/intel_soc_dts_thermal.c +++ b/drivers/thermal/intel_soc_dts_thermal.c @@ -360,6 +360,9 @@ static void proc_thermal_interrupt(void) u32 sticky_out; int status; u32 ptmc_out; + unsigned long flags; + + spin_lock_irqsave(&intr_notify_lock, flags); /* Clear APIC interrupt */ status = iosf_mbi_read(BT_MBI_UNIT_PMC, BT_MBI_BUNIT_READ, @@ -378,21 +381,20 @@ static void proc_thermal_interrupt(void) /* reset sticky bit */ status = iosf_mbi_write(BT_MBI_UNIT_PMC, BT_MBI_BUNIT_WRITE, SOC_DTS_OFFSET_PTTSS, sticky_out); + spin_unlock_irqrestore(&intr_notify_lock, flags); + for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) { pr_debug("TZD update for zone %d\n", i); thermal_zone_device_update(soc_dts[i]->tzone); } - } + } else + spin_unlock_irqrestore(&intr_notify_lock, flags); } static irqreturn_t soc_irq_thread_fn(int irq, void *dev_data) { - unsigned long flags; - - spin_lock_irqsave(&intr_notify_lock, flags); proc_thermal_interrupt(); - spin_unlock_irqrestore(&intr_notify_lock, flags); pr_debug("proc_thermal_interrupt\n"); return IRQ_HANDLED; diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c index 62143ba31001..d717f3dab6f1 100644 --- a/drivers/thermal/of-thermal.c +++ b/drivers/thermal/of-thermal.c @@ -30,27 +30,13 @@ #include <linux/err.h> #include <linux/export.h> #include <linux/string.h> +#include <linux/thermal.h> #include "thermal_core.h" /*** Private data structures to represent thermal device tree data ***/ /** - * struct __thermal_trip - representation of a point in temperature domain - * @np: pointer to struct device_node that this trip point was created from - * @temperature: temperature value in miliCelsius - * @hysteresis: relative hysteresis in miliCelsius - * @type: trip point type - */ - -struct __thermal_trip { - struct device_node *np; - unsigned long int temperature; - unsigned long int hysteresis; - enum thermal_trip_type type; -}; - -/** * struct __thermal_bind_param - a match between trip and cooling device * @cooling_device: a pointer to identify the referred cooling device * @trip_id: the trip point index @@ -77,8 +63,7 @@ struct __thermal_bind_params { * @num_tbps: number of thermal bind params * @tbps: an array of thermal bind params (0..num_tbps - 1) * @sensor_data: sensor private data used while reading temperature and trend - * @get_temp: sensor callback to read temperature - * @get_trend: sensor callback to read temperature trend + * @ops: set of callbacks to handle the thermal zone based on DT */ struct __thermal_zone { @@ -88,7 +73,7 @@ struct __thermal_zone { /* trip data */ int ntrips; - struct __thermal_trip *trips; + struct thermal_trip *trips; /* cooling binding data */ int num_tbps; @@ -96,8 +81,7 @@ struct __thermal_zone { /* sensor interface */ void *sensor_data; - int (*get_temp)(void *, long *); - int (*get_trend)(void *, long *); + const struct thermal_zone_of_device_ops *ops; }; /*** DT thermal zone device callbacks ***/ @@ -107,10 +91,96 @@ static int of_thermal_get_temp(struct thermal_zone_device *tz, { struct __thermal_zone *data = tz->devdata; - if (!data->get_temp) + if (!data->ops->get_temp) return -EINVAL; - return data->get_temp(data->sensor_data, temp); + return data->ops->get_temp(data->sensor_data, temp); +} + +/** + * of_thermal_get_ntrips - function to export number of available trip + * points. + * @tz: pointer to a thermal zone + * + * This function is a globally visible wrapper to get number of trip points + * stored in the local struct __thermal_zone + * + * Return: number of available trip points, -ENODEV when data not available + */ +int of_thermal_get_ntrips(struct thermal_zone_device *tz) +{ + struct __thermal_zone *data = tz->devdata; + + if (!data || IS_ERR(data)) + return -ENODEV; + + return data->ntrips; +} +EXPORT_SYMBOL_GPL(of_thermal_get_ntrips); + +/** + * of_thermal_is_trip_valid - function to check if trip point is valid + * + * @tz: pointer to a thermal zone + * @trip: trip point to evaluate + * + * This function is responsible for checking if passed trip point is valid + * + * Return: true if trip point is valid, false otherwise + */ +bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, int trip) +{ + struct __thermal_zone *data = tz->devdata; + + if (!data || trip >= data->ntrips || trip < 0) + return false; + + return true; +} +EXPORT_SYMBOL_GPL(of_thermal_is_trip_valid); + +/** + * of_thermal_get_trip_points - function to get access to a globally exported + * trip points + * + * @tz: pointer to a thermal zone + * + * This function provides a pointer to trip points table + * + * Return: pointer to trip points table, NULL otherwise + */ +const struct thermal_trip * +of_thermal_get_trip_points(struct thermal_zone_device *tz) +{ + struct __thermal_zone *data = tz->devdata; + + if (!data) + return NULL; + + return data->trips; +} +EXPORT_SYMBOL_GPL(of_thermal_get_trip_points); + +/** + * of_thermal_set_emul_temp - function to set emulated temperature + * + * @tz: pointer to a thermal zone + * @temp: temperature to set + * + * This function gives the ability to set emulated value of temperature, + * which is handy for debugging + * + * Return: zero on success, error code otherwise + */ +static int of_thermal_set_emul_temp(struct thermal_zone_device *tz, + unsigned long temp) +{ + struct __thermal_zone *data = tz->devdata; + + if (!data->ops || !data->ops->set_emul_temp) + return -EINVAL; + + return data->ops->set_emul_temp(data->sensor_data, temp); } static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip, @@ -120,10 +190,10 @@ static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip, long dev_trend; int r; - if (!data->get_trend) + if (!data->ops->get_trend) return -EINVAL; - r = data->get_trend(data->sensor_data, &dev_trend); + r = data->ops->get_trend(data->sensor_data, &dev_trend); if (r) return r; @@ -324,8 +394,7 @@ static struct thermal_zone_device_ops of_thermal_ops = { static struct thermal_zone_device * thermal_zone_of_add_sensor(struct device_node *zone, struct device_node *sensor, void *data, - int (*get_temp)(void *, long *), - int (*get_trend)(void *, long *)) + const struct thermal_zone_of_device_ops *ops) { struct thermal_zone_device *tzd; struct __thermal_zone *tz; @@ -336,13 +405,16 @@ thermal_zone_of_add_sensor(struct device_node *zone, tz = tzd->devdata; + if (!ops) + return ERR_PTR(-EINVAL); + mutex_lock(&tzd->lock); - tz->get_temp = get_temp; - tz->get_trend = get_trend; + tz->ops = ops; tz->sensor_data = data; tzd->ops->get_temp = of_thermal_get_temp; tzd->ops->get_trend = of_thermal_get_trend; + tzd->ops->set_emul_temp = of_thermal_set_emul_temp; mutex_unlock(&tzd->lock); return tzd; @@ -356,8 +428,7 @@ thermal_zone_of_add_sensor(struct device_node *zone, * than one sensors * @data: a private pointer (owned by the caller) that will be passed * back, when a temperature reading is needed. - * @get_temp: a pointer to a function that reads the sensor temperature. - * @get_trend: a pointer to a function that reads the sensor temperature trend. + * @ops: struct thermal_zone_of_device_ops *. Must contain at least .get_temp. * * This function will search the list of thermal zones described in device * tree and look for the zone that refer to the sensor device pointed by @@ -382,9 +453,8 @@ thermal_zone_of_add_sensor(struct device_node *zone, * check the return value with help of IS_ERR() helper. */ struct thermal_zone_device * -thermal_zone_of_sensor_register(struct device *dev, int sensor_id, - void *data, int (*get_temp)(void *, long *), - int (*get_trend)(void *, long *)) +thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data, + const struct thermal_zone_of_device_ops *ops) { struct device_node *np, *child, *sensor_np; struct thermal_zone_device *tzd = ERR_PTR(-ENODEV); @@ -426,9 +496,7 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id, if (sensor_specs.np == sensor_np && id == sensor_id) { tzd = thermal_zone_of_add_sensor(child, sensor_np, - data, - get_temp, - get_trend); + data, ops); of_node_put(sensor_specs.np); of_node_put(child); goto exit; @@ -475,9 +543,9 @@ void thermal_zone_of_sensor_unregister(struct device *dev, mutex_lock(&tzd->lock); tzd->ops->get_temp = NULL; tzd->ops->get_trend = NULL; + tzd->ops->set_emul_temp = NULL; - tz->get_temp = NULL; - tz->get_trend = NULL; + tz->ops = NULL; tz->sensor_data = NULL; mutex_unlock(&tzd->lock); } @@ -501,7 +569,7 @@ EXPORT_SYMBOL_GPL(thermal_zone_of_sensor_unregister); */ static int thermal_of_populate_bind_params(struct device_node *np, struct __thermal_bind_params *__tbp, - struct __thermal_trip *trips, + struct thermal_trip *trips, int ntrips) { struct of_phandle_args cooling_spec; @@ -604,7 +672,7 @@ static int thermal_of_get_trip_type(struct device_node *np, * Return: 0 on success, proper error code otherwise */ static int thermal_of_populate_trip(struct device_node *np, - struct __thermal_trip *trip) + struct thermal_trip *trip) { int prop; int ret; diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c index 8803e693fe68..2580a4872f90 100644 --- a/drivers/thermal/rcar_thermal.c +++ b/drivers/thermal/rcar_thermal.c @@ -63,7 +63,7 @@ struct rcar_thermal_priv { struct mutex lock; struct list_head list; int id; - int ctemp; + u32 ctemp; }; #define rcar_thermal_for_each_priv(pos, common) \ @@ -145,7 +145,7 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv) { struct device *dev = rcar_priv_to_dev(priv); int i; - int ctemp, old, new; + u32 ctemp, old, new; int ret = -EINVAL; mutex_lock(&priv->lock); @@ -372,6 +372,7 @@ static int rcar_thermal_probe(struct platform_device *pdev) int i; int ret = -ENODEV; int idle = IDLE_INTERVAL; + u32 enr_bits = 0; common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL); if (!common) @@ -390,7 +391,7 @@ static int rcar_thermal_probe(struct platform_device *pdev) /* * platform has IRQ support. - * Then, drier use common register + * Then, driver uses common registers */ ret = devm_request_irq(dev, irq->start, rcar_thermal_irq, 0, @@ -408,9 +409,6 @@ static int rcar_thermal_probe(struct platform_device *pdev) if (IS_ERR(common->base)) return PTR_ERR(common->base); - /* enable temperature comparation */ - rcar_thermal_common_write(common, ENR, 0x00030303); - idle = 0; /* polling delay is not needed */ } @@ -452,8 +450,15 @@ static int rcar_thermal_probe(struct platform_device *pdev) rcar_thermal_irq_enable(priv); list_move_tail(&priv->list, &common->head); + + /* update ENR bits */ + enr_bits |= 3 << (i * 8); } + /* enable temperature comparation */ + if (irq) + rcar_thermal_common_write(common, ENR, enr_bits); + platform_set_drvdata(pdev, common); dev_info(dev, "%d sensor probed\n", i); diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c new file mode 100644 index 000000000000..9c6ce548e363 --- /dev/null +++ b/drivers/thermal/rockchip_thermal.c @@ -0,0 +1,692 @@ +/* + * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/platform_device.h> +#include <linux/reset.h> +#include <linux/thermal.h> + +/** + * If the temperature over a period of time High, + * the resulting TSHUT gave CRU module,let it reset the entire chip, + * or via GPIO give PMIC. + */ +enum tshut_mode { + TSHUT_MODE_CRU = 0, + TSHUT_MODE_GPIO, +}; + +/** + * the system Temperature Sensors tshut(tshut) polarity + * the bit 8 is tshut polarity. + * 0: low active, 1: high active + */ +enum tshut_polarity { + TSHUT_LOW_ACTIVE = 0, + TSHUT_HIGH_ACTIVE, +}; + +/** + * The system has three Temperature Sensors. channel 0 is reserved, + * channel 1 is for CPU, and channel 2 is for GPU. + */ +enum sensor_id { + SENSOR_CPU = 1, + SENSOR_GPU, +}; + +struct rockchip_tsadc_chip { + /* The hardware-controlled tshut property */ + long tshut_temp; + enum tshut_mode tshut_mode; + enum tshut_polarity tshut_polarity; + + /* Chip-wide methods */ + void (*initialize)(void __iomem *reg, enum tshut_polarity p); + void (*irq_ack)(void __iomem *reg); + void (*control)(void __iomem *reg, bool on); + + /* Per-sensor methods */ + int (*get_temp)(int chn, void __iomem *reg, long *temp); + void (*set_tshut_temp)(int chn, void __iomem *reg, long temp); + void (*set_tshut_mode)(int chn, void __iomem *reg, enum tshut_mode m); +}; + +struct rockchip_thermal_sensor { + struct rockchip_thermal_data *thermal; + struct thermal_zone_device *tzd; + enum sensor_id id; +}; + +#define NUM_SENSORS 2 /* Ignore unused sensor 0 */ + +struct rockchip_thermal_data { + const struct rockchip_tsadc_chip *chip; + struct platform_device *pdev; + struct reset_control *reset; + + struct rockchip_thermal_sensor sensors[NUM_SENSORS]; + + struct clk *clk; + struct clk *pclk; + + void __iomem *regs; + + long tshut_temp; + enum tshut_mode tshut_mode; + enum tshut_polarity tshut_polarity; +}; + +/* TSADC V2 Sensor info define: */ +#define TSADCV2_AUTO_CON 0x04 +#define TSADCV2_INT_EN 0x08 +#define TSADCV2_INT_PD 0x0c +#define TSADCV2_DATA(chn) (0x20 + (chn) * 0x04) +#define TSADCV2_COMP_SHUT(chn) (0x40 + (chn) * 0x04) +#define TSADCV2_HIGHT_INT_DEBOUNCE 0x60 +#define TSADCV2_HIGHT_TSHUT_DEBOUNCE 0x64 +#define TSADCV2_AUTO_PERIOD 0x68 +#define TSADCV2_AUTO_PERIOD_HT 0x6c + +#define TSADCV2_AUTO_EN BIT(0) +#define TSADCV2_AUTO_DISABLE ~BIT(0) +#define TSADCV2_AUTO_SRC_EN(chn) BIT(4 + (chn)) +#define TSADCV2_AUTO_TSHUT_POLARITY_HIGH BIT(8) +#define TSADCV2_AUTO_TSHUT_POLARITY_LOW ~BIT(8) + +#define TSADCV2_INT_SRC_EN(chn) BIT(chn) +#define TSADCV2_SHUT_2GPIO_SRC_EN(chn) BIT(4 + (chn)) +#define TSADCV2_SHUT_2CRU_SRC_EN(chn) BIT(8 + (chn)) + +#define TSADCV2_INT_PD_CLEAR ~BIT(8) + +#define TSADCV2_DATA_MASK 0xfff +#define TSADCV2_HIGHT_INT_DEBOUNCE_COUNT 4 +#define TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT 4 +#define TSADCV2_AUTO_PERIOD_TIME 250 /* msec */ +#define TSADCV2_AUTO_PERIOD_HT_TIME 50 /* msec */ + +struct tsadc_table { + unsigned long code; + long temp; +}; + +static const struct tsadc_table v2_code_table[] = { + {TSADCV2_DATA_MASK, -40000}, + {3800, -40000}, + {3792, -35000}, + {3783, -30000}, + {3774, -25000}, + {3765, -20000}, + {3756, -15000}, + {3747, -10000}, + {3737, -5000}, + {3728, 0}, + {3718, 5000}, + {3708, 10000}, + {3698, 15000}, + {3688, 20000}, + {3678, 25000}, + {3667, 30000}, + {3656, 35000}, + {3645, 40000}, + {3634, 45000}, + {3623, 50000}, + {3611, 55000}, + {3600, 60000}, + {3588, 65000}, + {3575, 70000}, + {3563, 75000}, + {3550, 80000}, + {3537, 85000}, + {3524, 90000}, + {3510, 95000}, + {3496, 100000}, + {3482, 105000}, + {3467, 110000}, + {3452, 115000}, + {3437, 120000}, + {3421, 125000}, + {0, 125000}, +}; + +static u32 rk_tsadcv2_temp_to_code(long temp) +{ + int high, low, mid; + + low = 0; + high = ARRAY_SIZE(v2_code_table) - 1; + mid = (high + low) / 2; + + if (temp < v2_code_table[low].temp || temp > v2_code_table[high].temp) + return 0; + + while (low <= high) { + if (temp == v2_code_table[mid].temp) + return v2_code_table[mid].code; + else if (temp < v2_code_table[mid].temp) + high = mid - 1; + else + low = mid + 1; + mid = (low + high) / 2; + } + + return 0; +} + +static long rk_tsadcv2_code_to_temp(u32 code) +{ + int high, low, mid; + + low = 0; + high = ARRAY_SIZE(v2_code_table) - 1; + mid = (high + low) / 2; + + if (code > v2_code_table[low].code || code < v2_code_table[high].code) + return 125000; /* No code available, return max temperature */ + + while (low <= high) { + if (code >= v2_code_table[mid].code && code < + v2_code_table[mid - 1].code) + return v2_code_table[mid].temp; + else if (code < v2_code_table[mid].code) + low = mid + 1; + else + high = mid - 1; + mid = (low + high) / 2; + } + + return 125000; +} + +/** + * rk_tsadcv2_initialize - initialize TASDC Controller + * (1) Set TSADCV2_AUTO_PERIOD, configure the interleave between + * every two accessing of TSADC in normal operation. + * (2) Set TSADCV2_AUTO_PERIOD_HT, configure the interleave between + * every two accessing of TSADC after the temperature is higher + * than COM_SHUT or COM_INT. + * (3) Set TSADCV2_HIGH_INT_DEBOUNCE and TSADC_HIGHT_TSHUT_DEBOUNCE, + * if the temperature is higher than COMP_INT or COMP_SHUT for + * "debounce" times, TSADC controller will generate interrupt or TSHUT. + */ +static void rk_tsadcv2_initialize(void __iomem *regs, + enum tshut_polarity tshut_polarity) +{ + if (tshut_polarity == TSHUT_HIGH_ACTIVE) + writel_relaxed(0 | (TSADCV2_AUTO_TSHUT_POLARITY_HIGH), + regs + TSADCV2_AUTO_CON); + else + writel_relaxed(0 | (TSADCV2_AUTO_TSHUT_POLARITY_LOW), + regs + TSADCV2_AUTO_CON); + + writel_relaxed(TSADCV2_AUTO_PERIOD_TIME, regs + TSADCV2_AUTO_PERIOD); + writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT, + regs + TSADCV2_HIGHT_INT_DEBOUNCE); + writel_relaxed(TSADCV2_AUTO_PERIOD_HT_TIME, + regs + TSADCV2_AUTO_PERIOD_HT); + writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT, + regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE); +} + +static void rk_tsadcv2_irq_ack(void __iomem *regs) +{ + u32 val; + + val = readl_relaxed(regs + TSADCV2_INT_PD); + writel_relaxed(val & TSADCV2_INT_PD_CLEAR, regs + TSADCV2_INT_PD); +} + +static void rk_tsadcv2_control(void __iomem *regs, bool enable) +{ + u32 val; + + val = readl_relaxed(regs + TSADCV2_AUTO_CON); + if (enable) + val |= TSADCV2_AUTO_EN; + else + val &= ~TSADCV2_AUTO_EN; + + writel_relaxed(val, regs + TSADCV2_AUTO_CON); +} + +static int rk_tsadcv2_get_temp(int chn, void __iomem *regs, long *temp) +{ + u32 val; + + /* the A/D value of the channel last conversion need some time */ + val = readl_relaxed(regs + TSADCV2_DATA(chn)); + if (val == 0) + return -EAGAIN; + + *temp = rk_tsadcv2_code_to_temp(val); + + return 0; +} + +static void rk_tsadcv2_tshut_temp(int chn, void __iomem *regs, long temp) +{ + u32 tshut_value, val; + + tshut_value = rk_tsadcv2_temp_to_code(temp); + writel_relaxed(tshut_value, regs + TSADCV2_COMP_SHUT(chn)); + + /* TSHUT will be valid */ + val = readl_relaxed(regs + TSADCV2_AUTO_CON); + writel_relaxed(val | TSADCV2_AUTO_SRC_EN(chn), regs + TSADCV2_AUTO_CON); +} + +static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs, + enum tshut_mode mode) +{ + u32 val; + + val = readl_relaxed(regs + TSADCV2_INT_EN); + if (mode == TSHUT_MODE_GPIO) { + val &= ~TSADCV2_SHUT_2CRU_SRC_EN(chn); + val |= TSADCV2_SHUT_2GPIO_SRC_EN(chn); + } else { + val &= ~TSADCV2_SHUT_2GPIO_SRC_EN(chn); + val |= TSADCV2_SHUT_2CRU_SRC_EN(chn); + } + + writel_relaxed(val, regs + TSADCV2_INT_EN); +} + +static const struct rockchip_tsadc_chip rk3288_tsadc_data = { + .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ + .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */ + .tshut_temp = 95000, + + .initialize = rk_tsadcv2_initialize, + .irq_ack = rk_tsadcv2_irq_ack, + .control = rk_tsadcv2_control, + .get_temp = rk_tsadcv2_get_temp, + .set_tshut_temp = rk_tsadcv2_tshut_temp, + .set_tshut_mode = rk_tsadcv2_tshut_mode, +}; + +static const struct of_device_id of_rockchip_thermal_match[] = { + { + .compatible = "rockchip,rk3288-tsadc", + .data = (void *)&rk3288_tsadc_data, + }, + { /* end */ }, +}; +MODULE_DEVICE_TABLE(of, of_rockchip_thermal_match); + +static void +rockchip_thermal_toggle_sensor(struct rockchip_thermal_sensor *sensor, bool on) +{ + struct thermal_zone_device *tzd = sensor->tzd; + + tzd->ops->set_mode(tzd, + on ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED); +} + +static irqreturn_t rockchip_thermal_alarm_irq_thread(int irq, void *dev) +{ + struct rockchip_thermal_data *thermal = dev; + int i; + + dev_dbg(&thermal->pdev->dev, "thermal alarm\n"); + + thermal->chip->irq_ack(thermal->regs); + + for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) + thermal_zone_device_update(thermal->sensors[i].tzd); + + return IRQ_HANDLED; +} + +static int rockchip_thermal_get_temp(void *_sensor, long *out_temp) +{ + struct rockchip_thermal_sensor *sensor = _sensor; + struct rockchip_thermal_data *thermal = sensor->thermal; + const struct rockchip_tsadc_chip *tsadc = sensor->thermal->chip; + int retval; + + retval = tsadc->get_temp(sensor->id, thermal->regs, out_temp); + dev_dbg(&thermal->pdev->dev, "sensor %d - temp: %ld, retval: %d\n", + sensor->id, *out_temp, retval); + + return retval; +} + +static const struct thermal_zone_of_device_ops rockchip_of_thermal_ops = { + .get_temp = rockchip_thermal_get_temp, +}; + +static int rockchip_configure_from_dt(struct device *dev, + struct device_node *np, + struct rockchip_thermal_data *thermal) +{ + u32 shut_temp, tshut_mode, tshut_polarity; + + if (of_property_read_u32(np, "rockchip,hw-tshut-temp", &shut_temp)) { + dev_warn(dev, + "Missing tshut temp property, using default %ld\n", + thermal->chip->tshut_temp); + thermal->tshut_temp = thermal->chip->tshut_temp; + } else { + thermal->tshut_temp = shut_temp; + } + + if (thermal->tshut_temp > INT_MAX) { + dev_err(dev, "Invalid tshut temperature specified: %ld\n", + thermal->tshut_temp); + return -ERANGE; + } + + if (of_property_read_u32(np, "rockchip,hw-tshut-mode", &tshut_mode)) { + dev_warn(dev, + "Missing tshut mode property, using default (%s)\n", + thermal->chip->tshut_mode == TSHUT_MODE_GPIO ? + "gpio" : "cru"); + thermal->tshut_mode = thermal->chip->tshut_mode; + } else { + thermal->tshut_mode = tshut_mode; + } + + if (thermal->tshut_mode > 1) { + dev_err(dev, "Invalid tshut mode specified: %d\n", + thermal->tshut_mode); + return -EINVAL; + } + + if (of_property_read_u32(np, "rockchip,hw-tshut-polarity", + &tshut_polarity)) { + dev_warn(dev, + "Missing tshut-polarity property, using default (%s)\n", + thermal->chip->tshut_polarity == TSHUT_LOW_ACTIVE ? + "low" : "high"); + thermal->tshut_polarity = thermal->chip->tshut_polarity; + } else { + thermal->tshut_polarity = tshut_polarity; + } + + if (thermal->tshut_polarity > 1) { + dev_err(dev, "Invalid tshut-polarity specified: %d\n", + thermal->tshut_polarity); + return -EINVAL; + } + + return 0; +} + +static int +rockchip_thermal_register_sensor(struct platform_device *pdev, + struct rockchip_thermal_data *thermal, + struct rockchip_thermal_sensor *sensor, + enum sensor_id id) +{ + const struct rockchip_tsadc_chip *tsadc = thermal->chip; + int error; + + tsadc->set_tshut_mode(id, thermal->regs, thermal->tshut_mode); + tsadc->set_tshut_temp(id, thermal->regs, thermal->tshut_temp); + + sensor->thermal = thermal; + sensor->id = id; + sensor->tzd = thermal_zone_of_sensor_register(&pdev->dev, id, sensor, + &rockchip_of_thermal_ops); + if (IS_ERR(sensor->tzd)) { + error = PTR_ERR(sensor->tzd); + dev_err(&pdev->dev, "failed to register sensor %d: %d\n", + id, error); + return error; + } + + return 0; +} + +/* + * Reset TSADC Controller, reset all tsadc registers. + */ +static void rockchip_thermal_reset_controller(struct reset_control *reset) +{ + reset_control_assert(reset); + usleep_range(10, 20); + reset_control_deassert(reset); +} + +static int rockchip_thermal_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct rockchip_thermal_data *thermal; + const struct of_device_id *match; + struct resource *res; + int irq; + int i; + int error; + + match = of_match_node(of_rockchip_thermal_match, np); + if (!match) + return -ENXIO; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "no irq resource?\n"); + return -EINVAL; + } + + thermal = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_thermal_data), + GFP_KERNEL); + if (!thermal) + return -ENOMEM; + + thermal->pdev = pdev; + + thermal->chip = (const struct rockchip_tsadc_chip *)match->data; + if (!thermal->chip) + return -EINVAL; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + thermal->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(thermal->regs)) + return PTR_ERR(thermal->regs); + + thermal->reset = devm_reset_control_get(&pdev->dev, "tsadc-apb"); + if (IS_ERR(thermal->reset)) { + error = PTR_ERR(thermal->reset); + dev_err(&pdev->dev, "failed to get tsadc reset: %d\n", error); + return error; + } + + thermal->clk = devm_clk_get(&pdev->dev, "tsadc"); + if (IS_ERR(thermal->clk)) { + error = PTR_ERR(thermal->clk); + dev_err(&pdev->dev, "failed to get tsadc clock: %d\n", error); + return error; + } + + thermal->pclk = devm_clk_get(&pdev->dev, "apb_pclk"); + if (IS_ERR(thermal->pclk)) { + error = PTR_ERR(thermal->clk); + dev_err(&pdev->dev, "failed to get apb_pclk clock: %d\n", + error); + return error; + } + + error = clk_prepare_enable(thermal->clk); + if (error) { + dev_err(&pdev->dev, "failed to enable converter clock: %d\n", + error); + return error; + } + + error = clk_prepare_enable(thermal->pclk); + if (error) { + dev_err(&pdev->dev, "failed to enable pclk: %d\n", error); + goto err_disable_clk; + } + + rockchip_thermal_reset_controller(thermal->reset); + + error = rockchip_configure_from_dt(&pdev->dev, np, thermal); + if (error) { + dev_err(&pdev->dev, "failed to parse device tree data: %d\n", + error); + goto err_disable_pclk; + } + + thermal->chip->initialize(thermal->regs, thermal->tshut_polarity); + + error = rockchip_thermal_register_sensor(pdev, thermal, + &thermal->sensors[0], + SENSOR_CPU); + if (error) { + dev_err(&pdev->dev, + "failed to register CPU thermal sensor: %d\n", error); + goto err_disable_pclk; + } + + error = rockchip_thermal_register_sensor(pdev, thermal, + &thermal->sensors[1], + SENSOR_GPU); + if (error) { + dev_err(&pdev->dev, + "failed to register GPU thermal sensor: %d\n", error); + goto err_unregister_cpu_sensor; + } + + error = devm_request_threaded_irq(&pdev->dev, irq, NULL, + &rockchip_thermal_alarm_irq_thread, + IRQF_ONESHOT, + "rockchip_thermal", thermal); + if (error) { + dev_err(&pdev->dev, + "failed to request tsadc irq: %d\n", error); + goto err_unregister_gpu_sensor; + } + + thermal->chip->control(thermal->regs, true); + + for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) + rockchip_thermal_toggle_sensor(&thermal->sensors[i], true); + + platform_set_drvdata(pdev, thermal); + + return 0; + +err_unregister_gpu_sensor: + thermal_zone_of_sensor_unregister(&pdev->dev, thermal->sensors[1].tzd); +err_unregister_cpu_sensor: + thermal_zone_of_sensor_unregister(&pdev->dev, thermal->sensors[0].tzd); +err_disable_pclk: + clk_disable_unprepare(thermal->pclk); +err_disable_clk: + clk_disable_unprepare(thermal->clk); + + return error; +} + +static int rockchip_thermal_remove(struct platform_device *pdev) +{ + struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) { + struct rockchip_thermal_sensor *sensor = &thermal->sensors[i]; + + rockchip_thermal_toggle_sensor(sensor, false); + thermal_zone_of_sensor_unregister(&pdev->dev, sensor->tzd); + } + + thermal->chip->control(thermal->regs, false); + + clk_disable_unprepare(thermal->pclk); + clk_disable_unprepare(thermal->clk); + + return 0; +} + +static int __maybe_unused rockchip_thermal_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) + rockchip_thermal_toggle_sensor(&thermal->sensors[i], false); + + thermal->chip->control(thermal->regs, false); + + clk_disable(thermal->pclk); + clk_disable(thermal->clk); + + return 0; +} + +static int __maybe_unused rockchip_thermal_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev); + int i; + int error; + + error = clk_enable(thermal->clk); + if (error) + return error; + + error = clk_enable(thermal->pclk); + if (error) + return error; + + rockchip_thermal_reset_controller(thermal->reset); + + thermal->chip->initialize(thermal->regs, thermal->tshut_polarity); + + for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) { + enum sensor_id id = thermal->sensors[i].id; + + thermal->chip->set_tshut_mode(id, thermal->regs, + thermal->tshut_mode); + thermal->chip->set_tshut_temp(id, thermal->regs, + thermal->tshut_temp); + } + + thermal->chip->control(thermal->regs, true); + + for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) + rockchip_thermal_toggle_sensor(&thermal->sensors[i], true); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(rockchip_thermal_pm_ops, + rockchip_thermal_suspend, rockchip_thermal_resume); + +static struct platform_driver rockchip_thermal_driver = { + .driver = { + .name = "rockchip-thermal", + .pm = &rockchip_thermal_pm_ops, + .of_match_table = of_rockchip_thermal_match, + }, + .probe = rockchip_thermal_probe, + .remove = rockchip_thermal_remove, +}; + +module_platform_driver(rockchip_thermal_driver); + +MODULE_DESCRIPTION("ROCKCHIP THERMAL Driver"); +MODULE_AUTHOR("Rockchip, Inc."); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:rockchip-thermal"); diff --git a/drivers/thermal/samsung/Kconfig b/drivers/thermal/samsung/Kconfig index f760389a204c..c43306ecc0ab 100644 --- a/drivers/thermal/samsung/Kconfig +++ b/drivers/thermal/samsung/Kconfig @@ -1,6 +1,6 @@ config EXYNOS_THERMAL tristate "Exynos thermal management unit driver" - depends on ARCH_HAS_BANDGAP && OF + depends on OF help If you say yes here you get support for the TMU (Thermal Management Unit) driver for SAMSUNG EXYNOS series of SoCs. This driver initialises diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c index b6be572704a4..6dc3815cc73f 100644 --- a/drivers/thermal/samsung/exynos_thermal_common.c +++ b/drivers/thermal/samsung/exynos_thermal_common.c @@ -347,7 +347,6 @@ void exynos_report_trigger(struct thermal_sensor_conf *conf) int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf) { int ret; - struct cpumask mask_val; struct exynos_thermal_zone *th_zone; if (!sensor_conf || !sensor_conf->read_temperature) { @@ -367,13 +366,14 @@ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf) * sensor */ if (sensor_conf->cooling_data.freq_clip_count > 0) { - cpumask_set_cpu(0, &mask_val); th_zone->cool_dev[th_zone->cool_dev_size] = - cpufreq_cooling_register(&mask_val); + cpufreq_cooling_register(cpu_present_mask); if (IS_ERR(th_zone->cool_dev[th_zone->cool_dev_size])) { - dev_err(sensor_conf->dev, - "Failed to register cpufreq cooling device\n"); - ret = -EINVAL; + ret = PTR_ERR(th_zone->cool_dev[th_zone->cool_dev_size]); + if (ret != -EPROBE_DEFER) + dev_err(sensor_conf->dev, + "Failed to register cpufreq cooling device: %d\n", + ret); goto err_unregister; } th_zone->cool_dev_size++; diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h index 158f5aa8dc5d..cd4471925cdd 100644 --- a/drivers/thermal/samsung/exynos_thermal_common.h +++ b/drivers/thermal/samsung/exynos_thermal_common.h @@ -27,7 +27,6 @@ #define SENSOR_NAME_LEN 16 #define MAX_TRIP_COUNT 8 #define MAX_COOLING_DEVICE 4 -#define MAX_TRIMINFO_CTRL_REG 2 #define ACTIVE_INTERVAL 500 #define IDLE_INTERVAL 10000 diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 1e7d0736e862..d2f1e62a4232 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -33,7 +33,87 @@ #include "exynos_thermal_common.h" #include "exynos_tmu.h" -#include "exynos_tmu_data.h" + +/* Exynos generic registers */ +#define EXYNOS_TMU_REG_TRIMINFO 0x0 +#define EXYNOS_TMU_REG_CONTROL 0x20 +#define EXYNOS_TMU_REG_STATUS 0x28 +#define EXYNOS_TMU_REG_CURRENT_TEMP 0x40 +#define EXYNOS_TMU_REG_INTEN 0x70 +#define EXYNOS_TMU_REG_INTSTAT 0x74 +#define EXYNOS_TMU_REG_INTCLEAR 0x78 + +#define EXYNOS_TMU_TEMP_MASK 0xff +#define EXYNOS_TMU_REF_VOLTAGE_SHIFT 24 +#define EXYNOS_TMU_REF_VOLTAGE_MASK 0x1f +#define EXYNOS_TMU_BUF_SLOPE_SEL_MASK 0xf +#define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT 8 +#define EXYNOS_TMU_CORE_EN_SHIFT 0 + +/* Exynos3250 specific registers */ +#define EXYNOS_TMU_TRIMINFO_CON1 0x10 + +/* Exynos4210 specific registers */ +#define EXYNOS4210_TMU_REG_THRESHOLD_TEMP 0x44 +#define EXYNOS4210_TMU_REG_TRIG_LEVEL0 0x50 + +/* Exynos5250, Exynos4412, Exynos3250 specific registers */ +#define EXYNOS_TMU_TRIMINFO_CON2 0x14 +#define EXYNOS_THD_TEMP_RISE 0x50 +#define EXYNOS_THD_TEMP_FALL 0x54 +#define EXYNOS_EMUL_CON 0x80 + +#define EXYNOS_TRIMINFO_RELOAD_ENABLE 1 +#define EXYNOS_TRIMINFO_25_SHIFT 0 +#define EXYNOS_TRIMINFO_85_SHIFT 8 +#define EXYNOS_TMU_TRIP_MODE_SHIFT 13 +#define EXYNOS_TMU_TRIP_MODE_MASK 0x7 +#define EXYNOS_TMU_THERM_TRIP_EN_SHIFT 12 + +#define EXYNOS_TMU_INTEN_RISE0_SHIFT 0 +#define EXYNOS_TMU_INTEN_RISE1_SHIFT 4 +#define EXYNOS_TMU_INTEN_RISE2_SHIFT 8 +#define EXYNOS_TMU_INTEN_RISE3_SHIFT 12 +#define EXYNOS_TMU_INTEN_FALL0_SHIFT 16 + +#define EXYNOS_EMUL_TIME 0x57F0 +#define EXYNOS_EMUL_TIME_MASK 0xffff +#define EXYNOS_EMUL_TIME_SHIFT 16 +#define EXYNOS_EMUL_DATA_SHIFT 8 +#define EXYNOS_EMUL_DATA_MASK 0xFF +#define EXYNOS_EMUL_ENABLE 0x1 + +/* Exynos5260 specific */ +#define EXYNOS5260_TMU_REG_INTEN 0xC0 +#define EXYNOS5260_TMU_REG_INTSTAT 0xC4 +#define EXYNOS5260_TMU_REG_INTCLEAR 0xC8 +#define EXYNOS5260_EMUL_CON 0x100 + +/* Exynos4412 specific */ +#define EXYNOS4412_MUX_ADDR_VALUE 6 +#define EXYNOS4412_MUX_ADDR_SHIFT 20 + +/*exynos5440 specific registers*/ +#define EXYNOS5440_TMU_S0_7_TRIM 0x000 +#define EXYNOS5440_TMU_S0_7_CTRL 0x020 +#define EXYNOS5440_TMU_S0_7_DEBUG 0x040 +#define EXYNOS5440_TMU_S0_7_TEMP 0x0f0 +#define EXYNOS5440_TMU_S0_7_TH0 0x110 +#define EXYNOS5440_TMU_S0_7_TH1 0x130 +#define EXYNOS5440_TMU_S0_7_TH2 0x150 +#define EXYNOS5440_TMU_S0_7_IRQEN 0x210 +#define EXYNOS5440_TMU_S0_7_IRQ 0x230 +/* exynos5440 common registers */ +#define EXYNOS5440_TMU_IRQ_STATUS 0x000 +#define EXYNOS5440_TMU_PMIN 0x004 + +#define EXYNOS5440_TMU_INTEN_RISE0_SHIFT 0 +#define EXYNOS5440_TMU_INTEN_RISE1_SHIFT 1 +#define EXYNOS5440_TMU_INTEN_RISE2_SHIFT 2 +#define EXYNOS5440_TMU_INTEN_RISE3_SHIFT 3 +#define EXYNOS5440_TMU_INTEN_FALL0_SHIFT 4 +#define EXYNOS5440_TMU_TH_RISE4_SHIFT 24 +#define EXYNOS5440_EFUSE_SWAP_OFFSET 8 /** * struct exynos_tmu_data : A structure to hold the private data of the TMU @@ -52,6 +132,11 @@ * @temp_error2: fused value of the second point trim. * @regulator: pointer to the TMU regulator structure. * @reg_conf: pointer to structure to register with core thermal. + * @tmu_initialize: SoC specific TMU initialization method + * @tmu_control: SoC specific TMU control method + * @tmu_read: SoC specific TMU temperature read method + * @tmu_set_emulation: SoC specific TMU emulation setting method + * @tmu_clear_irqs: SoC specific TMU interrupts clearing method */ struct exynos_tmu_data { int id; @@ -66,6 +151,12 @@ struct exynos_tmu_data { u8 temp_error1, temp_error2; struct regulator *regulator; struct thermal_sensor_conf *reg_conf; + int (*tmu_initialize)(struct platform_device *pdev); + void (*tmu_control)(struct platform_device *pdev, bool on); + int (*tmu_read)(struct exynos_tmu_data *data); + void (*tmu_set_emulation)(struct exynos_tmu_data *data, + unsigned long temp); + void (*tmu_clear_irqs)(struct exynos_tmu_data *data); }; /* @@ -122,83 +213,10 @@ static int code_to_temp(struct exynos_tmu_data *data, u8 temp_code) return temp; } -static void exynos_tmu_clear_irqs(struct exynos_tmu_data *data) -{ - const struct exynos_tmu_registers *reg = data->pdata->registers; - unsigned int val_irq; - - val_irq = readl(data->base + reg->tmu_intstat); - /* - * Clear the interrupts. Please note that the documentation for - * Exynos3250, Exynos4412, Exynos5250 and Exynos5260 incorrectly - * states that INTCLEAR register has a different placing of bits - * responsible for FALL IRQs than INTSTAT register. Exynos5420 - * and Exynos5440 documentation is correct (Exynos4210 doesn't - * support FALL IRQs at all). - */ - writel(val_irq, data->base + reg->tmu_intclear); -} - -static int exynos_tmu_initialize(struct platform_device *pdev) +static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info) { - struct exynos_tmu_data *data = platform_get_drvdata(pdev); struct exynos_tmu_platform_data *pdata = data->pdata; - const struct exynos_tmu_registers *reg = pdata->registers; - unsigned int status, trim_info = 0, con, ctrl; - unsigned int rising_threshold = 0, falling_threshold = 0; - int ret = 0, threshold_code, i; - - mutex_lock(&data->lock); - clk_enable(data->clk); - if (!IS_ERR(data->clk_sec)) - clk_enable(data->clk_sec); - if (TMU_SUPPORTS(pdata, READY_STATUS)) { - status = readb(data->base + reg->tmu_status); - if (!status) { - ret = -EBUSY; - goto out; - } - } - - if (TMU_SUPPORTS(pdata, TRIM_RELOAD)) { - for (i = 0; i < reg->triminfo_ctrl_count; i++) { - if (pdata->triminfo_reload[i]) { - ctrl = readl(data->base + - reg->triminfo_ctrl[i]); - ctrl |= pdata->triminfo_reload[i]; - writel(ctrl, data->base + - reg->triminfo_ctrl[i]); - } - } - } - - /* Save trimming info in order to perform calibration */ - if (data->soc == SOC_ARCH_EXYNOS5440) { - /* - * For exynos5440 soc triminfo value is swapped between TMU0 and - * TMU2, so the below logic is needed. - */ - switch (data->id) { - case 0: - trim_info = readl(data->base + - EXYNOS5440_EFUSE_SWAP_OFFSET + reg->triminfo_data); - break; - case 1: - trim_info = readl(data->base + reg->triminfo_data); - break; - case 2: - trim_info = readl(data->base - - EXYNOS5440_EFUSE_SWAP_OFFSET + reg->triminfo_data); - } - } else { - /* On exynos5420 the triminfo register is in the shared space */ - if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) - trim_info = readl(data->base_second + - reg->triminfo_data); - else - trim_info = readl(data->base + reg->triminfo_data); - } data->temp_error1 = trim_info & EXYNOS_TMU_TEMP_MASK; data->temp_error2 = ((trim_info >> EXYNOS_TRIMINFO_85_SHIFT) & EXYNOS_TMU_TEMP_MASK); @@ -212,69 +230,37 @@ static int exynos_tmu_initialize(struct platform_device *pdev) data->temp_error2 = (pdata->efuse_value >> EXYNOS_TRIMINFO_85_SHIFT) & EXYNOS_TMU_TEMP_MASK; +} - rising_threshold = readl(data->base + reg->threshold_th0); +static u32 get_th_reg(struct exynos_tmu_data *data, u32 threshold, bool falling) +{ + struct exynos_tmu_platform_data *pdata = data->pdata; + int i; - if (data->soc == SOC_ARCH_EXYNOS4210) { - /* Write temperature code for threshold */ - threshold_code = temp_to_code(data, pdata->threshold); - writeb(threshold_code, - data->base + reg->threshold_temp); - for (i = 0; i < pdata->non_hw_trigger_levels; i++) - writeb(pdata->trigger_levels[i], data->base + - reg->threshold_th0 + i * sizeof(reg->threshold_th0)); + for (i = 0; i < pdata->non_hw_trigger_levels; i++) { + u8 temp = pdata->trigger_levels[i]; - exynos_tmu_clear_irqs(data); - } else { - /* Write temperature code for rising and falling threshold */ - for (i = 0; i < pdata->non_hw_trigger_levels; i++) { - threshold_code = temp_to_code(data, - pdata->trigger_levels[i]); - rising_threshold &= ~(0xff << 8 * i); - rising_threshold |= threshold_code << 8 * i; - if (pdata->threshold_falling) { - threshold_code = temp_to_code(data, - pdata->trigger_levels[i] - - pdata->threshold_falling); - falling_threshold |= threshold_code << 8 * i; - } - } + if (falling) + temp -= pdata->threshold_falling; + else + threshold &= ~(0xff << 8 * i); - writel(rising_threshold, - data->base + reg->threshold_th0); - writel(falling_threshold, - data->base + reg->threshold_th1); - - exynos_tmu_clear_irqs(data); - - /* if last threshold limit is also present */ - i = pdata->max_trigger_level - 1; - if (pdata->trigger_levels[i] && - (pdata->trigger_type[i] == HW_TRIP)) { - threshold_code = temp_to_code(data, - pdata->trigger_levels[i]); - if (i == EXYNOS_MAX_TRIGGER_PER_REG - 1) { - /* 1-4 level to be assigned in th0 reg */ - rising_threshold &= ~(0xff << 8 * i); - rising_threshold |= threshold_code << 8 * i; - writel(rising_threshold, - data->base + reg->threshold_th0); - } else if (i == EXYNOS_MAX_TRIGGER_PER_REG) { - /* 5th level to be assigned in th2 reg */ - rising_threshold = - threshold_code << reg->threshold_th3_l0_shift; - writel(rising_threshold, - data->base + reg->threshold_th2); - } - con = readl(data->base + reg->tmu_ctrl); - con |= (1 << reg->therm_trip_en_shift); - writel(con, data->base + reg->tmu_ctrl); - } + threshold |= temp_to_code(data, temp) << 8 * i; } - /*Clear the PMIN in the common TMU register*/ - if (reg->tmu_pmin && !data->id) - writel(0, data->base_second + reg->tmu_pmin); -out: + + return threshold; +} + +static int exynos_tmu_initialize(struct platform_device *pdev) +{ + struct exynos_tmu_data *data = platform_get_drvdata(pdev); + int ret; + + mutex_lock(&data->lock); + clk_enable(data->clk); + if (!IS_ERR(data->clk_sec)) + clk_enable(data->clk_sec); + ret = data->tmu_initialize(pdev); clk_disable(data->clk); mutex_unlock(&data->lock); if (!IS_ERR(data->clk_sec)) @@ -283,20 +269,13 @@ out: return ret; } -static void exynos_tmu_control(struct platform_device *pdev, bool on) +static u32 get_con_reg(struct exynos_tmu_data *data, u32 con) { - struct exynos_tmu_data *data = platform_get_drvdata(pdev); struct exynos_tmu_platform_data *pdata = data->pdata; - const struct exynos_tmu_registers *reg = pdata->registers; - unsigned int con, interrupt_en; - mutex_lock(&data->lock); - clk_enable(data->clk); - - con = readl(data->base + reg->tmu_ctrl); - - if (pdata->test_mux) - con |= (pdata->test_mux << reg->test_mux_addr_shift); + if (data->soc == SOC_ARCH_EXYNOS4412 || + data->soc == SOC_ARCH_EXYNOS3250) + con |= (EXYNOS4412_MUX_ADDR_VALUE << EXYNOS4412_MUX_ADDR_SHIFT); con &= ~(EXYNOS_TMU_REF_VOLTAGE_MASK << EXYNOS_TMU_REF_VOLTAGE_SHIFT); con |= pdata->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT; @@ -305,95 +284,287 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on) con |= (pdata->gain << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT); if (pdata->noise_cancel_mode) { - con &= ~(reg->therm_trip_mode_mask << - reg->therm_trip_mode_shift); - con |= (pdata->noise_cancel_mode << reg->therm_trip_mode_shift); + con &= ~(EXYNOS_TMU_TRIP_MODE_MASK << EXYNOS_TMU_TRIP_MODE_SHIFT); + con |= (pdata->noise_cancel_mode << EXYNOS_TMU_TRIP_MODE_SHIFT); } - if (on) { - con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); - interrupt_en = - pdata->trigger_enable[3] << reg->inten_rise3_shift | - pdata->trigger_enable[2] << reg->inten_rise2_shift | - pdata->trigger_enable[1] << reg->inten_rise1_shift | - pdata->trigger_enable[0] << reg->inten_rise0_shift; - if (TMU_SUPPORTS(pdata, FALLING_TRIP)) - interrupt_en |= - interrupt_en << reg->inten_fall0_shift; - } else { - con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); - interrupt_en = 0; /* Disable all interrupts */ - } - writel(interrupt_en, data->base + reg->tmu_inten); - writel(con, data->base + reg->tmu_ctrl); + return con; +} + +static void exynos_tmu_control(struct platform_device *pdev, bool on) +{ + struct exynos_tmu_data *data = platform_get_drvdata(pdev); + mutex_lock(&data->lock); + clk_enable(data->clk); + data->tmu_control(pdev, on); clk_disable(data->clk); mutex_unlock(&data->lock); } -static int exynos_tmu_read(struct exynos_tmu_data *data) +static int exynos4210_tmu_initialize(struct platform_device *pdev) { + struct exynos_tmu_data *data = platform_get_drvdata(pdev); struct exynos_tmu_platform_data *pdata = data->pdata; - const struct exynos_tmu_registers *reg = pdata->registers; - u8 temp_code; - int temp; + unsigned int status; + int ret = 0, threshold_code, i; - mutex_lock(&data->lock); - clk_enable(data->clk); + status = readb(data->base + EXYNOS_TMU_REG_STATUS); + if (!status) { + ret = -EBUSY; + goto out; + } - temp_code = readb(data->base + reg->tmu_cur_temp); + sanitize_temp_error(data, readl(data->base + EXYNOS_TMU_REG_TRIMINFO)); - if (data->soc == SOC_ARCH_EXYNOS4210) - /* temp_code should range between 75 and 175 */ - if (temp_code < 75 || temp_code > 175) { - temp = -ENODATA; - goto out; + /* Write temperature code for threshold */ + threshold_code = temp_to_code(data, pdata->threshold); + writeb(threshold_code, data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP); + + for (i = 0; i < pdata->non_hw_trigger_levels; i++) + writeb(pdata->trigger_levels[i], data->base + + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + i * 4); + + data->tmu_clear_irqs(data); +out: + return ret; +} + +static int exynos4412_tmu_initialize(struct platform_device *pdev) +{ + struct exynos_tmu_data *data = platform_get_drvdata(pdev); + struct exynos_tmu_platform_data *pdata = data->pdata; + unsigned int status, trim_info, con, ctrl, rising_threshold; + int ret = 0, threshold_code, i; + + status = readb(data->base + EXYNOS_TMU_REG_STATUS); + if (!status) { + ret = -EBUSY; + goto out; + } + + if (data->soc == SOC_ARCH_EXYNOS3250 || + data->soc == SOC_ARCH_EXYNOS4412 || + data->soc == SOC_ARCH_EXYNOS5250) { + if (data->soc == SOC_ARCH_EXYNOS3250) { + ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON1); + ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE; + writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON1); } + ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON2); + ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE; + writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON2); + } - temp = code_to_temp(data, temp_code); + /* On exynos5420 the triminfo register is in the shared space */ + if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) + trim_info = readl(data->base_second + EXYNOS_TMU_REG_TRIMINFO); + else + trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); + + sanitize_temp_error(data, trim_info); + + /* Write temperature code for rising and falling threshold */ + rising_threshold = readl(data->base + EXYNOS_THD_TEMP_RISE); + rising_threshold = get_th_reg(data, rising_threshold, false); + writel(rising_threshold, data->base + EXYNOS_THD_TEMP_RISE); + writel(get_th_reg(data, 0, true), data->base + EXYNOS_THD_TEMP_FALL); + + data->tmu_clear_irqs(data); + + /* if last threshold limit is also present */ + i = pdata->max_trigger_level - 1; + if (pdata->trigger_levels[i] && pdata->trigger_type[i] == HW_TRIP) { + threshold_code = temp_to_code(data, pdata->trigger_levels[i]); + /* 1-4 level to be assigned in th0 reg */ + rising_threshold &= ~(0xff << 8 * i); + rising_threshold |= threshold_code << 8 * i; + writel(rising_threshold, data->base + EXYNOS_THD_TEMP_RISE); + con = readl(data->base + EXYNOS_TMU_REG_CONTROL); + con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT); + writel(con, data->base + EXYNOS_TMU_REG_CONTROL); + } out: - clk_disable(data->clk); - mutex_unlock(&data->lock); + return ret; +} - return temp; +static int exynos5440_tmu_initialize(struct platform_device *pdev) +{ + struct exynos_tmu_data *data = platform_get_drvdata(pdev); + struct exynos_tmu_platform_data *pdata = data->pdata; + unsigned int trim_info = 0, con, rising_threshold; + int ret = 0, threshold_code, i; + + /* + * For exynos5440 soc triminfo value is swapped between TMU0 and + * TMU2, so the below logic is needed. + */ + switch (data->id) { + case 0: + trim_info = readl(data->base + EXYNOS5440_EFUSE_SWAP_OFFSET + + EXYNOS5440_TMU_S0_7_TRIM); + break; + case 1: + trim_info = readl(data->base + EXYNOS5440_TMU_S0_7_TRIM); + break; + case 2: + trim_info = readl(data->base - EXYNOS5440_EFUSE_SWAP_OFFSET + + EXYNOS5440_TMU_S0_7_TRIM); + } + sanitize_temp_error(data, trim_info); + + /* Write temperature code for rising and falling threshold */ + rising_threshold = readl(data->base + EXYNOS5440_TMU_S0_7_TH0); + rising_threshold = get_th_reg(data, rising_threshold, false); + writel(rising_threshold, data->base + EXYNOS5440_TMU_S0_7_TH0); + writel(0, data->base + EXYNOS5440_TMU_S0_7_TH1); + + data->tmu_clear_irqs(data); + + /* if last threshold limit is also present */ + i = pdata->max_trigger_level - 1; + if (pdata->trigger_levels[i] && pdata->trigger_type[i] == HW_TRIP) { + threshold_code = temp_to_code(data, pdata->trigger_levels[i]); + /* 5th level to be assigned in th2 reg */ + rising_threshold = + threshold_code << EXYNOS5440_TMU_TH_RISE4_SHIFT; + writel(rising_threshold, data->base + EXYNOS5440_TMU_S0_7_TH2); + con = readl(data->base + EXYNOS5440_TMU_S0_7_CTRL); + con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT); + writel(con, data->base + EXYNOS5440_TMU_S0_7_CTRL); + } + /* Clear the PMIN in the common TMU register */ + if (!data->id) + writel(0, data->base_second + EXYNOS5440_TMU_PMIN); + return ret; } -#ifdef CONFIG_THERMAL_EMULATION -static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) +static void exynos4210_tmu_control(struct platform_device *pdev, bool on) { - struct exynos_tmu_data *data = drv_data; + struct exynos_tmu_data *data = platform_get_drvdata(pdev); struct exynos_tmu_platform_data *pdata = data->pdata; - const struct exynos_tmu_registers *reg = pdata->registers; - unsigned int val; - int ret = -EINVAL; + unsigned int con, interrupt_en; - if (!TMU_SUPPORTS(pdata, EMULATION)) - goto out; + con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL)); - if (temp && temp < MCELSIUS) - goto out; + if (on) { + con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); + interrupt_en = + pdata->trigger_enable[3] << EXYNOS_TMU_INTEN_RISE3_SHIFT | + pdata->trigger_enable[2] << EXYNOS_TMU_INTEN_RISE2_SHIFT | + pdata->trigger_enable[1] << EXYNOS_TMU_INTEN_RISE1_SHIFT | + pdata->trigger_enable[0] << EXYNOS_TMU_INTEN_RISE0_SHIFT; + if (data->soc != SOC_ARCH_EXYNOS4210) + interrupt_en |= + interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT; + } else { + con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); + interrupt_en = 0; /* Disable all interrupts */ + } + writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN); + writel(con, data->base + EXYNOS_TMU_REG_CONTROL); +} + +static void exynos5440_tmu_control(struct platform_device *pdev, bool on) +{ + struct exynos_tmu_data *data = platform_get_drvdata(pdev); + struct exynos_tmu_platform_data *pdata = data->pdata; + unsigned int con, interrupt_en; + + con = get_con_reg(data, readl(data->base + EXYNOS5440_TMU_S0_7_CTRL)); + + if (on) { + con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); + interrupt_en = + pdata->trigger_enable[3] << EXYNOS5440_TMU_INTEN_RISE3_SHIFT | + pdata->trigger_enable[2] << EXYNOS5440_TMU_INTEN_RISE2_SHIFT | + pdata->trigger_enable[1] << EXYNOS5440_TMU_INTEN_RISE1_SHIFT | + pdata->trigger_enable[0] << EXYNOS5440_TMU_INTEN_RISE0_SHIFT; + interrupt_en |= interrupt_en << EXYNOS5440_TMU_INTEN_FALL0_SHIFT; + } else { + con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); + interrupt_en = 0; /* Disable all interrupts */ + } + writel(interrupt_en, data->base + EXYNOS5440_TMU_S0_7_IRQEN); + writel(con, data->base + EXYNOS5440_TMU_S0_7_CTRL); +} + +static int exynos_tmu_read(struct exynos_tmu_data *data) +{ + int ret; mutex_lock(&data->lock); clk_enable(data->clk); + ret = data->tmu_read(data); + if (ret >= 0) + ret = code_to_temp(data, ret); + clk_disable(data->clk); + mutex_unlock(&data->lock); - val = readl(data->base + reg->emul_con); + return ret; +} +#ifdef CONFIG_THERMAL_EMULATION +static u32 get_emul_con_reg(struct exynos_tmu_data *data, unsigned int val, + unsigned long temp) +{ if (temp) { temp /= MCELSIUS; - if (TMU_SUPPORTS(pdata, EMUL_TIME)) { - val &= ~(EXYNOS_EMUL_TIME_MASK << reg->emul_time_shift); - val |= (EXYNOS_EMUL_TIME << reg->emul_time_shift); + if (data->soc != SOC_ARCH_EXYNOS5440) { + val &= ~(EXYNOS_EMUL_TIME_MASK << EXYNOS_EMUL_TIME_SHIFT); + val |= (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT); } - val &= ~(EXYNOS_EMUL_DATA_MASK << reg->emul_temp_shift); - val |= (temp_to_code(data, temp) << reg->emul_temp_shift) | + val &= ~(EXYNOS_EMUL_DATA_MASK << EXYNOS_EMUL_DATA_SHIFT); + val |= (temp_to_code(data, temp) << EXYNOS_EMUL_DATA_SHIFT) | EXYNOS_EMUL_ENABLE; } else { val &= ~EXYNOS_EMUL_ENABLE; } - writel(val, data->base + reg->emul_con); + return val; +} + +static void exynos4412_tmu_set_emulation(struct exynos_tmu_data *data, + unsigned long temp) +{ + unsigned int val; + u32 emul_con; + + if (data->soc == SOC_ARCH_EXYNOS5260) + emul_con = EXYNOS5260_EMUL_CON; + else + emul_con = EXYNOS_EMUL_CON; + + val = readl(data->base + emul_con); + val = get_emul_con_reg(data, val, temp); + writel(val, data->base + emul_con); +} + +static void exynos5440_tmu_set_emulation(struct exynos_tmu_data *data, + unsigned long temp) +{ + unsigned int val; + + val = readl(data->base + EXYNOS5440_TMU_S0_7_DEBUG); + val = get_emul_con_reg(data, val, temp); + writel(val, data->base + EXYNOS5440_TMU_S0_7_DEBUG); +} + +static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) +{ + struct exynos_tmu_data *data = drv_data; + int ret = -EINVAL; + + if (data->soc == SOC_ARCH_EXYNOS4210) + goto out; + if (temp && temp < MCELSIUS) + goto out; + + mutex_lock(&data->lock); + clk_enable(data->clk); + data->tmu_set_emulation(data, temp); clk_disable(data->clk); mutex_unlock(&data->lock); return 0; @@ -401,23 +572,41 @@ out: return ret; } #else +#define exynos4412_tmu_set_emulation NULL +#define exynos5440_tmu_set_emulation NULL static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) { return -EINVAL; } #endif/*CONFIG_THERMAL_EMULATION*/ +static int exynos4210_tmu_read(struct exynos_tmu_data *data) +{ + int ret = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP); + + /* "temp_code" should range between 75 and 175 */ + return (ret < 75 || ret > 175) ? -ENODATA : ret; +} + +static int exynos4412_tmu_read(struct exynos_tmu_data *data) +{ + return readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP); +} + +static int exynos5440_tmu_read(struct exynos_tmu_data *data) +{ + return readb(data->base + EXYNOS5440_TMU_S0_7_TEMP); +} + static void exynos_tmu_work(struct work_struct *work) { struct exynos_tmu_data *data = container_of(work, struct exynos_tmu_data, irq_work); - struct exynos_tmu_platform_data *pdata = data->pdata; - const struct exynos_tmu_registers *reg = pdata->registers; unsigned int val_type; if (!IS_ERR(data->clk_sec)) clk_enable(data->clk_sec); /* Find which sensor generated this interrupt */ - if (reg->tmu_irqstatus) { - val_type = readl(data->base_second + reg->tmu_irqstatus); + if (data->soc == SOC_ARCH_EXYNOS5440) { + val_type = readl(data->base_second + EXYNOS5440_TMU_IRQ_STATUS); if (!((val_type >> data->id) & 0x1)) goto out; } @@ -429,7 +618,7 @@ static void exynos_tmu_work(struct work_struct *work) clk_enable(data->clk); /* TODO: take action based on particular interrupt */ - exynos_tmu_clear_irqs(data); + data->tmu_clear_irqs(data); clk_disable(data->clk); mutex_unlock(&data->lock); @@ -437,6 +626,40 @@ out: enable_irq(data->irq); } +static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data) +{ + unsigned int val_irq; + u32 tmu_intstat, tmu_intclear; + + if (data->soc == SOC_ARCH_EXYNOS5260) { + tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT; + tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR; + } else { + tmu_intstat = EXYNOS_TMU_REG_INTSTAT; + tmu_intclear = EXYNOS_TMU_REG_INTCLEAR; + } + + val_irq = readl(data->base + tmu_intstat); + /* + * Clear the interrupts. Please note that the documentation for + * Exynos3250, Exynos4412, Exynos5250 and Exynos5260 incorrectly + * states that INTCLEAR register has a different placing of bits + * responsible for FALL IRQs than INTSTAT register. Exynos5420 + * and Exynos5440 documentation is correct (Exynos4210 doesn't + * support FALL IRQs at all). + */ + writel(val_irq, data->base + tmu_intclear); +} + +static void exynos5440_tmu_clear_irqs(struct exynos_tmu_data *data) +{ + unsigned int val_irq; + + val_irq = readl(data->base + EXYNOS5440_TMU_S0_7_IRQ); + /* clear the interrupts */ + writel(val_irq, data->base + EXYNOS5440_TMU_S0_7_IRQ); +} + static irqreturn_t exynos_tmu_irq(int irq, void *id) { struct exynos_tmu_data *data = id; @@ -450,35 +673,35 @@ static irqreturn_t exynos_tmu_irq(int irq, void *id) static const struct of_device_id exynos_tmu_match[] = { { .compatible = "samsung,exynos3250-tmu", - .data = (void *)EXYNOS3250_TMU_DRV_DATA, + .data = &exynos3250_default_tmu_data, }, { .compatible = "samsung,exynos4210-tmu", - .data = (void *)EXYNOS4210_TMU_DRV_DATA, + .data = &exynos4210_default_tmu_data, }, { .compatible = "samsung,exynos4412-tmu", - .data = (void *)EXYNOS4412_TMU_DRV_DATA, + .data = &exynos4412_default_tmu_data, }, { .compatible = "samsung,exynos5250-tmu", - .data = (void *)EXYNOS5250_TMU_DRV_DATA, + .data = &exynos5250_default_tmu_data, }, { .compatible = "samsung,exynos5260-tmu", - .data = (void *)EXYNOS5260_TMU_DRV_DATA, + .data = &exynos5260_default_tmu_data, }, { .compatible = "samsung,exynos5420-tmu", - .data = (void *)EXYNOS5420_TMU_DRV_DATA, + .data = &exynos5420_default_tmu_data, }, { .compatible = "samsung,exynos5420-tmu-ext-triminfo", - .data = (void *)EXYNOS5420_TMU_DRV_DATA, + .data = &exynos5420_default_tmu_data, }, { .compatible = "samsung,exynos5440-tmu", - .data = (void *)EXYNOS5440_TMU_DRV_DATA, + .data = &exynos5440_default_tmu_data, }, {}, }; @@ -553,12 +776,47 @@ static int exynos_map_dt_data(struct platform_device *pdev) dev_err(&pdev->dev, "No platform init data supplied.\n"); return -ENODEV; } + data->pdata = pdata; + data->soc = pdata->type; + + switch (data->soc) { + case SOC_ARCH_EXYNOS4210: + data->tmu_initialize = exynos4210_tmu_initialize; + data->tmu_control = exynos4210_tmu_control; + data->tmu_read = exynos4210_tmu_read; + data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; + break; + case SOC_ARCH_EXYNOS3250: + case SOC_ARCH_EXYNOS4412: + case SOC_ARCH_EXYNOS5250: + case SOC_ARCH_EXYNOS5260: + case SOC_ARCH_EXYNOS5420: + case SOC_ARCH_EXYNOS5420_TRIMINFO: + data->tmu_initialize = exynos4412_tmu_initialize; + data->tmu_control = exynos4210_tmu_control; + data->tmu_read = exynos4412_tmu_read; + data->tmu_set_emulation = exynos4412_tmu_set_emulation; + data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; + break; + case SOC_ARCH_EXYNOS5440: + data->tmu_initialize = exynos5440_tmu_initialize; + data->tmu_control = exynos5440_tmu_control; + data->tmu_read = exynos5440_tmu_read; + data->tmu_set_emulation = exynos5440_tmu_set_emulation; + data->tmu_clear_irqs = exynos5440_tmu_clear_irqs; + break; + default: + dev_err(&pdev->dev, "Platform not supported\n"); + return -EINVAL; + } + /* * Check if the TMU shares some registers and then try to map the * memory of common registers. */ - if (!TMU_SUPPORTS(pdata, ADDRESS_MULTIPLE)) + if (data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO && + data->soc != SOC_ARCH_EXYNOS5440) return 0; if (of_address_to_resource(pdev->dev.of_node, 1, &res)) { @@ -625,20 +883,6 @@ static int exynos_tmu_probe(struct platform_device *pdev) goto err_clk_sec; } - if (pdata->type == SOC_ARCH_EXYNOS3250 || - pdata->type == SOC_ARCH_EXYNOS4210 || - pdata->type == SOC_ARCH_EXYNOS4412 || - pdata->type == SOC_ARCH_EXYNOS5250 || - pdata->type == SOC_ARCH_EXYNOS5260 || - pdata->type == SOC_ARCH_EXYNOS5420_TRIMINFO || - pdata->type == SOC_ARCH_EXYNOS5440) - data->soc = pdata->type; - else { - ret = -EINVAL; - dev_err(&pdev->dev, "Platform not supported\n"); - goto err_clk; - } - ret = exynos_tmu_initialize(pdev); if (ret) { dev_err(&pdev->dev, "Failed to initialize TMU\n"); @@ -683,7 +927,10 @@ static int exynos_tmu_probe(struct platform_device *pdev) /* Register the sensor with thermal management interface */ ret = exynos_register_thermal(sensor_conf); if (ret) { - dev_err(&pdev->dev, "Failed to register thermal interface\n"); + if (ret != -EPROBE_DEFER) + dev_err(&pdev->dev, + "Failed to register thermal interface: %d\n", + ret); goto err_clk; } data->reg_conf = sensor_conf; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index c58c7663a3fe..da3009bff6c4 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -40,115 +40,12 @@ enum soc_type { SOC_ARCH_EXYNOS4412, SOC_ARCH_EXYNOS5250, SOC_ARCH_EXYNOS5260, + SOC_ARCH_EXYNOS5420, SOC_ARCH_EXYNOS5420_TRIMINFO, SOC_ARCH_EXYNOS5440, }; /** - * EXYNOS TMU supported features. - * TMU_SUPPORT_EMULATION - This features is used to set user defined - * temperature to the TMU controller. - * TMU_SUPPORT_MULTI_INST - This features denotes that the soc - * has many instances of TMU. - * TMU_SUPPORT_TRIM_RELOAD - This features shows that trimming can - * be reloaded. - * TMU_SUPPORT_FALLING_TRIP - This features shows that interrupt can - * be registered for falling trips also. - * TMU_SUPPORT_READY_STATUS - This feature tells that the TMU current - * state(active/idle) can be checked. - * TMU_SUPPORT_EMUL_TIME - This features allows to set next temp emulation - * sample time. - * TMU_SUPPORT_ADDRESS_MULTIPLE - This feature tells that the different TMU - * sensors shares some common registers. - * TMU_SUPPORT - macro to compare the above features with the supplied. - */ -#define TMU_SUPPORT_EMULATION BIT(0) -#define TMU_SUPPORT_MULTI_INST BIT(1) -#define TMU_SUPPORT_TRIM_RELOAD BIT(2) -#define TMU_SUPPORT_FALLING_TRIP BIT(3) -#define TMU_SUPPORT_READY_STATUS BIT(4) -#define TMU_SUPPORT_EMUL_TIME BIT(5) -#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(6) - -#define TMU_SUPPORTS(a, b) (a->features & TMU_SUPPORT_ ## b) - -/** - * struct exynos_tmu_register - register descriptors to access registers and - * bitfields. The register validity, offsets and bitfield values may vary - * slightly across different exynos SOC's. - * @triminfo_data: register containing 2 pont trimming data - * @triminfo_ctrl: trim info controller register. - * @triminfo_ctrl_count: the number of trim info controller register. - * @tmu_ctrl: TMU main controller register. - * @test_mux_addr_shift: shift bits of test mux address. - * @therm_trip_mode_shift: shift bits of tripping mode in tmu_ctrl register. - * @therm_trip_mode_mask: mask bits of tripping mode in tmu_ctrl register. - * @therm_trip_en_shift: shift bits of tripping enable in tmu_ctrl register. - * @tmu_status: register drescribing the TMU status. - * @tmu_cur_temp: register containing the current temperature of the TMU. - * @threshold_temp: register containing the base threshold level. - * @threshold_th0: Register containing first set of rising levels. - * @threshold_th1: Register containing second set of rising levels. - * @threshold_th2: Register containing third set of rising levels. - * @threshold_th3_l0_shift: shift bits of level0 threshold temperature. - * @tmu_inten: register containing the different threshold interrupt - enable bits. - * @inten_rise0_shift: shift bits of rising 0 interrupt bits. - * @inten_rise1_shift: shift bits of rising 1 interrupt bits. - * @inten_rise2_shift: shift bits of rising 2 interrupt bits. - * @inten_rise3_shift: shift bits of rising 3 interrupt bits. - * @inten_fall0_shift: shift bits of falling 0 interrupt bits. - * @tmu_intstat: Register containing the interrupt status values. - * @tmu_intclear: Register for clearing the raised interrupt status. - * @emul_con: TMU emulation controller register. - * @emul_temp_shift: shift bits of emulation temperature. - * @emul_time_shift: shift bits of emulation time. - * @tmu_irqstatus: register to find which TMU generated interrupts. - * @tmu_pmin: register to get/set the Pmin value. - */ -struct exynos_tmu_registers { - u32 triminfo_data; - - u32 triminfo_ctrl[MAX_TRIMINFO_CTRL_REG]; - u32 triminfo_ctrl_count; - - u32 tmu_ctrl; - u32 test_mux_addr_shift; - u32 therm_trip_mode_shift; - u32 therm_trip_mode_mask; - u32 therm_trip_en_shift; - - u32 tmu_status; - - u32 tmu_cur_temp; - - u32 threshold_temp; - - u32 threshold_th0; - u32 threshold_th1; - u32 threshold_th2; - u32 threshold_th3_l0_shift; - - u32 tmu_inten; - u32 inten_rise0_shift; - u32 inten_rise1_shift; - u32 inten_rise2_shift; - u32 inten_rise3_shift; - u32 inten_fall0_shift; - - u32 tmu_intstat; - - u32 tmu_intclear; - - u32 emul_con; - u32 emul_temp_shift; - u32 emul_time_shift; - - u32 tmu_irqstatus; - u32 tmu_pmin; -}; - -/** * struct exynos_tmu_platform_data * @threshold: basic temperature for generating interrupt * 25 <= threshold <= 125 [unit: degree Celsius] @@ -192,16 +89,10 @@ struct exynos_tmu_registers { * @first_point_trim: temp value of the first point trimming * @second_point_trim: temp value of the second point trimming * @default_temp_offset: default temperature offset in case of no trimming - * @test_mux; information if SoC supports test MUX - * @triminfo_reload: reload value to read TRIMINFO register * @cal_type: calibration type for temperature * @freq_clip_table: Table representing frequency reduction percentage. * @freq_tab_count: Count of the above table as frequency reduction may * applicable to only some of the trigger levels. - * @registers: Pointer to structure containing all the TMU controller registers - * and bitfields shifts and masks. - * @features: a bitfield value indicating the features supported in SOC like - * emulation, multi instance etc * * This structure is required for configuration of exynos_tmu driver. */ @@ -223,15 +114,11 @@ struct exynos_tmu_platform_data { u8 first_point_trim; u8 second_point_trim; u8 default_temp_offset; - u8 test_mux; - u8 triminfo_reload[MAX_TRIMINFO_CTRL_REG]; enum calibration_type cal_type; enum soc_type type; struct freq_clip_table freq_tab[4]; unsigned int freq_tab_count; - const struct exynos_tmu_registers *registers; - unsigned int features; }; /** @@ -246,4 +133,12 @@ struct exynos_tmu_init_data { struct exynos_tmu_platform_data tmu_data[]; }; +extern struct exynos_tmu_init_data const exynos3250_default_tmu_data; +extern struct exynos_tmu_init_data const exynos4210_default_tmu_data; +extern struct exynos_tmu_init_data const exynos4412_default_tmu_data; +extern struct exynos_tmu_init_data const exynos5250_default_tmu_data; +extern struct exynos_tmu_init_data const exynos5260_default_tmu_data; +extern struct exynos_tmu_init_data const exynos5420_default_tmu_data; +extern struct exynos_tmu_init_data const exynos5440_default_tmu_data; + #endif /* _EXYNOS_TMU_H */ diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 1724f6cdaef8..b23910069f68 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -22,24 +22,6 @@ #include "exynos_thermal_common.h" #include "exynos_tmu.h" -#include "exynos_tmu_data.h" - -#if defined(CONFIG_CPU_EXYNOS4210) -static const struct exynos_tmu_registers exynos4210_tmu_registers = { - .triminfo_data = EXYNOS_TMU_REG_TRIMINFO, - .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .tmu_status = EXYNOS_TMU_REG_STATUS, - .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .threshold_temp = EXYNOS4210_TMU_REG_THRESHOLD_TEMP, - .threshold_th0 = EXYNOS4210_TMU_REG_TRIG_LEVEL0, - .tmu_inten = EXYNOS_TMU_REG_INTEN, - .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, - .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, - .inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT, - .inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT, - .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, - .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, -}; struct exynos_tmu_init_data const exynos4210_default_tmu_data = { .tmu_data = { @@ -75,40 +57,10 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { }, .freq_tab_count = 2, .type = SOC_ARCH_EXYNOS4210, - .registers = &exynos4210_tmu_registers, - .features = TMU_SUPPORT_READY_STATUS, }, }, .tmu_count = 1, }; -#endif - -#if defined(CONFIG_SOC_EXYNOS3250) -static const struct exynos_tmu_registers exynos3250_tmu_registers = { - .triminfo_data = EXYNOS_TMU_REG_TRIMINFO, - .triminfo_ctrl[0] = EXYNOS_TMU_TRIMINFO_CON1, - .triminfo_ctrl[1] = EXYNOS_TMU_TRIMINFO_CON2, - .triminfo_ctrl_count = 2, - .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .test_mux_addr_shift = EXYNOS4412_MUX_ADDR_SHIFT, - .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, - .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, - .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, - .tmu_status = EXYNOS_TMU_REG_STATUS, - .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .threshold_th0 = EXYNOS_THD_TEMP_RISE, - .threshold_th1 = EXYNOS_THD_TEMP_FALL, - .tmu_inten = EXYNOS_TMU_REG_INTEN, - .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, - .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, - .inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT, - .inten_fall0_shift = EXYNOS_TMU_INTEN_FALL0_SHIFT, - .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, - .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, - .emul_con = EXYNOS_EMUL_CON, - .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT, - .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, -}; #define EXYNOS3250_TMU_DATA \ .threshold_falling = 10, \ @@ -144,54 +96,17 @@ static const struct exynos_tmu_registers exynos3250_tmu_registers = { .freq_clip_max = 400 * 1000, \ .temp_level = 95, \ }, \ - .freq_tab_count = 2, \ - .triminfo_reload[0] = EXYNOS_TRIMINFO_RELOAD_ENABLE, \ - .triminfo_reload[1] = EXYNOS_TRIMINFO_RELOAD_ENABLE, \ - .registers = &exynos3250_tmu_registers, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD | \ - TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_READY_STATUS | \ - TMU_SUPPORT_EMUL_TIME) -#endif + .freq_tab_count = 2 -#if defined(CONFIG_SOC_EXYNOS3250) struct exynos_tmu_init_data const exynos3250_default_tmu_data = { .tmu_data = { { EXYNOS3250_TMU_DATA, .type = SOC_ARCH_EXYNOS3250, - .test_mux = EXYNOS4412_MUX_ADDR_VALUE, }, }, .tmu_count = 1, }; -#endif - -#if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) -static const struct exynos_tmu_registers exynos4412_tmu_registers = { - .triminfo_data = EXYNOS_TMU_REG_TRIMINFO, - .triminfo_ctrl[0] = EXYNOS_TMU_TRIMINFO_CON2, - .triminfo_ctrl_count = 1, - .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .test_mux_addr_shift = EXYNOS4412_MUX_ADDR_SHIFT, - .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, - .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, - .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, - .tmu_status = EXYNOS_TMU_REG_STATUS, - .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .threshold_th0 = EXYNOS_THD_TEMP_RISE, - .threshold_th1 = EXYNOS_THD_TEMP_FALL, - .tmu_inten = EXYNOS_TMU_REG_INTEN, - .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, - .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, - .inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT, - .inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT, - .inten_fall0_shift = EXYNOS_TMU_INTEN_FALL0_SHIFT, - .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, - .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, - .emul_con = EXYNOS_EMUL_CON, - .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT, - .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, -}; #define EXYNOS4412_TMU_DATA \ .threshold_falling = 10, \ @@ -227,28 +142,18 @@ static const struct exynos_tmu_registers exynos4412_tmu_registers = { .freq_clip_max = 400 * 1000, \ .temp_level = 95, \ }, \ - .freq_tab_count = 2, \ - .triminfo_reload[0] = EXYNOS_TRIMINFO_RELOAD_ENABLE, \ - .registers = &exynos4412_tmu_registers, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD | \ - TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_READY_STATUS | \ - TMU_SUPPORT_EMUL_TIME) -#endif + .freq_tab_count = 2 -#if defined(CONFIG_SOC_EXYNOS4412) struct exynos_tmu_init_data const exynos4412_default_tmu_data = { .tmu_data = { { EXYNOS4412_TMU_DATA, .type = SOC_ARCH_EXYNOS4412, - .test_mux = EXYNOS4412_MUX_ADDR_VALUE, }, }, .tmu_count = 1, }; -#endif -#if defined(CONFIG_SOC_EXYNOS5250) struct exynos_tmu_init_data const exynos5250_default_tmu_data = { .tmu_data = { { @@ -258,31 +163,6 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { }, .tmu_count = 1, }; -#endif - -#if defined(CONFIG_SOC_EXYNOS5260) -static const struct exynos_tmu_registers exynos5260_tmu_registers = { - .triminfo_data = EXYNOS_TMU_REG_TRIMINFO, - .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, - .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, - .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, - .tmu_status = EXYNOS_TMU_REG_STATUS, - .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .threshold_th0 = EXYNOS_THD_TEMP_RISE, - .threshold_th1 = EXYNOS_THD_TEMP_FALL, - .tmu_inten = EXYNOS5260_TMU_REG_INTEN, - .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, - .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, - .inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT, - .inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT, - .inten_fall0_shift = EXYNOS_TMU_INTEN_FALL0_SHIFT, - .tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT, - .tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR, - .emul_con = EXYNOS5260_EMUL_CON, - .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT, - .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, -}; #define __EXYNOS5260_TMU_DATA \ .threshold_falling = 10, \ @@ -319,13 +199,10 @@ static const struct exynos_tmu_registers exynos5260_tmu_registers = { .temp_level = 103, \ }, \ .freq_tab_count = 2, \ - .registers = &exynos5260_tmu_registers, \ #define EXYNOS5260_TMU_DATA \ __EXYNOS5260_TMU_DATA \ - .type = SOC_ARCH_EXYNOS5260, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_READY_STATUS | TMU_SUPPORT_EMUL_TIME) + .type = SOC_ARCH_EXYNOS5260 struct exynos_tmu_init_data const exynos5260_default_tmu_data = { .tmu_data = { @@ -337,82 +214,14 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { }, .tmu_count = 5, }; -#endif - -#if defined(CONFIG_SOC_EXYNOS5420) -static const struct exynos_tmu_registers exynos5420_tmu_registers = { - .triminfo_data = EXYNOS_TMU_REG_TRIMINFO, - .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, - .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, - .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, - .tmu_status = EXYNOS_TMU_REG_STATUS, - .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .threshold_th0 = EXYNOS_THD_TEMP_RISE, - .threshold_th1 = EXYNOS_THD_TEMP_FALL, - .tmu_inten = EXYNOS_TMU_REG_INTEN, - .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, - .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, - .inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT, - /* INTEN_RISE3 Not availble in exynos5420 */ - .inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT, - .inten_fall0_shift = EXYNOS_TMU_INTEN_FALL0_SHIFT, - .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, - .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, - .emul_con = EXYNOS_EMUL_CON, - .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT, - .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, -}; - -#define __EXYNOS5420_TMU_DATA \ - .threshold_falling = 10, \ - .trigger_levels[0] = 85, \ - .trigger_levels[1] = 103, \ - .trigger_levels[2] = 110, \ - .trigger_levels[3] = 120, \ - .trigger_enable[0] = true, \ - .trigger_enable[1] = true, \ - .trigger_enable[2] = true, \ - .trigger_enable[3] = false, \ - .trigger_type[0] = THROTTLE_ACTIVE, \ - .trigger_type[1] = THROTTLE_ACTIVE, \ - .trigger_type[2] = SW_TRIP, \ - .trigger_type[3] = HW_TRIP, \ - .max_trigger_level = 4, \ - .non_hw_trigger_levels = 3, \ - .gain = 8, \ - .reference_voltage = 16, \ - .noise_cancel_mode = 4, \ - .cal_type = TYPE_ONE_POINT_TRIMMING, \ - .efuse_value = 55, \ - .min_efuse_value = 40, \ - .max_efuse_value = 100, \ - .first_point_trim = 25, \ - .second_point_trim = 85, \ - .default_temp_offset = 50, \ - .freq_tab[0] = { \ - .freq_clip_max = 800 * 1000, \ - .temp_level = 85, \ - }, \ - .freq_tab[1] = { \ - .freq_clip_max = 200 * 1000, \ - .temp_level = 103, \ - }, \ - .freq_tab_count = 2, \ - .registers = &exynos5420_tmu_registers, \ #define EXYNOS5420_TMU_DATA \ - __EXYNOS5420_TMU_DATA \ - .type = SOC_ARCH_EXYNOS5250, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_READY_STATUS | TMU_SUPPORT_EMUL_TIME) + __EXYNOS5260_TMU_DATA \ + .type = SOC_ARCH_EXYNOS5420 #define EXYNOS5420_TMU_DATA_SHARED \ - __EXYNOS5420_TMU_DATA \ - .type = SOC_ARCH_EXYNOS5420_TRIMINFO, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_READY_STATUS | TMU_SUPPORT_EMUL_TIME | \ - TMU_SUPPORT_ADDRESS_MULTIPLE) + __EXYNOS5260_TMU_DATA \ + .type = SOC_ARCH_EXYNOS5420_TRIMINFO struct exynos_tmu_init_data const exynos5420_default_tmu_data = { .tmu_data = { @@ -424,34 +233,6 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { }, .tmu_count = 5, }; -#endif - -#if defined(CONFIG_SOC_EXYNOS5440) -static const struct exynos_tmu_registers exynos5440_tmu_registers = { - .triminfo_data = EXYNOS5440_TMU_S0_7_TRIM, - .tmu_ctrl = EXYNOS5440_TMU_S0_7_CTRL, - .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, - .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, - .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, - .tmu_status = EXYNOS5440_TMU_S0_7_STATUS, - .tmu_cur_temp = EXYNOS5440_TMU_S0_7_TEMP, - .threshold_th0 = EXYNOS5440_TMU_S0_7_TH0, - .threshold_th1 = EXYNOS5440_TMU_S0_7_TH1, - .threshold_th2 = EXYNOS5440_TMU_S0_7_TH2, - .threshold_th3_l0_shift = EXYNOS5440_TMU_TH_RISE4_SHIFT, - .tmu_inten = EXYNOS5440_TMU_S0_7_IRQEN, - .inten_rise0_shift = EXYNOS5440_TMU_INTEN_RISE0_SHIFT, - .inten_rise1_shift = EXYNOS5440_TMU_INTEN_RISE1_SHIFT, - .inten_rise2_shift = EXYNOS5440_TMU_INTEN_RISE2_SHIFT, - .inten_rise3_shift = EXYNOS5440_TMU_INTEN_RISE3_SHIFT, - .inten_fall0_shift = EXYNOS5440_TMU_INTEN_FALL0_SHIFT, - .tmu_intstat = EXYNOS5440_TMU_S0_7_IRQ, - .tmu_intclear = EXYNOS5440_TMU_S0_7_IRQ, - .tmu_irqstatus = EXYNOS5440_TMU_IRQ_STATUS, - .emul_con = EXYNOS5440_TMU_S0_7_DEBUG, - .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT, - .tmu_pmin = EXYNOS5440_TMU_PMIN, -}; #define EXYNOS5440_TMU_DATA \ .trigger_levels[0] = 100, \ @@ -471,10 +252,7 @@ static const struct exynos_tmu_registers exynos5440_tmu_registers = { .first_point_trim = 25, \ .second_point_trim = 70, \ .default_temp_offset = 25, \ - .type = SOC_ARCH_EXYNOS5440, \ - .registers = &exynos5440_tmu_registers, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_MULTI_INST | TMU_SUPPORT_ADDRESS_MULTIPLE), + .type = SOC_ARCH_EXYNOS5440 struct exynos_tmu_init_data const exynos5440_default_tmu_data = { .tmu_data = { @@ -484,4 +262,3 @@ struct exynos_tmu_init_data const exynos5440_default_tmu_data = { }, .tmu_count = 3, }; -#endif diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h deleted file mode 100644 index 63de598c9c2c..000000000000 --- a/drivers/thermal/samsung/exynos_tmu_data.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * exynos_tmu_data.h - Samsung EXYNOS tmu data header file - * - * Copyright (C) 2013 Samsung Electronics - * Amit Daniel Kachhap <amit.daniel@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef _EXYNOS_TMU_DATA_H -#define _EXYNOS_TMU_DATA_H - -/* Exynos generic registers */ -#define EXYNOS_TMU_REG_TRIMINFO 0x0 -#define EXYNOS_TMU_REG_CONTROL 0x20 -#define EXYNOS_TMU_REG_STATUS 0x28 -#define EXYNOS_TMU_REG_CURRENT_TEMP 0x40 -#define EXYNOS_TMU_REG_INTEN 0x70 -#define EXYNOS_TMU_REG_INTSTAT 0x74 -#define EXYNOS_TMU_REG_INTCLEAR 0x78 - -#define EXYNOS_TMU_TEMP_MASK 0xff -#define EXYNOS_TMU_REF_VOLTAGE_SHIFT 24 -#define EXYNOS_TMU_REF_VOLTAGE_MASK 0x1f -#define EXYNOS_TMU_BUF_SLOPE_SEL_MASK 0xf -#define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT 8 -#define EXYNOS_TMU_CORE_EN_SHIFT 0 - -/* Exynos3250 specific registers */ -#define EXYNOS_TMU_TRIMINFO_CON1 0x10 - -/* Exynos4210 specific registers */ -#define EXYNOS4210_TMU_REG_THRESHOLD_TEMP 0x44 -#define EXYNOS4210_TMU_REG_TRIG_LEVEL0 0x50 - -/* Exynos5250, Exynos4412, Exynos3250 specific registers */ -#define EXYNOS_TMU_TRIMINFO_CON2 0x14 -#define EXYNOS_THD_TEMP_RISE 0x50 -#define EXYNOS_THD_TEMP_FALL 0x54 -#define EXYNOS_EMUL_CON 0x80 - -#define EXYNOS_TRIMINFO_RELOAD_ENABLE 1 -#define EXYNOS_TRIMINFO_25_SHIFT 0 -#define EXYNOS_TRIMINFO_85_SHIFT 8 -#define EXYNOS_TMU_TRIP_MODE_SHIFT 13 -#define EXYNOS_TMU_TRIP_MODE_MASK 0x7 -#define EXYNOS_TMU_THERM_TRIP_EN_SHIFT 12 - -#define EXYNOS_TMU_INTEN_RISE0_SHIFT 0 -#define EXYNOS_TMU_INTEN_RISE1_SHIFT 4 -#define EXYNOS_TMU_INTEN_RISE2_SHIFT 8 -#define EXYNOS_TMU_INTEN_RISE3_SHIFT 12 -#define EXYNOS_TMU_INTEN_FALL0_SHIFT 16 - -#define EXYNOS_EMUL_TIME 0x57F0 -#define EXYNOS_EMUL_TIME_MASK 0xffff -#define EXYNOS_EMUL_TIME_SHIFT 16 -#define EXYNOS_EMUL_DATA_SHIFT 8 -#define EXYNOS_EMUL_DATA_MASK 0xFF -#define EXYNOS_EMUL_ENABLE 0x1 - -#define EXYNOS_MAX_TRIGGER_PER_REG 4 - -/* Exynos5260 specific */ -#define EXYNOS5260_TMU_REG_INTEN 0xC0 -#define EXYNOS5260_TMU_REG_INTSTAT 0xC4 -#define EXYNOS5260_TMU_REG_INTCLEAR 0xC8 -#define EXYNOS5260_EMUL_CON 0x100 - -/* Exynos4412 specific */ -#define EXYNOS4412_MUX_ADDR_VALUE 6 -#define EXYNOS4412_MUX_ADDR_SHIFT 20 - -/*exynos5440 specific registers*/ -#define EXYNOS5440_TMU_S0_7_TRIM 0x000 -#define EXYNOS5440_TMU_S0_7_CTRL 0x020 -#define EXYNOS5440_TMU_S0_7_DEBUG 0x040 -#define EXYNOS5440_TMU_S0_7_STATUS 0x060 -#define EXYNOS5440_TMU_S0_7_TEMP 0x0f0 -#define EXYNOS5440_TMU_S0_7_TH0 0x110 -#define EXYNOS5440_TMU_S0_7_TH1 0x130 -#define EXYNOS5440_TMU_S0_7_TH2 0x150 -#define EXYNOS5440_TMU_S0_7_IRQEN 0x210 -#define EXYNOS5440_TMU_S0_7_IRQ 0x230 -/* exynos5440 common registers */ -#define EXYNOS5440_TMU_IRQ_STATUS 0x000 -#define EXYNOS5440_TMU_PMIN 0x004 - -#define EXYNOS5440_TMU_INTEN_RISE0_SHIFT 0 -#define EXYNOS5440_TMU_INTEN_RISE1_SHIFT 1 -#define EXYNOS5440_TMU_INTEN_RISE2_SHIFT 2 -#define EXYNOS5440_TMU_INTEN_RISE3_SHIFT 3 -#define EXYNOS5440_TMU_INTEN_FALL0_SHIFT 4 -#define EXYNOS5440_TMU_TH_RISE4_SHIFT 24 -#define EXYNOS5440_EFUSE_SWAP_OFFSET 8 - -#if defined(CONFIG_SOC_EXYNOS3250) -extern struct exynos_tmu_init_data const exynos3250_default_tmu_data; -#define EXYNOS3250_TMU_DRV_DATA (&exynos3250_default_tmu_data) -#else -#define EXYNOS3250_TMU_DRV_DATA (NULL) -#endif - -#if defined(CONFIG_CPU_EXYNOS4210) -extern struct exynos_tmu_init_data const exynos4210_default_tmu_data; -#define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data) -#else -#define EXYNOS4210_TMU_DRV_DATA (NULL) -#endif - -#if defined(CONFIG_SOC_EXYNOS4412) -extern struct exynos_tmu_init_data const exynos4412_default_tmu_data; -#define EXYNOS4412_TMU_DRV_DATA (&exynos4412_default_tmu_data) -#else -#define EXYNOS4412_TMU_DRV_DATA (NULL) -#endif - -#if defined(CONFIG_SOC_EXYNOS5250) -extern struct exynos_tmu_init_data const exynos5250_default_tmu_data; -#define EXYNOS5250_TMU_DRV_DATA (&exynos5250_default_tmu_data) -#else -#define EXYNOS5250_TMU_DRV_DATA (NULL) -#endif - -#if defined(CONFIG_SOC_EXYNOS5260) -extern struct exynos_tmu_init_data const exynos5260_default_tmu_data; -#define EXYNOS5260_TMU_DRV_DATA (&exynos5260_default_tmu_data) -#else -#define EXYNOS5260_TMU_DRV_DATA (NULL) -#endif - -#if defined(CONFIG_SOC_EXYNOS5420) -extern struct exynos_tmu_init_data const exynos5420_default_tmu_data; -#define EXYNOS5420_TMU_DRV_DATA (&exynos5420_default_tmu_data) -#else -#define EXYNOS5420_TMU_DRV_DATA (NULL) -#endif - -#if defined(CONFIG_SOC_EXYNOS5440) -extern struct exynos_tmu_init_data const exynos5440_default_tmu_data; -#define EXYNOS5440_TMU_DRV_DATA (&exynos5440_default_tmu_data) -#else -#define EXYNOS5440_TMU_DRV_DATA (NULL) -#endif - -#endif /*_EXYNOS_TMU_DATA_H*/ diff --git a/drivers/thermal/tegra_soctherm.c b/drivers/thermal/tegra_soctherm.c new file mode 100644 index 000000000000..9197fc05c5cc --- /dev/null +++ b/drivers/thermal/tegra_soctherm.c @@ -0,0 +1,476 @@ +/* + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. + * + * Author: + * Mikko Perttunen <mperttunen@nvidia.com> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <linux/bitops.h> +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/reset.h> +#include <linux/thermal.h> + +#include <soc/tegra/fuse.h> + +#define SENSOR_CONFIG0 0 +#define SENSOR_CONFIG0_STOP BIT(0) +#define SENSOR_CONFIG0_TALL_SHIFT 8 +#define SENSOR_CONFIG0_TCALC_OVER BIT(4) +#define SENSOR_CONFIG0_OVER BIT(3) +#define SENSOR_CONFIG0_CPTR_OVER BIT(2) + +#define SENSOR_CONFIG1 4 +#define SENSOR_CONFIG1_TSAMPLE_SHIFT 0 +#define SENSOR_CONFIG1_TIDDQ_EN_SHIFT 15 +#define SENSOR_CONFIG1_TEN_COUNT_SHIFT 24 +#define SENSOR_CONFIG1_TEMP_ENABLE BIT(31) + +#define SENSOR_CONFIG2 8 +#define SENSOR_CONFIG2_THERMA_SHIFT 16 +#define SENSOR_CONFIG2_THERMB_SHIFT 0 + +#define SENSOR_PDIV 0x1c0 +#define SENSOR_PDIV_T124 0x8888 +#define SENSOR_HOTSPOT_OFF 0x1c4 +#define SENSOR_HOTSPOT_OFF_T124 0x00060600 +#define SENSOR_TEMP1 0x1c8 +#define SENSOR_TEMP2 0x1cc + +#define SENSOR_TEMP_MASK 0xffff +#define READBACK_VALUE_MASK 0xff00 +#define READBACK_VALUE_SHIFT 8 +#define READBACK_ADD_HALF BIT(7) +#define READBACK_NEGATE BIT(1) + +#define FUSE_TSENSOR8_CALIB 0x180 +#define FUSE_SPARE_REALIGNMENT_REG_0 0x1fc + +#define FUSE_TSENSOR_CALIB_CP_TS_BASE_MASK 0x1fff +#define FUSE_TSENSOR_CALIB_FT_TS_BASE_MASK (0x1fff << 13) +#define FUSE_TSENSOR_CALIB_FT_TS_BASE_SHIFT 13 + +#define FUSE_TSENSOR8_CALIB_CP_TS_BASE_MASK 0x3ff +#define FUSE_TSENSOR8_CALIB_FT_TS_BASE_MASK (0x7ff << 10) +#define FUSE_TSENSOR8_CALIB_FT_TS_BASE_SHIFT 10 + +#define FUSE_SPARE_REALIGNMENT_REG_SHIFT_CP_MASK 0x3f +#define FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_MASK (0x1f << 21) +#define FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_SHIFT 21 + +#define NOMINAL_CALIB_FT_T124 105 +#define NOMINAL_CALIB_CP_T124 25 + +struct tegra_tsensor_configuration { + u32 tall, tsample, tiddq_en, ten_count, pdiv, tsample_ate, pdiv_ate; +}; + +struct tegra_tsensor { + const struct tegra_tsensor_configuration *config; + u32 base, calib_fuse_offset; + /* Correction values used to modify values read from calibration fuses */ + s32 fuse_corr_alpha, fuse_corr_beta; +}; + +struct tegra_thermctl_zone { + void __iomem *reg; + unsigned int shift; +}; + +static const struct tegra_tsensor_configuration t124_tsensor_config = { + .tall = 16300, + .tsample = 120, + .tiddq_en = 1, + .ten_count = 1, + .pdiv = 8, + .tsample_ate = 480, + .pdiv_ate = 8 +}; + +static const struct tegra_tsensor t124_tsensors[] = { + { + .config = &t124_tsensor_config, + .base = 0xc0, + .calib_fuse_offset = 0x098, + .fuse_corr_alpha = 1135400, + .fuse_corr_beta = -6266900, + }, + { + .config = &t124_tsensor_config, + .base = 0xe0, + .calib_fuse_offset = 0x084, + .fuse_corr_alpha = 1122220, + .fuse_corr_beta = -5700700, + }, + { + .config = &t124_tsensor_config, + .base = 0x100, + .calib_fuse_offset = 0x088, + .fuse_corr_alpha = 1127000, + .fuse_corr_beta = -6768200, + }, + { + .config = &t124_tsensor_config, + .base = 0x120, + .calib_fuse_offset = 0x12c, + .fuse_corr_alpha = 1110900, + .fuse_corr_beta = -6232000, + }, + { + .config = &t124_tsensor_config, + .base = 0x140, + .calib_fuse_offset = 0x158, + .fuse_corr_alpha = 1122300, + .fuse_corr_beta = -5936400, + }, + { + .config = &t124_tsensor_config, + .base = 0x160, + .calib_fuse_offset = 0x15c, + .fuse_corr_alpha = 1145700, + .fuse_corr_beta = -7124600, + }, + { + .config = &t124_tsensor_config, + .base = 0x180, + .calib_fuse_offset = 0x154, + .fuse_corr_alpha = 1120100, + .fuse_corr_beta = -6000500, + }, + { + .config = &t124_tsensor_config, + .base = 0x1a0, + .calib_fuse_offset = 0x160, + .fuse_corr_alpha = 1106500, + .fuse_corr_beta = -6729300, + }, +}; + +struct tegra_soctherm { + struct reset_control *reset; + struct clk *clock_tsensor; + struct clk *clock_soctherm; + void __iomem *regs; + + struct thermal_zone_device *thermctl_tzs[4]; +}; + +struct tsensor_shared_calibration { + u32 base_cp, base_ft; + u32 actual_temp_cp, actual_temp_ft; +}; + +static int calculate_shared_calibration(struct tsensor_shared_calibration *r) +{ + u32 val, shifted_cp, shifted_ft; + int err; + + err = tegra_fuse_readl(FUSE_TSENSOR8_CALIB, &val); + if (err) + return err; + r->base_cp = val & FUSE_TSENSOR8_CALIB_CP_TS_BASE_MASK; + r->base_ft = (val & FUSE_TSENSOR8_CALIB_FT_TS_BASE_MASK) + >> FUSE_TSENSOR8_CALIB_FT_TS_BASE_SHIFT; + val = ((val & FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_MASK) + >> FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_SHIFT); + shifted_ft = sign_extend32(val, 4); + + err = tegra_fuse_readl(FUSE_SPARE_REALIGNMENT_REG_0, &val); + if (err) + return err; + shifted_cp = sign_extend32(val, 5); + + r->actual_temp_cp = 2 * NOMINAL_CALIB_CP_T124 + shifted_cp; + r->actual_temp_ft = 2 * NOMINAL_CALIB_FT_T124 + shifted_ft; + + return 0; +} + +static s64 div64_s64_precise(s64 a, s64 b) +{ + s64 r, al; + + /* Scale up for increased precision division */ + al = a << 16; + + r = div64_s64(al * 2 + 1, 2 * b); + return r >> 16; +} + +static int +calculate_tsensor_calibration(const struct tegra_tsensor *sensor, + const struct tsensor_shared_calibration *shared, + u32 *calib) +{ + u32 val; + s32 actual_tsensor_ft, actual_tsensor_cp, delta_sens, delta_temp, + mult, div; + s16 therma, thermb; + s64 tmp; + int err; + + err = tegra_fuse_readl(sensor->calib_fuse_offset, &val); + if (err) + return err; + + actual_tsensor_cp = (shared->base_cp * 64) + sign_extend32(val, 12); + val = (val & FUSE_TSENSOR_CALIB_FT_TS_BASE_MASK) + >> FUSE_TSENSOR_CALIB_FT_TS_BASE_SHIFT; + actual_tsensor_ft = (shared->base_ft * 32) + sign_extend32(val, 12); + + delta_sens = actual_tsensor_ft - actual_tsensor_cp; + delta_temp = shared->actual_temp_ft - shared->actual_temp_cp; + + mult = sensor->config->pdiv * sensor->config->tsample_ate; + div = sensor->config->tsample * sensor->config->pdiv_ate; + + therma = div64_s64_precise((s64) delta_temp * (1LL << 13) * mult, + (s64) delta_sens * div); + + tmp = (s64)actual_tsensor_ft * shared->actual_temp_cp - + (s64)actual_tsensor_cp * shared->actual_temp_ft; + thermb = div64_s64_precise(tmp, (s64)delta_sens); + + therma = div64_s64_precise((s64)therma * sensor->fuse_corr_alpha, + (s64)1000000LL); + thermb = div64_s64_precise((s64)thermb * sensor->fuse_corr_alpha + + sensor->fuse_corr_beta, (s64)1000000LL); + + *calib = ((u16)therma << SENSOR_CONFIG2_THERMA_SHIFT) | + ((u16)thermb << SENSOR_CONFIG2_THERMB_SHIFT); + + return 0; +} + +static int enable_tsensor(struct tegra_soctherm *tegra, + const struct tegra_tsensor *sensor, + const struct tsensor_shared_calibration *shared) +{ + void __iomem *base = tegra->regs + sensor->base; + unsigned int val; + u32 calib; + int err; + + err = calculate_tsensor_calibration(sensor, shared, &calib); + if (err) + return err; + + val = sensor->config->tall << SENSOR_CONFIG0_TALL_SHIFT; + writel(val, base + SENSOR_CONFIG0); + + val = (sensor->config->tsample - 1) << SENSOR_CONFIG1_TSAMPLE_SHIFT; + val |= sensor->config->tiddq_en << SENSOR_CONFIG1_TIDDQ_EN_SHIFT; + val |= sensor->config->ten_count << SENSOR_CONFIG1_TEN_COUNT_SHIFT; + val |= SENSOR_CONFIG1_TEMP_ENABLE; + writel(val, base + SENSOR_CONFIG1); + + writel(calib, base + SENSOR_CONFIG2); + + return 0; +} + +/* + * Translate from soctherm readback format to millicelsius. + * The soctherm readback format in bits is as follows: + * TTTTTTTT H______N + * where T's contain the temperature in Celsius, + * H denotes an addition of 0.5 Celsius and N denotes negation + * of the final value. + */ +static long translate_temp(u16 val) +{ + long t; + + t = ((val & READBACK_VALUE_MASK) >> READBACK_VALUE_SHIFT) * 1000; + if (val & READBACK_ADD_HALF) + t += 500; + if (val & READBACK_NEGATE) + t *= -1; + + return t; +} + +static int tegra_thermctl_get_temp(void *data, long *out_temp) +{ + struct tegra_thermctl_zone *zone = data; + u32 val; + + val = (readl(zone->reg) >> zone->shift) & SENSOR_TEMP_MASK; + *out_temp = translate_temp(val); + + return 0; +} + +static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = { + .get_temp = tegra_thermctl_get_temp, +}; + +static const struct of_device_id tegra_soctherm_of_match[] = { + { .compatible = "nvidia,tegra124-soctherm" }, + { }, +}; +MODULE_DEVICE_TABLE(of, tegra_soctherm_of_match); + +struct thermctl_zone_desc { + unsigned int offset; + unsigned int shift; +}; + +static const struct thermctl_zone_desc t124_thermctl_temp_zones[] = { + { SENSOR_TEMP1, 16 }, + { SENSOR_TEMP2, 16 }, + { SENSOR_TEMP1, 0 }, + { SENSOR_TEMP2, 0 } +}; + +static int tegra_soctherm_probe(struct platform_device *pdev) +{ + struct tegra_soctherm *tegra; + struct thermal_zone_device *tz; + struct tsensor_shared_calibration shared_calib; + struct resource *res; + unsigned int i; + int err; + + const struct tegra_tsensor *tsensors = t124_tsensors; + + tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL); + if (!tegra) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + tegra->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(tegra->regs)) + return PTR_ERR(tegra->regs); + + tegra->reset = devm_reset_control_get(&pdev->dev, "soctherm"); + if (IS_ERR(tegra->reset)) { + dev_err(&pdev->dev, "can't get soctherm reset\n"); + return PTR_ERR(tegra->reset); + } + + tegra->clock_tsensor = devm_clk_get(&pdev->dev, "tsensor"); + if (IS_ERR(tegra->clock_tsensor)) { + dev_err(&pdev->dev, "can't get tsensor clock\n"); + return PTR_ERR(tegra->clock_tsensor); + } + + tegra->clock_soctherm = devm_clk_get(&pdev->dev, "soctherm"); + if (IS_ERR(tegra->clock_soctherm)) { + dev_err(&pdev->dev, "can't get soctherm clock\n"); + return PTR_ERR(tegra->clock_soctherm); + } + + reset_control_assert(tegra->reset); + + err = clk_prepare_enable(tegra->clock_soctherm); + if (err) + return err; + + err = clk_prepare_enable(tegra->clock_tsensor); + if (err) { + clk_disable_unprepare(tegra->clock_soctherm); + return err; + } + + reset_control_deassert(tegra->reset); + + /* Initialize raw sensors */ + + err = calculate_shared_calibration(&shared_calib); + if (err) + goto disable_clocks; + + for (i = 0; i < ARRAY_SIZE(t124_tsensors); ++i) { + err = enable_tsensor(tegra, tsensors + i, &shared_calib); + if (err) + goto disable_clocks; + } + + writel(SENSOR_PDIV_T124, tegra->regs + SENSOR_PDIV); + writel(SENSOR_HOTSPOT_OFF_T124, tegra->regs + SENSOR_HOTSPOT_OFF); + + /* Initialize thermctl sensors */ + + for (i = 0; i < ARRAY_SIZE(tegra->thermctl_tzs); ++i) { + struct tegra_thermctl_zone *zone = + devm_kzalloc(&pdev->dev, sizeof(*zone), GFP_KERNEL); + if (!zone) { + err = -ENOMEM; + goto unregister_tzs; + } + + zone->reg = tegra->regs + t124_thermctl_temp_zones[i].offset; + zone->shift = t124_thermctl_temp_zones[i].shift; + + tz = thermal_zone_of_sensor_register(&pdev->dev, i, zone, + &tegra_of_thermal_ops); + if (IS_ERR(tz)) { + err = PTR_ERR(tz); + dev_err(&pdev->dev, "failed to register sensor: %d\n", + err); + goto unregister_tzs; + } + + tegra->thermctl_tzs[i] = tz; + } + + return 0; + +unregister_tzs: + while (i--) + thermal_zone_of_sensor_unregister(&pdev->dev, + tegra->thermctl_tzs[i]); + +disable_clocks: + clk_disable_unprepare(tegra->clock_tsensor); + clk_disable_unprepare(tegra->clock_soctherm); + + return err; +} + +static int tegra_soctherm_remove(struct platform_device *pdev) +{ + struct tegra_soctherm *tegra = platform_get_drvdata(pdev); + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(tegra->thermctl_tzs); ++i) { + thermal_zone_of_sensor_unregister(&pdev->dev, + tegra->thermctl_tzs[i]); + } + + clk_disable_unprepare(tegra->clock_tsensor); + clk_disable_unprepare(tegra->clock_soctherm); + + return 0; +} + +static struct platform_driver tegra_soctherm_driver = { + .probe = tegra_soctherm_probe, + .remove = tegra_soctherm_remove, + .driver = { + .name = "tegra-soctherm", + .of_match_table = tegra_soctherm_of_match, + }, +}; +module_platform_driver(tegra_soctherm_driver); + +MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>"); +MODULE_DESCRIPTION("NVIDIA Tegra SOCTHERM thermal management driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 43b90709585f..87e0b0782023 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -368,7 +368,7 @@ static void handle_critical_trips(struct thermal_zone_device *tz, tz->ops->get_trip_temp(tz, trip, &trip_temp); /* If we have not crossed the trip_temp, we do not care. */ - if (tz->temperature < trip_temp) + if (trip_temp <= 0 || tz->temperature < trip_temp) return; trace_thermal_zone_trip(tz, trip, trip_type); @@ -757,6 +757,7 @@ policy_store(struct device *dev, struct device_attribute *attr, snprintf(name, sizeof(name), "%s", buf); mutex_lock(&thermal_governor_lock); + mutex_lock(&tz->lock); gov = __find_governor(strim(name)); if (!gov) @@ -766,6 +767,7 @@ policy_store(struct device *dev, struct device_attribute *attr, ret = count; exit: + mutex_unlock(&tz->lock); mutex_unlock(&thermal_governor_lock); return ret; } @@ -928,7 +930,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, struct thermal_zone_device *pos1; struct thermal_cooling_device *pos2; unsigned long max_state; - int result; + int result, ret; if (trip >= tz->trips || (trip < 0 && trip != THERMAL_TRIPS_NONE)) return -EINVAL; @@ -945,7 +947,9 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, if (tz != pos1 || cdev != pos2) return -EINVAL; - cdev->ops->get_max_state(cdev, &max_state); + ret = cdev->ops->get_max_state(cdev, &max_state); + if (ret) + return ret; /* lower default 0, upper default max_state */ lower = lower == THERMAL_NO_LIMIT ? 0 : lower; @@ -1835,10 +1839,10 @@ static int __init thermal_init(void) exit_netlink: genetlink_exit(); -unregister_governors: - thermal_unregister_governors(); unregister_class: class_unregister(&thermal_class); +unregister_governors: + thermal_unregister_governors(); error: idr_destroy(&thermal_tz_idr); idr_destroy(&thermal_cdev_idr); diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index d15d243de27a..0531c752fbbb 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -89,9 +89,27 @@ static inline void thermal_gov_user_space_unregister(void) {} #ifdef CONFIG_THERMAL_OF int of_parse_thermal_zones(void); void of_thermal_destroy_zones(void); +int of_thermal_get_ntrips(struct thermal_zone_device *); +bool of_thermal_is_trip_valid(struct thermal_zone_device *, int); +const struct thermal_trip * +of_thermal_get_trip_points(struct thermal_zone_device *); #else static inline int of_parse_thermal_zones(void) { return 0; } static inline void of_thermal_destroy_zones(void) { } +static inline int of_thermal_get_ntrips(struct thermal_zone_device *tz) +{ + return 0; +} +static inline bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, + int trip) +{ + return 0; +} +static inline const struct thermal_trip * +of_thermal_get_trip_points(struct thermal_zone_device *tz) +{ + return NULL; +} #endif #endif /* __THERMAL_CORE_H__ */ diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c index 9eec26dc0448..3fb054a10f6a 100644 --- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c +++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c @@ -28,7 +28,6 @@ #include <linux/kernel.h> #include <linux/workqueue.h> #include <linux/thermal.h> -#include <linux/cpufreq.h> #include <linux/cpumask.h> #include <linux/cpu_cooling.h> #include <linux/of.h> @@ -286,6 +285,11 @@ static int ti_thermal_get_crit_temp(struct thermal_zone_device *thermal, return ti_thermal_get_trip_temp(thermal, OMAP_TRIP_NUMBER - 1, temp); } +static const struct thermal_zone_of_device_ops ti_of_thermal_ops = { + .get_temp = __ti_thermal_get_temp, + .get_trend = __ti_thermal_get_trend, +}; + static struct thermal_zone_device_ops ti_thermal_ops = { .get_temp = ti_thermal_get_temp, .get_trend = ti_thermal_get_trend, @@ -333,8 +337,7 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id, /* in case this is specified by DT */ data->ti_thermal = thermal_zone_of_sensor_register(bgp->dev, id, - data, __ti_thermal_get_temp, - __ti_thermal_get_trend); + data, &ti_of_thermal_ops); if (IS_ERR(data->ti_thermal)) { /* Create thermal zone */ data->ti_thermal = thermal_zone_device_register(domain, @@ -403,17 +406,17 @@ int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id) if (!data) return -EINVAL; - if (!cpufreq_get_current_driver()) { - dev_dbg(bgp->dev, "no cpufreq driver yet\n"); - return -EPROBE_DEFER; - } - /* Register cooling device */ data->cool_dev = cpufreq_cooling_register(cpu_present_mask); if (IS_ERR(data->cool_dev)) { - dev_err(bgp->dev, - "Failed to register cpufreq cooling device\n"); - return PTR_ERR(data->cool_dev); + int ret = PTR_ERR(data->cool_dev); + + if (ret != -EPROBE_DEFER) + dev_err(bgp->dev, + "Failed to register cpu cooling device %d\n", + ret); + + return ret; } ti_bandgap_set_sensor_data(bgp, id, data); diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index d2b496750d59..4ddfa60c9222 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -2399,17 +2399,12 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file, poll_wait(file, &tty->read_wait, wait); poll_wait(file, &tty->write_wait, wait); - if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) - mask |= POLLHUP; if (input_available_p(tty, 1)) mask |= POLLIN | POLLRDNORM; - else if (mask & POLLHUP) { - tty_flush_to_ldisc(tty); - if (input_available_p(tty, 1)) - mask |= POLLIN | POLLRDNORM; - } if (tty->packet && tty->link->ctrl_status) mask |= POLLPRI | POLLIN | POLLRDNORM; + if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) + mask |= POLLHUP; if (tty_hung_up_p(file)) mask |= POLLHUP; if (!(mask & (POLLHUP | POLLIN | POLLRDNORM))) { diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index b4b58ae24c61..555de07db593 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -530,7 +530,7 @@ static int dw8250_resume(struct device *dev) } #endif /* CONFIG_PM_SLEEP */ -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM static int dw8250_runtime_suspend(struct device *dev) { struct dw8250_data *data = dev_get_drvdata(dev); diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c index 6f93123a428a..7a11fac775c4 100644 --- a/drivers/tty/serial/8250/8250_mtk.c +++ b/drivers/tty/serial/8250/8250_mtk.c @@ -244,7 +244,7 @@ static int mtk8250_resume(struct device *dev) } #endif /* CONFIG_PM_SLEEP */ -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM static int mtk8250_runtime_suspend(struct device *dev) { struct mtk8250_data *data = dev_get_drvdata(dev); diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 336602eb453e..96b69bfd773f 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -561,7 +561,7 @@ static int omap_8250_startup(struct uart_port *port) if (ret) goto err; -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM up->capabilities |= UART_CAP_RPM; #endif @@ -997,12 +997,12 @@ static int omap8250_probe(struct platform_device *pdev) up.port.fifosize = 64; up.tx_loadsz = 64; up.capabilities = UART_CAP_FIFO; -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM /* - * PM_RUNTIME is mostly transparent. However to do it right we need to a + * Runtime PM is mostly transparent. However to do it right we need to a * TX empty interrupt before we can put the device to auto idle. So if - * PM_RUNTIME is not enabled we don't add that flag and can spare that - * one extra interrupt in the TX path. + * PM is not enabled we don't add that flag and can spare that one extra + * interrupt in the TX path. */ up.capabilities |= UART_CAP_RPM; #endif @@ -1105,7 +1105,7 @@ static int omap8250_remove(struct platform_device *pdev) return 0; } -#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM_RUNTIME) +#ifdef CONFIG_PM static inline void omap8250_enable_wakeirq(struct omap8250_priv *priv, bool enable) @@ -1179,7 +1179,7 @@ static int omap8250_resume(struct device *dev) #define omap8250_complete NULL #endif -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM static int omap8250_lost_context(struct uart_8250_port *up) { u32 val; diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 31feeb2d0a66..d1f8dc6aabcb 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1815,7 +1815,7 @@ pci_wch_ch353_setup(struct serial_private *priv, } static int -pci_wch_ch382_setup(struct serial_private *priv, +pci_wch_ch38x_setup(struct serial_private *priv, const struct pciserial_board *board, struct uart_8250_port *port, int idx) { @@ -1880,6 +1880,7 @@ pci_wch_ch382_setup(struct serial_private *priv, #define PCIE_VENDOR_ID_WCH 0x1c00 #define PCIE_DEVICE_ID_WCH_CH382_2S1P 0x3250 +#define PCIE_DEVICE_ID_WCH_CH384_4S 0x3470 /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 @@ -2571,13 +2572,21 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .subdevice = PCI_ANY_ID, .setup = pci_wch_ch353_setup, }, - /* WCH CH382 2S1P card (16750 clone) */ + /* WCH CH382 2S1P card (16850 clone) */ { .vendor = PCIE_VENDOR_ID_WCH, .device = PCIE_DEVICE_ID_WCH_CH382_2S1P, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, - .setup = pci_wch_ch382_setup, + .setup = pci_wch_ch38x_setup, + }, + /* WCH CH384 4S card (16850 clone) */ + { + .vendor = PCIE_VENDOR_ID_WCH, + .device = PCIE_DEVICE_ID_WCH_CH384_4S, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .setup = pci_wch_ch38x_setup, }, /* * ASIX devices with FIFO bug @@ -2876,6 +2885,7 @@ enum pci_board_num_t { pbn_fintek_4, pbn_fintek_8, pbn_fintek_12, + pbn_wch384_4, }; /* @@ -3675,6 +3685,14 @@ static struct pciserial_board pci_boards[] = { .base_baud = 115200, .first_offset = 0x40, }, + + [pbn_wch384_4] = { + .flags = FL_BASE0, + .num_ports = 4, + .base_baud = 115200, + .uart_offset = 8, + .first_offset = 0xC0, + }, }; static const struct pci_device_id blacklist[] = { @@ -3687,6 +3705,7 @@ static const struct pci_device_id blacklist[] = { { PCI_DEVICE(0x4348, 0x7053), }, /* WCH CH353 2S1P */ { PCI_DEVICE(0x4348, 0x5053), }, /* WCH CH353 1S1P */ { PCI_DEVICE(0x1c00, 0x3250), }, /* WCH CH382 2S1P */ + { PCI_DEVICE(0x1c00, 0x3470), }, /* WCH CH384 4S */ }; /* @@ -5400,6 +5419,10 @@ static struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b0_bt_2_115200 }, + { PCIE_VENDOR_ID_WCH, PCIE_DEVICE_ID_WCH_CH384_4S, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, pbn_wch384_4 }, + /* * Commtech, Inc. Fastcom adapters */ diff --git a/drivers/tty/serial/mfd.c b/drivers/tty/serial/mfd.c index e1f4fdad02c9..8fe4501d7565 100644 --- a/drivers/tty/serial/mfd.c +++ b/drivers/tty/serial/mfd.c @@ -1252,12 +1252,7 @@ static int serial_hsu_resume(struct pci_dev *pdev) } return 0; } -#else -#define serial_hsu_suspend NULL -#define serial_hsu_resume NULL -#endif -#ifdef CONFIG_PM_RUNTIME static int serial_hsu_runtime_idle(struct device *dev) { pm_schedule_suspend(dev, 500); @@ -1274,6 +1269,8 @@ static int serial_hsu_runtime_resume(struct device *dev) return 0; } #else +#define serial_hsu_suspend NULL +#define serial_hsu_resume NULL #define serial_hsu_runtime_idle NULL #define serial_hsu_runtime_suspend NULL #define serial_hsu_runtime_resume NULL diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c index 8abe8ea65658..62da8534ba75 100644 --- a/drivers/tty/serial/msm_serial_hs.c +++ b/drivers/tty/serial/msm_serial_hs.c @@ -1792,7 +1792,7 @@ static void __exit msm_serial_hs_exit(void) } module_exit(msm_serial_hs_exit); -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM static int msm_hs_runtime_idle(struct device *dev) { /* diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 435478a245d3..2e1073da6719 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1776,7 +1776,7 @@ static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1) } } -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM static void serial_omap_restore_context(struct uart_omap_port *up) { if (up->errata & UART_ERRATA_i202_MDR1_ACCESS) diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 19273e31d224..107e80722575 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -1757,32 +1757,43 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = { #endif #if defined(CONFIG_ARCH_EXYNOS) +#define EXYNOS_COMMON_SERIAL_DRV_DATA \ + .info = &(struct s3c24xx_uart_info) { \ + .name = "Samsung Exynos UART", \ + .type = PORT_S3C6400, \ + .has_divslot = 1, \ + .rx_fifomask = S5PV210_UFSTAT_RXMASK, \ + .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, \ + .rx_fifofull = S5PV210_UFSTAT_RXFULL, \ + .tx_fifofull = S5PV210_UFSTAT_TXFULL, \ + .tx_fifomask = S5PV210_UFSTAT_TXMASK, \ + .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, \ + .def_clk_sel = S3C2410_UCON_CLKSEL0, \ + .num_clks = 1, \ + .clksel_mask = 0, \ + .clksel_shift = 0, \ + }, \ + .def_cfg = &(struct s3c2410_uartcfg) { \ + .ucon = S5PV210_UCON_DEFAULT, \ + .ufcon = S5PV210_UFCON_DEFAULT, \ + .has_fracval = 1, \ + } \ + static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = { - .info = &(struct s3c24xx_uart_info) { - .name = "Samsung Exynos4 UART", - .type = PORT_S3C6400, - .has_divslot = 1, - .rx_fifomask = S5PV210_UFSTAT_RXMASK, - .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, - .rx_fifofull = S5PV210_UFSTAT_RXFULL, - .tx_fifofull = S5PV210_UFSTAT_TXFULL, - .tx_fifomask = S5PV210_UFSTAT_TXMASK, - .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, - .def_clk_sel = S3C2410_UCON_CLKSEL0, - .num_clks = 1, - .clksel_mask = 0, - .clksel_shift = 0, - }, - .def_cfg = &(struct s3c2410_uartcfg) { - .ucon = S5PV210_UCON_DEFAULT, - .ufcon = S5PV210_UFCON_DEFAULT, - .has_fracval = 1, - }, + EXYNOS_COMMON_SERIAL_DRV_DATA, .fifosize = { 256, 64, 16, 16 }, }; + +static struct s3c24xx_serial_drv_data exynos5433_serial_drv_data = { + EXYNOS_COMMON_SERIAL_DRV_DATA, + .fifosize = { 64, 256, 16, 256 }, +}; + #define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos4210_serial_drv_data) +#define EXYNOS5433_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos5433_serial_drv_data) #else #define EXYNOS4210_SERIAL_DRV_DATA (kernel_ulong_t)NULL +#define EXYNOS5433_SERIAL_DRV_DATA (kernel_ulong_t)NULL #endif static struct platform_device_id s3c24xx_serial_driver_ids[] = { @@ -1804,6 +1815,9 @@ static struct platform_device_id s3c24xx_serial_driver_ids[] = { }, { .name = "exynos4210-uart", .driver_data = EXYNOS4210_SERIAL_DRV_DATA, + }, { + .name = "exynos5433-uart", + .driver_data = EXYNOS5433_SERIAL_DRV_DATA, }, { }, }; @@ -1823,6 +1837,8 @@ static const struct of_device_id s3c24xx_uart_dt_match[] = { .data = (void *)S5PV210_SERIAL_DRV_DATA }, { .compatible = "samsung,exynos4210-uart", .data = (void *)EXYNOS4210_SERIAL_DRV_DATA }, + { .compatible = "samsung,exynos5433-uart", + .data = (void *)EXYNOS5433_SERIAL_DRV_DATA }, {}, }; MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match); diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 57ca61b14670..984605bb5bf1 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2164,7 +2164,9 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port) break; } - dev_info(port->dev, "%s%d at %s (irq = %d, base_baud = %d) is a %s\n", + printk(KERN_INFO "%s%s%s%d at %s (irq = %d, base_baud = %d) is a %s\n", + port->dev ? dev_name(port->dev) : "", + port->dev ? ": " : "", drv->dev_name, drv->tty_driver->name_base + port->line, address, port->irq, port->uartclk / 16, uart_type(port)); diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 4f35b43e2475..51f066aa375e 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1464,6 +1464,9 @@ static int tty_reopen(struct tty_struct *tty) driver->subtype == PTY_TYPE_MASTER) return -EIO; + if (test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN)) + return -EBUSY; + tty->count++; WARN_ON(!tty->ldisc); @@ -2106,10 +2109,6 @@ retry_open: retval = -ENODEV; filp->f_flags = saved_flags; - if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && - !capable(CAP_SYS_ADMIN)) - retval = -EBUSY; - if (retval) { #ifdef TTY_DEBUG_HANGUP printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 5b9825a4538a..a57dc8866fc5 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -669,7 +669,6 @@ static int ci_hdrc_probe(struct platform_device *pdev) if (!ci) return -ENOMEM; - platform_set_drvdata(pdev, ci); ci->dev = dev; ci->platdata = dev_get_platdata(dev); ci->imx28_write_fix = !!(ci->platdata->flags & @@ -783,6 +782,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) } } + platform_set_drvdata(pdev, ci); ret = devm_request_irq(dev, ci->irq, ci_irq, IRQF_SHARED, ci->platdata->name, ci); if (ret) diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index c1694cff1eaf..48731d0bab35 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -91,6 +91,7 @@ static int host_start(struct ci_hdrc *ci) if (!hcd) return -ENOMEM; + dev_set_drvdata(ci->dev, ci); hcd->rsrc_start = ci->hw_bank.phys; hcd->rsrc_len = ci->hw_bank.size; hcd->regs = ci->hw_bank.abs; diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index 9cfda6a72194..cc0ced08bae2 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig @@ -43,7 +43,7 @@ config USB_DYNAMIC_MINORS config USB_OTG bool "OTG support" - depends on PM_RUNTIME + depends on PM default n help The most notable feature of USB OTG is support for a diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 200168ec2d75..79242008085b 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2567,7 +2567,7 @@ error: * s3c_hsotg_ep_disable - disable given endpoint * @ep: The endpoint to disable. */ -static int s3c_hsotg_ep_disable(struct usb_ep *ep) +static int s3c_hsotg_ep_disable_force(struct usb_ep *ep, bool force) { struct s3c_hsotg_ep *hs_ep = our_ep(ep); struct dwc2_hsotg *hsotg = hs_ep->parent; @@ -2588,7 +2588,7 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep) spin_lock_irqsave(&hsotg->lock, flags); /* terminate all requests with shutdown */ - kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, false); + kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, force); hsotg->fifo_map &= ~(1<<hs_ep->fifo_index); hs_ep->fifo_index = 0; @@ -2609,6 +2609,10 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep) return 0; } +static int s3c_hsotg_ep_disable(struct usb_ep *ep) +{ + return s3c_hsotg_ep_disable_force(ep, false); +} /** * on_list - check request is on the given endpoint * @ep: The endpoint to check. @@ -2924,7 +2928,7 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget) /* all endpoints should be shutdown */ for (ep = 1; ep < hsotg->num_of_eps; ep++) - s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); + s3c_hsotg_ep_disable_force(&hsotg->eps[ep].ep, true); spin_lock_irqsave(&hsotg->lock, flags); diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 7c4faf738747..b642a2f998f9 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -33,6 +33,8 @@ #define PCI_DEVICE_ID_INTEL_BYT 0x0f37 #define PCI_DEVICE_ID_INTEL_MRFLD 0x119e #define PCI_DEVICE_ID_INTEL_BSW 0x22B7 +#define PCI_DEVICE_ID_INTEL_SPTLP 0x9d30 +#define PCI_DEVICE_ID_INTEL_SPTH 0xa130 struct dwc3_pci { struct device *dev; @@ -219,6 +221,8 @@ static const struct pci_device_id dwc3_pci_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTLP), }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTH), }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), }, { } /* Terminating Entry */ }; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index f03b136ecfce..8f65ab3a3b92 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -882,8 +882,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting) if (i == (request->num_mapped_sgs - 1) || sg_is_last(s)) { - if (list_is_last(&req->list, - &dep->request_list)) + if (list_empty(&dep->request_list)) last_one = true; chain = false; } @@ -901,6 +900,9 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting) if (last_one) break; } + + if (last_one) + break; } else { dma = req->request.dma; length = req->request.length; diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 6e04e302dc3a..a1bc3e3a0b09 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -399,8 +399,9 @@ static int hidg_setup(struct usb_function *f, value = __le16_to_cpu(ctrl->wValue); length = __le16_to_cpu(ctrl->wLength); - VDBG(cdev, "hid_setup crtl_request : bRequestType:0x%x bRequest:0x%x " - "Value:0x%x\n", ctrl->bRequestType, ctrl->bRequest, value); + VDBG(cdev, + "%s crtl_request : bRequestType:0x%x bRequest:0x%x Value:0x%x\n", + __func__, ctrl->bRequestType, ctrl->bRequest, value); switch ((ctrl->bRequestType << 8) | ctrl->bRequest) { case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index a90440300735..259b656c0b3e 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -520,7 +520,7 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req) req = midi_alloc_ep_req(ep, midi->buflen); if (!req) { - ERROR(midi, "gmidi_transmit: alloc_ep_request failed\n"); + ERROR(midi, "%s: alloc_ep_request failed\n", __func__); return; } req->length = 0; diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index f7b203293205..e9715845f82e 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -897,7 +897,6 @@ static void f_audio_free_inst(struct usb_function_instance *f) struct f_uac1_opts *opts; opts = container_of(f, struct f_uac1_opts, func_inst); - gaudio_cleanup(opts->card); if (opts->fn_play_alloc) kfree(opts->fn_play); if (opts->fn_cap_alloc) @@ -935,6 +934,7 @@ static void f_audio_free(struct usb_function *f) struct f_audio *audio = func_to_audio(f); struct f_uac1_opts *opts; + gaudio_cleanup(&audio->card); opts = container_of(f->fi, struct f_uac1_opts, func_inst); kfree(audio); mutex_lock(&opts->lock); diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index c744e4975d74..db49ec4c748e 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -441,6 +441,7 @@ ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) kbuf = memdup_user(buf, len); if (IS_ERR(kbuf)) { value = PTR_ERR(kbuf); + kbuf = NULL; goto free1; } @@ -449,6 +450,7 @@ ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) data->name, len, (int) value); free1: mutex_unlock(&data->lock); + kfree (kbuf); return value; } diff --git a/drivers/usb/gadget/legacy/tcm_usb_gadget.c b/drivers/usb/gadget/legacy/tcm_usb_gadget.c index 024f58475a94..3a494168661e 100644 --- a/drivers/usb/gadget/legacy/tcm_usb_gadget.c +++ b/drivers/usb/gadget/legacy/tcm_usb_gadget.c @@ -1131,19 +1131,19 @@ static int usbg_submit_command(struct f_uas *fu, switch (cmd_iu->prio_attr & 0x7) { case UAS_HEAD_TAG: - cmd->prio_attr = MSG_HEAD_TAG; + cmd->prio_attr = TCM_HEAD_TAG; break; case UAS_ORDERED_TAG: - cmd->prio_attr = MSG_ORDERED_TAG; + cmd->prio_attr = TCM_ORDERED_TAG; break; case UAS_ACA: - cmd->prio_attr = MSG_ACA_TAG; + cmd->prio_attr = TCM_ACA_TAG; break; default: pr_debug_once("Unsupported prio_attr: %02x.\n", cmd_iu->prio_attr); case UAS_SIMPLE_TAG: - cmd->prio_attr = MSG_SIMPLE_TAG; + cmd->prio_attr = TCM_SIMPLE_TAG; break; } @@ -1240,7 +1240,7 @@ static int bot_submit_command(struct f_uas *fu, goto err; } - cmd->prio_attr = MSG_SIMPLE_TAG; + cmd->prio_attr = TCM_SIMPLE_TAG; se_cmd = &cmd->se_cmd; cmd->unpacked_lun = cbw->Lun; cmd->is_read = cbw->Flags & US_BULK_FLAG_IN ? 1 : 0; diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index ce882371786b..9f93bed42052 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -716,10 +716,10 @@ static int queue_dma(struct usba_udc *udc, struct usba_ep *ep, req->using_dma = 1; req->ctrl = USBA_BF(DMA_BUF_LEN, req->req.length) | USBA_DMA_CH_EN | USBA_DMA_END_BUF_IE - | USBA_DMA_END_TR_EN | USBA_DMA_END_TR_IE; + | USBA_DMA_END_BUF_EN; - if (ep->is_in) - req->ctrl |= USBA_DMA_END_BUF_EN; + if (!ep->is_in) + req->ctrl |= USBA_DMA_END_TR_EN | USBA_DMA_END_TR_IE; /* * Add this request to the queue and submit for DMA if @@ -828,7 +828,7 @@ static int usba_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) { struct usba_ep *ep = to_usba_ep(_ep); struct usba_udc *udc = ep->udc; - struct usba_request *req = to_usba_req(_req); + struct usba_request *req; unsigned long flags; u32 status; @@ -837,6 +837,16 @@ static int usba_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) spin_lock_irqsave(&udc->lock, flags); + list_for_each_entry(req, &ep->queue, queue) { + if (&req->req == _req) + break; + } + + if (&req->req != _req) { + spin_unlock_irqrestore(&udc->lock, flags); + return -EINVAL; + } + if (req->using_dma) { /* * If this request is currently being transferred, @@ -1563,7 +1573,6 @@ static void usba_ep_irq(struct usba_udc *udc, struct usba_ep *ep) if ((epstatus & epctrl) & USBA_RX_BK_RDY) { DBG(DBG_BUS, "%s: RX data ready\n", ep->ep.name); receive_data(ep); - usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY); } } diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.c b/drivers/usb/gadget/udc/bdc/bdc_ep.c index ff67ceac77c4..d4fe8d769bd6 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_ep.c +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c @@ -718,10 +718,11 @@ static int ep_queue(struct bdc_ep *ep, struct bdc_req *req) struct bdc *bdc; int ret = 0; - bdc = ep->bdc; if (!req || !ep || !ep->usb_ep.desc) return -EINVAL; + bdc = ep->bdc; + req->usb_req.actual = 0; req->usb_req.status = -EINPROGRESS; req->epnum = ep->ep_num; diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index e113fd73aeae..f9a332775c47 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1581,6 +1581,10 @@ iso_stream_schedule ( else next = (now + 2 + 7) & ~0x07; /* full frame cache */ + /* If needed, initialize last_iso_frame so that this URB will be seen */ + if (ehci->isoc_count == 0) + ehci->last_iso_frame = now >> 3; + /* * Use ehci->last_iso_frame as the base. There can't be any * TDs scheduled for earlier than that. @@ -1600,11 +1604,11 @@ iso_stream_schedule ( */ now2 = (now - base) & (mod - 1); - /* Is the schedule already full? */ + /* Is the schedule about to wrap around? */ if (unlikely(!empty && start < period)) { - ehci_dbg(ehci, "iso sched full %p (%u-%u < %u mod %u)\n", + ehci_dbg(ehci, "request %p would overflow (%u-%u < %u mod %u)\n", urb, stream->next_uframe, base, period, mod); - status = -ENOSPC; + status = -EFBIG; goto fail; } @@ -1671,10 +1675,6 @@ iso_stream_schedule ( urb->start_frame = start & (mod - 1); if (!stream->highspeed) urb->start_frame >>= 3; - - /* Make sure scan_isoc() sees these */ - if (ehci->isoc_count == 0) - ehci->last_iso_frame = now >> 3; return status; fail: diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 19a9af1b4d74..ff9af29b4e9f 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -451,7 +451,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0); if (IS_ERR(u_phy)) { - err = PTR_ERR(u_phy); + err = -EPROBE_DEFER; goto cleanup_clk_en; } hcd->usb_phy = u_phy; diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index e752c3098f38..395649f357aa 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -1739,7 +1739,7 @@ static int isp1760_hub_status_data(struct usb_hcd *hcd, char *buf) int retval = 1; unsigned long flags; - /* if !PM_RUNTIME, root hub timers won't get shut down ... */ + /* if !PM, root hub timers won't get shut down ... */ if (!HC_IS_RUNNING(hcd->state)) return 0; diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index 75811dd5a9d7..036924e640f5 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c @@ -3087,7 +3087,7 @@ static int oxu_hub_status_data(struct usb_hcd *hcd, char *buf) int ports, i, retval = 1; unsigned long flags; - /* if !PM_RUNTIME, root hub timers won't get shut down ... */ + /* if !PM, root hub timers won't get shut down ... */ if (!HC_IS_RUNNING(hcd->state)) return 0; diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index dd483c13565b..ce636466edb7 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -567,7 +567,8 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev) { void __iomem *base; u32 control; - u32 fminterval; + u32 fminterval = 0; + bool no_fminterval = false; int cnt; if (!mmio_resource_enabled(pdev, 0)) @@ -577,6 +578,13 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev) if (base == NULL) return; + /* + * ULi M5237 OHCI controller locks the whole system when accessing + * the OHCI_FMINTERVAL offset. + */ + if (pdev->vendor == PCI_VENDOR_ID_AL && pdev->device == 0x5237) + no_fminterval = true; + control = readl(base + OHCI_CONTROL); /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ @@ -615,7 +623,9 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev) } /* software reset of the controller, preserving HcFmInterval */ - fminterval = readl(base + OHCI_FMINTERVAL); + if (!no_fminterval) + fminterval = readl(base + OHCI_FMINTERVAL); + writel(OHCI_HCR, base + OHCI_CMDSTATUS); /* reset requires max 10 us delay */ @@ -624,7 +634,9 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev) break; udelay(1); } - writel(fminterval, base + OHCI_FMINTERVAL); + + if (!no_fminterval) + writel(fminterval, base + OHCI_FMINTERVAL); /* Now the controller is safely in SUSPEND and nothing can wake it up */ iounmap(base); diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 142b601f9563..7f76c8a12f89 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -82,6 +82,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) "must be suspended extra slowly", pdev->revision); } + if (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK) + xhci->quirks |= XHCI_BROKEN_STREAMS; /* Fresco Logic confirms: all revisions of this chip do not * support MSI, even though some of them claim to in their PCI * capabilities. diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 01fcbb5eb06e..c50d8d202618 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -3803,6 +3803,15 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, return -EINVAL; } + if (setup == SETUP_CONTEXT_ONLY) { + slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); + if (GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state)) == + SLOT_STATE_DEFAULT) { + xhci_dbg(xhci, "Slot already in default state\n"); + return 0; + } + } + command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); if (!command) return -ENOMEM; diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 9d68372dd9aa..b005010240e5 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -72,6 +72,8 @@ config USB_MUSB_DA8XX config USB_MUSB_TUSB6010 tristate "TUSB6010" + depends on ARCH_OMAP2PLUS || COMPILE_TEST + depends on NOP_USB_XCEIV = USB_MUSB_HDRC # both built-in or both modules config USB_MUSB_OMAP2PLUS tristate "OMAP2430 and onwards" @@ -85,6 +87,7 @@ config USB_MUSB_AM35X config USB_MUSB_DSPS tristate "TI DSPS platforms" select USB_MUSB_AM335X_CHILD + depends on ARCH_OMAP2PLUS || COMPILE_TEST depends on OF_IRQ config USB_MUSB_BLACKFIN @@ -93,6 +96,7 @@ config USB_MUSB_BLACKFIN config USB_MUSB_UX500 tristate "Ux500 platforms" + depends on ARCH_U8500 || COMPILE_TEST config USB_MUSB_JZ4740 tristate "JZ4740" diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index a441a2de8619..178250145613 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -63,7 +63,7 @@ static void bfin_writew(void __iomem *addr, unsigned offset, u16 data) bfin_write16(addr + offset, data); } -static void binf_writel(void __iomem *addr, unsigned offset, u32 data) +static void bfin_writel(void __iomem *addr, unsigned offset, u32 data) { bfin_write16(addr + offset, (u16)data); } diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index f64fd964dc6d..c39a16ad7832 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c @@ -628,9 +628,9 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller) ret = of_property_read_string_index(np, "dma-names", i, &str); if (ret) goto err; - if (!strncmp(str, "tx", 2)) + if (strstarts(str, "tx")) is_tx = 1; - else if (!strncmp(str, "rx", 2)) + else if (strstarts(str, "rx")) is_tx = 0; else { dev_err(dev, "Wrong dmatype %s\n", str); diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c index ad3701a97389..48131aa8472c 100644 --- a/drivers/usb/musb/musb_debugfs.c +++ b/drivers/usb/musb/musb_debugfs.c @@ -59,20 +59,12 @@ static const struct musb_register_map musb_regmap[] = { { "RxMaxPp", MUSB_RXMAXP, 16 }, { "RxCSR", MUSB_RXCSR, 16 }, { "RxCount", MUSB_RXCOUNT, 16 }, - { "ConfigData", MUSB_CONFIGDATA,8 }, { "IntrRxE", MUSB_INTRRXE, 16 }, { "IntrTxE", MUSB_INTRTXE, 16 }, { "IntrUsbE", MUSB_INTRUSBE, 8 }, { "DevCtl", MUSB_DEVCTL, 8 }, - { "BabbleCtl", MUSB_BABBLE_CTL,8 }, - { "TxFIFOsz", MUSB_TXFIFOSZ, 8 }, - { "RxFIFOsz", MUSB_RXFIFOSZ, 8 }, - { "TxFIFOadd", MUSB_TXFIFOADD, 16 }, - { "RxFIFOadd", MUSB_RXFIFOADD, 16 }, { "VControl", 0x68, 32 }, { "HWVers", 0x69, 16 }, - { "EPInfo", MUSB_EPINFO, 8 }, - { "RAMInfo", MUSB_RAMINFO, 8 }, { "LinkInfo", MUSB_LINKINFO, 8 }, { "VPLen", MUSB_VPLEN, 8 }, { "HS_EOF1", MUSB_HS_EOF1, 8 }, @@ -103,6 +95,16 @@ static const struct musb_register_map musb_regmap[] = { { "DMA_CNTLch7", 0x274, 16 }, { "DMA_ADDRch7", 0x278, 32 }, { "DMA_COUNTch7", 0x27C, 32 }, +#ifndef CONFIG_BLACKFIN + { "ConfigData", MUSB_CONFIGDATA,8 }, + { "BabbleCtl", MUSB_BABBLE_CTL,8 }, + { "TxFIFOsz", MUSB_TXFIFOSZ, 8 }, + { "RxFIFOsz", MUSB_RXFIFOSZ, 8 }, + { "TxFIFOadd", MUSB_TXFIFOADD, 16 }, + { "RxFIFOadd", MUSB_RXFIFOADD, 16 }, + { "EPInfo", MUSB_EPINFO, 8 }, + { "RAMInfo", MUSB_RAMINFO, 8 }, +#endif { } /* Terminating Entry */ }; @@ -197,30 +199,30 @@ static ssize_t musb_test_mode_write(struct file *file, if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) return -EFAULT; - if (!strncmp(buf, "force host", 9)) + if (strstarts(buf, "force host")) test = MUSB_TEST_FORCE_HOST; - if (!strncmp(buf, "fifo access", 11)) + if (strstarts(buf, "fifo access")) test = MUSB_TEST_FIFO_ACCESS; - if (!strncmp(buf, "force full-speed", 15)) + if (strstarts(buf, "force full-speed")) test = MUSB_TEST_FORCE_FS; - if (!strncmp(buf, "force high-speed", 15)) + if (strstarts(buf, "force high-speed")) test = MUSB_TEST_FORCE_HS; - if (!strncmp(buf, "test packet", 10)) { + if (strstarts(buf, "test packet")) { test = MUSB_TEST_PACKET; musb_load_testpacket(musb); } - if (!strncmp(buf, "test K", 6)) + if (strstarts(buf, "test K")) test = MUSB_TEST_K; - if (!strncmp(buf, "test J", 6)) + if (strstarts(buf, "test J")) test = MUSB_TEST_J; - if (!strncmp(buf, "test SE0 NAK", 12)) + if (strstarts(buf, "test SE0 NAK")) test = MUSB_TEST_SE0_NAK; musb_writeb(musb->mregs, MUSB_TESTMODE, test); diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 23d474d3d7f4..883a9adfdfff 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2663,7 +2663,6 @@ void musb_host_cleanup(struct musb *musb) if (musb->port_mode == MUSB_PORT_MODE_GADGET) return; usb_remove_hcd(musb->hcd); - musb->hcd = NULL; } void musb_host_free(struct musb *musb) diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 0cd1f44f0ee8..c6d0c8e745b9 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -20,7 +20,7 @@ config AB8500_USB config FSL_USB2_OTG bool "Freescale USB OTG Transceiver Driver" - depends on USB_EHCI_FSL && USB_FSL_USB2 && USB_OTG_FSM && PM_RUNTIME + depends on USB_EHCI_FSL && USB_FSL_USB2 && USB_OTG_FSM && PM select USB_OTG select USB_PHY help @@ -153,7 +153,7 @@ config USB_MSM_OTG config USB_MV_OTG tristate "Marvell USB OTG support" - depends on USB_EHCI_MV && USB_MV_UDC && PM_RUNTIME + depends on USB_EHCI_MV && USB_MV_UDC && PM select USB_OTG select USB_PHY help diff --git a/drivers/usb/phy/phy-mv-usb.c b/drivers/usb/phy/phy-mv-usb.c index 699e38c73d82..697a741a0cb1 100644 --- a/drivers/usb/phy/phy-mv-usb.c +++ b/drivers/usb/phy/phy-mv-usb.c @@ -338,7 +338,6 @@ static void mv_otg_update_inputs(struct mv_otg *mvotg) static void mv_otg_update_state(struct mv_otg *mvotg) { struct mv_otg_ctrl *otg_ctrl = &mvotg->otg_ctrl; - struct usb_phy *phy = &mvotg->phy; int old_state = mvotg->phy.otg->state; switch (old_state) { @@ -858,10 +857,10 @@ static int mv_otg_suspend(struct platform_device *pdev, pm_message_t state) { struct mv_otg *mvotg = platform_get_drvdata(pdev); - if (mvotg->phy.state != OTG_STATE_B_IDLE) { + if (mvotg->phy.otg->state != OTG_STATE_B_IDLE) { dev_info(&pdev->dev, "OTG state is not B_IDLE, it is %d!\n", - mvotg->phy.state); + mvotg->phy.otg->state); return -EAGAIN; } diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index b4066a001ba0..ccfdfb24b240 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c @@ -34,7 +34,7 @@ static struct usb_phy *__usb_find_phy(struct list_head *list, return phy; } - return ERR_PTR(-ENODEV); + return ERR_PTR(-EPROBE_DEFER); } static struct usb_phy *__usb_find_phy_dev(struct device *dev, @@ -59,6 +59,9 @@ static struct usb_phy *__of_usb_find_phy(struct device_node *node) { struct usb_phy *phy; + if (!of_device_is_available(node)) + return ERR_PTR(-ENODEV); + list_for_each_entry(phy, &phy_list, head) { if (node != phy->dev->of_node) continue; @@ -66,7 +69,7 @@ static struct usb_phy *__of_usb_find_phy(struct device_node *node) return phy; } - return ERR_PTR(-ENODEV); + return ERR_PTR(-EPROBE_DEFER); } static void devm_usb_phy_release(struct device *dev, void *res) @@ -190,10 +193,13 @@ struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, spin_lock_irqsave(&phy_lock, flags); phy = __of_usb_find_phy(node); - if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { - if (!IS_ERR(phy)) - phy = ERR_PTR(-EPROBE_DEFER); + if (IS_ERR(phy)) { + devres_free(ptr); + goto err1; + } + if (!try_module_get(phy->dev->driver->owner)) { + phy = ERR_PTR(-ENODEV); devres_free(ptr); goto err1; } diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 8d7fc48b1f30..29fa1c3d0089 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c @@ -46,6 +46,8 @@ static struct console usbcons; * ------------------------------------------------------------ */ +static const struct tty_operations usb_console_fake_tty_ops = { +}; /* * The parsing of the command line works exactly like the @@ -137,13 +139,17 @@ static int usb_console_setup(struct console *co, char *options) goto reset_open_count; } kref_init(&tty->kref); - tty_port_tty_set(&port->port, tty); tty->driver = usb_serial_tty_driver; tty->index = co->index; + init_ldsem(&tty->ldisc_sem); + INIT_LIST_HEAD(&tty->tty_files); + kref_get(&tty->driver->kref); + tty->ops = &usb_console_fake_tty_ops; if (tty_init_termios(tty)) { retval = -ENOMEM; - goto free_tty; + goto put_tty; } + tty_port_tty_set(&port->port, tty); } /* only call the device specific open if this @@ -161,7 +167,7 @@ static int usb_console_setup(struct console *co, char *options) serial->type->set_termios(tty, port, &dummy); tty_port_tty_set(&port->port, NULL); - kfree(tty); + tty_kref_put(tty); } set_bit(ASYNCB_INITIALIZED, &port->port.flags); } @@ -177,8 +183,8 @@ static int usb_console_setup(struct console *co, char *options) fail: tty_port_tty_set(&port->port, NULL); - free_tty: - kfree(tty); + put_tty: + tty_kref_put(tty); reset_open_count: port->port.count = 0; usb_autopm_put_interface(serial->interface); diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 6c4eb3cf5efd..f4c56fc1a9f6 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -120,10 +120,12 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */ { USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */ { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */ - { USB_DEVICE(0x10C4, 0x8875) }, /* CEL MeshConnect USB Stick */ + { USB_DEVICE(0x10C4, 0x8856) }, /* CEL EM357 ZigBee USB Stick - LR */ + { USB_DEVICE(0x10C4, 0x8857) }, /* CEL EM357 ZigBee USB Stick */ { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */ { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */ { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */ + { USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 1bd192290b08..ccf1df7c4b80 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -286,7 +286,7 @@ static int usb_serial_generic_submit_read_urb(struct usb_serial_port *port, res = usb_submit_urb(port->read_urbs[index], mem_flags); if (res) { - if (res != -EPERM) { + if (res != -EPERM && res != -ENODEV) { dev_err(&port->dev, "%s - usb_submit_urb failed: %d\n", __func__, res); @@ -373,7 +373,7 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb) __func__, urb->status); return; default: - dev_err(&port->dev, "%s - nonzero urb status: %d\n", + dev_dbg(&port->dev, "%s - nonzero urb status: %d\n", __func__, urb->status); goto resubmit; } diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 077c714f1285..e07b15ed5814 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -410,6 +410,8 @@ static void usa26_instat_callback(struct urb *urb) } port = serial->port[msg->port]; p_priv = usb_get_serial_port_data(port); + if (!p_priv) + goto resubmit; /* Update handshaking pin state information */ old_dcd_state = p_priv->dcd_state; @@ -420,7 +422,7 @@ static void usa26_instat_callback(struct urb *urb) if (old_dcd_state != p_priv->dcd_state) tty_port_tty_hangup(&port->port, true); - +resubmit: /* Resubmit urb so we continue receiving */ err = usb_submit_urb(urb, GFP_ATOMIC); if (err != 0) @@ -527,6 +529,8 @@ static void usa28_instat_callback(struct urb *urb) } port = serial->port[msg->port]; p_priv = usb_get_serial_port_data(port); + if (!p_priv) + goto resubmit; /* Update handshaking pin state information */ old_dcd_state = p_priv->dcd_state; @@ -537,7 +541,7 @@ static void usa28_instat_callback(struct urb *urb) if (old_dcd_state != p_priv->dcd_state && old_dcd_state) tty_port_tty_hangup(&port->port, true); - +resubmit: /* Resubmit urb so we continue receiving */ err = usb_submit_urb(urb, GFP_ATOMIC); if (err != 0) @@ -607,6 +611,8 @@ static void usa49_instat_callback(struct urb *urb) } port = serial->port[msg->portNumber]; p_priv = usb_get_serial_port_data(port); + if (!p_priv) + goto resubmit; /* Update handshaking pin state information */ old_dcd_state = p_priv->dcd_state; @@ -617,7 +623,7 @@ static void usa49_instat_callback(struct urb *urb) if (old_dcd_state != p_priv->dcd_state && old_dcd_state) tty_port_tty_hangup(&port->port, true); - +resubmit: /* Resubmit urb so we continue receiving */ err = usb_submit_urb(urb, GFP_ATOMIC); if (err != 0) @@ -855,6 +861,8 @@ static void usa90_instat_callback(struct urb *urb) port = serial->port[0]; p_priv = usb_get_serial_port_data(port); + if (!p_priv) + goto resubmit; /* Update handshaking pin state information */ old_dcd_state = p_priv->dcd_state; @@ -865,7 +873,7 @@ static void usa90_instat_callback(struct urb *urb) if (old_dcd_state != p_priv->dcd_state && old_dcd_state) tty_port_tty_hangup(&port->port, true); - +resubmit: /* Resubmit urb so we continue receiving */ err = usb_submit_urb(urb, GFP_ATOMIC); if (err != 0) @@ -926,6 +934,8 @@ static void usa67_instat_callback(struct urb *urb) port = serial->port[msg->port]; p_priv = usb_get_serial_port_data(port); + if (!p_priv) + goto resubmit; /* Update handshaking pin state information */ old_dcd_state = p_priv->dcd_state; @@ -934,7 +944,7 @@ static void usa67_instat_callback(struct urb *urb) if (old_dcd_state != p_priv->dcd_state && old_dcd_state) tty_port_tty_hangup(&port->port, true); - +resubmit: /* Resubmit urb so we continue receiving */ err = usb_submit_urb(urb, GFP_ATOMIC); if (err != 0) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 7a4c21b4f676..efdcee15b520 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -234,6 +234,8 @@ static void option_instat_callback(struct urb *urb); #define QUALCOMM_VENDOR_ID 0x05C6 +#define SIERRA_VENDOR_ID 0x1199 + #define CMOTECH_VENDOR_ID 0x16d8 #define CMOTECH_PRODUCT_6001 0x6001 #define CMOTECH_PRODUCT_CMU_300 0x6002 @@ -512,7 +514,7 @@ enum option_blacklist_reason { OPTION_BLACKLIST_RESERVED_IF = 2 }; -#define MAX_BL_NUM 8 +#define MAX_BL_NUM 11 struct option_blacklist_info { /* bitfield of interface numbers for OPTION_BLACKLIST_SENDSETUP */ const unsigned long sendsetup; @@ -601,6 +603,11 @@ static const struct option_blacklist_info telit_le920_blacklist = { .reserved = BIT(1) | BIT(5), }; +static const struct option_blacklist_info sierra_mc73xx_blacklist = { + .sendsetup = BIT(0) | BIT(2), + .reserved = BIT(8) | BIT(10) | BIT(11), +}; + static const struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, @@ -1098,6 +1105,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ + { USB_DEVICE_INTERFACE_CLASS(SIERRA_VENDOR_ID, 0x68c0, 0xff), + .driver_info = (kernel_ulong_t)&sierra_mc73xx_blacklist }, /* MC73xx */ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003), diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index cb3e14780a7e..9c63897b3a56 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -142,7 +142,6 @@ static const struct usb_device_id id_table[] = { {DEVICE_SWI(0x0f3d, 0x68a2)}, /* Sierra Wireless MC7700 */ {DEVICE_SWI(0x114f, 0x68a2)}, /* Sierra Wireless MC7750 */ {DEVICE_SWI(0x1199, 0x68a2)}, /* Sierra Wireless MC7710 */ - {DEVICE_SWI(0x1199, 0x68c0)}, /* Sierra Wireless MC73xx */ {DEVICE_SWI(0x1199, 0x901c)}, /* Sierra Wireless EM7700 */ {DEVICE_SWI(0x1199, 0x901f)}, /* Sierra Wireless EM7355 */ {DEVICE_SWI(0x1199, 0x9040)}, /* Sierra Wireless Modem */ diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index 715f299af6ea..ec84758f0e23 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig @@ -41,7 +41,7 @@ config USB_STORAGE_REALTEK config REALTEK_AUTOPM bool "Realtek Card Reader autosuspend support" - depends on USB_STORAGE_REALTEK && PM_RUNTIME + depends on USB_STORAGE_REALTEK && PM default y config USB_STORAGE_DATAFAB diff --git a/drivers/usb/storage/uas-detect.h b/drivers/usb/storage/uas-detect.h index 8a6f371ed6e7..9893d696fc97 100644 --- a/drivers/usb/storage/uas-detect.h +++ b/drivers/usb/storage/uas-detect.h @@ -69,16 +69,39 @@ static int uas_use_uas_driver(struct usb_interface *intf, return 0; /* - * ASM1051 and older ASM1053 devices have the same usb-id, and UAS is - * broken on the ASM1051, use the number of streams to differentiate. - * New ASM1053-s also support 32 streams, but have a different prod-id. + * ASMedia has a number of usb3 to sata bridge chips, at the time of + * this writing the following versions exist: + * ASM1051 - no uas support version + * ASM1051 - with broken (*) uas support + * ASM1053 - with working uas support + * ASM1153 - with working uas support + * + * Devices with these chips re-use a number of device-ids over the + * entire line, so the device-id is useless to determine if we're + * dealing with an ASM1051 (which we want to avoid). + * + * The ASM1153 can be identified by config.MaxPower == 0, + * where as the ASM105x models have config.MaxPower == 36. + * + * Differentiating between the ASM1053 and ASM1051 is trickier, when + * connected over USB-3 we can look at the number of streams supported, + * ASM1051 supports 32 streams, where as early ASM1053 versions support + * 16 streams, newer ASM1053-s also support 32 streams, but have a + * different prod-id. + * + * (*) ASM1051 chips do work with UAS with some disks (with the + * US_FL_NO_REPORT_OPCODES quirk), but are broken with other disks */ if (le16_to_cpu(udev->descriptor.idVendor) == 0x174c && - le16_to_cpu(udev->descriptor.idProduct) == 0x55aa) { - if (udev->speed < USB_SPEED_SUPER) { + (le16_to_cpu(udev->descriptor.idProduct) == 0x5106 || + le16_to_cpu(udev->descriptor.idProduct) == 0x55aa)) { + if (udev->actconfig->desc.bMaxPower == 0) { + /* ASM1153, do nothing */ + } else if (udev->speed < USB_SPEED_SUPER) { /* No streams info, assume ASM1051 */ flags |= US_FL_IGNORE_UAS; } else if (usb_ss_max_streams(&eps[1]->ss_ep_comp) == 32) { + /* Possibly an ASM1051, disable uas */ flags |= US_FL_IGNORE_UAS; } } diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index 18a283d6de1c..6df4357d9ee3 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h @@ -40,6 +40,16 @@ * and don't forget to CC: the USB development list <linux-usb@vger.kernel.org> */ +/* + * Apricorn USB3 dongle sometimes returns "USBSUSBSUSBS" in response to SCSI + * commands in UAS mode. Observed with the 1.28 firmware; are there others? + */ +UNUSUAL_DEV(0x0984, 0x0301, 0x0128, 0x0128, + "Apricorn", + "", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_UAS), + /* https://bugzilla.kernel.org/show_bug.cgi?id=79511 */ UNUSUAL_DEV(0x0bc2, 0x2312, 0x0000, 0x9999, "Seagate", @@ -68,6 +78,20 @@ UNUSUAL_DEV(0x0bc2, 0xa003, 0x0000, 0x9999, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NO_ATA_1X), +/* Reported-by: Marcin ZajÄ…czkowski <mszpak@wp.pl> */ +UNUSUAL_DEV(0x0bc2, 0xa013, 0x0000, 0x9999, + "Seagate", + "Backup Plus", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_ATA_1X), + +/* Reported-by: Hans de Goede <hdegoede@redhat.com> */ +UNUSUAL_DEV(0x0bc2, 0xa0a4, 0x0000, 0x9999, + "Seagate", + "Backup Plus Desk", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_ATA_1X), + /* https://bbs.archlinux.org/viewtopic.php?id=183190 */ UNUSUAL_DEV(0x0bc2, 0xab20, 0x0000, 0x9999, "Seagate", @@ -82,6 +106,13 @@ UNUSUAL_DEV(0x0bc2, 0xab21, 0x0000, 0x9999, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NO_ATA_1X), +/* Reported-by: G. Richard Bellamy <rbellamy@pteradigm.com> */ +UNUSUAL_DEV(0x0bc2, 0xab2a, 0x0000, 0x9999, + "Seagate", + "BUP Fast HDD", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_ATA_1X), + /* Reported-by: Claudio Bizzarri <claudio.bizzarri@gmail.com> */ UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x9999, "JMicron", @@ -89,14 +120,6 @@ UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x9999, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NO_REPORT_OPCODES), -/* Most ASM1051 based devices have issues with uas, blacklist them all */ -/* Reported-by: Hans de Goede <hdegoede@redhat.com> */ -UNUSUAL_DEV(0x174c, 0x5106, 0x0000, 0x9999, - "ASMedia", - "ASM1051", - USB_SC_DEVICE, USB_PR_DEVICE, NULL, - US_FL_IGNORE_UAS), - /* Reported-by: Hans de Goede <hdegoede@redhat.com> */ UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999, "VIA", @@ -104,6 +127,13 @@ UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NO_ATA_1X), +/* Reported-by: Takeo Nakayama <javhera@gmx.com> */ +UNUSUAL_DEV(0x357d, 0x7788, 0x0000, 0x9999, + "JMicron", + "JMS566", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_REPORT_OPCODES), + /* Reported-by: Hans de Goede <hdegoede@redhat.com> */ UNUSUAL_DEV(0x4971, 0x1012, 0x0000, 0x9999, "Hitachi", diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig index d8c57636b9ce..14e27ab32456 100644 --- a/drivers/vfio/Kconfig +++ b/drivers/vfio/Kconfig @@ -16,7 +16,7 @@ config VFIO_SPAPR_EEH menuconfig VFIO tristate "VFIO Non-Privileged userspace driver framework" depends on IOMMU_API - select VFIO_IOMMU_TYPE1 if X86 + select VFIO_IOMMU_TYPE1 if (X86 || S390 || ARM_SMMU) select VFIO_IOMMU_SPAPR_TCE if (PPC_POWERNV || PPC_PSERIES) select VFIO_SPAPR_EEH if (PPC_POWERNV || PPC_PSERIES) select ANON_INODES diff --git a/drivers/vfio/pci/Kconfig b/drivers/vfio/pci/Kconfig index c41b01e2b693..c6bb5da2d2a7 100644 --- a/drivers/vfio/pci/Kconfig +++ b/drivers/vfio/pci/Kconfig @@ -16,3 +16,11 @@ config VFIO_PCI_VGA BIOS and generic video drivers. If you don't know what to do here, say N. + +config VFIO_PCI_MMAP + depends on VFIO_PCI + def_bool y if !S390 + +config VFIO_PCI_INTX + depends on VFIO_PCI + def_bool y if !S390 diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index 9558da3f06a0..7cc0122a18ce 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -215,7 +215,7 @@ static int vfio_pci_get_irq_count(struct vfio_pci_device *vdev, int irq_type) if (irq_type == VFIO_PCI_INTX_IRQ_INDEX) { u8 pin; pci_read_config_byte(vdev->pdev, PCI_INTERRUPT_PIN, &pin); - if (pin) + if (IS_ENABLED(CONFIG_VFIO_PCI_INTX) && pin) return 1; } else if (irq_type == VFIO_PCI_MSI_IRQ_INDEX) { @@ -406,7 +406,8 @@ static long vfio_pci_ioctl(void *device_data, info.flags = VFIO_REGION_INFO_FLAG_READ | VFIO_REGION_INFO_FLAG_WRITE; - if (pci_resource_flags(pdev, info.index) & + if (IS_ENABLED(CONFIG_VFIO_PCI_MMAP) && + pci_resource_flags(pdev, info.index) & IORESOURCE_MEM && info.size >= PAGE_SIZE) info.flags |= VFIO_REGION_INFO_FLAG_MMAP; break; @@ -839,13 +840,11 @@ static const struct vfio_device_ops vfio_pci_ops = { static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { - u8 type; struct vfio_pci_device *vdev; struct iommu_group *group; int ret; - pci_read_config_byte(pdev, PCI_HEADER_TYPE, &type); - if ((type & PCI_HEADER_TYPE) != PCI_HEADER_TYPE_NORMAL) + if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL) return -EINVAL; group = iommu_group_get(&pdev->dev); diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c index 1de3f94aa7de..ff75ca31a199 100644 --- a/drivers/vfio/pci/vfio_pci_config.c +++ b/drivers/vfio/pci/vfio_pci_config.c @@ -609,6 +609,10 @@ static int __init init_pci_cap_basic_perm(struct perm_bits *perm) /* Sometimes used by sw, just virtualize */ p_setb(perm, PCI_INTERRUPT_LINE, (u8)ALL_VIRT, (u8)ALL_WRITE); + + /* Virtualize interrupt pin to allow hiding INTx */ + p_setb(perm, PCI_INTERRUPT_PIN, (u8)ALL_VIRT, (u8)NO_WRITE); + return 0; } @@ -1445,6 +1449,9 @@ int vfio_config_init(struct vfio_pci_device *vdev) *(__le16 *)&vconfig[PCI_DEVICE_ID] = cpu_to_le16(pdev->device); } + if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX)) + vconfig[PCI_INTERRUPT_PIN] = 0; + ret = vfio_cap_init(vdev); if (ret) goto out; diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 14419a8ccbb6..d415d69dc237 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -538,7 +538,7 @@ static int get_rx_bufs(struct vhost_virtqueue *vq, ++headcount; seg += in; } - heads[headcount - 1].len = cpu_to_vhost32(vq, len - datalen); + heads[headcount - 1].len = cpu_to_vhost32(vq, len + datalen); *iovcount = seg; if (unlikely(log)) *log_num = nlogs; diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 01c01cb3933f..d695b1673ae5 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -911,6 +911,23 @@ vhost_scsi_map_iov_to_prot(struct tcm_vhost_cmd *cmd, return 0; } +static int vhost_scsi_to_tcm_attr(int attr) +{ + switch (attr) { + case VIRTIO_SCSI_S_SIMPLE: + return TCM_SIMPLE_TAG; + case VIRTIO_SCSI_S_ORDERED: + return TCM_ORDERED_TAG; + case VIRTIO_SCSI_S_HEAD: + return TCM_HEAD_TAG; + case VIRTIO_SCSI_S_ACA: + return TCM_ACA_TAG; + default: + break; + } + return TCM_SIMPLE_TAG; +} + static void tcm_vhost_submission_work(struct work_struct *work) { struct tcm_vhost_cmd *cmd = @@ -936,9 +953,10 @@ static void tcm_vhost_submission_work(struct work_struct *work) rc = target_submit_cmd_map_sgls(se_cmd, tv_nexus->tvn_se_sess, cmd->tvc_cdb, &cmd->tvc_sense_buf[0], cmd->tvc_lun, cmd->tvc_exp_data_len, - cmd->tvc_task_attr, cmd->tvc_data_direction, - TARGET_SCF_ACK_KREF, sg_ptr, cmd->tvc_sgl_count, - NULL, 0, sg_prot_ptr, cmd->tvc_prot_sgl_count); + vhost_scsi_to_tcm_attr(cmd->tvc_task_attr), + cmd->tvc_data_direction, TARGET_SCF_ACK_KREF, + sg_ptr, cmd->tvc_sgl_count, NULL, 0, sg_prot_ptr, + cmd->tvc_prot_sgl_count); if (rc < 0) { transport_send_check_condition_and_sense(se_cmd, TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index ed71b5347a76..cb807d0ea498 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -713,9 +713,13 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp) r = -EFAULT; break; } - if ((a.avail_user_addr & (sizeof *vq->avail->ring - 1)) || - (a.used_user_addr & (sizeof *vq->used->ring - 1)) || - (a.log_guest_addr & (sizeof *vq->used->ring - 1))) { + + /* Make sure it's safe to cast pointers to vring types. */ + BUILD_BUG_ON(__alignof__ *vq->avail > VRING_AVAIL_ALIGN_SIZE); + BUILD_BUG_ON(__alignof__ *vq->used > VRING_USED_ALIGN_SIZE); + if ((a.avail_user_addr & (VRING_AVAIL_ALIGN_SIZE - 1)) || + (a.used_user_addr & (VRING_USED_ALIGN_SIZE - 1)) || + (a.log_guest_addr & (sizeof(u64) - 1))) { r = -EINVAL; break; } diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c index 5174ebac288d..3bb02c60a2f5 100644 --- a/drivers/vhost/vringh.c +++ b/drivers/vhost/vringh.c @@ -11,6 +11,7 @@ #include <linux/uaccess.h> #include <linux/slab.h> #include <linux/export.h> +#include <uapi/linux/virtio_config.h> static __printf(1,2) __cold void vringh_bad(const char *fmt, ...) { @@ -28,13 +29,14 @@ static __printf(1,2) __cold void vringh_bad(const char *fmt, ...) /* Returns vring->num if empty, -ve on error. */ static inline int __vringh_get_head(const struct vringh *vrh, - int (*getu16)(u16 *val, const u16 *p), + int (*getu16)(const struct vringh *vrh, + u16 *val, const __virtio16 *p), u16 *last_avail_idx) { u16 avail_idx, i, head; int err; - err = getu16(&avail_idx, &vrh->vring.avail->idx); + err = getu16(vrh, &avail_idx, &vrh->vring.avail->idx); if (err) { vringh_bad("Failed to access avail idx at %p", &vrh->vring.avail->idx); @@ -49,7 +51,7 @@ static inline int __vringh_get_head(const struct vringh *vrh, i = *last_avail_idx & (vrh->vring.num - 1); - err = getu16(&head, &vrh->vring.avail->ring[i]); + err = getu16(vrh, &head, &vrh->vring.avail->ring[i]); if (err) { vringh_bad("Failed to read head: idx %d address %p", *last_avail_idx, &vrh->vring.avail->ring[i]); @@ -144,28 +146,32 @@ static inline bool no_range_check(struct vringh *vrh, u64 addr, size_t *len, } /* No reason for this code to be inline. */ -static int move_to_indirect(int *up_next, u16 *i, void *addr, +static int move_to_indirect(const struct vringh *vrh, + int *up_next, u16 *i, void *addr, const struct vring_desc *desc, struct vring_desc **descs, int *desc_max) { + u32 len; + /* Indirect tables can't have indirect. */ if (*up_next != -1) { vringh_bad("Multilevel indirect %u->%u", *up_next, *i); return -EINVAL; } - if (unlikely(desc->len % sizeof(struct vring_desc))) { + len = vringh32_to_cpu(vrh, desc->len); + if (unlikely(len % sizeof(struct vring_desc))) { vringh_bad("Strange indirect len %u", desc->len); return -EINVAL; } /* We will check this when we follow it! */ - if (desc->flags & VRING_DESC_F_NEXT) - *up_next = desc->next; + if (desc->flags & cpu_to_vringh16(vrh, VRING_DESC_F_NEXT)) + *up_next = vringh16_to_cpu(vrh, desc->next); else *up_next = -2; *descs = addr; - *desc_max = desc->len / sizeof(struct vring_desc); + *desc_max = len / sizeof(struct vring_desc); /* Now, start at the first indirect. */ *i = 0; @@ -287,22 +293,25 @@ __vringh_iov(struct vringh *vrh, u16 i, if (unlikely(err)) goto fail; - if (unlikely(desc.flags & VRING_DESC_F_INDIRECT)) { + if (unlikely(desc.flags & + cpu_to_vringh16(vrh, VRING_DESC_F_INDIRECT))) { + u64 a = vringh64_to_cpu(vrh, desc.addr); + /* Make sure it's OK, and get offset. */ - len = desc.len; - if (!rcheck(vrh, desc.addr, &len, &range, getrange)) { + len = vringh32_to_cpu(vrh, desc.len); + if (!rcheck(vrh, a, &len, &range, getrange)) { err = -EINVAL; goto fail; } - if (unlikely(len != desc.len)) { + if (unlikely(len != vringh32_to_cpu(vrh, desc.len))) { slow = true; /* We need to save this range to use offset */ slowrange = range; } - addr = (void *)(long)(desc.addr + range.offset); - err = move_to_indirect(&up_next, &i, addr, &desc, + addr = (void *)(long)(a + range.offset); + err = move_to_indirect(vrh, &up_next, &i, addr, &desc, &descs, &desc_max); if (err) goto fail; @@ -315,7 +324,7 @@ __vringh_iov(struct vringh *vrh, u16 i, goto fail; } - if (desc.flags & VRING_DESC_F_WRITE) + if (desc.flags & cpu_to_vringh16(vrh, VRING_DESC_F_WRITE)) iov = wiov; else { iov = riov; @@ -336,12 +345,14 @@ __vringh_iov(struct vringh *vrh, u16 i, again: /* Make sure it's OK, and get offset. */ - len = desc.len; - if (!rcheck(vrh, desc.addr, &len, &range, getrange)) { + len = vringh32_to_cpu(vrh, desc.len); + if (!rcheck(vrh, vringh64_to_cpu(vrh, desc.addr), &len, &range, + getrange)) { err = -EINVAL; goto fail; } - addr = (void *)(unsigned long)(desc.addr + range.offset); + addr = (void *)(unsigned long)(vringh64_to_cpu(vrh, desc.addr) + + range.offset); if (unlikely(iov->used == (iov->max_num & ~VRINGH_IOV_ALLOCATED))) { err = resize_iovec(iov, gfp); @@ -353,14 +364,16 @@ __vringh_iov(struct vringh *vrh, u16 i, iov->iov[iov->used].iov_len = len; iov->used++; - if (unlikely(len != desc.len)) { - desc.len -= len; - desc.addr += len; + if (unlikely(len != vringh32_to_cpu(vrh, desc.len))) { + desc.len = cpu_to_vringh32(vrh, + vringh32_to_cpu(vrh, desc.len) - len); + desc.addr = cpu_to_vringh64(vrh, + vringh64_to_cpu(vrh, desc.addr) + len); goto again; } - if (desc.flags & VRING_DESC_F_NEXT) { - i = desc.next; + if (desc.flags & cpu_to_vringh16(vrh, VRING_DESC_F_NEXT)) { + i = vringh16_to_cpu(vrh, desc.next); } else { /* Just in case we need to finish traversing above. */ if (unlikely(up_next > 0)) { @@ -387,7 +400,8 @@ fail: static inline int __vringh_complete(struct vringh *vrh, const struct vring_used_elem *used, unsigned int num_used, - int (*putu16)(u16 *p, u16 val), + int (*putu16)(const struct vringh *vrh, + __virtio16 *p, u16 val), int (*putused)(struct vring_used_elem *dst, const struct vring_used_elem *src, unsigned num)) @@ -420,7 +434,7 @@ static inline int __vringh_complete(struct vringh *vrh, /* Make sure buffer is written before we update index. */ virtio_wmb(vrh->weak_barriers); - err = putu16(&vrh->vring.used->idx, used_idx + num_used); + err = putu16(vrh, &vrh->vring.used->idx, used_idx + num_used); if (err) { vringh_bad("Failed to update used index at %p", &vrh->vring.used->idx); @@ -433,7 +447,9 @@ static inline int __vringh_complete(struct vringh *vrh, static inline int __vringh_need_notify(struct vringh *vrh, - int (*getu16)(u16 *val, const u16 *p)) + int (*getu16)(const struct vringh *vrh, + u16 *val, + const __virtio16 *p)) { bool notify; u16 used_event; @@ -447,7 +463,7 @@ static inline int __vringh_need_notify(struct vringh *vrh, /* Old-style, without event indices. */ if (!vrh->event_indices) { u16 flags; - err = getu16(&flags, &vrh->vring.avail->flags); + err = getu16(vrh, &flags, &vrh->vring.avail->flags); if (err) { vringh_bad("Failed to get flags at %p", &vrh->vring.avail->flags); @@ -457,7 +473,7 @@ static inline int __vringh_need_notify(struct vringh *vrh, } /* Modern: we know when other side wants to know. */ - err = getu16(&used_event, &vring_used_event(&vrh->vring)); + err = getu16(vrh, &used_event, &vring_used_event(&vrh->vring)); if (err) { vringh_bad("Failed to get used event idx at %p", &vring_used_event(&vrh->vring)); @@ -478,20 +494,22 @@ static inline int __vringh_need_notify(struct vringh *vrh, } static inline bool __vringh_notify_enable(struct vringh *vrh, - int (*getu16)(u16 *val, const u16 *p), - int (*putu16)(u16 *p, u16 val)) + int (*getu16)(const struct vringh *vrh, + u16 *val, const __virtio16 *p), + int (*putu16)(const struct vringh *vrh, + __virtio16 *p, u16 val)) { u16 avail; if (!vrh->event_indices) { /* Old-school; update flags. */ - if (putu16(&vrh->vring.used->flags, 0) != 0) { + if (putu16(vrh, &vrh->vring.used->flags, 0) != 0) { vringh_bad("Clearing used flags %p", &vrh->vring.used->flags); return true; } } else { - if (putu16(&vring_avail_event(&vrh->vring), + if (putu16(vrh, &vring_avail_event(&vrh->vring), vrh->last_avail_idx) != 0) { vringh_bad("Updating avail event index %p", &vring_avail_event(&vrh->vring)); @@ -503,7 +521,7 @@ static inline bool __vringh_notify_enable(struct vringh *vrh, * sure it's written, then check again. */ virtio_mb(vrh->weak_barriers); - if (getu16(&avail, &vrh->vring.avail->idx) != 0) { + if (getu16(vrh, &avail, &vrh->vring.avail->idx) != 0) { vringh_bad("Failed to check avail idx at %p", &vrh->vring.avail->idx); return true; @@ -516,11 +534,13 @@ static inline bool __vringh_notify_enable(struct vringh *vrh, } static inline void __vringh_notify_disable(struct vringh *vrh, - int (*putu16)(u16 *p, u16 val)) + int (*putu16)(const struct vringh *vrh, + __virtio16 *p, u16 val)) { if (!vrh->event_indices) { /* Old-school; update flags. */ - if (putu16(&vrh->vring.used->flags, VRING_USED_F_NO_NOTIFY)) { + if (putu16(vrh, &vrh->vring.used->flags, + VRING_USED_F_NO_NOTIFY)) { vringh_bad("Setting used flags %p", &vrh->vring.used->flags); } @@ -528,14 +548,18 @@ static inline void __vringh_notify_disable(struct vringh *vrh, } /* Userspace access helpers: in this case, addresses are really userspace. */ -static inline int getu16_user(u16 *val, const u16 *p) +static inline int getu16_user(const struct vringh *vrh, u16 *val, const __virtio16 *p) { - return get_user(*val, (__force u16 __user *)p); + __virtio16 v = 0; + int rc = get_user(v, (__force __virtio16 __user *)p); + *val = vringh16_to_cpu(vrh, v); + return rc; } -static inline int putu16_user(u16 *p, u16 val) +static inline int putu16_user(const struct vringh *vrh, __virtio16 *p, u16 val) { - return put_user(val, (__force u16 __user *)p); + __virtio16 v = cpu_to_vringh16(vrh, val); + return put_user(v, (__force __virtio16 __user *)p); } static inline int copydesc_user(void *dst, const void *src, size_t len) @@ -577,7 +601,7 @@ static inline int xfer_to_user(void *dst, void *src, size_t len) * Returns an error if num is invalid: you should check pointers * yourself! */ -int vringh_init_user(struct vringh *vrh, u32 features, +int vringh_init_user(struct vringh *vrh, u64 features, unsigned int num, bool weak_barriers, struct vring_desc __user *desc, struct vring_avail __user *avail, @@ -589,6 +613,7 @@ int vringh_init_user(struct vringh *vrh, u32 features, return -EINVAL; } + vrh->little_endian = (features & (1ULL << VIRTIO_F_VERSION_1)); vrh->event_indices = (features & (1 << VIRTIO_RING_F_EVENT_IDX)); vrh->weak_barriers = weak_barriers; vrh->completed = 0; @@ -729,8 +754,8 @@ int vringh_complete_user(struct vringh *vrh, u16 head, u32 len) { struct vring_used_elem used; - used.id = head; - used.len = len; + used.id = cpu_to_vringh32(vrh, head); + used.len = cpu_to_vringh32(vrh, len); return __vringh_complete(vrh, &used, 1, putu16_user, putused_user); } EXPORT_SYMBOL(vringh_complete_user); @@ -792,15 +817,16 @@ int vringh_need_notify_user(struct vringh *vrh) EXPORT_SYMBOL(vringh_need_notify_user); /* Kernelspace access helpers. */ -static inline int getu16_kern(u16 *val, const u16 *p) +static inline int getu16_kern(const struct vringh *vrh, + u16 *val, const __virtio16 *p) { - *val = ACCESS_ONCE(*p); + *val = vringh16_to_cpu(vrh, ACCESS_ONCE(*p)); return 0; } -static inline int putu16_kern(u16 *p, u16 val) +static inline int putu16_kern(const struct vringh *vrh, __virtio16 *p, u16 val) { - ACCESS_ONCE(*p) = val; + ACCESS_ONCE(*p) = cpu_to_vringh16(vrh, val); return 0; } @@ -836,7 +862,7 @@ static inline int xfer_kern(void *src, void *dst, size_t len) * * Returns an error if num is invalid. */ -int vringh_init_kern(struct vringh *vrh, u32 features, +int vringh_init_kern(struct vringh *vrh, u64 features, unsigned int num, bool weak_barriers, struct vring_desc *desc, struct vring_avail *avail, @@ -848,6 +874,7 @@ int vringh_init_kern(struct vringh *vrh, u32 features, return -EINVAL; } + vrh->little_endian = (features & (1ULL << VIRTIO_F_VERSION_1)); vrh->event_indices = (features & (1 << VIRTIO_RING_F_EVENT_IDX)); vrh->weak_barriers = weak_barriers; vrh->completed = 0; @@ -962,8 +989,8 @@ int vringh_complete_kern(struct vringh *vrh, u16 head, u32 len) { struct vring_used_elem used; - used.id = head; - used.len = len; + used.id = cpu_to_vringh32(vrh, head); + used.len = cpu_to_vringh32(vrh, len); return __vringh_complete(vrh, &used, 1, putu16_kern, putused_kern); } diff --git a/drivers/video/fbdev/broadsheetfb.c b/drivers/video/fbdev/broadsheetfb.c index 1c29bd19e3d5..0e5fde1d3ffb 100644 --- a/drivers/video/fbdev/broadsheetfb.c +++ b/drivers/video/fbdev/broadsheetfb.c @@ -636,7 +636,7 @@ static int broadsheet_spiflash_rewrite_sector(struct broadsheetfb_par *par, err = broadsheet_spiflash_read_range(par, start_sector_addr, data_start_addr, sector_buffer); if (err) - return err; + goto out; } /* now we copy our data into the right place in the sector buffer */ @@ -657,7 +657,7 @@ static int broadsheet_spiflash_rewrite_sector(struct broadsheetfb_par *par, err = broadsheet_spiflash_read_range(par, tail_start_addr, tail_len, sector_buffer + tail_start_addr); if (err) - return err; + goto out; } /* if we got here we have the full sector that we want to rewrite. */ @@ -665,11 +665,13 @@ static int broadsheet_spiflash_rewrite_sector(struct broadsheetfb_par *par, /* first erase the sector */ err = broadsheet_spiflash_erase_sector(par, start_sector_addr); if (err) - return err; + goto out; /* now write it */ err = broadsheet_spiflash_write_sector(par, start_sector_addr, sector_buffer, sector_size); +out: + kfree(sector_buffer); return err; } diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c index 900aa4ecd617..d6cab1fd9a47 100644 --- a/drivers/video/fbdev/core/fb_defio.c +++ b/drivers/video/fbdev/core/fb_defio.c @@ -83,9 +83,10 @@ int fb_deferred_io_fsync(struct file *file, loff_t start, loff_t end, int datasy cancel_delayed_work_sync(&info->deferred_work); /* Run it immediately */ - err = schedule_delayed_work(&info->deferred_work, 0); + schedule_delayed_work(&info->deferred_work, 0); mutex_unlock(&inode->i_mutex); - return err; + + return 0; } EXPORT_SYMBOL_GPL(fb_deferred_io_fsync); diff --git a/drivers/video/fbdev/omap2/dss/hdmi_pll.c b/drivers/video/fbdev/omap2/dss/hdmi_pll.c index 87accdb59c81..ac83ef5cfd7d 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi_pll.c +++ b/drivers/video/fbdev/omap2/dss/hdmi_pll.c @@ -132,7 +132,6 @@ static const struct dss_pll_hw dss_omap4_hdmi_pll_hw = { .mX_max = 127, .fint_min = 500000, .fint_max = 2500000, - .clkdco_max = 1800000000, .clkdco_min = 500000000, .clkdco_low = 1000000000, @@ -156,7 +155,6 @@ static const struct dss_pll_hw dss_omap5_hdmi_pll_hw = { .mX_max = 127, .fint_min = 620000, .fint_max = 2500000, - .clkdco_max = 1800000000, .clkdco_min = 750000000, .clkdco_low = 1500000000, diff --git a/drivers/video/fbdev/omap2/dss/pll.c b/drivers/video/fbdev/omap2/dss/pll.c index 50bc62c5d367..335ffac224b9 100644 --- a/drivers/video/fbdev/omap2/dss/pll.c +++ b/drivers/video/fbdev/omap2/dss/pll.c @@ -97,7 +97,8 @@ int dss_pll_enable(struct dss_pll *pll) return 0; err_enable: - regulator_disable(pll->regulator); + if (pll->regulator) + regulator_disable(pll->regulator); err_reg: clk_disable_unprepare(pll->clkin); return r; diff --git a/drivers/video/fbdev/omap2/dss/sdi.c b/drivers/video/fbdev/omap2/dss/sdi.c index d51a983075bc..5c2ccab5a958 100644 --- a/drivers/video/fbdev/omap2/dss/sdi.c +++ b/drivers/video/fbdev/omap2/dss/sdi.c @@ -342,6 +342,8 @@ static void sdi_init_output(struct platform_device *pdev) out->output_type = OMAP_DISPLAY_TYPE_SDI; out->name = "sdi.0"; out->dispc_channel = OMAP_DSS_CHANNEL_LCD; + /* We have SDI only on OMAP3, where it's on port 1 */ + out->port_num = 1; out->ops.sdi = &sdi_ops; out->owner = THIS_MODULE; diff --git a/drivers/video/fbdev/s3c-fb.c b/drivers/video/fbdev/s3c-fb.c index a623a4d0c94f..7e3a05fc47aa 100644 --- a/drivers/video/fbdev/s3c-fb.c +++ b/drivers/video/fbdev/s3c-fb.c @@ -1630,7 +1630,7 @@ static int s3c_fb_resume(struct device *dev) } #endif -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM static int s3c_fb_runtime_suspend(struct device *dev) { struct s3c_fb *sfb = dev_get_drvdata(dev); diff --git a/drivers/video/fbdev/sh_mobile_meram.c b/drivers/video/fbdev/sh_mobile_meram.c index 1d56108dee9c..baadfb207b2e 100644 --- a/drivers/video/fbdev/sh_mobile_meram.c +++ b/drivers/video/fbdev/sh_mobile_meram.c @@ -569,7 +569,7 @@ EXPORT_SYMBOL_GPL(sh_mobile_meram_cache_update); * Power management */ -#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM_RUNTIME) +#ifdef CONFIG_PM static int sh_mobile_meram_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); @@ -612,7 +612,7 @@ static int sh_mobile_meram_resume(struct device *dev) meram_write_reg(priv->base, common_regs[i], priv->regs[i]); return 0; } -#endif /* CONFIG_PM_SLEEP || CONFIG_PM_RUNTIME */ +#endif /* CONFIG_PM */ static UNIVERSAL_DEV_PM_OPS(sh_mobile_meram_dev_pm_ops, sh_mobile_meram_suspend, diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c index 92cac803dee3..1085c0432158 100644 --- a/drivers/video/fbdev/simplefb.c +++ b/drivers/video/fbdev/simplefb.c @@ -402,7 +402,7 @@ static int __init simplefb_init(void) if (ret) return ret; - if (IS_ENABLED(CONFIG_OF) && of_chosen) { + if (IS_ENABLED(CONFIG_OF_ADDRESS) && of_chosen) { for_each_child_of_node(of_chosen, np) { if (of_device_is_compatible(np, "simple-framebuffer")) of_platform_device_create(np, NULL, NULL); diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c index 940cd196eef5..10fbfd8ab963 100644 --- a/drivers/video/logo/logo.c +++ b/drivers/video/logo/logo.c @@ -21,6 +21,21 @@ static bool nologo; module_param(nologo, bool, 0); MODULE_PARM_DESC(nologo, "Disables startup logo"); +/* + * Logos are located in the initdata, and will be freed in kernel_init. + * Use late_init to mark the logos as freed to prevent any further use. + */ + +static bool logos_freed; + +static int __init fb_logo_late_init(void) +{ + logos_freed = true; + return 0; +} + +late_initcall(fb_logo_late_init); + /* logo's are marked __initdata. Use __init_refok to tell * modpost that it is intended that this function uses data * marked __initdata. @@ -29,7 +44,7 @@ const struct linux_logo * __init_refok fb_find_logo(int depth) { const struct linux_logo *logo = NULL; - if (nologo) + if (nologo || logos_freed) return NULL; if (depth >= 1) { diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index f22665868781..b9f70dfc4751 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c @@ -162,6 +162,27 @@ static void virtio_config_enable(struct virtio_device *dev) spin_unlock_irq(&dev->config_lock); } +static int virtio_finalize_features(struct virtio_device *dev) +{ + int ret = dev->config->finalize_features(dev); + unsigned status; + + if (ret) + return ret; + + if (!virtio_has_feature(dev, VIRTIO_F_VERSION_1)) + return 0; + + add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK); + status = dev->config->get_status(dev); + if (!(status & VIRTIO_CONFIG_S_FEATURES_OK)) { + dev_err(&dev->dev, "virtio: device refuses features: %x\n", + status); + return -ENODEV; + } + return 0; +} + static int virtio_dev_probe(struct device *_d) { int err, i; @@ -170,7 +191,6 @@ static int virtio_dev_probe(struct device *_d) u64 device_features; u64 driver_features; u64 driver_features_legacy; - unsigned status; /* We have a driver! */ add_status(dev, VIRTIO_CONFIG_S_DRIVER); @@ -208,21 +228,10 @@ static int virtio_dev_probe(struct device *_d) if (device_features & (1ULL << i)) __virtio_set_bit(dev, i); - err = dev->config->finalize_features(dev); + err = virtio_finalize_features(dev); if (err) goto err; - if (virtio_has_feature(dev, VIRTIO_F_VERSION_1)) { - add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK); - status = dev->config->get_status(dev); - if (!(status & VIRTIO_CONFIG_S_FEATURES_OK)) { - dev_err(_d, "virtio: device refuses features: %x\n", - status); - err = -ENODEV; - goto err; - } - } - err = drv->probe(dev); if (err) goto err; @@ -372,7 +381,7 @@ int virtio_device_restore(struct virtio_device *dev) /* We have a driver! */ add_status(dev, VIRTIO_CONFIG_S_DRIVER); - ret = dev->config->finalize_features(dev); + ret = virtio_finalize_features(dev); if (ret) goto err; diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index c9703d4d6f67..50c5f42d7a9f 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -28,6 +28,7 @@ #include <linux/slab.h> #include <linux/module.h> #include <linux/balloon_compaction.h> +#include <linux/oom.h> /* * Balloon device works in 4K page units. So each page is pointed to by @@ -36,6 +37,12 @@ */ #define VIRTIO_BALLOON_PAGES_PER_PAGE (unsigned)(PAGE_SIZE >> VIRTIO_BALLOON_PFN_SHIFT) #define VIRTIO_BALLOON_ARRAY_PFNS_MAX 256 +#define OOM_VBALLOON_DEFAULT_PAGES 256 +#define VIRTBALLOON_OOM_NOTIFY_PRIORITY 80 + +static int oom_pages = OOM_VBALLOON_DEFAULT_PAGES; +module_param(oom_pages, int, S_IRUSR | S_IWUSR); +MODULE_PARM_DESC(oom_pages, "pages to free on OOM"); struct virtio_balloon { @@ -71,6 +78,9 @@ struct virtio_balloon /* Memory statistics */ int need_stats_update; struct virtio_balloon_stat stats[VIRTIO_BALLOON_S_NR]; + + /* To register callback in oom notifier call chain */ + struct notifier_block nb; }; static struct virtio_device_id id_table[] = { @@ -168,8 +178,9 @@ static void release_pages_by_pfn(const u32 pfns[], unsigned int num) } } -static void leak_balloon(struct virtio_balloon *vb, size_t num) +static unsigned leak_balloon(struct virtio_balloon *vb, size_t num) { + unsigned num_freed_pages; struct page *page; struct balloon_dev_info *vb_dev_info = &vb->vb_dev_info; @@ -186,6 +197,7 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num) vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE; } + num_freed_pages = vb->num_pfns; /* * Note that if * virtio_has_feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST); @@ -195,6 +207,7 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num) tell_host(vb, vb->deflate_vq); mutex_unlock(&vb->balloon_lock); release_pages_by_pfn(vb->pfns, vb->num_pfns); + return num_freed_pages; } static inline void update_stat(struct virtio_balloon *vb, int idx, @@ -287,6 +300,38 @@ static void update_balloon_size(struct virtio_balloon *vb) &actual); } +/* + * virtballoon_oom_notify - release pages when system is under severe + * memory pressure (called from out_of_memory()) + * @self : notifier block struct + * @dummy: not used + * @parm : returned - number of freed pages + * + * The balancing of memory by use of the virtio balloon should not cause + * the termination of processes while there are pages in the balloon. + * If virtio balloon manages to release some memory, it will make the + * system return and retry the allocation that forced the OOM killer + * to run. + */ +static int virtballoon_oom_notify(struct notifier_block *self, + unsigned long dummy, void *parm) +{ + struct virtio_balloon *vb; + unsigned long *freed; + unsigned num_freed_pages; + + vb = container_of(self, struct virtio_balloon, nb); + if (!virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_DEFLATE_ON_OOM)) + return NOTIFY_OK; + + freed = parm; + num_freed_pages = leak_balloon(vb, oom_pages); + update_balloon_size(vb); + *freed += num_freed_pages; + + return NOTIFY_OK; +} + static int balloon(void *_vballoon) { struct virtio_balloon *vb = _vballoon; @@ -443,6 +488,12 @@ static int virtballoon_probe(struct virtio_device *vdev) if (err) goto out_free_vb; + vb->nb.notifier_call = virtballoon_oom_notify; + vb->nb.priority = VIRTBALLOON_OOM_NOTIFY_PRIORITY; + err = register_oom_notifier(&vb->nb); + if (err < 0) + goto out_oom_notify; + vb->thread = kthread_run(balloon, vb, "vballoon"); if (IS_ERR(vb->thread)) { err = PTR_ERR(vb->thread); @@ -452,6 +503,8 @@ static int virtballoon_probe(struct virtio_device *vdev) return 0; out_del_vqs: + unregister_oom_notifier(&vb->nb); +out_oom_notify: vdev->config->del_vqs(vdev); out_free_vb: kfree(vb); @@ -476,6 +529,7 @@ static void virtballoon_remove(struct virtio_device *vdev) { struct virtio_balloon *vb = vdev->priv; + unregister_oom_notifier(&vb->nb); kthread_stop(vb->thread); remove_common(vb); kfree(vb); @@ -515,6 +569,7 @@ static int virtballoon_restore(struct virtio_device *vdev) static unsigned int features[] = { VIRTIO_BALLOON_F_MUST_TELL_HOST, VIRTIO_BALLOON_F_STATS_VQ, + VIRTIO_BALLOON_F_DEFLATE_ON_OOM, }; static struct virtio_driver virtio_balloon_driver = { diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c index 953057d84185..9756f21b809e 100644 --- a/drivers/virtio/virtio_pci_common.c +++ b/drivers/virtio/virtio_pci_common.c @@ -282,6 +282,7 @@ void vp_del_vqs(struct virtio_device *vdev) vp_free_vectors(vdev); kfree(vp_dev->vqs); + vp_dev->vqs = NULL; } static int vp_try_to_find_vqs(struct virtio_device *vdev, unsigned nvqs, @@ -421,15 +422,6 @@ int vp_set_vq_affinity(struct virtqueue *vq, int cpu) return 0; } -void virtio_pci_release_dev(struct device *_d) -{ - /* - * No need for a release method as we allocate/free - * all devices together with the pci devices. - * Provide an empty one to avoid getting a warning from core. - */ -} - #ifdef CONFIG_PM_SLEEP static int virtio_pci_freeze(struct device *dev) { @@ -458,7 +450,44 @@ static int virtio_pci_restore(struct device *dev) return virtio_device_restore(&vp_dev->vdev); } -const struct dev_pm_ops virtio_pci_pm_ops = { +static const struct dev_pm_ops virtio_pci_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(virtio_pci_freeze, virtio_pci_restore) }; #endif + + +/* Qumranet donated their vendor ID for devices 0x1000 thru 0x10FF. */ +static const struct pci_device_id virtio_pci_id_table[] = { + { PCI_DEVICE(0x1af4, PCI_ANY_ID) }, + { 0 } +}; + +MODULE_DEVICE_TABLE(pci, virtio_pci_id_table); + +static int virtio_pci_probe(struct pci_dev *pci_dev, + const struct pci_device_id *id) +{ + return virtio_pci_legacy_probe(pci_dev, id); +} + +static void virtio_pci_remove(struct pci_dev *pci_dev) +{ + virtio_pci_legacy_remove(pci_dev); +} + +static struct pci_driver virtio_pci_driver = { + .name = "virtio-pci", + .id_table = virtio_pci_id_table, + .probe = virtio_pci_probe, + .remove = virtio_pci_remove, +#ifdef CONFIG_PM_SLEEP + .driver.pm = &virtio_pci_pm_ops, +#endif +}; + +module_pci_driver(virtio_pci_driver); + +MODULE_AUTHOR("Anthony Liguori <aliguori@us.ibm.com>"); +MODULE_DESCRIPTION("virtio-pci"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("1"); diff --git a/drivers/virtio/virtio_pci_common.h b/drivers/virtio/virtio_pci_common.h index d840dad4149d..5a497289b7e9 100644 --- a/drivers/virtio/virtio_pci_common.h +++ b/drivers/virtio/virtio_pci_common.h @@ -27,7 +27,6 @@ #include <linux/virtio.h> #include <linux/virtio_config.h> #include <linux/virtio_ring.h> -#define VIRTIO_PCI_NO_LEGACY #include <linux/virtio_pci.h> #include <linux/highmem.h> #include <linux/spinlock.h> @@ -127,10 +126,9 @@ const char *vp_bus_name(struct virtio_device *vdev); * - ignore the affinity request if we're using INTX */ int vp_set_vq_affinity(struct virtqueue *vq, int cpu); -void virtio_pci_release_dev(struct device *); -#ifdef CONFIG_PM_SLEEP -extern const struct dev_pm_ops virtio_pci_pm_ops; -#endif +int virtio_pci_legacy_probe(struct pci_dev *pci_dev, + const struct pci_device_id *id); +void virtio_pci_legacy_remove(struct pci_dev *pci_dev); #endif diff --git a/drivers/virtio/virtio_pci_legacy.c b/drivers/virtio/virtio_pci_legacy.c index 2588252e5c1c..a5486e65e04b 100644 --- a/drivers/virtio/virtio_pci_legacy.c +++ b/drivers/virtio/virtio_pci_legacy.c @@ -19,14 +19,6 @@ #include "virtio_pci_common.h" -/* Qumranet donated their vendor ID for devices 0x1000 thru 0x10FF. */ -static const struct pci_device_id virtio_pci_id_table[] = { - { PCI_DEVICE(0x1af4, PCI_ANY_ID) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, virtio_pci_id_table); - /* virtio config->get_features() implementation */ static u64 vp_get_features(struct virtio_device *vdev) { @@ -219,8 +211,19 @@ static const struct virtio_config_ops virtio_pci_config_ops = { .set_vq_affinity = vp_set_vq_affinity, }; +static void virtio_pci_release_dev(struct device *_d) +{ + struct virtio_device *vdev = dev_to_virtio(_d); + struct virtio_pci_device *vp_dev = to_vp_device(vdev); + + /* As struct device is a kobject, it's not safe to + * free the memory (including the reference counter itself) + * until it's release callback. */ + kfree(vp_dev); +} + /* the PCI probing function */ -static int virtio_pci_probe(struct pci_dev *pci_dev, +int virtio_pci_legacy_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) { struct virtio_pci_device *vp_dev; @@ -300,7 +303,7 @@ out: return err; } -static void virtio_pci_remove(struct pci_dev *pci_dev) +void virtio_pci_legacy_remove(struct pci_dev *pci_dev) { struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); @@ -310,17 +313,4 @@ static void virtio_pci_remove(struct pci_dev *pci_dev) pci_iounmap(pci_dev, vp_dev->ioaddr); pci_release_regions(pci_dev); pci_disable_device(pci_dev); - kfree(vp_dev); } - -static struct pci_driver virtio_pci_driver = { - .name = "virtio-pci", - .id_table = virtio_pci_id_table, - .probe = virtio_pci_probe, - .remove = virtio_pci_remove, -#ifdef CONFIG_PM_SLEEP - .driver.pm = &virtio_pci_pm_ops, -#endif -}; - -module_pci_driver(virtio_pci_driver); diff --git a/drivers/watchdog/cadence_wdt.c b/drivers/watchdog/cadence_wdt.c index 5927c0a98a74..bcfd2a22208f 100644 --- a/drivers/watchdog/cadence_wdt.c +++ b/drivers/watchdog/cadence_wdt.c @@ -503,7 +503,6 @@ static struct platform_driver cdns_wdt_driver = { .shutdown = cdns_wdt_shutdown, .driver = { .name = "cdns-wdt", - .owner = THIS_MODULE, .of_match_table = cdns_wdt_of_match, .pm = &cdns_wdt_pm_ops, }, diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index 65b84d8c0b93..5142bbabe027 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c @@ -52,6 +52,8 @@ #define IMX2_WDT_WRSR 0x04 /* Reset Status Register */ #define IMX2_WDT_WRSR_TOUT (1 << 1) /* -> Reset due to Timeout */ +#define IMX2_WDT_WMCR 0x08 /* Misc Register */ + #define IMX2_WDT_MAX_TIME 128 #define IMX2_WDT_DEFAULT_TIME 60 /* in seconds */ @@ -274,6 +276,13 @@ static int __init imx2_wdt_probe(struct platform_device *pdev) imx2_wdt_ping_if_active(wdog); + /* + * Disable the watchdog power down counter at boot. Otherwise the power + * down counter will pull down the #WDOG interrupt line for one clock + * cycle. + */ + regmap_write(wdev->regmap, IMX2_WDT_WMCR, 0); + ret = watchdog_register_device(wdog); if (ret) { dev_err(&pdev->dev, "cannot register watchdog device\n"); @@ -326,6 +335,65 @@ static void imx2_wdt_shutdown(struct platform_device *pdev) } } +#ifdef CONFIG_PM_SLEEP +/* Disable watchdog if it is active or non-active but still running */ +static int imx2_wdt_suspend(struct device *dev) +{ + struct watchdog_device *wdog = dev_get_drvdata(dev); + struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog); + + /* The watchdog IP block is running */ + if (imx2_wdt_is_running(wdev)) { + imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME); + imx2_wdt_ping(wdog); + + /* The watchdog is not active */ + if (!watchdog_active(wdog)) + del_timer_sync(&wdev->timer); + } + + clk_disable_unprepare(wdev->clk); + + return 0; +} + +/* Enable watchdog and configure it if necessary */ +static int imx2_wdt_resume(struct device *dev) +{ + struct watchdog_device *wdog = dev_get_drvdata(dev); + struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog); + + clk_prepare_enable(wdev->clk); + + if (watchdog_active(wdog) && !imx2_wdt_is_running(wdev)) { + /* + * If the watchdog is still active and resumes + * from deep sleep state, need to restart the + * watchdog again. + */ + imx2_wdt_setup(wdog); + imx2_wdt_set_timeout(wdog, wdog->timeout); + imx2_wdt_ping(wdog); + } else if (imx2_wdt_is_running(wdev)) { + /* Resuming from non-deep sleep state. */ + imx2_wdt_set_timeout(wdog, wdog->timeout); + imx2_wdt_ping(wdog); + /* + * But the watchdog is not active, then start + * the timer again. + */ + if (!watchdog_active(wdog)) + mod_timer(&wdev->timer, + jiffies + wdog->timeout * HZ / 2); + } + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(imx2_wdt_pm_ops, imx2_wdt_suspend, + imx2_wdt_resume); + static const struct of_device_id imx2_wdt_dt_ids[] = { { .compatible = "fsl,imx21-wdt", }, { /* sentinel */ } @@ -337,6 +405,7 @@ static struct platform_driver imx2_wdt_driver = { .shutdown = imx2_wdt_shutdown, .driver = { .name = DRIVER_NAME, + .pm = &imx2_wdt_pm_ops, .of_match_table = imx2_wdt_dt_ids, }, }; diff --git a/drivers/watchdog/meson_wdt.c b/drivers/watchdog/meson_wdt.c index ef6a298e8c45..1f4155ee3404 100644 --- a/drivers/watchdog/meson_wdt.c +++ b/drivers/watchdog/meson_wdt.c @@ -215,7 +215,6 @@ static struct platform_driver meson_wdt_driver = { .remove = meson_wdt_remove, .shutdown = meson_wdt_shutdown, .driver = { - .owner = THIS_MODULE, .name = DRV_NAME, .of_match_table = meson_wdt_dt_ids, }, diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c index 50610a6acf3d..e999496eda3e 100644 --- a/drivers/xen/xen-scsiback.c +++ b/drivers/xen/xen-scsiback.c @@ -606,7 +606,7 @@ static void scsiback_device_action(struct vscsibk_pend *pending_req, init_waitqueue_head(&tmr->tmr_wait); transport_init_se_cmd(se_cmd, tpg->se_tpg.se_tpg_tfo, - tpg->tpg_nexus->tvn_se_sess, 0, DMA_NONE, MSG_SIMPLE_TAG, + tpg->tpg_nexus->tvn_se_sess, 0, DMA_NONE, TCM_SIMPLE_TAG, &pending_req->sense_buffer[0]); rc = core_tmr_alloc_req(se_cmd, tmr, act, GFP_KERNEL); |